mirror of
https://github.com/Theaninova/TheaninovOS.git
synced 2026-01-22 17:42:43 +00:00
update ags
This commit is contained in:
8
desktops/hyprland/ags/.idea/prettier.xml
generated
Normal file
8
desktops/hyprland/ags/.idea/prettier.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||
<option name="myRunOnSave" value="true" />
|
||||
<option name="myFilesPattern" value="{**/*,*}.{js,ts,jsx,tsx,vue,astro,md,json}" />
|
||||
</component>
|
||||
</project>
|
||||
8
desktops/hyprland/ags/README.md
Normal file
8
desktops/hyprland/ags/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Setup
|
||||
|
||||
To generate type definitions
|
||||
|
||||
```shell
|
||||
nix-shell
|
||||
./setup.sh $PWD
|
||||
```
|
||||
@@ -1,53 +1,42 @@
|
||||
// Import
|
||||
import { App, Utils } from './imports.js';
|
||||
// Windows
|
||||
import Bar from './windows/bar.js';
|
||||
import Cheatsheet from './windows/cheatsheet.js';
|
||||
import { CornerTopleft, CornerTopright, CornerBottomleft, CornerBottomright } from './windows/corners.js';
|
||||
import Indicator from './windows/osd.js';
|
||||
import Osk from './windows/osk.js';
|
||||
import Overview from './windows/overview.js';
|
||||
import Session from './windows/session.js';
|
||||
import SideLeft from './windows/sideleft.js';
|
||||
import SideRight from './windows/sideright.js';
|
||||
import App from "resource:///com/github/Aylur/ags/app.js"
|
||||
import Bar from "./windows/bar.js"
|
||||
import Corner from "./windows/corners.js"
|
||||
import Overview from "./windows/overview.js"
|
||||
|
||||
const CLOSE_ANIM_TIME = 150;
|
||||
const CLOSE_ANIM_TIME = 150
|
||||
|
||||
// Init
|
||||
Utils.exec(`bash -c 'mkdir -p ~/.cache/ags/user'`);
|
||||
// SCSS compilation
|
||||
Utils.exec(`sassc ${App.configDir}/scss/main.scss ${App.configDir}/style.css`);
|
||||
App.resetCss();
|
||||
App.applyCss(`${App.configDir}/style.css`);
|
||||
Utils.exec(`bash -c 'mkdir -p ~/.cache/ags/user'`)
|
||||
Utils.exec(`sassc ${App.configDir}/scss/main.scss ${App.configDir}/style.css`)
|
||||
App.resetCss()
|
||||
App.applyCss(`${App.configDir}/style.css`)
|
||||
|
||||
// Config object
|
||||
export default {
|
||||
style: `${App.configDir}/style.css`,
|
||||
stackTraceOnError: true,
|
||||
closeWindowDelay: {
|
||||
// For animations
|
||||
'sideright': CLOSE_ANIM_TIME,
|
||||
'sideleft': CLOSE_ANIM_TIME,
|
||||
'osk': CLOSE_ANIM_TIME,
|
||||
// No anims, but allow menu service update
|
||||
'session': 1,
|
||||
'overview': 1,
|
||||
'cheatsheet': 1,
|
||||
},
|
||||
windows: [
|
||||
Bar(),
|
||||
...Array.from({length: 3}, (_, i) => [
|
||||
CornerTopleft(i),
|
||||
CornerTopright(i),
|
||||
CornerBottomleft(i),
|
||||
CornerBottomright(i),
|
||||
]),
|
||||
Overview(),
|
||||
Indicator(),
|
||||
Cheatsheet(),
|
||||
SideRight(),
|
||||
SideLeft(),
|
||||
Osk(), // On-screen keyboard
|
||||
Session(),
|
||||
],
|
||||
};
|
||||
/** @type {Partial<(typeof import('resource:///com/github/Aylur/ags/app.js').default)['config']>} */
|
||||
const config = {
|
||||
style: `${App.configDir}/style.css`,
|
||||
closeWindowDelay: {
|
||||
sideright: CLOSE_ANIM_TIME,
|
||||
sideleft: CLOSE_ANIM_TIME,
|
||||
osk: CLOSE_ANIM_TIME,
|
||||
session: 1,
|
||||
overview: 1,
|
||||
cheatsheet: 1,
|
||||
},
|
||||
windows: [
|
||||
Bar(),
|
||||
...Array.from({length: 3}, (_, i) => [
|
||||
Corner("top", "left", i),
|
||||
Corner("top", "right", i),
|
||||
Corner("bottom", "left", i),
|
||||
Corner("bottom", "right", i),
|
||||
]),
|
||||
Overview(),
|
||||
// Indicator(),
|
||||
// Cheatsheet(),
|
||||
// SideRight(),
|
||||
// SideLeft(),
|
||||
// Osk(), // On-screen keyboard
|
||||
// Session(),
|
||||
],
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
@@ -1,82 +1,83 @@
|
||||
export const keybindList = [[
|
||||
export const keybindList = [
|
||||
[
|
||||
{
|
||||
"icon": "pin_drop",
|
||||
"name": "Workspaces: navigation",
|
||||
"binds": [
|
||||
{ "keys": ["", "+", "#"], "action": "Go to workspace #" },
|
||||
{ "keys": ["", "+", "S"], "action": "Toggle special workspace" },
|
||||
{ "keys": ["", "+", "(Scroll ↑↓)"], "action": "Go to workspace -1/+1" },
|
||||
{ "keys": ["Ctrl", "", "+", "←"], "action": "Go to workspace on the left" },
|
||||
{ "keys": ["Ctrl", "", "+", "→"], "action": "Go to workspace on the right" },
|
||||
{ "keys": ["", "+", "PageUp"], "action": "Go to workspace on the left" },
|
||||
{ "keys": ["", "+", "PageDown"], "action": "Go to workspace on the right" }
|
||||
],
|
||||
"appeartick": 1
|
||||
icon: "pin_drop",
|
||||
name: "Workspaces: navigation",
|
||||
binds: [
|
||||
{keys: ["", "+", "#"], action: "Go to workspace #"},
|
||||
{keys: ["", "+", "S"], action: "Toggle special workspace"},
|
||||
{keys: ["", "+", "(Scroll ↑↓)"], action: "Go to workspace -1/+1"},
|
||||
{keys: ["Ctrl", "", "+", "←"], action: "Go to workspace on the left"},
|
||||
{keys: ["Ctrl", "", "+", "→"], action: "Go to workspace on the right"},
|
||||
{keys: ["", "+", "PageUp"], action: "Go to workspace on the left"},
|
||||
{keys: ["", "+", "PageDown"], action: "Go to workspace on the right"},
|
||||
],
|
||||
appeartick: 1,
|
||||
},
|
||||
{
|
||||
"icon": "overview_key",
|
||||
"name": "Workspaces: management",
|
||||
"binds": [
|
||||
{ "keys": ["", "Alt", "+", "#"], "action": "Move window to workspace #" },
|
||||
{ "keys": ["", "Alt", "+", "S"], "action": "Move window to special workspace" },
|
||||
{ "keys": ["", "Alt", "+", "PageUp"], "action": "Move window to workspace on the left" },
|
||||
{ "keys": ["", "Alt", "+", "PageDown"], "action": "Move window to workspace on the right" }
|
||||
],
|
||||
"appeartick": 1
|
||||
icon: "overview_key",
|
||||
name: "Workspaces: management",
|
||||
binds: [
|
||||
{keys: ["", "Alt", "+", "#"], action: "Move window to workspace #"},
|
||||
{keys: ["", "Alt", "+", "S"], action: "Move window to special workspace"},
|
||||
{keys: ["", "Alt", "+", "PageUp"], action: "Move window to workspace on the left"},
|
||||
{keys: ["", "Alt", "+", "PageDown"], action: "Move window to workspace on the right"},
|
||||
],
|
||||
appeartick: 1,
|
||||
},
|
||||
{
|
||||
"icon": "move_group",
|
||||
"name": "Windows",
|
||||
"binds": [
|
||||
{ "keys": ["", "+", "←↑→↓"], "action": "Focus window in direction" },
|
||||
{ "keys": ["", "Shift", "+", "←↑→↓"], "action": "Swap window in direction" },
|
||||
{ "keys": ["", "+", ";"], "action": "Split ratio -" },
|
||||
{ "keys": ["", "+", "'"], "action": "Split ratio +" },
|
||||
{ "keys": ["", "+", "Lmb"], "action": "Move window" },
|
||||
{ "keys": ["", "+", "Mmb"], "action": "Move window" },
|
||||
{ "keys": ["", "+", "Rmb"], "action": "Resize window" },
|
||||
{ "keys": ["", "+", "F"], "action": "Fullscreen" },
|
||||
{ "keys": ["", "Alt", "+", "F"], "action": "Fake fullscreen" }
|
||||
],
|
||||
"appeartick": 1
|
||||
}
|
||||
],
|
||||
[
|
||||
icon: "move_group",
|
||||
name: "Windows",
|
||||
binds: [
|
||||
{keys: ["", "+", "←↑→↓"], action: "Focus window in direction"},
|
||||
{keys: ["", "Shift", "+", "←↑→↓"], action: "Swap window in direction"},
|
||||
{keys: ["", "+", ";"], action: "Split ratio -"},
|
||||
{keys: ["", "+", "'"], action: "Split ratio +"},
|
||||
{keys: ["", "+", "Lmb"], action: "Move window"},
|
||||
{keys: ["", "+", "Mmb"], action: "Move window"},
|
||||
{keys: ["", "+", "Rmb"], action: "Resize window"},
|
||||
{keys: ["", "+", "F"], action: "Fullscreen"},
|
||||
{keys: ["", "Alt", "+", "F"], action: "Fake fullscreen"},
|
||||
],
|
||||
appeartick: 1,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
"icon": "widgets",
|
||||
"name": "Widgets (AGS)",
|
||||
"binds": [
|
||||
{ "keys": ["", "OR", "", "+", "Tab"], "action": "Toggle overview/launcher" },
|
||||
{ "keys": ["Ctrl", "", "+", "R"], "action": "Restart AGS" },
|
||||
{ "keys": ["", "+", "/"], "action": "Toggle this cheatsheet" },
|
||||
{ "keys": ["", "+", "N"], "action": "Toggle sidebar" },
|
||||
{ "keys": ["", "+", "K"], "action": "Toggle virtual keyboard" },
|
||||
{ "keys": ["Ctrl", "Alt", "+", "Del"], "action": "Power/Session menu" },
|
||||
icon: "widgets",
|
||||
name: "Widgets (AGS)",
|
||||
binds: [
|
||||
{keys: ["", "OR", "", "+", "Tab"], action: "Toggle overview/launcher"},
|
||||
{keys: ["Ctrl", "", "+", "R"], action: "Restart AGS"},
|
||||
{keys: ["", "+", "/"], action: "Toggle this cheatsheet"},
|
||||
{keys: ["", "+", "N"], action: "Toggle sidebar"},
|
||||
{keys: ["", "+", "K"], action: "Toggle virtual keyboard"},
|
||||
{keys: ["Ctrl", "Alt", "+", "Del"], action: "Power/Session menu"},
|
||||
|
||||
{ "keys": ["Esc"], "action": "Exit a window" },
|
||||
{ "keys": ["rightCtrl"], "action": "Dismiss/close sidebar" },
|
||||
{keys: ["Esc"], action: "Exit a window"},
|
||||
{keys: ["rightCtrl"], action: "Dismiss/close sidebar"},
|
||||
|
||||
// { "keys": ["", "+", "B"], "action": "Toggle left sidebar" },
|
||||
// { "keys": ["", "+", "N"], "action": "Toggle right sidebar" },
|
||||
// { "keys": ["", "+", "G"], "action": "Toggle volume mixer" },
|
||||
// { "keys": ["", "+", "M"], "action": "Toggle useless audio visualizer" },
|
||||
// { "keys": ["(right)Ctrl"], "action": "Dismiss notification & close menus" }
|
||||
],
|
||||
"appeartick": 2
|
||||
// { "keys": ["", "+", "B"], "action": "Toggle left sidebar" },
|
||||
// { "keys": ["", "+", "N"], "action": "Toggle right sidebar" },
|
||||
// { "keys": ["", "+", "G"], "action": "Toggle volume mixer" },
|
||||
// { "keys": ["", "+", "M"], "action": "Toggle useless audio visualizer" },
|
||||
// { "keys": ["(right)Ctrl"], "action": "Dismiss notification & close menus" }
|
||||
],
|
||||
appeartick: 2,
|
||||
},
|
||||
{
|
||||
"icon": "construction",
|
||||
"name": "Utilities",
|
||||
"binds": [
|
||||
{ "keys": ["PrtSc"], "action": "Screenshot >> clipboard" },
|
||||
{ "keys": ["", "Shift", "+", "S"], "action": "Screen snip >> clipboard" },
|
||||
{ "keys": ["", "Shift", "+", "T"], "action": "Image to text >> clipboard" },
|
||||
{ "keys": ["", "Shift", "+", "C"], "action": "Color picker" },
|
||||
{ "keys": ["", "Alt", "+", "R"], "action": "Record region" },
|
||||
{ "keys": ["Ctrl", "Alt", "+", "R"], "action": "Record region with sound" },
|
||||
{ "keys": ["", "Shift", "Alt", "+", "R"], "action": "Record screen with sound" }
|
||||
],
|
||||
"appeartick": 2
|
||||
icon: "construction",
|
||||
name: "Utilities",
|
||||
binds: [
|
||||
{keys: ["PrtSc"], action: "Screenshot >> clipboard"},
|
||||
{keys: ["", "Shift", "+", "S"], action: "Screen snip >> clipboard"},
|
||||
{keys: ["", "Shift", "+", "T"], action: "Image to text >> clipboard"},
|
||||
{keys: ["", "Shift", "+", "C"], action: "Color picker"},
|
||||
{keys: ["", "Alt", "+", "R"], action: "Record region"},
|
||||
{keys: ["Ctrl", "Alt", "+", "R"], action: "Record region with sound"},
|
||||
{keys: ["", "Shift", "Alt", "+", "R"], action: "Record screen with sound"},
|
||||
],
|
||||
appeartick: 2,
|
||||
},
|
||||
// {
|
||||
// "icon": "edit",
|
||||
@@ -92,41 +93,42 @@ export const keybindList = [[
|
||||
// ],
|
||||
// "appeartick": 2
|
||||
// }
|
||||
],
|
||||
[
|
||||
],
|
||||
[
|
||||
{
|
||||
"icon": "apps",
|
||||
"name": "Apps",
|
||||
"binds": [
|
||||
{ "keys": ["", "+", "T"], "action": "Launch terminal: foot" },
|
||||
{ "keys": ["", "+", "↵"], "action": "Launch terminal: WezTerm" },
|
||||
{ "keys": ["", "+", "W"], "action": "Launch browser: Firefox" },
|
||||
{ "keys": ["", "+", "C"], "action": "Launch editor: vscode" },
|
||||
{ "keys": ["", "+", "X"], "action": "Launch editor: GNOME Text Editor" },
|
||||
{ "keys": ["", "+", "I"], "action": "Launch settings: GNOME Control center" }
|
||||
],
|
||||
"appeartick": 3
|
||||
icon: "apps",
|
||||
name: "Apps",
|
||||
binds: [
|
||||
{keys: ["", "+", "T"], action: "Launch terminal: foot"},
|
||||
{keys: ["", "+", "↵"], action: "Launch terminal: WezTerm"},
|
||||
{keys: ["", "+", "W"], action: "Launch browser: Firefox"},
|
||||
{keys: ["", "+", "C"], action: "Launch editor: vscode"},
|
||||
{keys: ["", "+", "X"], action: "Launch editor: GNOME Text Editor"},
|
||||
{keys: ["", "+", "I"], action: "Launch settings: GNOME Control center"},
|
||||
],
|
||||
appeartick: 3,
|
||||
},
|
||||
{
|
||||
"icon": "keyboard",
|
||||
"name": "Typing",
|
||||
"binds": [
|
||||
{ "keys": ["", "+", "V"], "action": "Clipboard history >> clipboard" },
|
||||
{ "keys": ["", "+", "."], "action": "Emoji picker >> clipboard" },
|
||||
{ "keys": ["", "+", " "], "action": "Switch language" }
|
||||
],
|
||||
"appeartick": 3
|
||||
icon: "keyboard",
|
||||
name: "Typing",
|
||||
binds: [
|
||||
{keys: ["", "+", "V"], action: "Clipboard history >> clipboard"},
|
||||
{keys: ["", "+", "."], action: "Emoji picker >> clipboard"},
|
||||
{keys: ["", "+", " "], action: "Switch language"},
|
||||
],
|
||||
appeartick: 3,
|
||||
},
|
||||
{
|
||||
"icon": "terminal",
|
||||
"name": "Launcher commands",
|
||||
"binds": [
|
||||
{ "keys": [">raw"], "action": "Toggle mouse acceleration" },
|
||||
{ "keys": [">img"], "action": "Select wallpaper and generate colorscheme" },
|
||||
{ "keys": [">light"], "action": "Use light theme for next color generations" },
|
||||
{ "keys": [">dark"], "action": "Use dark theme for next color generations" },
|
||||
{ "keys": [">todo"], "action": "Type something after that to add a To-do item" },
|
||||
],
|
||||
"appeartick": 3
|
||||
}
|
||||
]];
|
||||
icon: "terminal",
|
||||
name: "Launcher commands",
|
||||
binds: [
|
||||
{keys: [">raw"], action: "Toggle mouse acceleration"},
|
||||
{keys: [">img"], action: "Select wallpaper and generate colorscheme"},
|
||||
{keys: [">light"], action: "Use light theme for next color generations"},
|
||||
{keys: [">dark"], action: "Use dark theme for next color generations"},
|
||||
{keys: [">todo"], action: "Type something after that to add a To-do item"},
|
||||
],
|
||||
appeartick: 3,
|
||||
},
|
||||
],
|
||||
]
|
||||
|
||||
@@ -3,112 +3,112 @@
|
||||
|
||||
export const defaultOskLayout = "qwerty_full"
|
||||
export const oskLayouts = {
|
||||
qwerty_full: {
|
||||
name: "QWERTY - Full",
|
||||
name_short: "US",
|
||||
comment: "Like physical keyboard",
|
||||
// A key looks like this: { k: "a", ks: "A", t: "normal" } (key, key-shift, type)
|
||||
// key types are: normal, tab, caps, shift, control, fn (normal w/ half height), space, expand
|
||||
// keys: [
|
||||
// [{ k: "Esc", t: "fn" }, { k: "F1", t: "fn" }, { k: "F2", t: "fn" }, { k: "F3", t: "fn" }, { k: "F4", t: "fn" }, { k: "F5", t: "fn" }, { k: "F6", t: "fn" }, { k: "F7", t: "fn" }, { k: "F8", t: "fn" }, { k: "F9", t: "fn" }, { k: "F10", t: "fn" }, { k: "F11", t: "fn" }, { k: "F12", t: "fn" }, { k: "PrtSc", t: "fn" }, { k: "Del", t: "fn" }],
|
||||
// [{ k: "`", ks: "~", t: "normal" }, { k: "1", ks: "!", t: "normal" }, { k: "2", ks: "@", t: "normal" }, { k: "3", ks: "#", t: "normal" }, { k: "4", ks: "$", t: "normal" }, { k: "5", ks: "%", t: "normal" }, { k: "6", ks: "^", t: "normal" }, { k: "7", ks: "&", t: "normal" }, { k: "8", ks: "*", t: "normal" }, { k: "9", ks: "(", t: "normal" }, { k: "0", ks: ")", t: "normal" }, { k: "-", ks: "_", t: "normal" }, { k: "=", ks: "+", t: "normal" }, { k: "Backspace", t: "shift" }],
|
||||
// [{ k: "Tab", t: "tab" }, { k: "q", ks: "Q", t: "normal" }, { k: "w", ks: "W", t: "normal" }, { k: "e", ks: "E", t: "normal" }, { k: "r", ks: "R", t: "normal" }, { k: "t", ks: "T", t: "normal" }, { k: "y", ks: "Y", t: "normal" }, { k: "u", ks: "U", t: "normal" }, { k: "i", ks: "I", t: "normal" }, { k: "o", ks: "O", t: "normal" }, { k: "p", ks: "P", t: "normal" }, { k: "[", ks: "{", t: "normal" }, { k: "]", ks: "}", t: "normal" }, { k: "\\", ks: "|", t: "expand" }],
|
||||
// [{ k: "Caps", t: "caps" }, { k: "a", ks: "A", t: "normal" }, { k: "s", ks: "S", t: "normal" }, { k: "d", ks: "D", t: "normal" }, { k: "f", ks: "F", t: "normal" }, { k: "g", ks: "G", t: "normal" }, { k: "h", ks: "H", t: "normal" }, { k: "j", ks: "J", t: "normal" }, { k: "k", ks: "K", t: "normal" }, { k: "l", ks: "L", t: "normal" }, { k: ";", ks: ":", t: "normal" }, { k: "'", ks: '"', t: "normal" }, { k: "Enter", t: "expand" }],
|
||||
// [{ k: "Shift", t: "shift" }, { k: "z", ks: "Z", t: "normal" }, { k: "x", ks: "X", t: "normal" }, { k: "c", ks: "C", t: "normal" }, { k: "v", ks: "V", t: "normal" }, { k: "b", ks: "B", t: "normal" }, { k: "n", ks: "N", t: "normal" }, { k: "m", ks: "M", t: "normal" }, { k: ",", ks: "<", t: "normal" }, { k: ".", ks: ">", t: "normal" }, { k: "/", ks: "?", t: "normal" }, { k: "Shift", t: "expand" }],
|
||||
// [{ k: "Ctrl", t: "control" }, { k: "Fn", t: "normal" }, { k: "Win", t: "normal" }, { k: "Alt", t: "normal" }, { k: "Space", t: "space" }, { k: "Alt", t: "normal" }, { k: "Menu", t: "normal" }, { k: "Ctrl", t: "control" }]
|
||||
// ]
|
||||
// A normal key looks like this: {label: "a", labelShift: "A", shape: "normal", keycode: 30, type: "normal"}
|
||||
// A modkey looks like this: {label: "Ctrl", shape: "control", keycode: 29, type: "modkey"}
|
||||
// key types are: normal, tab, caps, shift, control, fn (normal w/ half height), space, expand
|
||||
keys: [
|
||||
[
|
||||
{ keytype: "normal", label: "Esc", shape: "fn", keycode: 1 },
|
||||
{ keytype: "normal", label: "F1", shape: "fn", keycode: 59 },
|
||||
{ keytype: "normal", label: "F2", shape: "fn", keycode: 60 },
|
||||
{ keytype: "normal", label: "F3", shape: "fn", keycode: 61 },
|
||||
{ keytype: "normal", label: "F4", shape: "fn", keycode: 62 },
|
||||
{ keytype: "normal", label: "F5", shape: "fn", keycode: 63 },
|
||||
{ keytype: "normal", label: "F6", shape: "fn", keycode: 64 },
|
||||
{ keytype: "normal", label: "F7", shape: "fn", keycode: 65 },
|
||||
{ keytype: "normal", label: "F8", shape: "fn", keycode: 66 },
|
||||
{ keytype: "normal", label: "F9", shape: "fn", keycode: 67 },
|
||||
{ keytype: "normal", label: "F10", shape: "fn", keycode: 68 },
|
||||
{ keytype: "normal", label: "F11", shape: "fn", keycode: 87 },
|
||||
{ keytype: "normal", label: "F12", shape: "fn", keycode: 88 },
|
||||
{ keytype: "normal", label: "PrtSc", shape: "fn", keycode: 99 },
|
||||
{ keytype: "normal", label: "Del", shape: "fn", keycode: 111 }
|
||||
],
|
||||
[
|
||||
{ keytype: "normal", label: "`", labelShift: "~", shape: "normal", keycode: 41 },
|
||||
{ keytype: "normal", label: "1", labelShift: "!", shape: "normal", keycode: 2 },
|
||||
{ keytype: "normal", label: "2", labelShift: "@", shape: "normal", keycode: 3 },
|
||||
{ keytype: "normal", label: "3", labelShift: "#", shape: "normal", keycode: 4 },
|
||||
{ keytype: "normal", label: "4", labelShift: "$", shape: "normal", keycode: 5 },
|
||||
{ keytype: "normal", label: "5", labelShift: "%", shape: "normal", keycode: 6 },
|
||||
{ keytype: "normal", label: "6", labelShift: "^", shape: "normal", keycode: 7 },
|
||||
{ keytype: "normal", label: "7", labelShift: "&", shape: "normal", keycode: 8 },
|
||||
{ keytype: "normal", label: "8", labelShift: "*", shape: "normal", keycode: 9 },
|
||||
{ keytype: "normal", label: "9", labelShift: "(", shape: "normal", keycode: 10 },
|
||||
{ keytype: "normal", label: "0", labelShift: ")", shape: "normal", keycode: 11 },
|
||||
{ keytype: "normal", label: "-", labelShift: "_", shape: "normal", keycode: 12 },
|
||||
{ keytype: "normal", label: "=", labelShift: "+", shape: "normal", keycode: 13 },
|
||||
{ keytype: "normal", label: "Backspace", shape: "expand", keycode: 14 }
|
||||
],
|
||||
[
|
||||
{ keytype: "normal", label: "Tab", shape: "tab", keycode: 15 },
|
||||
{ keytype: "normal", label: "q", labelShift: "Q", shape: "normal", keycode: 16 },
|
||||
{ keytype: "normal", label: "w", labelShift: "W", shape: "normal", keycode: 17 },
|
||||
{ keytype: "normal", label: "e", labelShift: "E", shape: "normal", keycode: 18 },
|
||||
{ keytype: "normal", label: "r", labelShift: "R", shape: "normal", keycode: 19 },
|
||||
{ keytype: "normal", label: "t", labelShift: "T", shape: "normal", keycode: 20 },
|
||||
{ keytype: "normal", label: "y", labelShift: "Y", shape: "normal", keycode: 21 },
|
||||
{ keytype: "normal", label: "u", labelShift: "U", shape: "normal", keycode: 22 },
|
||||
{ keytype: "normal", label: "i", labelShift: "I", shape: "normal", keycode: 23 },
|
||||
{ keytype: "normal", label: "o", labelShift: "O", shape: "normal", keycode: 24 },
|
||||
{ keytype: "normal", label: "p", labelShift: "P", shape: "normal", keycode: 25 },
|
||||
{ keytype: "normal", label: "[", labelShift: "{", shape: "normal", keycode: 26 },
|
||||
{ keytype: "normal", label: "]", labelShift: "}", shape: "normal", keycode: 27 },
|
||||
{ keytype: "normal", label: "\\", labelShift: "|", shape: "expand", keycode: 43 }
|
||||
],
|
||||
[
|
||||
{ keytype: "normal", label: "Caps", shape: "caps", keycode: 58 },
|
||||
{ keytype: "normal", label: "a", labelShift: "A", shape: "normal", keycode: 30 },
|
||||
{ keytype: "normal", label: "s", labelShift: "S", shape: "normal", keycode: 31 },
|
||||
{ keytype: "normal", label: "d", labelShift: "D", shape: "normal", keycode: 32 },
|
||||
{ keytype: "normal", label: "f", labelShift: "F", shape: "normal", keycode: 33 },
|
||||
{ keytype: "normal", label: "g", labelShift: "G", shape: "normal", keycode: 34 },
|
||||
{ keytype: "normal", label: "h", labelShift: "H", shape: "normal", keycode: 35 },
|
||||
{ keytype: "normal", label: "j", labelShift: "J", shape: "normal", keycode: 36 },
|
||||
{ keytype: "normal", label: "k", labelShift: "K", shape: "normal", keycode: 37 },
|
||||
{ keytype: "normal", label: "l", labelShift: "L", shape: "normal", keycode: 38 },
|
||||
{ keytype: "normal", label: ";", labelShift: ":", shape: "normal", keycode: 39 },
|
||||
{ keytype: "normal", label: "'", labelShift: '"', shape: "normal", keycode: 40 },
|
||||
{ keytype: "normal", label: "Enter", shape: "expand", keycode: 28 }
|
||||
],
|
||||
[
|
||||
{ keytype: "modkey", label: "Shift", shape: "shift", keycode: 42 },
|
||||
{ keytype: "normal", label: "z", labelShift: "Z", shape: "normal", keycode: 44 },
|
||||
{ keytype: "normal", label: "x", labelShift: "X", shape: "normal", keycode: 45 },
|
||||
{ keytype: "normal", label: "c", labelShift: "C", shape: "normal", keycode: 46 },
|
||||
{ keytype: "normal", label: "v", labelShift: "V", shape: "normal", keycode: 47 },
|
||||
{ keytype: "normal", label: "b", labelShift: "B", shape: "normal", keycode: 48 },
|
||||
{ keytype: "normal", label: "n", labelShift: "N", shape: "normal", keycode: 49 },
|
||||
{ keytype: "normal", label: "m", labelShift: "M", shape: "normal", keycode: 50 },
|
||||
{ keytype: "normal", label: ",", labelShift: "<", shape: "normal", keycode: 51 },
|
||||
{ keytype: "normal", label: ".", labelShift: ">", shape: "normal", keycode: 52 },
|
||||
{ keytype: "normal", label: "/", labelShift: "?", shape: "normal", keycode: 53 },
|
||||
{ keytype: "modkey", label: "Shift", shape: "expand", keycode: 54 }
|
||||
],
|
||||
[
|
||||
{ keytype: "modkey", label: "Ctrl", shape: "control", keycode: 29 },
|
||||
// { label: "Super", shape: "normal", keycode: 125 }, // dangerous
|
||||
{ keytype: "modkey", label: "Alt", shape: "normal", keycode: 56 },
|
||||
{ keytype: "normal", label: "Space", shape: "space", keycode: 57 },
|
||||
{ keytype: "modkey", label: "Alt", shape: "normal", keycode: 100 },
|
||||
// { label: "Super", shape: "normal", keycode: 126 }, // dangerous
|
||||
{ keytype: "normal", label: "Menu", shape: "normal", keycode: 139 },
|
||||
{ keytype: "modkey", label: "Ctrl", shape: "control", keycode: 97 }
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
qwerty_full: {
|
||||
name: "QWERTY - Full",
|
||||
name_short: "US",
|
||||
comment: "Like physical keyboard",
|
||||
// A key looks like this: { k: "a", ks: "A", t: "normal" } (key, key-shift, type)
|
||||
// key types are: normal, tab, caps, shift, control, fn (normal w/ half height), space, expand
|
||||
// keys: [
|
||||
// [{ k: "Esc", t: "fn" }, { k: "F1", t: "fn" }, { k: "F2", t: "fn" }, { k: "F3", t: "fn" }, { k: "F4", t: "fn" }, { k: "F5", t: "fn" }, { k: "F6", t: "fn" }, { k: "F7", t: "fn" }, { k: "F8", t: "fn" }, { k: "F9", t: "fn" }, { k: "F10", t: "fn" }, { k: "F11", t: "fn" }, { k: "F12", t: "fn" }, { k: "PrtSc", t: "fn" }, { k: "Del", t: "fn" }],
|
||||
// [{ k: "`", ks: "~", t: "normal" }, { k: "1", ks: "!", t: "normal" }, { k: "2", ks: "@", t: "normal" }, { k: "3", ks: "#", t: "normal" }, { k: "4", ks: "$", t: "normal" }, { k: "5", ks: "%", t: "normal" }, { k: "6", ks: "^", t: "normal" }, { k: "7", ks: "&", t: "normal" }, { k: "8", ks: "*", t: "normal" }, { k: "9", ks: "(", t: "normal" }, { k: "0", ks: ")", t: "normal" }, { k: "-", ks: "_", t: "normal" }, { k: "=", ks: "+", t: "normal" }, { k: "Backspace", t: "shift" }],
|
||||
// [{ k: "Tab", t: "tab" }, { k: "q", ks: "Q", t: "normal" }, { k: "w", ks: "W", t: "normal" }, { k: "e", ks: "E", t: "normal" }, { k: "r", ks: "R", t: "normal" }, { k: "t", ks: "T", t: "normal" }, { k: "y", ks: "Y", t: "normal" }, { k: "u", ks: "U", t: "normal" }, { k: "i", ks: "I", t: "normal" }, { k: "o", ks: "O", t: "normal" }, { k: "p", ks: "P", t: "normal" }, { k: "[", ks: "{", t: "normal" }, { k: "]", ks: "}", t: "normal" }, { k: "\\", ks: "|", t: "expand" }],
|
||||
// [{ k: "Caps", t: "caps" }, { k: "a", ks: "A", t: "normal" }, { k: "s", ks: "S", t: "normal" }, { k: "d", ks: "D", t: "normal" }, { k: "f", ks: "F", t: "normal" }, { k: "g", ks: "G", t: "normal" }, { k: "h", ks: "H", t: "normal" }, { k: "j", ks: "J", t: "normal" }, { k: "k", ks: "K", t: "normal" }, { k: "l", ks: "L", t: "normal" }, { k: ";", ks: ":", t: "normal" }, { k: "'", ks: '"', t: "normal" }, { k: "Enter", t: "expand" }],
|
||||
// [{ k: "Shift", t: "shift" }, { k: "z", ks: "Z", t: "normal" }, { k: "x", ks: "X", t: "normal" }, { k: "c", ks: "C", t: "normal" }, { k: "v", ks: "V", t: "normal" }, { k: "b", ks: "B", t: "normal" }, { k: "n", ks: "N", t: "normal" }, { k: "m", ks: "M", t: "normal" }, { k: ",", ks: "<", t: "normal" }, { k: ".", ks: ">", t: "normal" }, { k: "/", ks: "?", t: "normal" }, { k: "Shift", t: "expand" }],
|
||||
// [{ k: "Ctrl", t: "control" }, { k: "Fn", t: "normal" }, { k: "Win", t: "normal" }, { k: "Alt", t: "normal" }, { k: "Space", t: "space" }, { k: "Alt", t: "normal" }, { k: "Menu", t: "normal" }, { k: "Ctrl", t: "control" }]
|
||||
// ]
|
||||
// A normal key looks like this: {label: "a", labelShift: "A", shape: "normal", keycode: 30, type: "normal"}
|
||||
// A modkey looks like this: {label: "Ctrl", shape: "control", keycode: 29, type: "modkey"}
|
||||
// key types are: normal, tab, caps, shift, control, fn (normal w/ half height), space, expand
|
||||
keys: [
|
||||
[
|
||||
{keytype: "normal", label: "Esc", shape: "fn", keycode: 1},
|
||||
{keytype: "normal", label: "F1", shape: "fn", keycode: 59},
|
||||
{keytype: "normal", label: "F2", shape: "fn", keycode: 60},
|
||||
{keytype: "normal", label: "F3", shape: "fn", keycode: 61},
|
||||
{keytype: "normal", label: "F4", shape: "fn", keycode: 62},
|
||||
{keytype: "normal", label: "F5", shape: "fn", keycode: 63},
|
||||
{keytype: "normal", label: "F6", shape: "fn", keycode: 64},
|
||||
{keytype: "normal", label: "F7", shape: "fn", keycode: 65},
|
||||
{keytype: "normal", label: "F8", shape: "fn", keycode: 66},
|
||||
{keytype: "normal", label: "F9", shape: "fn", keycode: 67},
|
||||
{keytype: "normal", label: "F10", shape: "fn", keycode: 68},
|
||||
{keytype: "normal", label: "F11", shape: "fn", keycode: 87},
|
||||
{keytype: "normal", label: "F12", shape: "fn", keycode: 88},
|
||||
{keytype: "normal", label: "PrtSc", shape: "fn", keycode: 99},
|
||||
{keytype: "normal", label: "Del", shape: "fn", keycode: 111},
|
||||
],
|
||||
[
|
||||
{keytype: "normal", label: "`", labelShift: "~", shape: "normal", keycode: 41},
|
||||
{keytype: "normal", label: "1", labelShift: "!", shape: "normal", keycode: 2},
|
||||
{keytype: "normal", label: "2", labelShift: "@", shape: "normal", keycode: 3},
|
||||
{keytype: "normal", label: "3", labelShift: "#", shape: "normal", keycode: 4},
|
||||
{keytype: "normal", label: "4", labelShift: "$", shape: "normal", keycode: 5},
|
||||
{keytype: "normal", label: "5", labelShift: "%", shape: "normal", keycode: 6},
|
||||
{keytype: "normal", label: "6", labelShift: "^", shape: "normal", keycode: 7},
|
||||
{keytype: "normal", label: "7", labelShift: "&", shape: "normal", keycode: 8},
|
||||
{keytype: "normal", label: "8", labelShift: "*", shape: "normal", keycode: 9},
|
||||
{keytype: "normal", label: "9", labelShift: "(", shape: "normal", keycode: 10},
|
||||
{keytype: "normal", label: "0", labelShift: ")", shape: "normal", keycode: 11},
|
||||
{keytype: "normal", label: "-", labelShift: "_", shape: "normal", keycode: 12},
|
||||
{keytype: "normal", label: "=", labelShift: "+", shape: "normal", keycode: 13},
|
||||
{keytype: "normal", label: "Backspace", shape: "expand", keycode: 14},
|
||||
],
|
||||
[
|
||||
{keytype: "normal", label: "Tab", shape: "tab", keycode: 15},
|
||||
{keytype: "normal", label: "q", labelShift: "Q", shape: "normal", keycode: 16},
|
||||
{keytype: "normal", label: "w", labelShift: "W", shape: "normal", keycode: 17},
|
||||
{keytype: "normal", label: "e", labelShift: "E", shape: "normal", keycode: 18},
|
||||
{keytype: "normal", label: "r", labelShift: "R", shape: "normal", keycode: 19},
|
||||
{keytype: "normal", label: "t", labelShift: "T", shape: "normal", keycode: 20},
|
||||
{keytype: "normal", label: "y", labelShift: "Y", shape: "normal", keycode: 21},
|
||||
{keytype: "normal", label: "u", labelShift: "U", shape: "normal", keycode: 22},
|
||||
{keytype: "normal", label: "i", labelShift: "I", shape: "normal", keycode: 23},
|
||||
{keytype: "normal", label: "o", labelShift: "O", shape: "normal", keycode: 24},
|
||||
{keytype: "normal", label: "p", labelShift: "P", shape: "normal", keycode: 25},
|
||||
{keytype: "normal", label: "[", labelShift: "{", shape: "normal", keycode: 26},
|
||||
{keytype: "normal", label: "]", labelShift: "}", shape: "normal", keycode: 27},
|
||||
{keytype: "normal", label: "\\", labelShift: "|", shape: "expand", keycode: 43},
|
||||
],
|
||||
[
|
||||
{keytype: "normal", label: "Caps", shape: "caps", keycode: 58},
|
||||
{keytype: "normal", label: "a", labelShift: "A", shape: "normal", keycode: 30},
|
||||
{keytype: "normal", label: "s", labelShift: "S", shape: "normal", keycode: 31},
|
||||
{keytype: "normal", label: "d", labelShift: "D", shape: "normal", keycode: 32},
|
||||
{keytype: "normal", label: "f", labelShift: "F", shape: "normal", keycode: 33},
|
||||
{keytype: "normal", label: "g", labelShift: "G", shape: "normal", keycode: 34},
|
||||
{keytype: "normal", label: "h", labelShift: "H", shape: "normal", keycode: 35},
|
||||
{keytype: "normal", label: "j", labelShift: "J", shape: "normal", keycode: 36},
|
||||
{keytype: "normal", label: "k", labelShift: "K", shape: "normal", keycode: 37},
|
||||
{keytype: "normal", label: "l", labelShift: "L", shape: "normal", keycode: 38},
|
||||
{keytype: "normal", label: ";", labelShift: ":", shape: "normal", keycode: 39},
|
||||
{keytype: "normal", label: "'", labelShift: '"', shape: "normal", keycode: 40},
|
||||
{keytype: "normal", label: "Enter", shape: "expand", keycode: 28},
|
||||
],
|
||||
[
|
||||
{keytype: "modkey", label: "Shift", shape: "shift", keycode: 42},
|
||||
{keytype: "normal", label: "z", labelShift: "Z", shape: "normal", keycode: 44},
|
||||
{keytype: "normal", label: "x", labelShift: "X", shape: "normal", keycode: 45},
|
||||
{keytype: "normal", label: "c", labelShift: "C", shape: "normal", keycode: 46},
|
||||
{keytype: "normal", label: "v", labelShift: "V", shape: "normal", keycode: 47},
|
||||
{keytype: "normal", label: "b", labelShift: "B", shape: "normal", keycode: 48},
|
||||
{keytype: "normal", label: "n", labelShift: "N", shape: "normal", keycode: 49},
|
||||
{keytype: "normal", label: "m", labelShift: "M", shape: "normal", keycode: 50},
|
||||
{keytype: "normal", label: ",", labelShift: "<", shape: "normal", keycode: 51},
|
||||
{keytype: "normal", label: ".", labelShift: ">", shape: "normal", keycode: 52},
|
||||
{keytype: "normal", label: "/", labelShift: "?", shape: "normal", keycode: 53},
|
||||
{keytype: "modkey", label: "Shift", shape: "expand", keycode: 54},
|
||||
],
|
||||
[
|
||||
{keytype: "modkey", label: "Ctrl", shape: "control", keycode: 29},
|
||||
// { label: "Super", shape: "normal", keycode: 125 }, // dangerous
|
||||
{keytype: "modkey", label: "Alt", shape: "normal", keycode: 56},
|
||||
{keytype: "normal", label: "Space", shape: "space", keycode: 57},
|
||||
{keytype: "modkey", label: "Alt", shape: "normal", keycode: 100},
|
||||
// { label: "Super", shape: "normal", keycode: 126 }, // dangerous
|
||||
{keytype: "normal", label: "Menu", shape: "normal", keycode: 139},
|
||||
{keytype: "modkey", label: "Ctrl", shape: "control", keycode: 97},
|
||||
],
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
export const quotes = [
|
||||
{
|
||||
quote: 'Nvidia, fuck you',
|
||||
author: 'Linus Torvalds',
|
||||
},
|
||||
{
|
||||
quote: 'reproducible system? cock and vagina?',
|
||||
author: 'vaxry',
|
||||
},
|
||||
{
|
||||
quote: "haha pointers hee hee i love pointe-\\\nProcess Vaxry exited with signal SIGSEGV",
|
||||
author: 'vaxry',
|
||||
}
|
||||
];
|
||||
{
|
||||
quote: "Nvidia, fuck you",
|
||||
author: "Linus Torvalds",
|
||||
},
|
||||
{
|
||||
quote: "reproducible system? cock and vagina?",
|
||||
author: "vaxry",
|
||||
},
|
||||
{
|
||||
quote: "haha pointers hee hee i love pointe-\\\nProcess Vaxry exited with signal SIGSEGV",
|
||||
author: "vaxry",
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
const resource = file => `resource:///com/github/Aylur/ags/${file}.js`;
|
||||
const require = async file => (await import(resource(file))).default;
|
||||
const service = async file => (await require(`service/${file}`));
|
||||
|
||||
export const App = await require('app');
|
||||
export const Widget = await require('widget');
|
||||
export const Service = await require('service');
|
||||
export const Variable = await require('variable');
|
||||
export const Utils = await import(resource('utils'));
|
||||
|
||||
export const Applications = await service('applications');
|
||||
export const Audio = await service('audio');
|
||||
export const Battery = await service('battery');
|
||||
export const Bluetooth = await service('bluetooth');
|
||||
export const Hyprland = await service('hyprland');
|
||||
export const Mpris = await service('mpris');
|
||||
export const Network = await service('network');
|
||||
export const Notifications = await service('notifications');
|
||||
export const SystemTray = await service('systemtray');
|
||||
|
||||
globalThis['App'] = App; //////////////////////////////
|
||||
// globalThis['Widget'] = Widget;
|
||||
// globalThis['Service'] = Service;
|
||||
// globalThis['Variable'] = Variable;
|
||||
globalThis['Utils'] = Utils; ///////////////////////////
|
||||
// globalThis['Applications'] = Applications;
|
||||
// globalThis['Audio'] = Audio;
|
||||
// globalThis['Battery'] = Battery;
|
||||
// globalThis['Bluetooth'] = Bluetooth;
|
||||
// globalThis['Hyprland'] = Hyprland;
|
||||
// globalThis['Mpris'] = Mpris;
|
||||
// globalThis['Network'] = Network;
|
||||
globalThis['Notifications'] = Notifications;
|
||||
// globalThis['SystemTray'] = SystemTray;
|
||||
|
||||
const { exec } = Utils;
|
||||
const SCREEN_WIDTH = Number(exec(`bash -c "xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f1 | head -1"`));
|
||||
const SCREEN_HEIGHT = Number(exec(`bash -c "xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f2 | head -1"`));
|
||||
globalThis['SCREEN_WIDTH'] = SCREEN_WIDTH;
|
||||
globalThis['SCREEN_HEIGHT'] = SCREEN_HEIGHT;
|
||||
@@ -1,364 +1,393 @@
|
||||
const { Gio, Gdk, Gtk } = imports.gi;
|
||||
import { App, Widget, Utils } from '../imports.js';
|
||||
const { Box, CenterBox, Label, Button } = Widget;
|
||||
import { MaterialIcon } from "./lib/materialicon.js";
|
||||
import { getCalendarLayout } from "../scripts/calendarlayout.js";
|
||||
import Todo from "../scripts/todo.js";
|
||||
import { setupCursorHover } from "./lib/cursorhover.js";
|
||||
import { NavigationIndicator } from "./lib/navigationindicator.js";
|
||||
const {Gio, Gdk, Gtk} = imports.gi
|
||||
import {App, Widget, Utils} from "../imports.js"
|
||||
const {Box, CenterBox, Label, Button} = Widget
|
||||
import {MaterialIcon} from "./lib/materialicon.js"
|
||||
import {getCalendarLayout} from "../scripts/calendarlayout.js"
|
||||
import Todo from "../scripts/todo.js"
|
||||
import {setupCursorHover} from "./lib/cursorhover.js"
|
||||
import {NavigationIndicator} from "./lib/navigationindicator.js"
|
||||
|
||||
let calendarJson = getCalendarLayout(undefined, true);
|
||||
let monthshift = 0;
|
||||
let calendarJson = getCalendarLayout(undefined, true)
|
||||
let monthshift = 0
|
||||
|
||||
function fileExists(filePath) {
|
||||
let file = Gio.File.new_for_path(filePath);
|
||||
return file.query_exists(null);
|
||||
let file = Gio.File.new_for_path(filePath)
|
||||
return file.query_exists(null)
|
||||
}
|
||||
|
||||
function getDateInXMonthsTime(x) {
|
||||
var currentDate = new Date(); // Get the current date
|
||||
var targetMonth = currentDate.getMonth() + x; // Calculate the target month
|
||||
var targetYear = currentDate.getFullYear(); // Get the current year
|
||||
var currentDate = new Date() // Get the current date
|
||||
var targetMonth = currentDate.getMonth() + x // Calculate the target month
|
||||
var targetYear = currentDate.getFullYear() // Get the current year
|
||||
|
||||
// Adjust the year and month if necessary
|
||||
targetYear += Math.floor(targetMonth / 12);
|
||||
targetMonth = (targetMonth % 12 + 12) % 12;
|
||||
// Adjust the year and month if necessary
|
||||
targetYear += Math.floor(targetMonth / 12)
|
||||
targetMonth = ((targetMonth % 12) + 12) % 12
|
||||
|
||||
// Create a new date object with the target year and month
|
||||
var targetDate = new Date(targetYear, targetMonth, 1);
|
||||
// Create a new date object with the target year and month
|
||||
var targetDate = new Date(targetYear, targetMonth, 1)
|
||||
|
||||
// Set the day to the last day of the month to get the desired date
|
||||
// targetDate.setDate(0);
|
||||
// Set the day to the last day of the month to get the desired date
|
||||
// targetDate.setDate(0);
|
||||
|
||||
return targetDate;
|
||||
return targetDate
|
||||
}
|
||||
|
||||
const weekDays = [ // stupid stupid stupid!! how tf is Sunday the first day of the week??
|
||||
{ day: 'Su', today: 0 },
|
||||
{ day: 'Mo', today: 0 },
|
||||
{ day: 'Tu', today: 0 },
|
||||
{ day: 'We', today: 0 },
|
||||
{ day: 'Th', today: 0 },
|
||||
{ day: 'Fr', today: 0 },
|
||||
{ day: 'Sa', today: 0 },
|
||||
const weekDays = [
|
||||
// stupid stupid stupid!! how tf is Sunday the first day of the week??
|
||||
{day: "Su", today: 0},
|
||||
{day: "Mo", today: 0},
|
||||
{day: "Tu", today: 0},
|
||||
{day: "We", today: 0},
|
||||
{day: "Th", today: 0},
|
||||
{day: "Fr", today: 0},
|
||||
{day: "Sa", today: 0},
|
||||
]
|
||||
|
||||
const CalendarDay = (day, today) => Widget.Button({
|
||||
className: `sidebar-calendar-btn ${today == 1 ? 'sidebar-calendar-btn-today' : (today == -1 ? 'sidebar-calendar-btn-othermonth' : '')}`,
|
||||
const CalendarDay = (day, today) =>
|
||||
Widget.Button({
|
||||
className: `sidebar-calendar-btn ${
|
||||
today == 1 ? "sidebar-calendar-btn-today" : today == -1 ? "sidebar-calendar-btn-othermonth" : ""
|
||||
}`,
|
||||
child: Widget.Overlay({
|
||||
child: Box({}),
|
||||
overlays: [Label({
|
||||
halign: 'center',
|
||||
className: 'txt-smallie txt-semibold sidebar-calendar-btn-txt',
|
||||
label: String(day),
|
||||
})],
|
||||
})
|
||||
})
|
||||
child: Box({}),
|
||||
overlays: [
|
||||
Label({
|
||||
halign: "center",
|
||||
className: "txt-smallie txt-semibold sidebar-calendar-btn-txt",
|
||||
label: String(day),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
const CalendarWidget = () => {
|
||||
const calendarMonthYear = Widget.Button({
|
||||
className: 'txt txt-large sidebar-calendar-monthyear-btn',
|
||||
onClicked: () => shiftCalendarXMonths(0),
|
||||
setup: (button) => {
|
||||
button.label = `${new Date().toLocaleString('default', { month: 'long' })} ${new Date().getFullYear()}`;
|
||||
setupCursorHover(button);
|
||||
}
|
||||
});
|
||||
const addCalendarChildren = (box, calendarJson) => {
|
||||
box.children = calendarJson.map((row, i) => Widget.Box({
|
||||
// homogeneous: true,
|
||||
className: 'spacing-h-5',
|
||||
children: row.map((day, i) =>
|
||||
CalendarDay(day.day, day.today)
|
||||
)
|
||||
}))
|
||||
}
|
||||
function shiftCalendarXMonths(x) {
|
||||
if (x == 0)
|
||||
monthshift = 0;
|
||||
else
|
||||
monthshift += x;
|
||||
var newDate = undefined;
|
||||
if (monthshift == 0)
|
||||
newDate = new Date();
|
||||
else
|
||||
newDate = getDateInXMonthsTime(monthshift);
|
||||
calendarJson = getCalendarLayout(newDate, monthshift == 0);
|
||||
calendarMonthYear.label = `${monthshift == 0 ? '' : '• '}${newDate.toLocaleString('default', { month: 'long' })} ${newDate.getFullYear()}`;
|
||||
addCalendarChildren(calendarDays, calendarJson);
|
||||
}
|
||||
const calendarHeader = Widget.Box({
|
||||
className: 'spacing-h-5 sidebar-calendar-header',
|
||||
setup: (box) => {
|
||||
box.pack_start(calendarMonthYear, false, false, 0);
|
||||
box.pack_end(Widget.Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
Button({
|
||||
className: 'sidebar-calendar-monthshift-btn',
|
||||
onClicked: () => shiftCalendarXMonths(-1),
|
||||
child: MaterialIcon('chevron_left', 'norm'),
|
||||
setup: (button) => setupCursorHover(button),
|
||||
}),
|
||||
Button({
|
||||
className: 'sidebar-calendar-monthshift-btn',
|
||||
onClicked: () => shiftCalendarXMonths(1),
|
||||
child: MaterialIcon('chevron_right', 'norm'),
|
||||
setup: (button) => setupCursorHover(button),
|
||||
})
|
||||
]
|
||||
}), false, false, 0);
|
||||
}
|
||||
})
|
||||
const calendarDays = Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
setup: (box) => {
|
||||
addCalendarChildren(box, calendarJson);
|
||||
}
|
||||
});
|
||||
return Widget.EventBox({
|
||||
onScrollUp: () => shiftCalendarXMonths(-1),
|
||||
onScrollDown: () => shiftCalendarXMonths(1),
|
||||
child: Widget.Box({
|
||||
halign: 'center',
|
||||
children: [
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
children: [
|
||||
calendarHeader,
|
||||
Widget.Box({
|
||||
homogeneous: true,
|
||||
className: 'spacing-h-5',
|
||||
children: weekDays.map((day, i) => CalendarDay(day.day, day.today))
|
||||
}),
|
||||
calendarDays,
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
const defaultTodoSelected = 'undone';
|
||||
|
||||
const todoItems = (isDone) => Widget.Scrollable({
|
||||
const calendarMonthYear = Widget.Button({
|
||||
className: "txt txt-large sidebar-calendar-monthyear-btn",
|
||||
onClicked: () => shiftCalendarXMonths(0),
|
||||
setup: button => {
|
||||
button.label = `${new Date().toLocaleString("default", {month: "long"})} ${new Date().getFullYear()}`
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
const addCalendarChildren = (box, calendarJson) => {
|
||||
box.children = calendarJson.map((row, i) =>
|
||||
Widget.Box({
|
||||
// homogeneous: true,
|
||||
className: "spacing-h-5",
|
||||
children: row.map((day, i) => CalendarDay(day.day, day.today)),
|
||||
}),
|
||||
)
|
||||
}
|
||||
function shiftCalendarXMonths(x) {
|
||||
if (x == 0) monthshift = 0
|
||||
else monthshift += x
|
||||
var newDate = undefined
|
||||
if (monthshift == 0) newDate = new Date()
|
||||
else newDate = getDateInXMonthsTime(monthshift)
|
||||
calendarJson = getCalendarLayout(newDate, monthshift == 0)
|
||||
calendarMonthYear.label = `${monthshift == 0 ? "" : "• "}${newDate.toLocaleString("default", {
|
||||
month: "long",
|
||||
})} ${newDate.getFullYear()}`
|
||||
addCalendarChildren(calendarDays, calendarJson)
|
||||
}
|
||||
const calendarHeader = Widget.Box({
|
||||
className: "spacing-h-5 sidebar-calendar-header",
|
||||
setup: box => {
|
||||
box.pack_start(calendarMonthYear, false, false, 0)
|
||||
box.pack_end(
|
||||
Widget.Box({
|
||||
className: "spacing-h-5",
|
||||
children: [
|
||||
Button({
|
||||
className: "sidebar-calendar-monthshift-btn",
|
||||
onClicked: () => shiftCalendarXMonths(-1),
|
||||
child: MaterialIcon("chevron_left", "norm"),
|
||||
setup: button => setupCursorHover(button),
|
||||
}),
|
||||
Button({
|
||||
className: "sidebar-calendar-monthshift-btn",
|
||||
onClicked: () => shiftCalendarXMonths(1),
|
||||
child: MaterialIcon("chevron_right", "norm"),
|
||||
setup: button => setupCursorHover(button),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
)
|
||||
},
|
||||
})
|
||||
const calendarDays = Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
setup: box => {
|
||||
addCalendarChildren(box, calendarJson)
|
||||
},
|
||||
})
|
||||
return Widget.EventBox({
|
||||
onScrollUp: () => shiftCalendarXMonths(-1),
|
||||
onScrollDown: () => shiftCalendarXMonths(1),
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
connections: [[Todo, (self) => {
|
||||
halign: "center",
|
||||
children: [
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
children: [
|
||||
calendarHeader,
|
||||
Widget.Box({
|
||||
homogeneous: true,
|
||||
className: "spacing-h-5",
|
||||
children: weekDays.map((day, i) => CalendarDay(day.day, day.today)),
|
||||
}),
|
||||
calendarDays,
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
const defaultTodoSelected = "undone"
|
||||
|
||||
const todoItems = isDone =>
|
||||
Widget.Scrollable({
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
connections: [
|
||||
[
|
||||
Todo,
|
||||
self => {
|
||||
self.children = Todo.todo_json.map((task, i) => {
|
||||
if (task.done != isDone) return null;
|
||||
return Widget.Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: 'txt txt-small',
|
||||
label: '•',
|
||||
}),
|
||||
Widget.Label({
|
||||
hexpand: true,
|
||||
xalign: 0,
|
||||
wrap: true,
|
||||
className: 'txt txt-small sidebar-todo-txt',
|
||||
label: task.content,
|
||||
}),
|
||||
Widget.Button({
|
||||
valign: 'center',
|
||||
className: 'txt sidebar-todo-item-action',
|
||||
child: MaterialIcon(`${isDone ? 'remove_done' : 'check'}`, 'norm', { valign: 'center' }),
|
||||
onClicked: () => {
|
||||
if (isDone)
|
||||
Todo.uncheck(i);
|
||||
else
|
||||
Todo.check(i);
|
||||
},
|
||||
setup: (button) => setupCursorHover(button),
|
||||
}),
|
||||
Widget.Button({
|
||||
valign: 'center',
|
||||
className: 'txt sidebar-todo-item-action',
|
||||
child: MaterialIcon('delete_forever', 'norm', { valign: 'center' }),
|
||||
onClicked: () => {
|
||||
Todo.remove(i);
|
||||
},
|
||||
setup: (button) => setupCursorHover(button),
|
||||
}),
|
||||
]
|
||||
});
|
||||
if (task.done != isDone) return null
|
||||
return Widget.Box({
|
||||
className: "spacing-h-5",
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: "txt txt-small",
|
||||
label: "•",
|
||||
}),
|
||||
Widget.Label({
|
||||
hexpand: true,
|
||||
xalign: 0,
|
||||
wrap: true,
|
||||
className: "txt txt-small sidebar-todo-txt",
|
||||
label: task.content,
|
||||
}),
|
||||
Widget.Button({
|
||||
valign: "center",
|
||||
className: "txt sidebar-todo-item-action",
|
||||
child: MaterialIcon(`${isDone ? "remove_done" : "check"}`, "norm", {valign: "center"}),
|
||||
onClicked: () => {
|
||||
if (isDone) Todo.uncheck(i)
|
||||
else Todo.check(i)
|
||||
},
|
||||
setup: button => setupCursorHover(button),
|
||||
}),
|
||||
Widget.Button({
|
||||
valign: "center",
|
||||
className: "txt sidebar-todo-item-action",
|
||||
child: MaterialIcon("delete_forever", "norm", {valign: "center"}),
|
||||
onClicked: () => {
|
||||
Todo.remove(i)
|
||||
},
|
||||
setup: button => setupCursorHover(button),
|
||||
}),
|
||||
],
|
||||
})
|
||||
})
|
||||
if (self.children.length == 0) {
|
||||
self.homogeneous = true;
|
||||
self.children = [
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
valign: 'center',
|
||||
className: 'txt',
|
||||
children: [
|
||||
MaterialIcon(`${isDone ? 'checklist' : 'check_circle'}`, 'badonkers'),
|
||||
Label({ label: `${isDone ? 'Finished tasks will go here' : 'Nothing here!'}` })
|
||||
]
|
||||
})
|
||||
]
|
||||
}
|
||||
else self.homogeneous = false;
|
||||
}, 'updated']]
|
||||
})
|
||||
});
|
||||
self.homogeneous = true
|
||||
self.children = [
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
valign: "center",
|
||||
className: "txt",
|
||||
children: [
|
||||
MaterialIcon(`${isDone ? "checklist" : "check_circle"}`, "badonkers"),
|
||||
Label({label: `${isDone ? "Finished tasks will go here" : "Nothing here!"}`}),
|
||||
],
|
||||
}),
|
||||
]
|
||||
} else self.homogeneous = false
|
||||
},
|
||||
"updated",
|
||||
],
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
const todoItemsBox = Widget.Stack({
|
||||
valign: 'fill',
|
||||
transition: 'slide_left_right',
|
||||
items: [
|
||||
['undone', todoItems(false)],
|
||||
['done', todoItems(true)],
|
||||
],
|
||||
});
|
||||
valign: "fill",
|
||||
transition: "slide_left_right",
|
||||
items: [
|
||||
["undone", todoItems(false)],
|
||||
["done", todoItems(true)],
|
||||
],
|
||||
})
|
||||
|
||||
const TodoWidget = () => {
|
||||
const TodoTabButton = (isDone, navIndex) => Widget.Button({
|
||||
hexpand: true,
|
||||
className: 'sidebar-todo-selector-tab',
|
||||
onClicked: (button) => {
|
||||
todoItemsBox.shown = `${isDone ? 'done' : 'undone'}`;
|
||||
const kids = button.get_parent().get_children();
|
||||
for (let i = 0; i < kids.length; i++) {
|
||||
if (kids[i] != button) kids[i].toggleClassName('sidebar-todo-selector-tab-active', false);
|
||||
else button.toggleClassName('sidebar-todo-selector-tab-active', true);
|
||||
}
|
||||
// Fancy highlighter line width
|
||||
const buttonWidth = button.get_allocated_width();
|
||||
const highlightWidth = button.get_children()[0].get_allocated_width();
|
||||
navIndicator.style = `
|
||||
font-size: ${navIndex}px;
|
||||
padding: 0px ${(buttonWidth - highlightWidth) / 2}px;
|
||||
`;
|
||||
},
|
||||
child: Box({
|
||||
halign: 'center',
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
MaterialIcon(`${isDone ? 'task_alt' : 'format_list_bulleted'}`, 'larger'),
|
||||
Label({
|
||||
className: 'txt txt-smallie',
|
||||
label: `${isDone ? 'Done' : 'Unfinished'}`,
|
||||
})
|
||||
]
|
||||
}),
|
||||
setup: (button) => {
|
||||
button.toggleClassName('sidebar-todo-selector-tab-active', defaultTodoSelected === `${isDone ? 'done' : 'undone'}`);
|
||||
setupCursorHover(button);
|
||||
},
|
||||
});
|
||||
const undoneButton = TodoTabButton(false, 0);
|
||||
const doneButton = TodoTabButton(true, 1);
|
||||
const navIndicator = NavigationIndicator(2, false, {
|
||||
className: 'sidebar-todo-selector-highlight',
|
||||
style: 'font-size: 0px;',
|
||||
setup: (self) => {
|
||||
// Fancy highlighter line width
|
||||
const buttonWidth = undoneButton.get_allocated_width();
|
||||
const highlightWidth = undoneButton.get_children()[0].get_allocated_width();
|
||||
navIndicator.style = `
|
||||
font-size: ${navIndex}px;
|
||||
padding: 0px ${(buttonWidth - highlightWidth) / 2}px;
|
||||
`;
|
||||
const TodoTabButton = (isDone, navIndex) =>
|
||||
Widget.Button({
|
||||
hexpand: true,
|
||||
className: "sidebar-todo-selector-tab",
|
||||
onClicked: button => {
|
||||
todoItemsBox.shown = `${isDone ? "done" : "undone"}`
|
||||
const kids = button.get_parent().get_children()
|
||||
for (let i = 0; i < kids.length; i++) {
|
||||
if (kids[i] != button) kids[i].toggleClassName("sidebar-todo-selector-tab-active", false)
|
||||
else button.toggleClassName("sidebar-todo-selector-tab-active", true)
|
||||
}
|
||||
// Fancy highlighter line width
|
||||
const buttonWidth = button.get_allocated_width()
|
||||
const highlightWidth = button.get_children()[0].get_allocated_width()
|
||||
navIndicator.style = `
|
||||
font-size: ${navIndex}px;
|
||||
padding: 0px ${(buttonWidth - highlightWidth) / 2}px;
|
||||
`
|
||||
},
|
||||
child: Box({
|
||||
halign: "center",
|
||||
className: "spacing-h-5",
|
||||
children: [
|
||||
MaterialIcon(`${isDone ? "task_alt" : "format_list_bulleted"}`, "larger"),
|
||||
Label({
|
||||
className: "txt txt-smallie",
|
||||
label: `${isDone ? "Done" : "Unfinished"}`,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
setup: button => {
|
||||
button.toggleClassName(
|
||||
"sidebar-todo-selector-tab-active",
|
||||
defaultTodoSelected === `${isDone ? "done" : "undone"}`,
|
||||
)
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
return Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
className: 'spacing-v-10',
|
||||
setup: (box) => {
|
||||
// undone/done selector rail
|
||||
box.pack_start(Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Box({
|
||||
className: 'sidebar-todo-selectors spacing-h-5',
|
||||
homogeneous: true,
|
||||
setup: (box) => {
|
||||
box.pack_start(undoneButton, false, true, 0);
|
||||
box.pack_start(doneButton, false, true, 0);
|
||||
}
|
||||
}),
|
||||
Widget.Box({
|
||||
className: 'sidebar-todo-selector-highlight-offset',
|
||||
homogeneous: true,
|
||||
children: [navIndicator]
|
||||
})
|
||||
]
|
||||
}), false, false, 0);
|
||||
box.pack_end(todoItemsBox, true, true, 0);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const defaultShown = 'calendar';
|
||||
const contentStack = Widget.Stack({
|
||||
const undoneButton = TodoTabButton(false, 0)
|
||||
const doneButton = TodoTabButton(true, 1)
|
||||
const navIndicator = NavigationIndicator(2, false, {
|
||||
className: "sidebar-todo-selector-highlight",
|
||||
style: "font-size: 0px;",
|
||||
setup: self => {
|
||||
// Fancy highlighter line width
|
||||
const buttonWidth = undoneButton.get_allocated_width()
|
||||
const highlightWidth = undoneButton.get_children()[0].get_allocated_width()
|
||||
navIndicator.style = `
|
||||
font-size: ${navIndex}px;
|
||||
padding: 0px ${(buttonWidth - highlightWidth) / 2}px;
|
||||
`
|
||||
},
|
||||
})
|
||||
return Widget.Box({
|
||||
hexpand: true,
|
||||
items: [
|
||||
['calendar', CalendarWidget()],
|
||||
['todo', TodoWidget()],
|
||||
// ['stars', Widget.Label({ label: 'GitHub feed will be here' })],
|
||||
],
|
||||
transition: 'slide_up_down',
|
||||
transitionDuration: 180,
|
||||
setup: (stack) => {
|
||||
stack.shown = defaultShown;
|
||||
}
|
||||
vertical: true,
|
||||
className: "spacing-v-10",
|
||||
setup: box => {
|
||||
// undone/done selector rail
|
||||
box.pack_start(
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Box({
|
||||
className: "sidebar-todo-selectors spacing-h-5",
|
||||
homogeneous: true,
|
||||
setup: box => {
|
||||
box.pack_start(undoneButton, false, true, 0)
|
||||
box.pack_start(doneButton, false, true, 0)
|
||||
},
|
||||
}),
|
||||
Widget.Box({
|
||||
className: "sidebar-todo-selector-highlight-offset",
|
||||
homogeneous: true,
|
||||
children: [navIndicator],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
)
|
||||
box.pack_end(todoItemsBox, true, true, 0)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const defaultShown = "calendar"
|
||||
const contentStack = Widget.Stack({
|
||||
hexpand: true,
|
||||
items: [
|
||||
["calendar", CalendarWidget()],
|
||||
["todo", TodoWidget()],
|
||||
// ['stars', Widget.Label({ label: 'GitHub feed will be here' })],
|
||||
],
|
||||
transition: "slide_up_down",
|
||||
transitionDuration: 180,
|
||||
setup: stack => {
|
||||
stack.shown = defaultShown
|
||||
},
|
||||
})
|
||||
|
||||
const StackButton = (stackItemName, icon, name) => Widget.Button({
|
||||
className: 'button-minsize sidebar-navrail-btn sidebar-button-alone txt-small spacing-h-5',
|
||||
onClicked: (button) => {
|
||||
contentStack.shown = stackItemName;
|
||||
const kids = button.get_parent().get_children();
|
||||
for (let i = 0; i < kids.length; i++) {
|
||||
if (kids[i] != button) kids[i].toggleClassName('sidebar-navrail-btn-active', false);
|
||||
else button.toggleClassName('sidebar-navrail-btn-active', true);
|
||||
}
|
||||
const StackButton = (stackItemName, icon, name) =>
|
||||
Widget.Button({
|
||||
className: "button-minsize sidebar-navrail-btn sidebar-button-alone txt-small spacing-h-5",
|
||||
onClicked: button => {
|
||||
contentStack.shown = stackItemName
|
||||
const kids = button.get_parent().get_children()
|
||||
for (let i = 0; i < kids.length; i++) {
|
||||
if (kids[i] != button) kids[i].toggleClassName("sidebar-navrail-btn-active", false)
|
||||
else button.toggleClassName("sidebar-navrail-btn-active", true)
|
||||
}
|
||||
},
|
||||
child: Box({
|
||||
className: 'spacing-v-5',
|
||||
vertical: true,
|
||||
children: [
|
||||
Label({
|
||||
className: `txt icon-material txt-hugeass`,
|
||||
label: icon,
|
||||
}),
|
||||
Label({
|
||||
label: name,
|
||||
className: 'txt txt-smallie',
|
||||
}),
|
||||
]
|
||||
className: "spacing-v-5",
|
||||
vertical: true,
|
||||
children: [
|
||||
Label({
|
||||
className: `txt icon-material txt-hugeass`,
|
||||
label: icon,
|
||||
}),
|
||||
Label({
|
||||
label: name,
|
||||
className: "txt txt-smallie",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
setup: (button) => {
|
||||
button.toggleClassName('sidebar-navrail-btn-active', defaultShown === stackItemName);
|
||||
setupCursorHover(button);
|
||||
}
|
||||
});
|
||||
setup: button => {
|
||||
button.toggleClassName("sidebar-navrail-btn-active", defaultShown === stackItemName)
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
|
||||
export const ModuleCalendar = () => Box({
|
||||
className: 'sidebar-group spacing-h-5',
|
||||
setup: (box) => {
|
||||
box.pack_start(Box({
|
||||
valign: 'center',
|
||||
homogeneous: true,
|
||||
vertical: true,
|
||||
className: 'sidebar-navrail spacing-v-10',
|
||||
children: [
|
||||
StackButton('calendar', 'calendar_month', 'Calendar'),
|
||||
StackButton('todo', 'checklist', 'To Do'),
|
||||
// StackButton(box, 'stars', 'star', 'GitHub'),
|
||||
]
|
||||
}), false, false, 0);
|
||||
// ags.Widget({ // TDOO: replace this sad default calendar with a custom one
|
||||
// type: imports.gi.Gtk.Calendar,
|
||||
// }),
|
||||
box.pack_end(contentStack, false, false, 0);
|
||||
}
|
||||
})
|
||||
export const ModuleCalendar = () =>
|
||||
Box({
|
||||
className: "sidebar-group spacing-h-5",
|
||||
setup: box => {
|
||||
box.pack_start(
|
||||
Box({
|
||||
valign: "center",
|
||||
homogeneous: true,
|
||||
vertical: true,
|
||||
className: "sidebar-navrail spacing-v-10",
|
||||
children: [
|
||||
StackButton("calendar", "calendar_month", "Calendar"),
|
||||
StackButton("todo", "checklist", "To Do"),
|
||||
// StackButton(box, 'stars', 'star', 'GitHub'),
|
||||
],
|
||||
}),
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
)
|
||||
// ags.Widget({ // TDOO: replace this sad default calendar with a custom one
|
||||
// type: imports.gi.Gtk.Calendar,
|
||||
// }),
|
||||
box.pack_end(contentStack, false, false, 0)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,60 +1,81 @@
|
||||
import { Widget } from '../imports.js';
|
||||
import { keybindList } from "../data/keybinds.js";
|
||||
import {Widget} from "../imports.js"
|
||||
import {keybindList} from "../data/keybinds.js"
|
||||
|
||||
export const Keybinds = () => Widget.Box({
|
||||
export const Keybinds = () =>
|
||||
Widget.Box({
|
||||
vertical: false,
|
||||
className: "spacing-h-15",
|
||||
homogeneous: true,
|
||||
children: keybindList.map((group, i) => Widget.Box({ // Columns
|
||||
children: keybindList.map((group, i) =>
|
||||
Widget.Box({
|
||||
// Columns
|
||||
vertical: true,
|
||||
className: "spacing-v-15",
|
||||
children: group.map((category, i) => Widget.Box({ // Categories
|
||||
children: group.map((category, i) =>
|
||||
Widget.Box({
|
||||
// Categories
|
||||
vertical: true,
|
||||
className: "spacing-v-15",
|
||||
children: [
|
||||
Widget.Box({ // Category header
|
||||
vertical: false,
|
||||
className: "spacing-h-10",
|
||||
children: [
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "icon-material txt txt-larger",
|
||||
label: category.icon,
|
||||
}),
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "cheatsheet-category-title txt",
|
||||
label: category.name,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
vertical: false,
|
||||
className: "spacing-h-10",
|
||||
children: [
|
||||
Widget.Box({ // Keys
|
||||
vertical: true,
|
||||
homogeneous: true,
|
||||
children: category.binds.map((keybinds, i) => Widget.Box({ // Binds
|
||||
vertical: false,
|
||||
children: keybinds.keys.map((key, i) => Widget.Label({ // Specific keys
|
||||
className: `${key == 'OR' || key == '+' ? 'cheatsheet-key-notkey' : 'cheatsheet-key'} txt-small`,
|
||||
label: key,
|
||||
}))
|
||||
}))
|
||||
}),
|
||||
Widget.Box({ // Actions
|
||||
vertical: true,
|
||||
homogeneous: true,
|
||||
children: category.binds.map((keybinds, i) => Widget.Label({ // Binds
|
||||
xalign: 0,
|
||||
label: keybinds.action,
|
||||
className: "txt chearsheet-action txt-small",
|
||||
}))
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
}))
|
||||
})),
|
||||
});
|
||||
Widget.Box({
|
||||
// Category header
|
||||
vertical: false,
|
||||
className: "spacing-h-10",
|
||||
children: [
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "icon-material txt txt-larger",
|
||||
label: category.icon,
|
||||
}),
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "cheatsheet-category-title txt",
|
||||
label: category.name,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
vertical: false,
|
||||
className: "spacing-h-10",
|
||||
children: [
|
||||
Widget.Box({
|
||||
// Keys
|
||||
vertical: true,
|
||||
homogeneous: true,
|
||||
children: category.binds.map((keybinds, i) =>
|
||||
Widget.Box({
|
||||
// Binds
|
||||
vertical: false,
|
||||
children: keybinds.keys.map((key, i) =>
|
||||
Widget.Label({
|
||||
// Specific keys
|
||||
className: `${
|
||||
key == "OR" || key == "+" ? "cheatsheet-key-notkey" : "cheatsheet-key"
|
||||
} txt-small`,
|
||||
label: key,
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
Widget.Box({
|
||||
// Actions
|
||||
vertical: true,
|
||||
homogeneous: true,
|
||||
children: category.binds.map((keybinds, i) =>
|
||||
Widget.Label({
|
||||
// Binds
|
||||
xalign: 0,
|
||||
label: keybinds.action,
|
||||
className: "txt chearsheet-action txt-small",
|
||||
}),
|
||||
),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
})
|
||||
|
||||
@@ -1,101 +1,99 @@
|
||||
import { App, Service, Utils, Widget } from '../imports.js';
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
const { CONFIG_DIR, exec, execAsync } = Utils;
|
||||
import { deflisten } from '../scripts/scripts.js';
|
||||
import { setupCursorHover } from "./lib/cursorhover.js";
|
||||
import { RoundedCorner } from "./lib/roundedcorner.js";
|
||||
import Brightness from '../scripts/brightness.js';
|
||||
import Indicator from '../scripts/indicator.js';
|
||||
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js"
|
||||
import {setupCursorHover} from "./lib/cursorhover.js"
|
||||
import RoundedCorner from "./lib/roundedcorner.js"
|
||||
import Brightness from "../scripts/brightness.js"
|
||||
import Indicator from "../scripts/indicator.js"
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
|
||||
// Removes everything after the last
|
||||
// em dash, en dash, minus, vertical bar, or middle dot (note: maybe add open parenthesis?)
|
||||
// For example:
|
||||
// • Discord | #ricing-theming | r/unixporn — Mozilla Firefox --> • Discord | #ricing-theming
|
||||
// GJS Error · Issue #112 · Aylur/ags — Mozilla Firefox --> GJS Error · Issue #112
|
||||
/**
|
||||
* Removes everything after the last em dash, en dash, minus, vertical bar, or middle (note: maybe add open parenthesis?)
|
||||
* @example
|
||||
* truncateTitle("• Discord | #ricing-theming | r/unixporn — Mozilla Firefox") // "• Discord | #ricing-theming"
|
||||
* @example
|
||||
* truncateTitle("GJS Error · Issue #112 · Aylur/ags — Mozilla Firefox") // "GJS Error · Issue #112"
|
||||
* @param str {string}
|
||||
* @returns {string}
|
||||
*/
|
||||
function truncateTitle(str) {
|
||||
let lastDash = -1;
|
||||
let found = -1; // 0: em dash, 1: en dash, 2: minus, 3: vertical bar, 4: middle dot
|
||||
for (let i = str.length - 1; i >= 0; i--) {
|
||||
if (str[i] === '—') {
|
||||
found = 0;
|
||||
lastDash = i;
|
||||
}
|
||||
else if (str[i] === '–' && found < 1) {
|
||||
found = 1;
|
||||
lastDash = i;
|
||||
}
|
||||
else if (str[i] === '-' && found < 2) {
|
||||
found = 2;
|
||||
lastDash = i;
|
||||
}
|
||||
else if (str[i] === '|' && found < 3) {
|
||||
found = 3;
|
||||
lastDash = i;
|
||||
}
|
||||
else if (str[i] === '·' && found < 4) {
|
||||
found = 4;
|
||||
lastDash = i;
|
||||
}
|
||||
}
|
||||
if (lastDash === -1) return str;
|
||||
return str.substring(0, lastDash);
|
||||
return str.replace(/\s*[—–\-|·][^—–\-|·]+$/, "")
|
||||
}
|
||||
|
||||
export const ModuleLeftSpace = () => Widget.EventBox({
|
||||
onScrollUp: () => {
|
||||
Indicator.popup(1); // Since the brightness and speaker are both on the same window
|
||||
Brightness.screen_value += 0.05;
|
||||
function WindowTitle() {
|
||||
return Widget.Button({
|
||||
class_name: "bar-space-button",
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Scrollable({
|
||||
hexpand: true,
|
||||
vexpand: true,
|
||||
hscroll: "automatic",
|
||||
vscroll: "never",
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "txt txt-smaller bar-topdesc",
|
||||
connections: [
|
||||
[
|
||||
Hyprland,
|
||||
label => {
|
||||
label.label =
|
||||
Hyprland.active.client._class.length === 0 ? "Desktop" : Hyprland.active.client._class
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "txt txt-smallie",
|
||||
connections: [
|
||||
[
|
||||
Hyprland,
|
||||
label => {
|
||||
// Hyprland.active.client
|
||||
label.label =
|
||||
Hyprland.active.client._title.length === 0
|
||||
? `Workspace ${Hyprland.active.workspace.id}`
|
||||
: truncateTitle(Hyprland.active.client._title)
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
setup: button => setupCursorHover(button),
|
||||
})
|
||||
}
|
||||
|
||||
export const ModuleLeftSpace = () =>
|
||||
Widget.EventBox({
|
||||
on_scroll_up() {
|
||||
Indicator.popup(1) // Since the brightness and speaker are both on the same window
|
||||
Brightness.screen_value += 0.05
|
||||
},
|
||||
onScrollDown: () => {
|
||||
Indicator.popup(1); // Since the brightness and speaker are both on the same window
|
||||
Brightness.screen_value -= 0.05;
|
||||
on_scroll_down() {
|
||||
Indicator.popup(1) // Since the brightness and speaker are both on the same window
|
||||
Brightness.screen_value -= 0.05
|
||||
},
|
||||
child: Widget.Box({
|
||||
homogeneous: false,
|
||||
children: [
|
||||
RoundedCorner('topleft', { className: 'corner-black' }),
|
||||
Widget.Overlay({
|
||||
overlays: [
|
||||
Widget.Box({ hexpand: true }),
|
||||
Widget.Box({
|
||||
className: 'bar-sidemodule', hexpand: true,
|
||||
children: [Widget.Button({
|
||||
className: 'bar-space-button',
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Scrollable({
|
||||
hexpand: true, vexpand: true,
|
||||
hscroll: 'automatic', vscroll: 'never',
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: 'txt txt-smaller bar-topdesc',
|
||||
connections: [[Hyprland, label => { // Hyprland.active.client
|
||||
label.label = Hyprland.active.client._class.length === 0 ? 'Desktop' : Hyprland.active.client._class;
|
||||
}]],
|
||||
}),
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: 'txt txt-smallie',
|
||||
connections: [
|
||||
[Hyprland, label => { // Hyprland.active.client
|
||||
label.label = Hyprland.active.client._title.length === 0 ? `Workspace ${Hyprland.active.workspace.id}` : truncateTitle(Hyprland.active.client._title);
|
||||
}]
|
||||
],
|
||||
})
|
||||
]
|
||||
})
|
||||
})
|
||||
]
|
||||
}),
|
||||
setup: (button) => setupCursorHover(button),
|
||||
})]
|
||||
}),
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
homogeneous: false,
|
||||
children: [
|
||||
RoundedCorner("top", "left", {className: "corner-black"}),
|
||||
Widget.Overlay({
|
||||
overlays: [
|
||||
Widget.Box({hexpand: true}),
|
||||
Widget.Box({
|
||||
class_name: "bar-sidemodule",
|
||||
hexpand: true,
|
||||
children: [WindowTitle()],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -1,97 +1,96 @@
|
||||
// Not yet used. For cool drag and drop stuff. Thanks DevAlien
|
||||
|
||||
const Toggles = {};
|
||||
Toggles.Wifi = NetworkToggle;
|
||||
Toggles.Bluetooth = BluetoothToggle;
|
||||
Toggles.DND = DNDToggle;
|
||||
Toggles.ThemeToggle = ThemeToggle;
|
||||
Toggles.ProfileToggle = ProfileToggle;
|
||||
const Toggles = {}
|
||||
Toggles.Wifi = NetworkToggle
|
||||
Toggles.Bluetooth = BluetoothToggle
|
||||
Toggles.DND = DNDToggle
|
||||
Toggles.ThemeToggle = ThemeToggle
|
||||
Toggles.ProfileToggle = ProfileToggle
|
||||
// Toggles.Record = RecordToggle;
|
||||
// Toggles.Airplane = AirplaneToggle;
|
||||
// Toggles.DoNotDisturb = DoNotDisturbToggle;
|
||||
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)];
|
||||
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)]
|
||||
|
||||
export class ActionCenter extends Gtk.Box {
|
||||
static {
|
||||
GObject.registerClass({
|
||||
GTypeName: 'ActionCenter',
|
||||
Properties: {
|
||||
|
||||
GObject.registerClass(
|
||||
{
|
||||
GTypeName: "ActionCenter",
|
||||
Properties: {},
|
||||
},
|
||||
}, this);
|
||||
this,
|
||||
)
|
||||
}
|
||||
|
||||
constructor({ className = "ActionCenter", toggles, ...rest }) {
|
||||
super(rest);
|
||||
constructor({className = "ActionCenter", toggles, ...rest}) {
|
||||
super(rest)
|
||||
this.toggles = Toggles
|
||||
this.currentToggles = Settings.getSetting("toggles", []);
|
||||
this.mainFlowBox = this._setupFlowBox(className + QSView.editing && className + "Editing");
|
||||
this.mainFlowBox.connect("drag_motion", this._dragMotionMain);
|
||||
this.mainFlowBox.connect("drag_drop", this._dragDropMain);
|
||||
this._dragged = {};
|
||||
this._draggedExtra = {};
|
||||
this.currentToggles = Settings.getSetting("toggles", [])
|
||||
this.mainFlowBox = this._setupFlowBox(className + QSView.editing && className + "Editing")
|
||||
this.mainFlowBox.connect("drag_motion", this._dragMotionMain)
|
||||
this.mainFlowBox.connect("drag_drop", this._dragDropMain)
|
||||
this._dragged = {}
|
||||
this._draggedExtra = {}
|
||||
|
||||
this._dragged;
|
||||
this._currentPosition = 0;
|
||||
this._orderedState;
|
||||
this._draggedName;
|
||||
this._dragged
|
||||
this._currentPosition = 0
|
||||
this._orderedState
|
||||
this._draggedName
|
||||
|
||||
this.updateList(toggles, this.mainFlowBox)
|
||||
|
||||
this.set_orientation(Gtk.Orientation.VERTICAL);
|
||||
this.set_orientation(Gtk.Orientation.VERTICAL)
|
||||
this.add(this.mainFlowBox)
|
||||
this.mainFlowBox.set_size_request(1, 30)
|
||||
if (QSView.editing) {
|
||||
this.extraFlowBox = this._setupFlowBox(className);
|
||||
this.extraFlowBox.connect("drag_motion", this._dragMotionExtra);
|
||||
this.extraFlowBox.connect("drag_drop", this._dragDropExtra);
|
||||
this.extraFlowBox = this._setupFlowBox(className)
|
||||
this.extraFlowBox.connect("drag_motion", this._dragMotionExtra)
|
||||
this.extraFlowBox.connect("drag_drop", this._dragDropExtra)
|
||||
this.updateList(this._getExtraToggles(), this.extraFlowBox)
|
||||
this.add(Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Label("Extra widgets"),
|
||||
Label("Drop here to remove or drag from here to add"),
|
||||
this.extraFlowBox
|
||||
]
|
||||
}))
|
||||
this.add(
|
||||
Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Label("Extra widgets"),
|
||||
Label("Drop here to remove or drag from here to add"),
|
||||
this.extraFlowBox,
|
||||
],
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_getExtraToggles() {
|
||||
let toggles = { ...this.toggles }
|
||||
let toggles = {...this.toggles}
|
||||
this.currentToggles.map(t => {
|
||||
if (toggles[t]) {
|
||||
delete toggles[t];
|
||||
delete toggles[t]
|
||||
}
|
||||
});
|
||||
return Object.keys(toggles);
|
||||
})
|
||||
return Object.keys(toggles)
|
||||
}
|
||||
|
||||
_setupFlowBox(className) {
|
||||
const flowBox = new Gtk.FlowBox();
|
||||
flowBox.set_valign(Gtk.Align.FILL);
|
||||
flowBox.set_min_children_per_line(2);
|
||||
flowBox.set_max_children_per_line(2);
|
||||
flowBox.set_selection_mode(Gtk.SelectionMode.NONE);
|
||||
flowBox.get_style_context().add_class(className);
|
||||
flowBox.set_homogeneous(true);
|
||||
flowBox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
|
||||
const flowBox = new Gtk.FlowBox()
|
||||
flowBox.set_valign(Gtk.Align.FILL)
|
||||
flowBox.set_min_children_per_line(2)
|
||||
flowBox.set_max_children_per_line(2)
|
||||
flowBox.set_selection_mode(Gtk.SelectionMode.NONE)
|
||||
flowBox.get_style_context().add_class(className)
|
||||
flowBox.set_homogeneous(true)
|
||||
flowBox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY)
|
||||
|
||||
return flowBox;
|
||||
return flowBox
|
||||
}
|
||||
|
||||
createWidget = (name, index, type) => {
|
||||
const editSetup = (widget) => {
|
||||
widget.drag_source_set(
|
||||
Gdk.ModifierType.BUTTON1_MASK,
|
||||
TARGET,
|
||||
Gdk.DragAction.COPY
|
||||
);
|
||||
const editSetup = widget => {
|
||||
widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.COPY)
|
||||
|
||||
widget.connect("drag-begin", (w, context) => {
|
||||
const widgetContainer = widget.get_parent();
|
||||
const widgetContainer = widget.get_parent()
|
||||
|
||||
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(widgetContainer));
|
||||
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(widgetContainer))
|
||||
this._dragged = {
|
||||
widget: widgetContainer.get_parent().get_parent(),
|
||||
container: widgetContainer,
|
||||
@@ -100,146 +99,143 @@ export class ActionCenter extends Gtk.Box {
|
||||
currentPositionExtra: type === "Extra" ? index : null,
|
||||
from: type,
|
||||
}
|
||||
widgetContainer.get_style_context().add_class("hidden");
|
||||
widgetContainer.get_style_context().add_class("hidden")
|
||||
if (type !== "Main") {
|
||||
this.extraFlowBox.remove(this._dragged.widget);
|
||||
this.extraFlowBox.remove(this._dragged.widget)
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
return true
|
||||
})
|
||||
widget.connect("drag-failed", () => {
|
||||
this.updateList(Settings.getSetting("toggles"), this.mainFlowBox)
|
||||
this.updateList(this._getExtraToggles(), this.extraFlowBox)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
let row = new Gtk.FlowBoxChild({ visible: true });
|
||||
row.add(Toggles[name]({ setup: QSView.editing && editSetup, QSView: QSView }));
|
||||
row._index = index;
|
||||
row._name = name;
|
||||
return row;
|
||||
let row = new Gtk.FlowBoxChild({visible: true})
|
||||
row.add(Toggles[name]({setup: QSView.editing && editSetup, QSView: QSView}))
|
||||
row._index = index
|
||||
row._name = name
|
||||
return row
|
||||
}
|
||||
|
||||
updateList(toggles, flowBox) {
|
||||
let type = flowBox === this.mainFlowBox ? "Main" : "Extra"
|
||||
var childrenBox = flowBox.get_children();
|
||||
childrenBox.forEach((element) => {
|
||||
flowBox.remove(element);
|
||||
element.destroy();
|
||||
});
|
||||
var childrenBox = flowBox.get_children()
|
||||
childrenBox.forEach(element => {
|
||||
flowBox.remove(element)
|
||||
element.destroy()
|
||||
})
|
||||
|
||||
if (!toggles) return;
|
||||
if (!toggles) return
|
||||
|
||||
toggles.forEach((name, i) => {
|
||||
if (Toggles[name])
|
||||
flowBox.add(this.createWidget(name, i, type));
|
||||
});
|
||||
flowBox.show_all();
|
||||
if (Toggles[name]) flowBox.add(this.createWidget(name, i, type))
|
||||
})
|
||||
flowBox.show_all()
|
||||
}
|
||||
|
||||
|
||||
_dragMotionMain = (widget, context, x, y, time) => {
|
||||
if (this._dragged.currentPositionExtra !== null) {
|
||||
this._dragged.currentPositionExtra = null;
|
||||
this._dragged.currentPositionExtra = null
|
||||
if (this._isChild(this.extraFlowBox, this._dragged.widget)) {
|
||||
this.extraFlowBox.remove(this._dragged.widget);
|
||||
this.extraFlowBox.remove(this._dragged.widget)
|
||||
}
|
||||
}
|
||||
const children = this.mainFlowBox.get_children();
|
||||
const sampleItem = children[0];
|
||||
const sampleWidth = sampleItem.get_allocation().width;
|
||||
const sampleHeight = sampleItem.get_allocated_height();
|
||||
const perLine = Math.floor(this.mainFlowBox.get_allocation().width / sampleWidth);
|
||||
const pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth);
|
||||
if (pos >= children.length && pos !== 0) return false;
|
||||
const children = this.mainFlowBox.get_children()
|
||||
const sampleItem = children[0]
|
||||
const sampleWidth = sampleItem.get_allocation().width
|
||||
const sampleHeight = sampleItem.get_allocated_height()
|
||||
const perLine = Math.floor(this.mainFlowBox.get_allocation().width / sampleWidth)
|
||||
const pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth)
|
||||
if (pos >= children.length && pos !== 0) return false
|
||||
|
||||
if (this._dragged.currentPosition === null) {
|
||||
this.mainFlowBox.insert(this._dragged.widget, pos);
|
||||
this.mainFlowBox.insert(this._dragged.widget, pos)
|
||||
|
||||
this._dragged.currentPosition = pos;
|
||||
this._dragged.currentPosition = pos
|
||||
} else if (this._dragged.currentPosition !== pos) {
|
||||
if (this._isChild(this.mainFlowBox, this._dragged.widget)) {
|
||||
this.mainFlowBox.remove(this._dragged.widget);
|
||||
this.mainFlowBox.remove(this._dragged.widget)
|
||||
}
|
||||
|
||||
this.mainFlowBox.insert(this._dragged.widget, pos);
|
||||
this.mainFlowBox.insert(this._dragged.widget, pos)
|
||||
|
||||
this._dragged.currentPosition = pos;
|
||||
this._dragged.currentPosition = pos
|
||||
}
|
||||
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
_dragDropMain = () => {
|
||||
if (this._dragged.from !== "Main") {
|
||||
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name);
|
||||
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name)
|
||||
} else {
|
||||
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name);
|
||||
this.currentToggles.splice(indexCurrentToggle, 1);
|
||||
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name);
|
||||
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name)
|
||||
this.currentToggles.splice(indexCurrentToggle, 1)
|
||||
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name)
|
||||
}
|
||||
|
||||
Settings.setSetting("toggles", this.currentToggles);
|
||||
this._dragged.container.get_style_context().remove_class("hidden");
|
||||
return true;
|
||||
Settings.setSetting("toggles", this.currentToggles)
|
||||
this._dragged.container.get_style_context().remove_class("hidden")
|
||||
return true
|
||||
}
|
||||
|
||||
_dragDropExtra = () => {
|
||||
if (this._dragged.from === "Main") {
|
||||
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name);
|
||||
this.currentToggles.splice(indexCurrentToggle, 1);
|
||||
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name)
|
||||
this.currentToggles.splice(indexCurrentToggle, 1)
|
||||
}
|
||||
|
||||
Settings.setSetting("toggles", this.currentToggles);
|
||||
this._dragged.container.get_style_context().remove_class("hidden");
|
||||
return true;
|
||||
Settings.setSetting("toggles", this.currentToggles)
|
||||
this._dragged.container.get_style_context().remove_class("hidden")
|
||||
return true
|
||||
}
|
||||
|
||||
_dragMotionExtra = (widget, context, x, y, time) => {
|
||||
if (this._dragged.currentPosition !== null) {
|
||||
this._dragged.currentPosition = null;
|
||||
this._dragged.currentPosition = null
|
||||
if (this._isChild(this.mainFlowBox, this._dragged.widget)) {
|
||||
this.mainFlowBox.remove(this._dragged.widget);
|
||||
this.mainFlowBox.remove(this._dragged.widget)
|
||||
}
|
||||
}
|
||||
|
||||
const children = this.extraFlowBox.get_children();
|
||||
const sampleItem = children[0];
|
||||
let pos = 0;
|
||||
const children = this.extraFlowBox.get_children()
|
||||
const sampleItem = children[0]
|
||||
let pos = 0
|
||||
if (sampleItem) {
|
||||
const sampleWidth = sampleItem.get_allocation().width;
|
||||
const sampleHeight = sampleItem.get_allocated_height();
|
||||
const perLine = Math.floor(this.extraFlowBox.get_allocation().width / sampleWidth);
|
||||
pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth);
|
||||
const sampleWidth = sampleItem.get_allocation().width
|
||||
const sampleHeight = sampleItem.get_allocated_height()
|
||||
const perLine = Math.floor(this.extraFlowBox.get_allocation().width / sampleWidth)
|
||||
pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth)
|
||||
}
|
||||
|
||||
if (pos >= children.length && pos !== 0) return false;
|
||||
if (pos >= children.length && pos !== 0) return false
|
||||
|
||||
if (this._dragged.currentPositionExtra === null) {
|
||||
this.extraFlowBox.insert(this._dragged.widget, pos);
|
||||
this.extraFlowBox.insert(this._dragged.widget, pos)
|
||||
|
||||
this._dragged.currentPositionExtra = pos;
|
||||
this._dragged.currentPositionExtra = pos
|
||||
}
|
||||
|
||||
if (this._dragged.currentPositionExtra !== pos) {
|
||||
if (this._isChild(this.extraFlowBox, this._dragged.widget)) {
|
||||
this.extraFlowBox.remove(this._dragged.widget);
|
||||
this.extraFlowBox.remove(this._dragged.widget)
|
||||
}
|
||||
|
||||
this.extraFlowBox.insert(this._dragged.widget, pos);
|
||||
this.extraFlowBox.insert(this._dragged.widget, pos)
|
||||
|
||||
this._dragged.currentPositionExtra = pos;
|
||||
this._dragged.currentPositionExtra = pos
|
||||
}
|
||||
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
_isChild(container, widget) {
|
||||
let found = false;
|
||||
container.get_children().forEach((c) => {
|
||||
if (c === widget) found = true;
|
||||
let found = false
|
||||
container.get_children().forEach(c => {
|
||||
if (c === widget) found = true
|
||||
})
|
||||
return found;
|
||||
return found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
import { Utils, Widget } from '../../imports.js';
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
const GObject = imports.gi.GObject
|
||||
const Lang = imports.lang
|
||||
import {Utils, Widget} from "../../imports.js"
|
||||
|
||||
// min-height for diameter
|
||||
// min-width for trough stroke
|
||||
@@ -11,64 +11,73 @@ import { Utils, Widget } from '../../imports.js';
|
||||
// color for progress color
|
||||
// font size for progress value (0-100px) (hacky i know, but i want animations)
|
||||
// TODO: border-radius for rounded ends maybe (unimportant)
|
||||
export const AnimatedCircProg = (props) => Widget({
|
||||
export const AnimatedCircProg = props =>
|
||||
Widget({
|
||||
...props,
|
||||
type: Gtk.DrawingArea,
|
||||
setup: (area) => {
|
||||
const styleContext = area.get_style_context();
|
||||
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
||||
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
||||
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
|
||||
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
|
||||
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
|
||||
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
|
||||
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
|
||||
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
|
||||
area.connect('draw', Lang.bind(area, (area, cr) => {
|
||||
const styleContext = area.get_style_context();
|
||||
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
||||
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
||||
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
|
||||
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
|
||||
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
|
||||
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
|
||||
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
|
||||
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
|
||||
setup: area => {
|
||||
const styleContext = area.get_style_context()
|
||||
const width = styleContext.get_property("min-height", Gtk.StateFlags.NORMAL)
|
||||
const height = styleContext.get_property("min-height", Gtk.StateFlags.NORMAL)
|
||||
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left
|
||||
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left
|
||||
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right
|
||||
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top
|
||||
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom
|
||||
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom)
|
||||
area.connect(
|
||||
"draw",
|
||||
Lang.bind(area, (area, cr) => {
|
||||
const styleContext = area.get_style_context()
|
||||
const width = styleContext.get_property("min-height", Gtk.StateFlags.NORMAL)
|
||||
const height = styleContext.get_property("min-height", Gtk.StateFlags.NORMAL)
|
||||
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left
|
||||
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left
|
||||
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right
|
||||
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top
|
||||
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom
|
||||
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom)
|
||||
|
||||
const progressValue = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100.0;
|
||||
|
||||
const bg_stroke = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
||||
const fg_stroke = bg_stroke - padding;
|
||||
const radius = Math.min(width, height) / 2.0 - Math.max(bg_stroke, fg_stroke) / 2.0;
|
||||
const center_x = width / 2.0 + marginLeft;
|
||||
const center_y = height / 2.0 + marginTop;
|
||||
const start_angle = -Math.PI / 2.0;
|
||||
const end_angle = start_angle + (2 * Math.PI * progressValue);
|
||||
const start_x = center_x + Math.cos(start_angle) * radius;
|
||||
const start_y = center_y + Math.sin(start_angle) * radius;
|
||||
const end_x = center_x + Math.cos(end_angle) * radius;
|
||||
const end_y = center_y + Math.sin(end_angle) * radius;
|
||||
const progressValue = styleContext.get_property("font-size", Gtk.StateFlags.NORMAL) / 100.0
|
||||
|
||||
// Draw background
|
||||
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
||||
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
|
||||
cr.arc(center_x, center_y, radius, 0, 2 * Math.PI);
|
||||
cr.setLineWidth(bg_stroke);
|
||||
cr.stroke();
|
||||
const bg_stroke = styleContext.get_property("min-width", Gtk.StateFlags.NORMAL)
|
||||
const fg_stroke = bg_stroke - padding
|
||||
const radius = Math.min(width, height) / 2.0 - Math.max(bg_stroke, fg_stroke) / 2.0
|
||||
const center_x = width / 2.0 + marginLeft
|
||||
const center_y = height / 2.0 + marginTop
|
||||
const start_angle = -Math.PI / 2.0
|
||||
const end_angle = start_angle + 2 * Math.PI * progressValue
|
||||
const start_x = center_x + Math.cos(start_angle) * radius
|
||||
const start_y = center_y + Math.sin(start_angle) * radius
|
||||
const end_x = center_x + Math.cos(end_angle) * radius
|
||||
const end_y = center_y + Math.sin(end_angle) * radius
|
||||
|
||||
// Draw progress
|
||||
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
||||
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
|
||||
cr.arc(center_x, center_y, radius, start_angle, end_angle);
|
||||
cr.setLineWidth(fg_stroke);
|
||||
cr.stroke();
|
||||
// Draw background
|
||||
const background_color = styleContext.get_property("background-color", Gtk.StateFlags.NORMAL)
|
||||
cr.setSourceRGBA(
|
||||
background_color.red,
|
||||
background_color.green,
|
||||
background_color.blue,
|
||||
background_color.alpha,
|
||||
)
|
||||
cr.arc(center_x, center_y, radius, 0, 2 * Math.PI)
|
||||
cr.setLineWidth(bg_stroke)
|
||||
cr.stroke()
|
||||
|
||||
// Draw rounded ends for progress arcs
|
||||
cr.setLineWidth(0);
|
||||
cr.arc(start_x, start_y, fg_stroke / 2, 0, 0 - 0.01);
|
||||
cr.fill();
|
||||
cr.arc(end_x, end_y, fg_stroke / 2, 0, 0 - 0.01);
|
||||
cr.fill();
|
||||
}))
|
||||
// Draw progress
|
||||
const color = styleContext.get_property("color", Gtk.StateFlags.NORMAL)
|
||||
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha)
|
||||
cr.arc(center_x, center_y, radius, start_angle, end_angle)
|
||||
cr.setLineWidth(fg_stroke)
|
||||
cr.stroke()
|
||||
|
||||
// Draw rounded ends for progress arcs
|
||||
cr.setLineWidth(0)
|
||||
cr.arc(start_x, start_y, fg_stroke / 2, 0, 0 - 0.01)
|
||||
cr.fill()
|
||||
cr.arc(end_x, end_y, fg_stroke / 2, 0, 0 - 0.01)
|
||||
cr.fill()
|
||||
}),
|
||||
)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { Widget } from '../../imports.js';
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
import {Widget} from "../../imports.js"
|
||||
|
||||
export const ContextMenuItem = ({ label, onClick }) => Widget({
|
||||
export const ContextMenuItem = ({label, onClick}) =>
|
||||
Widget({
|
||||
type: Gtk.MenuItem,
|
||||
label: `${label}`,
|
||||
setup: menuItem => {
|
||||
menuItem.connect("activate", onClick);
|
||||
}
|
||||
})
|
||||
menuItem.connect("activate", onClick)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
|
||||
const CLICK_BRIGHTEN_AMOUNT = 0.13;
|
||||
const CLICK_BRIGHTEN_AMOUNT = 0.13
|
||||
|
||||
export function setupCursorHover(button) {
|
||||
var clicked = false;
|
||||
var dummy = false;
|
||||
var cursorX = 0;
|
||||
var cursorY = 0;
|
||||
const styleContext = button.get_style_context();
|
||||
var clickColor = styleContext.get_property('background-color', Gtk.StateFlags.HOVER);
|
||||
clickColor.green += CLICK_BRIGHTEN_AMOUNT;
|
||||
clickColor.blue += CLICK_BRIGHTEN_AMOUNT;
|
||||
clickColor.red += CLICK_BRIGHTEN_AMOUNT;
|
||||
clickColor = clickColor.to_string();
|
||||
|
||||
const display = Gdk.Display.get_default();
|
||||
button.connect('enter-notify-event', () => {
|
||||
const cursor = Gdk.Cursor.new_from_name(display, 'pointer');
|
||||
button.get_window().set_cursor(cursor);
|
||||
});
|
||||
var clicked = false
|
||||
var dummy = false
|
||||
var cursorX = 0
|
||||
var cursorY = 0
|
||||
const styleContext = button.get_style_context()
|
||||
var clickColor = styleContext.get_property("background-color", Gtk.StateFlags.HOVER)
|
||||
clickColor.green += CLICK_BRIGHTEN_AMOUNT
|
||||
clickColor.blue += CLICK_BRIGHTEN_AMOUNT
|
||||
clickColor.red += CLICK_BRIGHTEN_AMOUNT
|
||||
clickColor = clickColor.to_string()
|
||||
|
||||
button.connect('leave-notify-event', () => {
|
||||
const cursor = Gdk.Cursor.new_from_name(display, 'default');
|
||||
button.get_window().set_cursor(cursor);
|
||||
});
|
||||
const display = Gdk.Display.get_default()
|
||||
button.connect("enter-notify-event", () => {
|
||||
const cursor = Gdk.Cursor.new_from_name(display, "pointer")
|
||||
button.get_window().set_cursor(cursor)
|
||||
})
|
||||
|
||||
// button.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
|
||||
// button.connect('motion-notify-event', (widget, event) => {
|
||||
// [dummy, cursorX, cursorY] = event.get_coords(); // Get the mouse coordinates relative to the widget
|
||||
// if(!clicked) widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%);
|
||||
// `;
|
||||
// });
|
||||
button.connect("leave-notify-event", () => {
|
||||
const cursor = Gdk.Cursor.new_from_name(display, "default")
|
||||
button.get_window().set_cursor(cursor)
|
||||
})
|
||||
|
||||
// button.connect('button-press-event', (widget, event) => {
|
||||
// clicked = true;
|
||||
// [dummy, cursorX, cursorY] = event.get_coords(); // Get the mouse coordinates relative to the widget
|
||||
// cursorX = Math.round(cursorX); cursorY = Math.round(cursorY);
|
||||
// widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%);
|
||||
// `;
|
||||
// widget.toggleClassName('growingRadial', true);
|
||||
// widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 70%, ${clickColor} 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%);
|
||||
// `
|
||||
// });
|
||||
// button.connect('button-release-event', (widget, event) => {
|
||||
// widget.toggleClassName('growingRadial', false);
|
||||
// widget.toggleClassName('fadingRadial', false);
|
||||
// widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%);
|
||||
// `
|
||||
// clicked = false;
|
||||
// });
|
||||
// button.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
|
||||
// button.connect('motion-notify-event', (widget, event) => {
|
||||
// [dummy, cursorX, cursorY] = event.get_coords(); // Get the mouse coordinates relative to the widget
|
||||
// if(!clicked) widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%);
|
||||
// `;
|
||||
// });
|
||||
|
||||
// button.connect('button-press-event', (widget, event) => {
|
||||
// clicked = true;
|
||||
// [dummy, cursorX, cursorY] = event.get_coords(); // Get the mouse coordinates relative to the widget
|
||||
// cursorX = Math.round(cursorX); cursorY = Math.round(cursorY);
|
||||
// widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%);
|
||||
// `;
|
||||
// widget.toggleClassName('growingRadial', true);
|
||||
// widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, ${clickColor} 0%, ${clickColor} 0%, ${clickColor} 70%, ${clickColor} 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%);
|
||||
// `
|
||||
// });
|
||||
// button.connect('button-release-event', (widget, event) => {
|
||||
// widget.toggleClassName('growingRadial', false);
|
||||
// widget.toggleClassName('fadingRadial', false);
|
||||
// widget.style = `
|
||||
// background-image: radial-gradient(circle at ${cursorX}px ${cursorY}px, rgba(0,0,0,0), rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%, rgba(0,0,0,0) 70%);
|
||||
// `
|
||||
// clicked = false;
|
||||
// });
|
||||
}
|
||||
|
||||
export function setupCursorHoverAim(button) {
|
||||
button.connect('enter-notify-event', () => {
|
||||
const display = Gdk.Display.get_default();
|
||||
const cursor = Gdk.Cursor.new_from_name(display, 'crosshair');
|
||||
button.get_window().set_cursor(cursor);
|
||||
});
|
||||
button.connect("enter-notify-event", () => {
|
||||
const display = Gdk.Display.get_default()
|
||||
const cursor = Gdk.Cursor.new_from_name(display, "crosshair")
|
||||
button.get_window().set_cursor(cursor)
|
||||
})
|
||||
|
||||
button.connect('leave-notify-event', () => {
|
||||
const display = Gdk.Display.get_default();
|
||||
const cursor = Gdk.Cursor.new_from_name(display, 'default');
|
||||
button.get_window().set_cursor(cursor);
|
||||
});
|
||||
}
|
||||
button.connect("leave-notify-event", () => {
|
||||
const display = Gdk.Display.get_default()
|
||||
const cursor = Gdk.Cursor.new_from_name(display, "default")
|
||||
button.get_window().set_cursor(cursor)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Widget } from '../../imports.js';
|
||||
import {Widget} from "../../imports.js"
|
||||
|
||||
export const MaterialIcon = (icon, size, props = {}) => Widget.Label({
|
||||
export const MaterialIcon = (icon, size, props = {}) =>
|
||||
Widget.Label({
|
||||
className: `icon-material txt-${size}`,
|
||||
label: icon,
|
||||
...props,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,73 +1,135 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
import { Utils, Widget } from '../../imports.js';
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
const GObject = imports.gi.GObject
|
||||
const Lang = imports.lang
|
||||
import {Utils, Widget} from "../../imports.js"
|
||||
|
||||
// min-height/min-width for height/width
|
||||
// background-color/color for background/indicator color
|
||||
// padding for pad of indicator
|
||||
// font-size for selected index (0-based)
|
||||
export const NavigationIndicator = (count, vertical, props) => Widget({
|
||||
export const NavigationIndicator = (count, vertical, props) =>
|
||||
Widget({
|
||||
...props,
|
||||
type: Gtk.DrawingArea,
|
||||
setup: (area) => {
|
||||
const styleContext = area.get_style_context();
|
||||
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
|
||||
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
|
||||
area.set_size_request(width, height);
|
||||
setup: area => {
|
||||
const styleContext = area.get_style_context()
|
||||
const width = Math.max(
|
||||
styleContext.get_property("min-width", Gtk.StateFlags.NORMAL),
|
||||
area.get_allocated_width(),
|
||||
)
|
||||
const height = Math.max(
|
||||
styleContext.get_property("min-height", Gtk.StateFlags.NORMAL),
|
||||
area.get_allocated_height(),
|
||||
)
|
||||
area.set_size_request(width, height)
|
||||
|
||||
area.connect('draw', Lang.bind(area, (area, cr) => {
|
||||
const styleContext = area.get_style_context();
|
||||
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
|
||||
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
|
||||
// console.log('allocated width/height:', area.get_allocated_width(), '/', area.get_allocated_height())
|
||||
area.set_size_request(width, height);
|
||||
const paddingLeft = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
|
||||
const paddingRight = styleContext.get_padding(Gtk.StateFlags.NORMAL).right;
|
||||
const paddingTop = styleContext.get_padding(Gtk.StateFlags.NORMAL).top;
|
||||
const paddingBottom = styleContext.get_padding(Gtk.StateFlags.NORMAL).bottom;
|
||||
area.connect(
|
||||
"draw",
|
||||
Lang.bind(area, (area, cr) => {
|
||||
const styleContext = area.get_style_context()
|
||||
const width = Math.max(
|
||||
styleContext.get_property("min-width", Gtk.StateFlags.NORMAL),
|
||||
area.get_allocated_width(),
|
||||
)
|
||||
const height = Math.max(
|
||||
styleContext.get_property("min-height", Gtk.StateFlags.NORMAL),
|
||||
area.get_allocated_height(),
|
||||
)
|
||||
// console.log('allocated width/height:', area.get_allocated_width(), '/', area.get_allocated_height())
|
||||
area.set_size_request(width, height)
|
||||
const paddingLeft = styleContext.get_padding(Gtk.StateFlags.NORMAL).left
|
||||
const paddingRight = styleContext.get_padding(Gtk.StateFlags.NORMAL).right
|
||||
const paddingTop = styleContext.get_padding(Gtk.StateFlags.NORMAL).top
|
||||
const paddingBottom = styleContext.get_padding(Gtk.StateFlags.NORMAL).bottom
|
||||
|
||||
const selectedCell = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
|
||||
const selectedCell = styleContext.get_property("font-size", Gtk.StateFlags.NORMAL)
|
||||
|
||||
let cellWidth = width;
|
||||
let cellHeight = height;
|
||||
if (vertical) cellHeight /= count;
|
||||
else cellWidth /= count;
|
||||
const indicatorWidth = cellWidth - paddingLeft - paddingRight;
|
||||
const indicatorHeight = cellHeight - paddingTop - paddingBottom;
|
||||
let cellWidth = width
|
||||
let cellHeight = height
|
||||
if (vertical) cellHeight /= count
|
||||
else cellWidth /= count
|
||||
const indicatorWidth = cellWidth - paddingLeft - paddingRight
|
||||
const indicatorHeight = cellHeight - paddingTop - paddingBottom
|
||||
|
||||
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
|
||||
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
|
||||
cr.setLineWidth(2);
|
||||
// Background
|
||||
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
|
||||
cr.rectangle(0, 0, width, height);
|
||||
cr.fill();
|
||||
const background_color = styleContext.get_property("background-color", Gtk.StateFlags.NORMAL)
|
||||
const color = styleContext.get_property("color", Gtk.StateFlags.NORMAL)
|
||||
cr.setLineWidth(2)
|
||||
// Background
|
||||
cr.setSourceRGBA(
|
||||
background_color.red,
|
||||
background_color.green,
|
||||
background_color.blue,
|
||||
background_color.alpha,
|
||||
)
|
||||
cr.rectangle(0, 0, width, height)
|
||||
cr.fill()
|
||||
|
||||
// The indicator line
|
||||
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
|
||||
if (vertical) {
|
||||
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
|
||||
cr.stroke();
|
||||
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
|
||||
cr.fill();
|
||||
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth / 2, Math.PI, 2 * Math.PI);
|
||||
cr.fill();
|
||||
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorHeight - indicatorWidth / 2, indicatorWidth / 2, 0, Math.PI);
|
||||
cr.fill();
|
||||
}
|
||||
else {
|
||||
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
|
||||
cr.stroke();
|
||||
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
|
||||
cr.fill();
|
||||
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, 0.5 * Math.PI, 1.5 * Math.PI);
|
||||
cr.fill();
|
||||
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorWidth - indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, -0.5 * Math.PI, 0.5 * Math.PI);
|
||||
cr.fill();
|
||||
}
|
||||
}))
|
||||
// The indicator line
|
||||
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha)
|
||||
if (vertical) {
|
||||
cr.rectangle(
|
||||
paddingLeft,
|
||||
paddingTop + cellHeight * selectedCell + indicatorWidth / 2,
|
||||
indicatorWidth,
|
||||
indicatorHeight - indicatorWidth,
|
||||
)
|
||||
cr.stroke()
|
||||
cr.rectangle(
|
||||
paddingLeft,
|
||||
paddingTop + cellHeight * selectedCell + indicatorWidth / 2,
|
||||
indicatorWidth,
|
||||
indicatorHeight - indicatorWidth,
|
||||
)
|
||||
cr.fill()
|
||||
cr.arc(
|
||||
paddingLeft + indicatorWidth / 2,
|
||||
paddingTop + cellHeight * selectedCell + indicatorWidth / 2,
|
||||
indicatorWidth / 2,
|
||||
Math.PI,
|
||||
2 * Math.PI,
|
||||
)
|
||||
cr.fill()
|
||||
cr.arc(
|
||||
paddingLeft + indicatorWidth / 2,
|
||||
paddingTop + cellHeight * selectedCell + indicatorHeight - indicatorWidth / 2,
|
||||
indicatorWidth / 2,
|
||||
0,
|
||||
Math.PI,
|
||||
)
|
||||
cr.fill()
|
||||
} else {
|
||||
cr.rectangle(
|
||||
paddingLeft + cellWidth * selectedCell + indicatorHeight / 2,
|
||||
paddingTop,
|
||||
indicatorWidth - indicatorHeight,
|
||||
indicatorHeight,
|
||||
)
|
||||
cr.stroke()
|
||||
cr.rectangle(
|
||||
paddingLeft + cellWidth * selectedCell + indicatorHeight / 2,
|
||||
paddingTop,
|
||||
indicatorWidth - indicatorHeight,
|
||||
indicatorHeight,
|
||||
)
|
||||
cr.fill()
|
||||
cr.arc(
|
||||
paddingLeft + cellWidth * selectedCell + indicatorHeight / 2,
|
||||
paddingTop + indicatorHeight / 2,
|
||||
indicatorHeight / 2,
|
||||
0.5 * Math.PI,
|
||||
1.5 * Math.PI,
|
||||
)
|
||||
cr.fill()
|
||||
cr.arc(
|
||||
paddingLeft + cellWidth * selectedCell + indicatorWidth - indicatorHeight / 2,
|
||||
paddingTop + indicatorHeight / 2,
|
||||
indicatorHeight / 2,
|
||||
-0.5 * Math.PI,
|
||||
0.5 * Math.PI,
|
||||
)
|
||||
cr.fill()
|
||||
}
|
||||
}),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
@@ -1,298 +1,311 @@
|
||||
// This file is for the actual widget for each single notification
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
import {lookUpIcon} from "resource:///com/github/Aylur/ags/utils.js"
|
||||
import GLib from "gi://GLib"
|
||||
import Gtk from "gi://Gtk"
|
||||
import Gdk from "gi://Gdk?version=3.0"
|
||||
import {MaterialIcon} from "./materialicon.js"
|
||||
import {setupCursorHover} from "./cursorhover.js"
|
||||
|
||||
const { GLib, Gdk, Gtk } = imports.gi;
|
||||
import { Utils, Widget } from '../../imports.js';
|
||||
const { lookUpIcon, timeout } = Utils;
|
||||
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
|
||||
import { MaterialIcon } from "./materialicon.js";
|
||||
import { setupCursorHover } from "./cursorhover.js";
|
||||
/**
|
||||
* @typedef {{appIcon: string; appEntry: string; image?: string; urgency: 'critical'}} NotificationObject
|
||||
*/
|
||||
|
||||
const NotificationIcon = (notifObject) => {
|
||||
// { appEntry, appIcon, image }, urgency = 'normal'
|
||||
if (notifObject.image) {
|
||||
return Box({
|
||||
valign: 'center',
|
||||
hexpand: false,
|
||||
className: 'notif-icon',
|
||||
style: `
|
||||
background-image: url("${notifObject.image}");
|
||||
background-size: auto 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
`,
|
||||
});
|
||||
}
|
||||
|
||||
let icon = 'NO_ICON';
|
||||
if (lookUpIcon(notifObject.appIcon))
|
||||
icon = notifObject.appIcon;
|
||||
if (lookUpIcon(notifObject.appEntry))
|
||||
icon = notifObject.appEntry;
|
||||
|
||||
return Box({
|
||||
valign: 'center',
|
||||
hexpand: false,
|
||||
className: 'notif-icon',
|
||||
setup: box => {
|
||||
if (icon != 'NO_ICON') box.pack_start(Icon({
|
||||
icon, size: 30,
|
||||
halign: 'center', hexpand: true,
|
||||
valign: 'center',
|
||||
setup: () => {
|
||||
box.toggleClassName(`notif-icon-material-${notifObject.urgency}`, true);
|
||||
},
|
||||
}), false, true, 0);
|
||||
else box.pack_start(MaterialIcon(`${notifObject.urgency == 'critical' ? 'release_alert' : 'chat'}`, 'hugeass', {
|
||||
hexpand: true,
|
||||
setup: () => box.toggleClassName(`notif-icon-material-${notifObject.urgency}`, true),
|
||||
}), false, true, 0)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default ({
|
||||
notifObject,
|
||||
isPopup = false,
|
||||
props = {},
|
||||
} = {}) => {
|
||||
const command = (isPopup ?
|
||||
() => notifObject.dismiss() :
|
||||
() => notifObject.close()
|
||||
)
|
||||
const destroyWithAnims = () => {
|
||||
widget.sensitive = false;
|
||||
notificationBox.setStyle(rightAnim1);
|
||||
Utils.timeout(200, () => {
|
||||
wholeThing.revealChild = false;
|
||||
});
|
||||
Utils.timeout(400, () => {
|
||||
command();
|
||||
wholeThing.destroy();
|
||||
});
|
||||
}
|
||||
const widget = EventBox({
|
||||
onHover: (self) => {
|
||||
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
||||
if (!wholeThing._hovered)
|
||||
wholeThing._hovered = true;
|
||||
},
|
||||
onHoverLost: (self) => {
|
||||
self.window.set_cursor(null);
|
||||
if (wholeThing._hovered)
|
||||
wholeThing._hovered = false;
|
||||
if(isPopup) {
|
||||
command();
|
||||
}
|
||||
},
|
||||
onMiddleClick: (self) => {
|
||||
destroyWithAnims();
|
||||
}
|
||||
});
|
||||
const wholeThing = Revealer({
|
||||
properties: [
|
||||
['id', notifObject.id],
|
||||
['close', undefined],
|
||||
['hovered', false],
|
||||
['dragging', false],
|
||||
['destroyWithAnims', () => destroyWithAnims]
|
||||
],
|
||||
revealChild: false,
|
||||
transition: 'slide_down',
|
||||
transitionDuration: 200,
|
||||
child: Box({ // Box to make sure css-based spacing works
|
||||
homogeneous: true,
|
||||
})
|
||||
});
|
||||
|
||||
const display = Gdk.Display.get_default();
|
||||
const notificationContent = Box({
|
||||
...props,
|
||||
className: `${isPopup ? 'popup-' : ''}notif-${notifObject.urgency} spacing-h-10`,
|
||||
children: [
|
||||
NotificationIcon(notifObject),
|
||||
Box({
|
||||
valign: 'center',
|
||||
vertical: true,
|
||||
hexpand: true,
|
||||
children: [
|
||||
Box({
|
||||
children: [
|
||||
Label({
|
||||
xalign: 0,
|
||||
className: 'txt-small txt-semibold titlefont',
|
||||
justify: Gtk.Justification.LEFT,
|
||||
hexpand: true,
|
||||
maxWidthChars: 24,
|
||||
ellipsize: 3,
|
||||
wrap: true,
|
||||
useMarkup: notifObject.summary.startsWith('<'),
|
||||
label: notifObject.summary,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Label({
|
||||
xalign: 0,
|
||||
className: 'txt-smallie notif-body-${urgency}',
|
||||
useMarkup: true,
|
||||
xalign: 0,
|
||||
justify: Gtk.Justification.LEFT,
|
||||
wrap: true,
|
||||
label: notifObject.body,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
Label({
|
||||
valign: 'center',
|
||||
className: 'txt-smaller txt-semibold',
|
||||
justify: Gtk.Justification.RIGHT,
|
||||
setup: (label) => {
|
||||
const messageTime = GLib.DateTime.new_from_unix_local(notifObject.time);
|
||||
if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year()) {
|
||||
label.label = messageTime.format('%H:%M');
|
||||
}
|
||||
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1) {
|
||||
label.label = messageTime.format('%H:%M\nYesterday');
|
||||
}
|
||||
else {
|
||||
label.label = messageTime.format('%H:%M\n%d/%m');
|
||||
}
|
||||
}
|
||||
}),
|
||||
Button({
|
||||
className: 'notif-close-btn',
|
||||
onClicked: () => {
|
||||
destroyWithAnims()
|
||||
},
|
||||
child: MaterialIcon('close', 'large', {
|
||||
valign: 'center',
|
||||
}),
|
||||
setup: (button) => setupCursorHover(button),
|
||||
}),
|
||||
]
|
||||
}),
|
||||
|
||||
// what is this? i think it should be at the bottom not on the right
|
||||
// Box({
|
||||
// className: 'actions',
|
||||
// children: actions.map(action => Button({
|
||||
// className: 'action-button',
|
||||
// onClicked: () => Notifications.invoke(id, action.id),
|
||||
// hexpand: true,
|
||||
// child: Label(action.label),
|
||||
// })),
|
||||
// }),
|
||||
]
|
||||
/**
|
||||
* @param notificationObject {NotificationObject}
|
||||
* @returns {import('types/widgets/box').default}
|
||||
* @constructor
|
||||
*/
|
||||
const NotificationIcon = notificationObject => {
|
||||
if (notificationObject.image) {
|
||||
return Widget.Box({
|
||||
valign: Gtk.Align.CENTER,
|
||||
hexpand: false,
|
||||
className: "notif-icon",
|
||||
style:
|
||||
`background-image: url("${notificationObject.image}");` +
|
||||
"background-size: auto 100%;" +
|
||||
"background-repeat: no-repeat;" +
|
||||
"background-position: center;",
|
||||
})
|
||||
}
|
||||
|
||||
// Gesture stuff
|
||||
let icon = "NO_ICON"
|
||||
if (lookUpIcon(notificationObject.appIcon)) icon = notificationObject.appIcon
|
||||
if (lookUpIcon(notificationObject.appEntry)) icon = notificationObject.appEntry
|
||||
|
||||
const gesture = Gtk.GestureDrag.new(widget);
|
||||
var initialDir = 0;
|
||||
// in px
|
||||
const startMargin = 0;
|
||||
const dragThreshold = 100;
|
||||
// in rem
|
||||
const maxOffset = 10.227;
|
||||
const endMargin = 20.455;
|
||||
const disappearHeight = 6.818;
|
||||
const leftAnim1 = `transition: 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
||||
return Widget.Box({
|
||||
valign: Gtk.Align.CENTER,
|
||||
hexpand: false,
|
||||
className: "notif-icon",
|
||||
setup: box => {
|
||||
if (icon !== "NO_ICON")
|
||||
box.pack_start(
|
||||
Widget.Icon({
|
||||
icon,
|
||||
size: 30,
|
||||
halign: Gtk.Align.CENTER,
|
||||
hexpand: true,
|
||||
valign: Gtk.Align.CENTER,
|
||||
setup: () => {
|
||||
box.toggleClassName(`notif-icon-material-${notificationObject.urgency}`, true)
|
||||
},
|
||||
}),
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
)
|
||||
else
|
||||
box.pack_start(
|
||||
MaterialIcon(`${notificationObject.urgency === "critical" ? "release_alert" : "chat"}`, "hugeass", {
|
||||
hexpand: true,
|
||||
setup: () => box.toggleClassName(`notif-icon-material-${notificationObject.urgency}`, true),
|
||||
}),
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param options {{notifObject?: NotificationObject; isPopup?: boolean, props?: object}}
|
||||
* @returns {import('types/widgets/revealer').default}
|
||||
*/
|
||||
export default ({notifObject, isPopup = false, props = {}} = {}) => {
|
||||
const command = isPopup ? () => notifObject.dismiss() : () => notifObject.close()
|
||||
const destroyWithAnims = () => {
|
||||
widget.sensitive = false
|
||||
notificationBox.setStyle(rightAnim1)
|
||||
Utils.timeout(200, () => {
|
||||
wholeThing.revealChild = false
|
||||
})
|
||||
Utils.timeout(400, () => {
|
||||
command()
|
||||
wholeThing.destroy()
|
||||
})
|
||||
}
|
||||
const widget = Widget.EventBox({
|
||||
onHover: self => {
|
||||
self.window.set_cursor(Gdk.Cursor.new_from_name(display, "grab"))
|
||||
if (!wholeThing._hovered) wholeThing._hovered = true
|
||||
},
|
||||
onHoverLost: self => {
|
||||
self.window.set_cursor(null)
|
||||
if (wholeThing._hovered) wholeThing._hovered = false
|
||||
if (isPopup) {
|
||||
command()
|
||||
}
|
||||
},
|
||||
onMiddleClick: self => {
|
||||
destroyWithAnims()
|
||||
},
|
||||
})
|
||||
const wholeThing = Widget.Revealer({
|
||||
properties: [
|
||||
["id", notifObject.id],
|
||||
["close", undefined],
|
||||
["hovered", false],
|
||||
["dragging", false],
|
||||
["destroyWithAnims", () => destroyWithAnims],
|
||||
],
|
||||
revealChild: false,
|
||||
transition: "slide_down",
|
||||
transitionDuration: 200,
|
||||
child: Widget.Box({
|
||||
// Box to make sure css-based spacing works
|
||||
homogeneous: true,
|
||||
}),
|
||||
})
|
||||
|
||||
const display = Gdk.Display.get_default()
|
||||
const notificationContent = Widget.Box({
|
||||
...props,
|
||||
className: `${isPopup ? "popup-" : ""}notif-${notifObject.urgency} spacing-h-10`,
|
||||
children: [
|
||||
NotificationIcon(notifObject),
|
||||
Widget.Box({
|
||||
valign: "center",
|
||||
vertical: true,
|
||||
hexpand: true,
|
||||
children: [
|
||||
Widget.Box({
|
||||
children: [
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "txt-small txt-semibold titlefont",
|
||||
justify: Gtk.Justification.LEFT,
|
||||
hexpand: true,
|
||||
maxWidthChars: 24,
|
||||
ellipsize: 3,
|
||||
wrap: true,
|
||||
useMarkup: notifObject.summary.startsWith("<"),
|
||||
label: notifObject.summary,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
className: "txt-smallie notif-body-${urgency}",
|
||||
useMarkup: true,
|
||||
justify: Gtk.Justification.LEFT,
|
||||
wrap: true,
|
||||
label: notifObject.body,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
className: "spacing-h-5",
|
||||
children: [
|
||||
Widget.Label({
|
||||
valign: "center",
|
||||
className: "txt-smaller txt-semibold",
|
||||
justify: Gtk.Justification.RIGHT,
|
||||
setup: label => {
|
||||
const messageTime = GLib.DateTime.new_from_unix_local(notifObject.time)
|
||||
if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year()) {
|
||||
label.label = messageTime.format("%H:%M")
|
||||
} else if (
|
||||
messageTime.get_day_of_year() ==
|
||||
GLib.DateTime.new_now_local().get_day_of_year() - 1
|
||||
) {
|
||||
label.label = messageTime.format("%H:%M\nYesterday")
|
||||
} else {
|
||||
label.label = messageTime.format("%H:%M\n%d/%m")
|
||||
}
|
||||
},
|
||||
}),
|
||||
Widget.Button({
|
||||
className: "notif-close-btn",
|
||||
onClicked: () => {
|
||||
destroyWithAnims()
|
||||
},
|
||||
child: MaterialIcon("close", "large", {
|
||||
valign: "center",
|
||||
}),
|
||||
setup: button => setupCursorHover(button),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
||||
// what is this? i think it should be at the bottom not on the right
|
||||
// Box({
|
||||
// className: 'actions',
|
||||
// children: actions.map(action => Button({
|
||||
// className: 'action-button',
|
||||
// onClicked: () => Notifications.invoke(id, action.id),
|
||||
// hexpand: true,
|
||||
// child: Label(action.label),
|
||||
// })),
|
||||
// }),
|
||||
],
|
||||
})
|
||||
|
||||
// Gesture stuff
|
||||
|
||||
const gesture = Gtk.GestureDrag.new(widget)
|
||||
let initialDir = 0
|
||||
// in px
|
||||
const startMargin = 0
|
||||
const dragThreshold = 100
|
||||
// in rem
|
||||
const maxOffset = 10.227
|
||||
const endMargin = 20.455
|
||||
const disappearHeight = 6.818
|
||||
const leftAnim1 = `transition: 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
||||
margin-left: -${Number(maxOffset + endMargin)}rem;
|
||||
margin-right: ${Number(maxOffset + endMargin)}rem;
|
||||
opacity: 0;`;
|
||||
opacity: 0;`
|
||||
|
||||
const rightAnim1 = `transition: 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
||||
const rightAnim1 = `transition: 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
||||
margin-left: ${Number(maxOffset + endMargin)}rem;
|
||||
margin-right: -${Number(maxOffset + endMargin)}rem;
|
||||
opacity: 0;`;
|
||||
opacity: 0;`
|
||||
|
||||
const notificationBox = Box({
|
||||
properties: [
|
||||
['leftAnim1', leftAnim1],
|
||||
['rightAnim1', rightAnim1],
|
||||
['ready', false],
|
||||
],
|
||||
homogeneous: true,
|
||||
children: [notificationContent],
|
||||
connections: [
|
||||
[gesture, self => {
|
||||
var offset = gesture.get_offset()[1];
|
||||
if (initialDir == 0 && offset != 0)
|
||||
initialDir = (offset > 0 ? 1 : -1)
|
||||
const notificationBox = Widget.Box({
|
||||
properties: [
|
||||
["leftAnim1", leftAnim1],
|
||||
["rightAnim1", rightAnim1],
|
||||
["ready", false],
|
||||
],
|
||||
homogeneous: true,
|
||||
children: [notificationContent],
|
||||
connections: [
|
||||
[
|
||||
gesture,
|
||||
self => {
|
||||
var offset = gesture.get_offset()[1]
|
||||
if (initialDir == 0 && offset != 0) initialDir = offset > 0 ? 1 : -1
|
||||
|
||||
if (offset > 0) {
|
||||
if (initialDir < 0)
|
||||
self.setStyle(`margin-left: 0px; margin-right: 0px;`);
|
||||
else
|
||||
self.setStyle(`
|
||||
if (offset > 0) {
|
||||
if (initialDir < 0) self.setStyle(`margin-left: 0px; margin-right: 0px;`)
|
||||
else
|
||||
self.setStyle(`
|
||||
margin-left: ${Number(offset + startMargin)}px;
|
||||
margin-right: -${Number(offset + startMargin)}px;
|
||||
`);
|
||||
}
|
||||
else if (offset < 0) {
|
||||
if (initialDir > 0)
|
||||
self.setStyle(`margin-left: 0px; margin-right: 0px;`);
|
||||
else {
|
||||
offset = Math.abs(offset);
|
||||
self.setStyle(`
|
||||
`)
|
||||
} else if (offset < 0) {
|
||||
if (initialDir > 0) self.setStyle(`margin-left: 0px; margin-right: 0px;`)
|
||||
else {
|
||||
offset = Math.abs(offset)
|
||||
self.setStyle(`
|
||||
margin-right: ${Number(offset + startMargin)}px;
|
||||
margin-left: -${Number(offset + startMargin)}px;
|
||||
`);
|
||||
}
|
||||
}
|
||||
`)
|
||||
}
|
||||
}
|
||||
|
||||
wholeThing._dragging = Math.abs(offset) > 10;
|
||||
wholeThing._dragging = Math.abs(offset) > 10
|
||||
|
||||
if (widget.window)
|
||||
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
|
||||
}, 'drag-update'],
|
||||
if (widget.window) widget.window.set_cursor(Gdk.Cursor.new_from_name(display, "grabbing"))
|
||||
},
|
||||
"drag-update",
|
||||
],
|
||||
|
||||
[gesture, self => {
|
||||
if (!self._ready) {
|
||||
wholeThing.revealChild = true;
|
||||
self._ready = true;
|
||||
return;
|
||||
}
|
||||
[
|
||||
gesture,
|
||||
self => {
|
||||
if (!self._ready) {
|
||||
wholeThing.revealChild = true
|
||||
self._ready = true
|
||||
return
|
||||
}
|
||||
|
||||
const offset = gesture.get_offset()[1];
|
||||
const offset = gesture.get_offset()[1] ?? NaN
|
||||
|
||||
if (Math.abs(offset) > dragThreshold && offset * initialDir > 0) {
|
||||
if (offset > 0) {
|
||||
self.setStyle(rightAnim1);
|
||||
widget.sensitive = false;
|
||||
}
|
||||
else {
|
||||
self.setStyle(leftAnim1);
|
||||
widget.sensitive = false;
|
||||
}
|
||||
Utils.timeout(200, () => {
|
||||
wholeThing.revealChild = false
|
||||
});
|
||||
Utils.timeout(400, () => {
|
||||
command();
|
||||
wholeThing.destroy();
|
||||
});
|
||||
}
|
||||
else {
|
||||
self.setStyle(`transition: margin 200ms cubic-bezier(0.05, 0.7, 0.1, 1), opacity 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
||||
if (Math.abs(offset) > dragThreshold && offset * initialDir > 0) {
|
||||
if (offset > 0) {
|
||||
self.set_style(rightAnim1)
|
||||
widget.sensitive = false
|
||||
} else {
|
||||
self.set_style(leftAnim1)
|
||||
widget.sensitive = false
|
||||
}
|
||||
Utils.timeout(200, () => {
|
||||
wholeThing.revealChild = false
|
||||
})
|
||||
Utils.timeout(400, () => {
|
||||
command()
|
||||
wholeThing.destroy()
|
||||
})
|
||||
} else {
|
||||
self.set_style(`transition: margin 200ms cubic-bezier(0.05, 0.7, 0.1, 1), opacity 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
||||
margin-left: ${startMargin}px;
|
||||
margin-right: ${startMargin}px;
|
||||
margin-bottom: unset; margin-top: unset;
|
||||
opacity: 1;`);
|
||||
if (widget.window)
|
||||
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
||||
opacity: 1;`)
|
||||
if (widget.window) widget.window.set_cursor(Gdk.Cursor.new_from_name(display, "grab"))
|
||||
|
||||
wholeThing._dragging = false;
|
||||
}
|
||||
initialDir = 0;
|
||||
}, 'drag-end'],
|
||||
wholeThing._dragging = false
|
||||
}
|
||||
initialDir = 0
|
||||
},
|
||||
"drag-end",
|
||||
],
|
||||
],
|
||||
})
|
||||
widget.add(notificationBox)
|
||||
wholeThing.child.children = [widget]
|
||||
|
||||
],
|
||||
})
|
||||
widget.add(notificationBox);
|
||||
wholeThing.child.children = [widget];
|
||||
|
||||
return wholeThing;
|
||||
return wholeThing
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import {lookUpIcon} from "resource:///com/github/Aylur/ags/utils.js"
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
import Gtk from "gi://Gtk"
|
||||
import {MaterialIcon} from "../materialicon"
|
||||
|
||||
/**
|
||||
* @param notificationObject {import('resource:///com/github/Aylur/ags/service/notifications.js').Notification}
|
||||
* @returns {import('types/widgets/box').default}
|
||||
* @constructor
|
||||
*/
|
||||
export const NotificationIcon = notificationObject => {
|
||||
if (notificationObject.image) {
|
||||
return Widget.Box({
|
||||
vpack: "center",
|
||||
class_name: "notif-icon",
|
||||
css:
|
||||
`background-image: url("${notificationObject.image}");` +
|
||||
"background-size: auto 100%;" +
|
||||
"background-repeat: no-repeat;" +
|
||||
"background-position: center;",
|
||||
})
|
||||
}
|
||||
|
||||
let icon = "NO_ICON"
|
||||
if (lookUpIcon(notificationObject.app_icon)) icon = notificationObject.app_icon
|
||||
if (notificationObject.app_entry && lookUpIcon(notificationObject.app_entry))
|
||||
icon = notificationObject.app_entry
|
||||
|
||||
return Widget.Box({
|
||||
vpack: "center",
|
||||
class_name: "notif-icon",
|
||||
setup: box => {
|
||||
if (icon !== "NO_ICON")
|
||||
box.pack_start(
|
||||
Widget.Icon({
|
||||
icon,
|
||||
size: 30,
|
||||
halign: Gtk.Align.CENTER,
|
||||
hexpand: true,
|
||||
valign: Gtk.Align.CENTER,
|
||||
setup: () => {
|
||||
box.toggleClassName(`notif-icon-material-${notificationObject.urgency}`, true)
|
||||
},
|
||||
}),
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
)
|
||||
else
|
||||
box.pack_start(
|
||||
MaterialIcon(`${notificationObject.urgency === "critical" ? "release_alert" : "chat"}`, "hugeass", {
|
||||
hexpand: true,
|
||||
setup: () => box.toggleClassName(`notif-icon-material-${notificationObject.urgency}`, true),
|
||||
}),
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,51 +1,56 @@
|
||||
import { Widget } from '../../imports.js';
|
||||
const { Gtk } = imports.gi;
|
||||
const Lang = imports.lang;
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
import Gtk from "gi://Gtk"
|
||||
|
||||
export const RoundedCorner = (place, props) => Widget({
|
||||
/**
|
||||
* @param vertical {'top' | 'bottom'}
|
||||
* @param horizontal {'left' | 'right'}
|
||||
* @param props {Parameters<Widget.DrawingArea>[0]}
|
||||
* @returns {import('resource:///com/github/Aylur/ags/widgets/widget.js').default}
|
||||
*/
|
||||
function RoundedCorner(vertical, horizontal, props) {
|
||||
return Widget.DrawingArea({
|
||||
...props,
|
||||
type: Gtk.DrawingArea,
|
||||
halign: place.includes('left') ? 'start' : 'end',
|
||||
valign: place.includes('top') ? 'start' : 'end',
|
||||
setup: widget => {
|
||||
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
|
||||
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
|
||||
widget.set_size_request(r, r);
|
||||
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
|
||||
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
|
||||
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
|
||||
// const borderColor = widget.get_style_context().get_property('color', Gtk.StateFlags.NORMAL);
|
||||
// const borderWidth = widget.get_style_context().get_border(Gtk.StateFlags.NORMAL).left; // ur going to write border-width: something anyway
|
||||
widget.set_size_request(r, r);
|
||||
hpack: horizontal === "left" ? "start" : "end",
|
||||
vpack: vertical === "top" ? "start" : "end",
|
||||
connection: [
|
||||
[
|
||||
"draw",
|
||||
/** @type {Gtk.Widget.DrawSignalCallback} */ (
|
||||
(self, cr) => {
|
||||
const color = self.get_style_context().get_property("background-color", Gtk.StateFlags.NORMAL)
|
||||
const radius = self.get_style_context().get_property("border-radius", Gtk.StateFlags.NORMAL)
|
||||
self.set_size_request(radius, radius)
|
||||
|
||||
switch (place) {
|
||||
case 'topleft':
|
||||
cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2);
|
||||
cr.lineTo(0, 0);
|
||||
break;
|
||||
switch (`${vertical}${horizontal}`) {
|
||||
case "topleft":
|
||||
cr.arc(radius, radius, radius, Math.PI, (3 * Math.PI) / 2)
|
||||
cr.lineTo(0, 0)
|
||||
break
|
||||
|
||||
case 'topright':
|
||||
cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI);
|
||||
cr.lineTo(r, 0);
|
||||
break;
|
||||
case "topright":
|
||||
cr.arc(0, radius, radius, (3 * Math.PI) / 2, 2 * Math.PI)
|
||||
cr.lineTo(radius, 0)
|
||||
break
|
||||
|
||||
case 'bottomleft':
|
||||
cr.arc(r, 0, r, Math.PI / 2, Math.PI);
|
||||
cr.lineTo(0, r);
|
||||
break;
|
||||
case "bottomleft":
|
||||
cr.arc(radius, 0, radius, Math.PI / 2, Math.PI)
|
||||
cr.lineTo(0, radius)
|
||||
break
|
||||
|
||||
case 'bottomright':
|
||||
cr.arc(0, 0, r, 0, Math.PI / 2);
|
||||
cr.lineTo(r, r);
|
||||
break;
|
||||
case "bottomright":
|
||||
cr.arc(0, 0, radius, 0, Math.PI / 2)
|
||||
cr.lineTo(radius, radius)
|
||||
break
|
||||
}
|
||||
|
||||
cr.closePath();
|
||||
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
|
||||
cr.fill();
|
||||
// cr.setLineWidth(borderWidth);
|
||||
// cr.setSourceRGBA(borderColor.red, borderColor.green, borderColor.blue, borderColor.alpha);
|
||||
// cr.stroke();
|
||||
}));
|
||||
},
|
||||
});
|
||||
cr.closePath()
|
||||
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha)
|
||||
cr.fill()
|
||||
}
|
||||
),
|
||||
],
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export default RoundedCorner
|
||||
|
||||
@@ -1,69 +1,5 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Widget } from '../../imports.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
import { setupCursorHover, setupCursorHoverAim } from "./cursorhover.js";
|
||||
import { MaterialIcon } from './materialicon.js';
|
||||
|
||||
export const searchItem = ({ materialIconName, name, actionName, content, onActivate }) => {
|
||||
const actionText = Widget.Revealer({
|
||||
revealChild: false,
|
||||
transition: "crossfade",
|
||||
transitionDuration: 200,
|
||||
child: Widget.Label({
|
||||
className: 'overview-search-results-txt txt txt-small txt-action',
|
||||
label: `${actionName}`,
|
||||
})
|
||||
});
|
||||
const actionTextRevealer = Widget.Revealer({
|
||||
revealChild: false,
|
||||
transition: "slide_left",
|
||||
transitionDuration: 300,
|
||||
child: actionText,
|
||||
})
|
||||
return Widget.Button({
|
||||
className: 'overview-search-result-btn',
|
||||
onClicked: onActivate,
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
Widget.Box({
|
||||
vertical: false,
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: `icon-material overview-search-results-icon`,
|
||||
label: `${materialIconName}`,
|
||||
}),
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
halign: 'start',
|
||||
className: 'overview-search-results-txt txt txt-smallie txt-subtext',
|
||||
label: `${name}`,
|
||||
truncate: "end",
|
||||
}),
|
||||
Widget.Label({
|
||||
halign: 'start',
|
||||
className: 'overview-search-results-txt txt txt-norm',
|
||||
label: `${content}`,
|
||||
truncate: "end",
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Widget.Box({ hexpand: true }),
|
||||
actionTextRevealer,
|
||||
],
|
||||
})
|
||||
]
|
||||
}),
|
||||
connections: [
|
||||
['focus-in-event', (button) => {
|
||||
actionText.revealChild = true;
|
||||
actionTextRevealer.revealChild = true;
|
||||
}],
|
||||
['focus-out-event', (button) => {
|
||||
actionText.revealChild = false;
|
||||
actionTextRevealer.revealChild = false;
|
||||
}],
|
||||
]
|
||||
});
|
||||
}
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
import {App, Service, Utils, Widget} from "../../imports.js"
|
||||
const {execAsync, exec} = Utils
|
||||
import {setupCursorHover, setupCursorHoverAim} from "./cursorhover.js"
|
||||
import {MaterialIcon} from "./materialicon.js"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Widget } from '../../imports.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
import { setupCursorHover, setupCursorHoverAim } from "./cursorhover.js";
|
||||
import { MaterialIcon } from './materialicon.js';
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
import {App, Service, Utils, Widget} from "../../imports.js"
|
||||
const {execAsync, exec} = Utils
|
||||
import {setupCursorHover, setupCursorHoverAim} from "./cursorhover.js"
|
||||
import {MaterialIcon} from "./materialicon.js"
|
||||
|
||||
export const separatorLine = Widget.Box({
|
||||
className: 'separator-line',
|
||||
})
|
||||
className: "separator-line",
|
||||
})
|
||||
|
||||
@@ -1,111 +1,122 @@
|
||||
import { App, Utils, Widget } from '../imports.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
import { MaterialIcon } from "./lib/materialicon.js";
|
||||
import { setupCursorHover } from "./lib/cursorhover.js";
|
||||
import {App, Utils, Widget} from "../imports.js"
|
||||
const {execAsync, exec} = Utils
|
||||
import {MaterialIcon} from "./lib/materialicon.js"
|
||||
import {setupCursorHover} from "./lib/cursorhover.js"
|
||||
|
||||
const RECORD_SCRIPT_DIR = `${App.configDir}/scripts/record-script.sh`;
|
||||
const RECORDER_PROCESS = 'record-script.sh';
|
||||
const CLOSE_ANIM_TIME = 150;
|
||||
const RECORD_SCRIPT_DIR = `${App.configDir}/scripts/record-script.sh`
|
||||
const RECORDER_PROCESS = "record-script.sh"
|
||||
const CLOSE_ANIM_TIME = 150
|
||||
|
||||
async function toggleSystemdService(serviceName, button) {
|
||||
const serviceState = exec(`systemctl is-enabled ${serviceName}`) == 'enabled';
|
||||
// console.log(`pkexec bash -c "systemctl ${serviceState ? 'disable' : 'enable'} ${serviceName}"`)
|
||||
exec(`pkexec bash -c "systemctl ${serviceState ? 'disable' : 'enable'} ${serviceName}"`);
|
||||
const newServiceState = exec(`systemctl is-enabled ${serviceName}`) == 'enabled';
|
||||
button.toggleClassName('sidebar-button-active', newServiceState);
|
||||
serviceState.toggleClassName('invisible', newServiceState);
|
||||
const serviceState = exec(`systemctl is-enabled ${serviceName}`) == "enabled"
|
||||
// console.log(`pkexec bash -c "systemctl ${serviceState ? 'disable' : 'enable'} ${serviceName}"`)
|
||||
exec(`pkexec bash -c "systemctl ${serviceState ? "disable" : "enable"} ${serviceName}"`)
|
||||
const newServiceState = exec(`systemctl is-enabled ${serviceName}`) == "enabled"
|
||||
button.toggleClassName("sidebar-button-active", newServiceState)
|
||||
serviceState.toggleClassName("invisible", newServiceState)
|
||||
}
|
||||
|
||||
const ModuleRecord = (props = {}) => Widget.Button({
|
||||
const ModuleRecord = (props = {}) =>
|
||||
Widget.Button({
|
||||
...props,
|
||||
className: 'button-minsize sidebar-button-nopad sidebar-button-alone-normal txt-small',
|
||||
className: "button-minsize sidebar-button-nopad sidebar-button-alone-normal txt-small",
|
||||
onClicked: () => {
|
||||
execAsync(['bash', '-c', RECORD_SCRIPT_DIR]).catch(print);
|
||||
setTimeout(() => {
|
||||
button.toggleClassName('sidebar-button-active', exec(`pidof ${RECORDER_PROCESS} >/dev/null && echo 1 || echo`) == '1');
|
||||
}, CLOSE_ANIM_TIME);
|
||||
execAsync(["bash", "-c", RECORD_SCRIPT_DIR]).catch(print)
|
||||
setTimeout(() => {
|
||||
button.toggleClassName(
|
||||
"sidebar-button-active",
|
||||
exec(`pidof ${RECORDER_PROCESS} >/dev/null && echo 1 || echo`) == "1",
|
||||
)
|
||||
}, CLOSE_ANIM_TIME)
|
||||
},
|
||||
child: MaterialIcon('screen_record', 'larger'),
|
||||
child: MaterialIcon("screen_record", "larger"),
|
||||
setup: button => {
|
||||
button.toggleClassName('sidebar-button-active', exec(`pidof ${RECORDER_PROCESS} >/dev/null && echo 1 || echo`));
|
||||
setupCursorHover(button);
|
||||
}
|
||||
})
|
||||
button.toggleClassName(
|
||||
"sidebar-button-active",
|
||||
exec(`pidof ${RECORDER_PROCESS} >/dev/null && echo 1 || echo`),
|
||||
)
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
|
||||
const SystemdService = (serviceName) => {
|
||||
const serviceState = Widget.Label({
|
||||
className: `icon-material txt-larger`,
|
||||
label: 'check',
|
||||
setup: label => {
|
||||
// label.toggleClassName('invisible', exec(`bash -c "systemctl is-enabled ${serviceName} >/dev/null && echo ON || echo OFF"`) == 'OFF');
|
||||
}
|
||||
});
|
||||
return Widget.Button({
|
||||
className: 'button-minsize sidebar-button sidebar-button-alone-normal txt-small',
|
||||
onClicked: (button) => {
|
||||
toggleSystemdService(serviceName, button);
|
||||
},
|
||||
setup: button => {
|
||||
button.toggleClassName('sidebar-button-active', exec(`systemctl is-enabled ${serviceName}`) == 'enabled');
|
||||
setupCursorHover(button);
|
||||
},
|
||||
child: Widget.Box({
|
||||
setup: box => {
|
||||
box.pack_start(Widget.Label({
|
||||
xalign: 0,
|
||||
label: serviceName,
|
||||
}), true, true, 0);
|
||||
// box.pack_end(serviceState, false, false, 0);
|
||||
}
|
||||
})
|
||||
});
|
||||
const SystemdService = serviceName => {
|
||||
const serviceState = Widget.Label({
|
||||
className: `icon-material txt-larger`,
|
||||
label: "check",
|
||||
setup: label => {
|
||||
// label.toggleClassName('invisible', exec(`bash -c "systemctl is-enabled ${serviceName} >/dev/null && echo ON || echo OFF"`) == 'OFF');
|
||||
},
|
||||
})
|
||||
return Widget.Button({
|
||||
className: "button-minsize sidebar-button sidebar-button-alone-normal txt-small",
|
||||
onClicked: button => {
|
||||
toggleSystemdService(serviceName, button)
|
||||
},
|
||||
setup: button => {
|
||||
button.toggleClassName(
|
||||
"sidebar-button-active",
|
||||
exec(`systemctl is-enabled ${serviceName}`) == "enabled",
|
||||
)
|
||||
setupCursorHover(button)
|
||||
},
|
||||
child: Widget.Box({
|
||||
setup: box => {
|
||||
box.pack_start(
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
label: serviceName,
|
||||
}),
|
||||
true,
|
||||
true,
|
||||
0,
|
||||
)
|
||||
// box.pack_end(serviceState, false, false, 0);
|
||||
},
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export const ModuleMiscToggles = () => {
|
||||
const PowerSavers = Widget.Revealer({
|
||||
revealChild: false,
|
||||
transition: 'slide_left',
|
||||
transitionDuration: 100,
|
||||
child: Widget.Box({
|
||||
className: 'spacing-v-5 margin-right-10',
|
||||
vertical: true,
|
||||
children: [
|
||||
SystemdService('tlp'),
|
||||
SystemdService('auto-cpufreq'),
|
||||
]
|
||||
})
|
||||
})
|
||||
const ModulePowerSavers = Widget.Button({
|
||||
className: 'button-minsize sidebar-button-nopad sidebar-button-alone-normal txt-small',
|
||||
child: MaterialIcon('keyboard_arrow_leftenergy_savings_leaf', 'larger', {
|
||||
xalign: 0.2,
|
||||
}),
|
||||
onClicked: (button) => {
|
||||
const revealed = PowerSavers.revealChild;
|
||||
PowerSavers.revealChild = !revealed;
|
||||
button.toggleClassName('sidebar-button-active', !revealed);
|
||||
button.child.label = revealed ? 'keyboard_arrow_leftenergy_savings_leaf' : 'keyboard_arrow_rightenergy_savings_leaf';
|
||||
},
|
||||
setup: (button) => setupCursorHover(button),
|
||||
})
|
||||
return Widget.Box({
|
||||
className: 'sidebar-group spacing-h-10',
|
||||
const PowerSavers = Widget.Revealer({
|
||||
revealChild: false,
|
||||
transition: "slide_left",
|
||||
transitionDuration: 100,
|
||||
child: Widget.Box({
|
||||
className: "spacing-v-5 margin-right-10",
|
||||
vertical: true,
|
||||
children: [SystemdService("tlp"), SystemdService("auto-cpufreq")],
|
||||
}),
|
||||
})
|
||||
const ModulePowerSavers = Widget.Button({
|
||||
className: "button-minsize sidebar-button-nopad sidebar-button-alone-normal txt-small",
|
||||
child: MaterialIcon("keyboard_arrow_leftenergy_savings_leaf", "larger", {
|
||||
xalign: 0.2,
|
||||
}),
|
||||
onClicked: button => {
|
||||
const revealed = PowerSavers.revealChild
|
||||
PowerSavers.revealChild = !revealed
|
||||
button.toggleClassName("sidebar-button-active", !revealed)
|
||||
button.child.label = revealed
|
||||
? "keyboard_arrow_leftenergy_savings_leaf"
|
||||
: "keyboard_arrow_rightenergy_savings_leaf"
|
||||
},
|
||||
setup: button => setupCursorHover(button),
|
||||
})
|
||||
return Widget.Box({
|
||||
className: "sidebar-group spacing-h-10",
|
||||
children: [
|
||||
PowerSavers,
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
children: [
|
||||
PowerSavers,
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
children: [
|
||||
ModulePowerSavers,
|
||||
Widget.Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
ModuleNightLight(),
|
||||
ModuleRecord(),
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
ModulePowerSavers,
|
||||
Widget.Box({
|
||||
className: "spacing-h-5",
|
||||
children: [ModuleNightLight(), ModuleRecord()],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,78 +1,104 @@
|
||||
import { Service, Utils, Widget } from '../imports.js';
|
||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
import { AnimatedCircProg } from "./lib/animatedcircularprogress.js";
|
||||
import {Service, Utils, Widget} from "../imports.js"
|
||||
import Mpris from "resource:///com/github/Aylur/ags/service/mpris.js"
|
||||
import Audio from "resource:///com/github/Aylur/ags/service/audio.js"
|
||||
const {execAsync, exec} = Utils
|
||||
import {AnimatedCircProg} from "./lib/animatedcircularprogress.js"
|
||||
|
||||
const TrackProgress = () => {
|
||||
const _updateProgress = (circprog) => {
|
||||
const mpris = Mpris.getPlayer('');
|
||||
if (!mpris) return;
|
||||
// Set circular progress (font size cuz that's how this hacky circprog works)
|
||||
circprog.style = `font-size: ${mpris.position / mpris.length * 100}px;`
|
||||
}
|
||||
return AnimatedCircProg({
|
||||
className: 'bar-music-circprog',
|
||||
valign: 'center',
|
||||
connections: [ // Update on change/once every 3 seconds
|
||||
[Mpris, _updateProgress],
|
||||
[3000, _updateProgress]
|
||||
]
|
||||
})
|
||||
const _updateProgress = circprog => {
|
||||
const mpris = Mpris.getPlayer("")
|
||||
if (!mpris) return
|
||||
// Set circular progress (font size cuz that's how this hacky circprog works)
|
||||
circprog.style = `font-size: ${(mpris.position / mpris.length) * 100}px;`
|
||||
}
|
||||
return AnimatedCircProg({
|
||||
className: "bar-music-circprog",
|
||||
valign: "center",
|
||||
connections: [
|
||||
// Update on change/once every 3 seconds
|
||||
[Mpris, _updateProgress],
|
||||
[3000, _updateProgress],
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export const ModuleMusic = () => Widget.EventBox({
|
||||
onScrollUp: () => execAsync('hyprctl dispatch workspace -1'),
|
||||
onScrollDown: () => execAsync('hyprctl dispatch workspace +1'),
|
||||
onSecondaryClick: () => Mpris.getPlayer('')?.next(),
|
||||
onMiddleClick: () => Mpris.getPlayer('')?.playPause(),
|
||||
export const ModuleMusic = () =>
|
||||
Widget.EventBox({
|
||||
onScrollUp: () => execAsync("hyprctl dispatch workspace -1"),
|
||||
onScrollDown: () => execAsync("hyprctl dispatch workspace +1"),
|
||||
onSecondaryClick: () => Mpris.getPlayer("")?.next(),
|
||||
onMiddleClick: () => Mpris.getPlayer("")?.playPause(),
|
||||
child: Widget.Box({
|
||||
className: 'bar-group-margin bar-sides',
|
||||
children: [
|
||||
className: "bar-group-margin bar-sides",
|
||||
children: [
|
||||
Widget.Box({
|
||||
className: "bar-group bar-group-standalone bar-group-pad-music spacing-h-10",
|
||||
children: [
|
||||
Widget.Box({
|
||||
className: 'bar-group bar-group-standalone bar-group-pad-music spacing-h-10',
|
||||
children: [
|
||||
Widget.Box({ // Wrap a box cuz overlay can't have margins itself
|
||||
homogeneous: true,
|
||||
children: [Widget.Overlay({
|
||||
child: Widget.Box({
|
||||
valign: 'center',
|
||||
className: 'bar-music-playstate',
|
||||
children: [Widget.Label({
|
||||
valign: 'center',
|
||||
className: 'bar-music-playstate-txt',
|
||||
connections: [[Mpris, label => {
|
||||
const mpris = Mpris.getPlayer('');
|
||||
label.label = `${mpris !== null && mpris.playBackStatus == 'Playing' ? '' : ''}`;
|
||||
}]],
|
||||
})],
|
||||
connections: [[Mpris, label => {
|
||||
const mpris = Mpris.getPlayer('');
|
||||
if (!mpris) return;
|
||||
label.toggleClassName('bar-music-playstate-playing', mpris !== null && mpris.playBackStatus == 'Playing');
|
||||
label.toggleClassName('bar-music-playstate', mpris !== null || mpris.playBackStatus == 'Paused');
|
||||
}]],
|
||||
}),
|
||||
overlays: [
|
||||
TrackProgress(),
|
||||
]
|
||||
})]
|
||||
}),
|
||||
Widget.Scrollable({
|
||||
hexpand: true,
|
||||
child: Widget.Label({
|
||||
className: 'txt txt-smallie',
|
||||
connections: [[Mpris, label => {
|
||||
const mpris = Mpris.getPlayer('');
|
||||
if (mpris)
|
||||
label.label = `${mpris.trackTitle} • ${mpris.trackArtists.join(', ')}`;
|
||||
else
|
||||
label.label = 'No mewwsic';
|
||||
}]],
|
||||
})
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
// Wrap a box cuz overlay can't have margins itself
|
||||
homogeneous: true,
|
||||
children: [
|
||||
Widget.Overlay({
|
||||
child: Widget.Box({
|
||||
valign: "center",
|
||||
className: "bar-music-playstate",
|
||||
children: [
|
||||
Widget.Label({
|
||||
valign: "center",
|
||||
className: "bar-music-playstate-txt",
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
label => {
|
||||
const mpris = Mpris.getPlayer("")
|
||||
label.label = `${
|
||||
mpris !== null && mpris.playBackStatus == "Playing" ? "" : ""
|
||||
}`
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
],
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
label => {
|
||||
const mpris = Mpris.getPlayer("")
|
||||
if (!mpris) return
|
||||
label.toggleClassName(
|
||||
"bar-music-playstate-playing",
|
||||
mpris !== null && mpris.playBackStatus == "Playing",
|
||||
)
|
||||
label.toggleClassName(
|
||||
"bar-music-playstate",
|
||||
mpris !== null || mpris.playBackStatus == "Paused",
|
||||
)
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
overlays: [TrackProgress()],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Scrollable({
|
||||
hexpand: true,
|
||||
child: Widget.Label({
|
||||
className: "txt txt-smallie",
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
label => {
|
||||
const mpris = Mpris.getPlayer("")
|
||||
if (mpris) label.label = `${mpris.trackTitle} • ${mpris.trackArtists.join(", ")}`
|
||||
else label.label = "No mewwsic"
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Service, Utils, Widget } from '../imports.js';
|
||||
const { Box, CenterBox, Label } = Widget;
|
||||
const { Mpris } = Service;
|
||||
const { timeout } = Utils;
|
||||
import { BluetoothIndicator, NetworkIndicator } from "./statusicons.js";
|
||||
import {Service, Utils, Widget} from "../imports.js"
|
||||
const {Box, CenterBox, Label} = Widget
|
||||
const {Mpris} = Service
|
||||
const {timeout} = Utils
|
||||
import {BluetoothIndicator, NetworkIndicator} from "./statusicons.js"
|
||||
|
||||
export const ModuleMusicControls = () => Box({
|
||||
|
||||
})
|
||||
export const ModuleMusicControls = () => Box({})
|
||||
|
||||
@@ -2,122 +2,137 @@
|
||||
// For the popup notifications, see onscreendisplay.js
|
||||
// The actual widget for each single notification is in lib/notification.js
|
||||
|
||||
const { GLib, Gtk } = imports.gi;
|
||||
import { Service, Utils, Widget } from '../imports.js';
|
||||
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
||||
const { lookUpIcon, timeout } = Utils;
|
||||
const { Box, Icon, Scrollable, Label, Button, Revealer } = Widget;
|
||||
import { MaterialIcon } from "./lib/materialicon.js";
|
||||
import { setupCursorHover } from "./lib/cursorhover.js";
|
||||
import Notification from "./lib/notification.js";
|
||||
const {GLib, Gtk} = imports.gi
|
||||
import {Service, Utils, Widget} from "../imports.js"
|
||||
import Notifications from "resource:///com/github/Aylur/ags/service/notifications.js"
|
||||
const {lookUpIcon, timeout} = Utils
|
||||
const {Box, Icon, Scrollable, Label, Button, Revealer} = Widget
|
||||
import {MaterialIcon} from "./lib/materialicon.js"
|
||||
import {setupCursorHover} from "./lib/cursorhover.js"
|
||||
import Notification from "./lib/notification.js"
|
||||
|
||||
const NotificationList = Box({
|
||||
vertical: true,
|
||||
valign: 'start',
|
||||
className: 'spacing-v-5-revealer',
|
||||
connections: [
|
||||
[Notifications, (box, id) => {
|
||||
if (box.children.length == 0) {
|
||||
Notifications.notifications
|
||||
.forEach(n => {
|
||||
box.pack_end(Notification({
|
||||
notifObject: n,
|
||||
isPopup: false,
|
||||
}), false, false, 0)
|
||||
});
|
||||
box.show_all();
|
||||
}
|
||||
else if (id) {
|
||||
const notif = Notifications.getNotification(id);
|
||||
vertical: true,
|
||||
valign: "start",
|
||||
className: "spacing-v-5-revealer",
|
||||
connections: [
|
||||
[
|
||||
Notifications,
|
||||
(box, id) => {
|
||||
if (box.children.length == 0) {
|
||||
Notifications.notifications.forEach(n => {
|
||||
box.pack_end(
|
||||
Notification({
|
||||
notifObject: n,
|
||||
isPopup: false,
|
||||
}),
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
)
|
||||
})
|
||||
box.show_all()
|
||||
} else if (id) {
|
||||
const notif = Notifications.getNotification(id)
|
||||
|
||||
const NewNotif = Notification({
|
||||
notifObject: notif,
|
||||
isPopup: false,
|
||||
});
|
||||
const NewNotif = Notification({
|
||||
notifObject: notif,
|
||||
isPopup: false,
|
||||
})
|
||||
|
||||
if (NewNotif) {
|
||||
box.pack_end(NewNotif, false, false, 0);
|
||||
box.show_all();
|
||||
}
|
||||
}
|
||||
}, 'notified'],
|
||||
|
||||
[Notifications, (box, id) => {
|
||||
if (!id) return;
|
||||
for (const ch of box.children) {
|
||||
if (ch._id === id) {
|
||||
ch._destroyWithAnims();
|
||||
}
|
||||
}
|
||||
}, 'closed'],
|
||||
|
||||
[Notifications, box => box.visible = Notifications.notifications.length > 0],
|
||||
if (NewNotif) {
|
||||
box.pack_end(NewNotif, false, false, 0)
|
||||
box.show_all()
|
||||
}
|
||||
}
|
||||
},
|
||||
"notified",
|
||||
],
|
||||
});
|
||||
|
||||
export default (props) => {
|
||||
const listTitle = Revealer({
|
||||
revealChild: false,
|
||||
connections: [[Notifications, (revealer) => {
|
||||
revealer.revealChild = (Notifications.notifications.length > 0);
|
||||
}]],
|
||||
child: Box({
|
||||
valign: 'start',
|
||||
className: 'sidebar-group-invisible txt',
|
||||
[
|
||||
Notifications,
|
||||
(box, id) => {
|
||||
if (!id) return
|
||||
for (const ch of box.children) {
|
||||
if (ch._id === id) {
|
||||
ch._destroyWithAnims()
|
||||
}
|
||||
}
|
||||
},
|
||||
"closed",
|
||||
],
|
||||
|
||||
[Notifications, box => (box.visible = Notifications.notifications.length > 0)],
|
||||
],
|
||||
})
|
||||
|
||||
export default props => {
|
||||
const listTitle = Revealer({
|
||||
revealChild: false,
|
||||
connections: [
|
||||
[
|
||||
Notifications,
|
||||
revealer => {
|
||||
revealer.revealChild = Notifications.notifications.length > 0
|
||||
},
|
||||
],
|
||||
],
|
||||
child: Box({
|
||||
valign: "start",
|
||||
className: "sidebar-group-invisible txt",
|
||||
children: [
|
||||
Label({
|
||||
hexpand: true,
|
||||
xalign: 0,
|
||||
className: "txt-title-small",
|
||||
label: "Notifications",
|
||||
}),
|
||||
Button({
|
||||
className: "notif-closeall-btn",
|
||||
onClicked: () => {
|
||||
Notifications.clear()
|
||||
},
|
||||
child: Box({
|
||||
className: "spacing-h-5",
|
||||
children: [
|
||||
Label({
|
||||
hexpand: true,
|
||||
xalign: 0,
|
||||
className: 'txt-title-small',
|
||||
label: 'Notifications',
|
||||
}),
|
||||
Button({
|
||||
className: 'notif-closeall-btn',
|
||||
onClicked: () => {
|
||||
Notifications.clear();
|
||||
},
|
||||
child: Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
MaterialIcon('clear_all', 'norm'),
|
||||
Label({
|
||||
className: 'txt-small',
|
||||
label: 'Clear',
|
||||
})
|
||||
]
|
||||
}),
|
||||
setup: button => {
|
||||
setupCursorHover(button);
|
||||
},
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
const listContents = Scrollable({
|
||||
hexpand: true,
|
||||
hscroll: 'never',
|
||||
vscroll: 'automatic',
|
||||
child: Widget({
|
||||
type: Gtk.Viewport,
|
||||
className: 'sidebar-viewport',
|
||||
setup: (viewport) => {
|
||||
viewport.add(Box({
|
||||
vexpand: true,
|
||||
children: [NotificationList],
|
||||
}));
|
||||
}
|
||||
})
|
||||
});
|
||||
listContents.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||
const vScrollbar = listContents.get_vscrollbar();
|
||||
vScrollbar.get_style_context().add_class('sidebar-scrollbar');
|
||||
return Box({
|
||||
...props,
|
||||
className: 'sidebar-group-invisible spacing-v-5',
|
||||
vertical: true,
|
||||
children: [
|
||||
listTitle,
|
||||
listContents,
|
||||
]
|
||||
});
|
||||
MaterialIcon("clear_all", "norm"),
|
||||
Label({
|
||||
className: "txt-small",
|
||||
label: "Clear",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
setup: button => {
|
||||
setupCursorHover(button)
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
const listContents = Scrollable({
|
||||
hexpand: true,
|
||||
hscroll: "never",
|
||||
vscroll: "automatic",
|
||||
child: Widget({
|
||||
type: Gtk.Viewport,
|
||||
className: "sidebar-viewport",
|
||||
setup: viewport => {
|
||||
viewport.add(
|
||||
Box({
|
||||
vexpand: true,
|
||||
children: [NotificationList],
|
||||
}),
|
||||
)
|
||||
},
|
||||
}),
|
||||
})
|
||||
listContents.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||
const vScrollbar = listContents.get_vscrollbar()
|
||||
vScrollbar.get_style_context().add_class("sidebar-scrollbar")
|
||||
return Box({
|
||||
...props,
|
||||
className: "sidebar-group-invisible spacing-v-5",
|
||||
vertical: true,
|
||||
children: [listTitle, listContents],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,191 +2,236 @@
|
||||
// For the notification widget on the sidebar, see notificationlist.js
|
||||
// The actual widget for each single notification is in lib/notification.js
|
||||
|
||||
const { GLib, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Widget } from '../imports.js';
|
||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
||||
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
||||
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
|
||||
import Brightness from '../scripts/brightness.js';
|
||||
import Indicator from '../scripts/indicator.js';
|
||||
import Notification from './lib/notification.js';
|
||||
const {GLib, Gtk} = imports.gi
|
||||
import {App, Service, Utils, Widget} from "../imports.js"
|
||||
import Audio from "resource:///com/github/Aylur/ags/service/audio.js"
|
||||
import Notifications from "resource:///com/github/Aylur/ags/service/notifications.js"
|
||||
const {Box, EventBox, Icon, Scrollable, Label, Button, Revealer} = Widget
|
||||
import Brightness from "../scripts/brightness.js"
|
||||
import Indicator from "../scripts/indicator.js"
|
||||
import Notification from "./lib/notification.js"
|
||||
|
||||
const OsdValue = (name, labelConnections, progressConnections, props = {}) => Widget.Box({ // Volume
|
||||
const OsdValue = (name, labelConnections, progressConnections, props = {}) =>
|
||||
Widget.Box({
|
||||
// Volume
|
||||
...props,
|
||||
vertical: true,
|
||||
className: 'osd-bg osd-value',
|
||||
className: "osd-bg osd-value",
|
||||
hexpand: true,
|
||||
children: [
|
||||
Widget.Box({
|
||||
vexpand: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
xalign: 0, yalign: 0, hexpand: true,
|
||||
className: 'osd-label',
|
||||
label: `${name}`,
|
||||
}),
|
||||
Widget.Label({
|
||||
hexpand: false, className: 'osd-value-txt',
|
||||
label: '100',
|
||||
connections: labelConnections,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Widget.ProgressBar({
|
||||
className: 'osd-progress',
|
||||
Widget.Box({
|
||||
vexpand: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
yalign: 0,
|
||||
hexpand: true,
|
||||
vertical: false,
|
||||
connections: progressConnections,
|
||||
})
|
||||
className: "osd-label",
|
||||
label: `${name}`,
|
||||
}),
|
||||
Widget.Label({
|
||||
hexpand: false,
|
||||
className: "osd-value-txt",
|
||||
label: "100",
|
||||
connections: labelConnections,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.ProgressBar({
|
||||
className: "osd-progress",
|
||||
hexpand: true,
|
||||
vertical: false,
|
||||
connections: progressConnections,
|
||||
}),
|
||||
],
|
||||
});
|
||||
})
|
||||
|
||||
const brightnessIndicator = OsdValue('Brightness',
|
||||
[[Brightness, self => {
|
||||
self.label = `${Math.round(Brightness.screen_value * 100)}`;
|
||||
}, 'notify::screen-value']],
|
||||
[[Brightness, (progress) => {
|
||||
const updateValue = Brightness.screen_value;
|
||||
progress.value = updateValue;
|
||||
}, 'notify::screen-value']],
|
||||
const brightnessIndicator = OsdValue(
|
||||
"Brightness",
|
||||
[
|
||||
[
|
||||
Brightness,
|
||||
self => {
|
||||
self.label = `${Math.round(Brightness.screen_value * 100)}`
|
||||
},
|
||||
"notify::screen-value",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
Brightness,
|
||||
progress => {
|
||||
const updateValue = Brightness.screen_value
|
||||
progress.value = updateValue
|
||||
},
|
||||
"notify::screen-value",
|
||||
],
|
||||
],
|
||||
)
|
||||
|
||||
const volumeIndicator = OsdValue('Volume',
|
||||
[[Audio, (label) => {
|
||||
label.label = `${Math.round(Audio.speaker?.volume * 100)}`;
|
||||
}]],
|
||||
[[Audio, (progress) => {
|
||||
const updateValue = Audio.speaker?.volume;
|
||||
if (!isNaN(updateValue)) progress.value = updateValue;
|
||||
}]],
|
||||
);
|
||||
const volumeIndicator = OsdValue(
|
||||
"Volume",
|
||||
[
|
||||
[
|
||||
Audio,
|
||||
label => {
|
||||
label.label = `${Math.round((Audio.speaker?.volume ?? 0) * 100)}`
|
||||
},
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
Audio,
|
||||
progress => {
|
||||
const updateValue = Audio.speaker?.volume ?? 0
|
||||
if (!isNaN(updateValue)) progress.value = updateValue
|
||||
},
|
||||
],
|
||||
],
|
||||
)
|
||||
|
||||
const indicatorValues = Widget.Revealer({
|
||||
transition: 'slide_down',
|
||||
connections: [
|
||||
[Indicator, (revealer, value) => {
|
||||
revealer.revealChild = (value > -1);
|
||||
}, 'popup'],
|
||||
transition: "slide_down",
|
||||
connections: [
|
||||
[
|
||||
Indicator,
|
||||
(revealer, value) => {
|
||||
revealer.revealChild = value > -1
|
||||
},
|
||||
"popup",
|
||||
],
|
||||
child: Widget.Box({
|
||||
halign: 'center',
|
||||
vertical: false,
|
||||
children: [
|
||||
brightnessIndicator,
|
||||
volumeIndicator,
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
const PopupNotification = (notifObject) => Widget.Box({
|
||||
homogeneous: true,
|
||||
children: [
|
||||
Widget.EventBox({
|
||||
onHoverLost: () => {
|
||||
notifObject.dismiss();
|
||||
},
|
||||
child: Widget.Revealer({
|
||||
revealChild: true,
|
||||
child: Widget.Box({
|
||||
children: [Notification({
|
||||
notifObject: notifObject,
|
||||
isPopup: true,
|
||||
props: { halign: 'fill' },
|
||||
})],
|
||||
}),
|
||||
})
|
||||
})
|
||||
]
|
||||
],
|
||||
child: Widget.Box({
|
||||
halign: "center",
|
||||
vertical: false,
|
||||
children: [brightnessIndicator, volumeIndicator],
|
||||
}),
|
||||
})
|
||||
|
||||
const naiveNotifPopupList = Widget.Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
connections: [
|
||||
[Notifications, (box) => {
|
||||
box.children = Notifications.popups.reverse()
|
||||
.map(notifItem => PopupNotification(notifItem));
|
||||
}],
|
||||
const PopupNotification = notifObject =>
|
||||
Widget.Box({
|
||||
homogeneous: true,
|
||||
children: [
|
||||
Widget.EventBox({
|
||||
onHoverLost: () => {
|
||||
notifObject.dismiss()
|
||||
},
|
||||
child: Widget.Revealer({
|
||||
revealChild: true,
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
Notification({
|
||||
notifObject: notifObject,
|
||||
isPopup: true,
|
||||
props: {halign: "fill"},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
const naiveNotifPopupList = Widget.Box({
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
connections: [
|
||||
[
|
||||
Notifications,
|
||||
box => {
|
||||
box.children = Notifications.popups.reverse().map(notifItem => PopupNotification(notifItem))
|
||||
},
|
||||
],
|
||||
],
|
||||
})
|
||||
|
||||
const notifPopupList = Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5-revealer',
|
||||
properties: [
|
||||
['map', new Map()],
|
||||
vertical: true,
|
||||
className: "spacing-v-5-revealer",
|
||||
properties: [
|
||||
["map", new Map()],
|
||||
|
||||
['dismiss', (box, id, force = false) => {
|
||||
if (!id || !box._map.has(id) || box._map.get(id)._hovered && !force)
|
||||
return;
|
||||
[
|
||||
"dismiss",
|
||||
(box, id, force = false) => {
|
||||
if (!id || !box._map.has(id) || (box._map.get(id)._hovered && !force)) return
|
||||
|
||||
const notif = box._map.get(id);
|
||||
// console.log(notif);
|
||||
notif.revealChild = false;
|
||||
Utils.timeout(200, () => {
|
||||
notif._destroyWithAnims();
|
||||
})
|
||||
}],
|
||||
|
||||
['notify', (box, id) => {
|
||||
if (!id || Notifications.dnd)
|
||||
return;
|
||||
|
||||
if (!Notifications.getNotification(id))
|
||||
return;
|
||||
|
||||
box._map.delete(id);
|
||||
|
||||
const notif = Notifications.getNotification(id);
|
||||
box._map.set(id, Notification({
|
||||
notifObject: notif,
|
||||
isPopup: true,
|
||||
}));
|
||||
|
||||
box.children = Array.from(box._map.values()).reverse();
|
||||
|
||||
Utils.timeout(10, () => {
|
||||
box.get_parent().revealChild = true;
|
||||
});
|
||||
|
||||
box._map.get(id).interval = Utils.interval(4500, () => {
|
||||
const notif = box._map.get(id);
|
||||
if (!notif._hovered) {
|
||||
if (notif.interval) {
|
||||
Utils.timeout(500, () => notif.destroy());
|
||||
GLib.source_remove(notif.interval);
|
||||
notif.interval = undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
}],
|
||||
const notif = box._map.get(id)
|
||||
// console.log(notif);
|
||||
notif.revealChild = false
|
||||
Utils.timeout(200, () => {
|
||||
notif._destroyWithAnims()
|
||||
})
|
||||
},
|
||||
],
|
||||
connections: [
|
||||
[Notifications, (box, id) => box._notify(box, id), 'notified'],
|
||||
[Notifications, (box, id) => box._dismiss(box, id), 'dismissed'],
|
||||
[Notifications, (box, id) => box._dismiss(box, id, true), 'closed'],
|
||||
],
|
||||
});
|
||||
|
||||
const notificationPopups = Widget.Revealer({
|
||||
className: 'osd-notifs',
|
||||
transition: 'slide_down',
|
||||
connections: [[Notifications, (self) => {
|
||||
self.revealChild = Notifications.popups.length > 0;
|
||||
}]],
|
||||
child: notifPopupList,
|
||||
[
|
||||
"notify",
|
||||
(box, id) => {
|
||||
if (!id || Notifications.dnd) return
|
||||
|
||||
if (!Notifications.getNotification(id)) return
|
||||
|
||||
box._map.delete(id)
|
||||
|
||||
const notif = Notifications.getNotification(id)
|
||||
box._map.set(
|
||||
id,
|
||||
Notification({
|
||||
notifObject: notif,
|
||||
isPopup: true,
|
||||
}),
|
||||
)
|
||||
|
||||
box.children = Array.from(box._map.values()).reverse()
|
||||
|
||||
Utils.timeout(10, () => {
|
||||
box.get_parent().revealChild = true
|
||||
})
|
||||
|
||||
box._map.get(id).interval = Utils.interval(4500, () => {
|
||||
const notif = box._map.get(id)
|
||||
if (!notif._hovered) {
|
||||
if (notif.interval) {
|
||||
Utils.timeout(500, () => notif.destroy())
|
||||
GLib.source_remove(notif.interval)
|
||||
notif.interval = undefined
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
],
|
||||
],
|
||||
connections: [
|
||||
[Notifications, (box, id) => box._notify(box, id), "notified"],
|
||||
[Notifications, (box, id) => box._dismiss(box, id), "dismissed"],
|
||||
[Notifications, (box, id) => box._dismiss(box, id, true), "closed"],
|
||||
],
|
||||
})
|
||||
|
||||
export default () => Widget.EventBox({
|
||||
onHover: () => { //make the widget hide when hovering
|
||||
Indicator.popup(-1);
|
||||
const notificationPopups = Widget.Revealer({
|
||||
className: "osd-notifs",
|
||||
transition: "slide_down",
|
||||
connections: [
|
||||
[
|
||||
Notifications,
|
||||
self => {
|
||||
self.revealChild = Notifications.popups.length > 0
|
||||
},
|
||||
],
|
||||
],
|
||||
child: notifPopupList,
|
||||
})
|
||||
|
||||
export default () =>
|
||||
Widget.EventBox({
|
||||
onHover: () => {
|
||||
//make the widget hide when hovering
|
||||
Indicator.popup(-1)
|
||||
},
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
style: 'padding: 1px;',
|
||||
children: [
|
||||
indicatorValues,
|
||||
notificationPopups,
|
||||
]
|
||||
})
|
||||
});
|
||||
vertical: true,
|
||||
style: "padding: 1px;",
|
||||
children: [indicatorValues, notificationPopups],
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -1,114 +1,120 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Widget } from '../imports.js';
|
||||
const { Box, EventBox, Button, Revealer } = Widget;
|
||||
const { execAsync, exec } = Utils;
|
||||
import { setupCursorHover, setupCursorHoverAim } from "./lib/cursorhover.js";
|
||||
import { MaterialIcon } from './lib/materialicon.js';
|
||||
import { separatorLine } from './lib/separator.js';
|
||||
import { defaultOskLayout, oskLayouts } from '../data/keyboardlayouts.js';
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
import {App, Service, Utils, Widget} from "../imports.js"
|
||||
const {Box, EventBox, Button, Revealer} = Widget
|
||||
const {execAsync, exec} = Utils
|
||||
import {setupCursorHover, setupCursorHoverAim} from "./lib/cursorhover.js"
|
||||
import {MaterialIcon} from "./lib/materialicon.js"
|
||||
import {separatorLine} from "./lib/separator.js"
|
||||
import {defaultOskLayout, oskLayouts} from "../data/keyboardlayouts.js"
|
||||
|
||||
const keyboardLayout = defaultOskLayout;
|
||||
const keyboardJson = oskLayouts[keyboardLayout];
|
||||
execAsync(`ydotoold`).catch(print); // Start ydotool daemon
|
||||
const keyboardLayout = defaultOskLayout
|
||||
const keyboardJson = oskLayouts[keyboardLayout]
|
||||
execAsync(`ydotoold`).catch(print) // Start ydotool daemon
|
||||
|
||||
function releaseAllKeys() {
|
||||
const keycodes = Array.from(Array(249).keys());
|
||||
execAsync([`ydotool`, `key`, ...keycodes.map(keycode => `${keycode}:0`)])
|
||||
.then(console.log('Released all keys'))
|
||||
.catch(print);
|
||||
const keycodes = Array.from(Array(249).keys())
|
||||
execAsync([`ydotool`, `key`, ...keycodes.map(keycode => `${keycode}:0`)])
|
||||
.then(console.log("Released all keys"))
|
||||
.catch(print)
|
||||
}
|
||||
var modsPressed = false;
|
||||
var modsPressed = false
|
||||
|
||||
const keyboardControlButton = (icon, text, runFunction) => Button({
|
||||
className: 'osk-control-button spacing-h-10',
|
||||
const keyboardControlButton = (icon, text, runFunction) =>
|
||||
Button({
|
||||
className: "osk-control-button spacing-h-10",
|
||||
onClicked: () => runFunction(),
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
MaterialIcon(icon, 'norm'),
|
||||
Widget.Label({
|
||||
label: `${text}`,
|
||||
}),
|
||||
]
|
||||
})
|
||||
})
|
||||
children: [
|
||||
MaterialIcon(icon, "norm"),
|
||||
Widget.Label({
|
||||
label: `${text}`,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
const keyboardControls = Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
children: [
|
||||
Button({
|
||||
className: 'osk-control-button txt-norm icon-material',
|
||||
onClicked: () => {
|
||||
releaseAllKeys();
|
||||
App.toggleWindow('osk');
|
||||
},
|
||||
label: 'keyboard_hide',
|
||||
}),
|
||||
Button({
|
||||
className: 'osk-control-button txt-norm',
|
||||
label: `${keyboardJson['name_short']}`,
|
||||
}),
|
||||
Button({
|
||||
className: 'osk-control-button txt-norm icon-material',
|
||||
onClicked: () => { // TODO: Proper clipboard widget, since fuzzel doesn't receive mouse inputs
|
||||
execAsync([`bash`, `-c`, "pkill fuzzel || cliphist list | fuzzel --no-fuzzy --dmenu | cliphist decode | wl-copy"]).catch(print);
|
||||
},
|
||||
label: 'assignment',
|
||||
}),
|
||||
]
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
children: [
|
||||
Button({
|
||||
className: "osk-control-button txt-norm icon-material",
|
||||
onClicked: () => {
|
||||
releaseAllKeys()
|
||||
App.toggleWindow("osk")
|
||||
},
|
||||
label: "keyboard_hide",
|
||||
}),
|
||||
Button({
|
||||
className: "osk-control-button txt-norm",
|
||||
label: `${keyboardJson["name_short"]}`,
|
||||
}),
|
||||
Button({
|
||||
className: "osk-control-button txt-norm icon-material",
|
||||
onClicked: () => {
|
||||
// TODO: Proper clipboard widget, since fuzzel doesn't receive mouse inputs
|
||||
execAsync([
|
||||
`bash`,
|
||||
`-c`,
|
||||
"pkill fuzzel || cliphist list | fuzzel --no-fuzzy --dmenu | cliphist decode | wl-copy",
|
||||
]).catch(print)
|
||||
},
|
||||
label: "assignment",
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
const keyboardItself = (kbJson) => {
|
||||
return Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
children: kbJson.keys.map(row => Box({
|
||||
vertical: false,
|
||||
className: 'spacing-h-5',
|
||||
children: row.map(key => {
|
||||
return Button({
|
||||
className: `osk-key osk-key-${key.shape}`,
|
||||
hexpand: (key.shape == "space" || key.shape == "expand"),
|
||||
label: key.label,
|
||||
setup: (button) => {
|
||||
let pressed = false;
|
||||
if (key.keytype == "normal") {
|
||||
button.connect('pressed', () => { // mouse down
|
||||
execAsync(`ydotool key ${key.keycode}:1`);
|
||||
});
|
||||
button.connect('clicked', () => { // release
|
||||
execAsync(`ydotool key ${key.keycode}:0`);
|
||||
});
|
||||
}
|
||||
else if (key.keytype == "modkey") {
|
||||
button.connect('pressed', () => { // release
|
||||
if (pressed) {
|
||||
execAsync(`ydotool key ${key.keycode}:0`);
|
||||
button.toggleClassName('osk-key-active', false);
|
||||
pressed = false;
|
||||
}
|
||||
else {
|
||||
execAsync(`ydotool key ${key.keycode}:1`);
|
||||
button.toggleClassName('osk-key-active', true);
|
||||
pressed = true;
|
||||
modsPressed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
const keyboardItself = kbJson => {
|
||||
return Box({
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
children: kbJson.keys.map(row =>
|
||||
Box({
|
||||
vertical: false,
|
||||
className: "spacing-h-5",
|
||||
children: row.map(key => {
|
||||
return Button({
|
||||
className: `osk-key osk-key-${key.shape}`,
|
||||
hexpand: key.shape == "space" || key.shape == "expand",
|
||||
label: key.label,
|
||||
setup: button => {
|
||||
let pressed = false
|
||||
if (key.keytype == "normal") {
|
||||
button.connect("pressed", () => {
|
||||
// mouse down
|
||||
execAsync(`ydotool key ${key.keycode}:1`)
|
||||
})
|
||||
})
|
||||
}))
|
||||
})
|
||||
button.connect("clicked", () => {
|
||||
// release
|
||||
execAsync(`ydotool key ${key.keycode}:0`)
|
||||
})
|
||||
} else if (key.keytype == "modkey") {
|
||||
button.connect("pressed", () => {
|
||||
// release
|
||||
if (pressed) {
|
||||
execAsync(`ydotool key ${key.keycode}:0`)
|
||||
button.toggleClassName("osk-key-active", false)
|
||||
pressed = false
|
||||
} else {
|
||||
execAsync(`ydotool key ${key.keycode}:1`)
|
||||
button.toggleClassName("osk-key-active", true)
|
||||
pressed = true
|
||||
modsPressed = true
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}),
|
||||
}),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
export default () => Box({
|
||||
export default () =>
|
||||
Box({
|
||||
vexpand: true,
|
||||
hexpand: true,
|
||||
className: 'osk-window spacing-h-10',
|
||||
children: [
|
||||
keyboardControls,
|
||||
separatorLine,
|
||||
keyboardItself(keyboardJson),
|
||||
],
|
||||
});
|
||||
className: "osk-window spacing-h-10",
|
||||
children: [keyboardControls, separatorLine, keyboardItself(keyboardJson)],
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,67 @@
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
import App from "resource:///com/github/Aylur/ags/app.js"
|
||||
|
||||
function DesktopEntryButton(app) {
|
||||
const actionText = Widget.Revealer({
|
||||
reveal_child: false,
|
||||
transition: "crossfade",
|
||||
transitionDuration: 200,
|
||||
child: Widget.Label({
|
||||
class_name: "overview-search-results-txt txt txt-small txt-action",
|
||||
label: "Launch",
|
||||
}),
|
||||
})
|
||||
|
||||
const actionTextRevealer = Widget.Revealer({
|
||||
reveal_child: false,
|
||||
transition: "slide_left",
|
||||
transitionDuration: 300,
|
||||
child: actionText,
|
||||
})
|
||||
|
||||
return Widget.Button({
|
||||
class_name: "overview-search-result-btn",
|
||||
on_clicked() {
|
||||
App.closeWindow("overview")
|
||||
app.launch()
|
||||
},
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
Widget.Box({
|
||||
vertical: false,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_name: "overview-search-results-icon",
|
||||
icon: app.iconName,
|
||||
size: 35, // TODO: Make this follow font size. made for 11pt.
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "overview-search-results-txt txt txt-norm",
|
||||
label: app.name,
|
||||
}),
|
||||
Widget.Box({hexpand: true}),
|
||||
actionTextRevealer,
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
connections: [
|
||||
[
|
||||
"focus-in-event",
|
||||
function () {
|
||||
actionText.revealChild = true
|
||||
actionTextRevealer.revealChild = true
|
||||
},
|
||||
],
|
||||
[
|
||||
"focus-out-event",
|
||||
function () {
|
||||
actionText.revealChild = false
|
||||
actionTextRevealer.revealChild = false
|
||||
},
|
||||
],
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export default DesktopEntryButton
|
||||
@@ -0,0 +1,11 @@
|
||||
import SearchItem from "../search-item"
|
||||
|
||||
function ExecuteCommandButton({command, terminal = false}) {
|
||||
SearchItem({
|
||||
materialIconName: `${terminal ? "terminal" : "settings_b_roll"}`,
|
||||
name: `Run command`,
|
||||
actionName: `Execute ${terminal ? "in terminal" : ""}`,
|
||||
content: `${command}`,
|
||||
onActivate: () => execAndClose(command, terminal),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import Todo from "../../scripts/todo"
|
||||
import {execAsync} from "resource:///com/github/Aylur/ags/utils.js"
|
||||
import App from "resource:///com/github/Aylur/ags/app.js"
|
||||
|
||||
/** @type {Record<string, string[] | undefined>} */
|
||||
const COMMANDS = {
|
||||
">raw": [
|
||||
`bash`,
|
||||
`-c`,
|
||||
`hyprctl keyword input:force_no_accel $(( 1 - $(hyprctl getoption input:force_no_accel -j | gojq ".int") ))`,
|
||||
`&`,
|
||||
],
|
||||
">img": [`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchwall.sh`, `&`],
|
||||
">light": [`bash`, `-c`, `mkdir -p ~/.cache/ags/user && echo "-l" > ~/.cache/ags/user/colormode.txt`, `&`],
|
||||
">dark": [`bash`, `-c`, `mkdir -p ~/.cache/ags/user && echo "" > ~/.cache/ags/user/colormode.txt`, `&`],
|
||||
">material": [
|
||||
`bash`,
|
||||
`-c`,
|
||||
`mkdir -p ~/.cache/ags/user && echo "material" > ~/.cache/ags/user/colorbackend.txt`,
|
||||
`&`,
|
||||
],
|
||||
">pywal": [
|
||||
`bash`,
|
||||
`-c`,
|
||||
`mkdir -p ~/.cache/ags/user && echo "material" > ~/.cache/ags/user/colorbackend.txt`,
|
||||
`&`,
|
||||
],
|
||||
">shutdown": [`bash`, `-c`, `systemctl poweroff`],
|
||||
">reboot": [`bash`, `-c`, `systemctl reboot`],
|
||||
">sleep": [`bash`, `-c`, `systemctl suspend`],
|
||||
">logout": [`bash`, `-c`, `loginctl terminate-user $USER`],
|
||||
}
|
||||
|
||||
/**
|
||||
* @param command {string}
|
||||
*/
|
||||
export function launchCustomCommand(command) {
|
||||
App.closeWindow("overview")
|
||||
const args = command.split(" ")
|
||||
const exec = COMMANDS[args[0]]
|
||||
if (exec !== undefined) {
|
||||
execAsync(exec).catch(print)
|
||||
} else if (args[0] === ">todo") {
|
||||
Todo.add(args.slice(1).join(" "))
|
||||
}
|
||||
}
|
||||
78
desktops/hyprland/ags/modules/overview/search-item.js
Normal file
78
desktops/hyprland/ags/modules/overview/search-item.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
|
||||
/**
|
||||
* @param options {{materialIconName: string; name: string; actionName: string; content: string; onActivate: (self: ReturnType<Widget.Button>) => void;}}
|
||||
*/
|
||||
function SearchItem({materialIconName, name, actionName, content, onActivate}) {
|
||||
const actionText = Widget.Revealer({
|
||||
reveal_child: false,
|
||||
transition: "crossfade",
|
||||
transition_duration: 200,
|
||||
child: Widget.Label({
|
||||
class_name: "overview-search-results-txt txt txt-small txt-action",
|
||||
label: actionName,
|
||||
}),
|
||||
})
|
||||
|
||||
const actionTextRevealer = Widget.Revealer({
|
||||
reveal_child: false,
|
||||
transition: "slide_left",
|
||||
transition_duration: 300,
|
||||
child: actionText,
|
||||
})
|
||||
|
||||
return Widget.Button({
|
||||
class_name: "overview-search-result-btn",
|
||||
on_clicked: onActivate,
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
Widget.Box({
|
||||
vertical: false,
|
||||
children: [
|
||||
Widget.Label({
|
||||
class_name: `icon-material overview-search-results-icon`,
|
||||
label: materialIconName,
|
||||
}),
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
halign: "start",
|
||||
class_name: "overview-search-results-txt txt txt-smallie txt-subtext",
|
||||
label: name,
|
||||
truncate: "end",
|
||||
}),
|
||||
Widget.Label({
|
||||
halign: "start",
|
||||
class_name: "overview-search-results-txt txt txt-norm",
|
||||
label: content,
|
||||
truncate: "end",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Box({hexpand: true}),
|
||||
actionTextRevealer,
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
connections: [
|
||||
[
|
||||
"focus-in-event",
|
||||
function () {
|
||||
actionText.reveal_child = true
|
||||
actionTextRevealer.reveal_child = true
|
||||
},
|
||||
],
|
||||
[
|
||||
"focus-out-event",
|
||||
function () {
|
||||
actionText.reveal_child = false
|
||||
actionTextRevealer.reveal_child = false
|
||||
},
|
||||
],
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export default SearchItem
|
||||
@@ -1,148 +1,176 @@
|
||||
import { Widget, Utils, Service } from '../imports.js';
|
||||
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
|
||||
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
import { BluetoothIndicator, NetworkIndicator } from "./statusicons.js";
|
||||
import { setupCursorHover } from "./lib/cursorhover.js";
|
||||
import { MaterialIcon } from './lib/materialicon.js';
|
||||
import {Widget, Utils, Service} from "../imports.js"
|
||||
import Bluetooth from "resource:///com/github/Aylur/ags/service/bluetooth.js"
|
||||
import Network from "resource:///com/github/Aylur/ags/service/network.js"
|
||||
const {execAsync, exec} = Utils
|
||||
import {BluetoothIndicator, NetworkIndicator} from "./statusicons.js"
|
||||
import {setupCursorHover} from "./lib/cursorhover.js"
|
||||
import {MaterialIcon} from "./lib/materialicon.js"
|
||||
|
||||
export const ToggleIconWifi = (props = {}) => Widget.Button({
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
tooltipText: 'Wifi | Right-click to configure',
|
||||
export const ToggleIconWifi = (props = {}) =>
|
||||
Widget.Button({
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
tooltipText: "Wifi | Right-click to configure",
|
||||
onClicked: Network.toggleWifi,
|
||||
onSecondaryClickRelease: () => {
|
||||
execAsync(['bash', '-c', 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center wifi', '&']);
|
||||
execAsync(["bash", "-c", 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center wifi', "&"])
|
||||
},
|
||||
child: NetworkIndicator(),
|
||||
connections: [
|
||||
[Network, button => {
|
||||
button.toggleClassName('sidebar-button-active', Network.wifi?.internet == 'connected' || Network.wired?.internet == 'connected')
|
||||
}],
|
||||
[Network, button => {
|
||||
button.tooltipText = (`${Network.wifi?.ssid} | Right-click to configure` || 'Unknown');
|
||||
}],
|
||||
[
|
||||
Network,
|
||||
button => {
|
||||
button.toggleClassName(
|
||||
"sidebar-button-active",
|
||||
Network.wifi?.internet == "connected" || Network.wired?.internet == "connected",
|
||||
)
|
||||
},
|
||||
],
|
||||
[
|
||||
Network,
|
||||
button => {
|
||||
button.tooltipText = `${Network.wifi?.ssid} | Right-click to configure` || "Unknown"
|
||||
},
|
||||
],
|
||||
],
|
||||
setup: (button) => setupCursorHover(button),
|
||||
setup: button => setupCursorHover(button),
|
||||
...props,
|
||||
});
|
||||
})
|
||||
|
||||
export const ToggleIconBluetooth = (props = {}) => Widget.Button({
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
tooltipText: 'Bluetooth | Right-click to configure',
|
||||
onClicked: () => { // Provided service doesn't work hmmm
|
||||
const status = Bluetooth?.enabled;
|
||||
if (status) {
|
||||
exec('rfkill block bluetooth');
|
||||
}
|
||||
else {
|
||||
exec('rfkill unblock bluetooth');
|
||||
}
|
||||
export const ToggleIconBluetooth = (props = {}) =>
|
||||
Widget.Button({
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
tooltipText: "Bluetooth | Right-click to configure",
|
||||
onClicked: () => {
|
||||
// Provided service doesn't work hmmm
|
||||
const status = Bluetooth?.enabled
|
||||
if (status) {
|
||||
exec("rfkill block bluetooth")
|
||||
} else {
|
||||
exec("rfkill unblock bluetooth")
|
||||
}
|
||||
},
|
||||
onSecondaryClickRelease: () => {
|
||||
execAsync(['bash', '-c', 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center bluetooth', '&']);
|
||||
execAsync(["bash", "-c", 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center bluetooth', "&"])
|
||||
},
|
||||
child: BluetoothIndicator(),
|
||||
connections: [
|
||||
[Bluetooth, button => {
|
||||
button.toggleClassName('sidebar-button-active', Bluetooth?.enabled)
|
||||
}],
|
||||
[
|
||||
Bluetooth,
|
||||
button => {
|
||||
button.toggleClassName("sidebar-button-active", Bluetooth?.enabled)
|
||||
},
|
||||
],
|
||||
],
|
||||
setup: (button) => setupCursorHover(button),
|
||||
setup: button => setupCursorHover(button),
|
||||
...props,
|
||||
});
|
||||
})
|
||||
|
||||
export const HyprToggleIcon = (icon, name, hyprlandConfigValue, props = {}) => Widget.Button({
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
export const HyprToggleIcon = (icon, name, hyprlandConfigValue, props = {}) =>
|
||||
Widget.Button({
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
tooltipText: `${name}`,
|
||||
onClicked: (button) => {
|
||||
// Set the value to 1 - value
|
||||
Utils.execAsync(`hyprctl -j getoption ${hyprlandConfigValue}`).then((result) => {
|
||||
const currentOption = JSON.parse(result).int;
|
||||
execAsync(['bash', '-c', `hyprctl keyword ${hyprlandConfigValue} ${1 - currentOption} &`]).catch(print);
|
||||
button.toggleClassName('sidebar-button-active', currentOption == 0);
|
||||
}).catch(print);
|
||||
onClicked: button => {
|
||||
// Set the value to 1 - value
|
||||
Utils.execAsync(`hyprctl -j getoption ${hyprlandConfigValue}`)
|
||||
.then(result => {
|
||||
const currentOption = JSON.parse(result).int
|
||||
execAsync(["bash", "-c", `hyprctl keyword ${hyprlandConfigValue} ${1 - currentOption} &`]).catch(
|
||||
print,
|
||||
)
|
||||
button.toggleClassName("sidebar-button-active", currentOption == 0)
|
||||
})
|
||||
.catch(print)
|
||||
},
|
||||
child: MaterialIcon(icon, 'norm', { halign: 'center' }),
|
||||
child: MaterialIcon(icon, "norm", {halign: "center"}),
|
||||
setup: button => {
|
||||
button.toggleClassName('sidebar-button-active', JSON.parse(Utils.exec(`hyprctl -j getoption ${hyprlandConfigValue}`)).int == 1);
|
||||
setupCursorHover(button);
|
||||
button.toggleClassName(
|
||||
"sidebar-button-active",
|
||||
JSON.parse(Utils.exec(`hyprctl -j getoption ${hyprlandConfigValue}`)).int == 1,
|
||||
)
|
||||
setupCursorHover(button)
|
||||
},
|
||||
...props,
|
||||
})
|
||||
})
|
||||
|
||||
export const ModuleNightLight = (props = {}) => Widget.Button({
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
tooltipText: 'Night Light',
|
||||
onClicked: (button) => {
|
||||
// Set the value to 1 - value
|
||||
const shaderPath = JSON.parse(exec('hyprctl -j getoption decoration:screen_shader')).str;
|
||||
if (shaderPath != "[[EMPTY]]" && shaderPath != "") {
|
||||
execAsync(['bash', '-c', `hyprctl keyword decoration:screen_shader ''`]).catch(print);
|
||||
button.toggleClassName('sidebar-button-active', false);
|
||||
}
|
||||
else {
|
||||
execAsync(['bash', '-c', `hyprctl keyword decoration:screen_shader ~/.config/hypr/shaders/extradark.frag`]).catch(print);
|
||||
button.toggleClassName('sidebar-button-active', true);
|
||||
}
|
||||
export const ModuleNightLight = (props = {}) =>
|
||||
Widget.Button({
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
tooltipText: "Night Light",
|
||||
onClicked: button => {
|
||||
// Set the value to 1 - value
|
||||
const shaderPath = JSON.parse(exec("hyprctl -j getoption decoration:screen_shader")).str
|
||||
if (shaderPath != "[[EMPTY]]" && shaderPath != "") {
|
||||
execAsync(["bash", "-c", `hyprctl keyword decoration:screen_shader ''`]).catch(print)
|
||||
button.toggleClassName("sidebar-button-active", false)
|
||||
} else {
|
||||
execAsync([
|
||||
"bash",
|
||||
"-c",
|
||||
`hyprctl keyword decoration:screen_shader ~/.config/hypr/shaders/extradark.frag`,
|
||||
]).catch(print)
|
||||
button.toggleClassName("sidebar-button-active", true)
|
||||
}
|
||||
},
|
||||
child: MaterialIcon('nightlight', 'norm'),
|
||||
setup: (button) => setupCursorHover(button),
|
||||
child: MaterialIcon("nightlight", "norm"),
|
||||
setup: button => setupCursorHover(button),
|
||||
...props,
|
||||
})
|
||||
})
|
||||
|
||||
export const ModuleEditIcon = (props = {}) => Widget.Button({ // TODO: Make this work
|
||||
export const ModuleEditIcon = (props = {}) =>
|
||||
Widget.Button({
|
||||
// TODO: Make this work
|
||||
...props,
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
onClicked: () => {
|
||||
execAsync(['bash', '-c', 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center', '&']);
|
||||
App.toggleWindow('sideright');
|
||||
execAsync(["bash", "-c", 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center', "&"])
|
||||
App.toggleWindow("sideright")
|
||||
},
|
||||
child: MaterialIcon('edit', 'norm'),
|
||||
child: MaterialIcon("edit", "norm"),
|
||||
setup: button => {
|
||||
setupCursorHover(button);
|
||||
}
|
||||
})
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
|
||||
export const ModuleReloadIcon = (props = {}) => Widget.Button({
|
||||
export const ModuleReloadIcon = (props = {}) =>
|
||||
Widget.Button({
|
||||
...props,
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
tooltipText: 'Reload Hyprland',
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
tooltipText: "Reload Hyprland",
|
||||
onClicked: () => {
|
||||
execAsync(['bash', '-c', 'hyprctl reload &']);
|
||||
App.toggleWindow('sideright');
|
||||
execAsync(["bash", "-c", "hyprctl reload &"])
|
||||
App.toggleWindow("sideright")
|
||||
},
|
||||
child: MaterialIcon('refresh', 'norm'),
|
||||
child: MaterialIcon("refresh", "norm"),
|
||||
setup: button => {
|
||||
setupCursorHover(button);
|
||||
}
|
||||
})
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
|
||||
export const ModuleSettingsIcon = (props = {}) => Widget.Button({
|
||||
export const ModuleSettingsIcon = (props = {}) =>
|
||||
Widget.Button({
|
||||
...props,
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
tooltipText: 'Open Settings',
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
tooltipText: "Open Settings",
|
||||
onClicked: () => {
|
||||
execAsync(['bash', '-c', 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center', '&']);
|
||||
App.toggleWindow('sideright');
|
||||
execAsync(["bash", "-c", 'XDG_CURRENT_DESKTOP="gnome" gnome-control-center', "&"])
|
||||
App.toggleWindow("sideright")
|
||||
},
|
||||
child: MaterialIcon('settings', 'norm'),
|
||||
child: MaterialIcon("settings", "norm"),
|
||||
setup: button => {
|
||||
setupCursorHover(button);
|
||||
}
|
||||
})
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
|
||||
export const ModulePowerIcon = (props = {}) => Widget.Button({
|
||||
export const ModulePowerIcon = (props = {}) =>
|
||||
Widget.Button({
|
||||
...props,
|
||||
className: 'txt-small sidebar-iconbutton',
|
||||
tooltipText: 'Session',
|
||||
className: "txt-small sidebar-iconbutton",
|
||||
tooltipText: "Session",
|
||||
onClicked: () => {
|
||||
App.toggleWindow('session');
|
||||
App.toggleWindow("session")
|
||||
},
|
||||
child: MaterialIcon('power_settings_new', 'norm'),
|
||||
child: MaterialIcon("power_settings_new", "norm"),
|
||||
setup: button => {
|
||||
setupCursorHover(button);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
setupCursorHover(button)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,44 +1,53 @@
|
||||
import { App, Service, Utils, Widget } from '../imports.js';
|
||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
||||
const { exec, execAsync, CONFIG_DIR } = Utils;
|
||||
import Indicator from '../scripts/indicator.js';
|
||||
import { StatusIcons } from "./statusicons.js";
|
||||
import { RoundedCorner } from "./lib/roundedcorner.js";
|
||||
import { Tray } from "./tray.js";
|
||||
import Audio from "resource:///com/github/Aylur/ags/service/audio.js"
|
||||
import Mpris from "resource:///com/github/Aylur/ags/service/mpris.js"
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
import Indicator from "../scripts/indicator.js"
|
||||
import StatusIcons from "./statusicons.js"
|
||||
import RoundedCorner from "./lib/roundedcorner.js"
|
||||
import Tray from "./tray.js"
|
||||
|
||||
export const ModuleRightSpace = () => Widget.EventBox({
|
||||
onScrollUp: () => {
|
||||
if (Audio.speaker == null) return;
|
||||
Audio.speaker.volume += 0.03;
|
||||
Indicator.popup(1);
|
||||
function ModuleRightSpace() {
|
||||
return Widget.EventBox({
|
||||
on_scroll_up() {
|
||||
if (Audio.speaker == null) return
|
||||
Audio.speaker.volume += 0.03
|
||||
Indicator.popup(1)
|
||||
},
|
||||
onScrollDown: () => {
|
||||
if (Audio.speaker == null) return;
|
||||
Audio.speaker.volume -= 0.03;
|
||||
Indicator.popup(1);
|
||||
on_scroll_down() {
|
||||
if (Audio.speaker == null) return
|
||||
Audio.speaker.volume -= 0.03
|
||||
Indicator.popup(1)
|
||||
},
|
||||
on_primary_click() {
|
||||
App.toggleWindow("sideright")
|
||||
},
|
||||
on_secondary_click() {
|
||||
Mpris.getPlayer("")?.next()
|
||||
},
|
||||
on_middle_click() {
|
||||
Mpris.getPlayer("")?.playPause()
|
||||
},
|
||||
onPrimaryClick: () => App.toggleWindow('sideright'),
|
||||
onSecondaryClick: () => Mpris.getPlayer('')?.next(),
|
||||
onMiddleClick: () => Mpris.getPlayer('')?.playPause(),
|
||||
child: Widget.Box({
|
||||
homogeneous: false,
|
||||
children: [
|
||||
homogeneous: false,
|
||||
children: [
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
className: "spacing-h-5 txt",
|
||||
children: [
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
className: 'spacing-h-5 txt',
|
||||
children: [
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
className: 'spacing-h-15 txt',
|
||||
setup: box => {
|
||||
box.pack_end(StatusIcons(), false, false, 0);
|
||||
box.pack_end(Tray(), false, false, 0);
|
||||
}
|
||||
}),
|
||||
]
|
||||
hexpand: true,
|
||||
className: "spacing-h-15 txt",
|
||||
setup: box => {
|
||||
box.pack_end(StatusIcons(), false, false, 0)
|
||||
box.pack_end(Tray(), false, false, 0)
|
||||
},
|
||||
}),
|
||||
RoundedCorner('topright', { className: 'corner-black' })
|
||||
]
|
||||
})
|
||||
});
|
||||
],
|
||||
}),
|
||||
RoundedCorner("top", "right", {class_name: "corner-black"}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export default ModuleRightSpace
|
||||
|
||||
@@ -1,144 +1,174 @@
|
||||
// This is for the cool memory indicator on the sidebar
|
||||
// For the right pill of the bar, see system.js
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
import { App, Service, Utils, Widget } from '../imports.js';
|
||||
const { exec, execAsync } = Utils;
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
const GObject = imports.gi.GObject
|
||||
const Lang = imports.lang
|
||||
import {App, Service, Utils, Widget} from "../imports.js"
|
||||
const {exec, execAsync} = Utils
|
||||
|
||||
const SessionButton = (name, icon, command, props = {}) => {
|
||||
const buttonDescription = Widget.Revealer({
|
||||
valign: 'end',
|
||||
transitionDuration: 200,
|
||||
transition: 'slide_down',
|
||||
revealChild: false,
|
||||
child: Widget.Label({
|
||||
className: 'txt-smaller session-button-desc',
|
||||
label: name,
|
||||
}),
|
||||
});
|
||||
return Widget.Button({
|
||||
onClicked: command,
|
||||
className: 'session-button',
|
||||
child: Widget.Overlay({
|
||||
className: 'session-button-box',
|
||||
child: Widget.Label({
|
||||
vexpand: true,
|
||||
className: 'icon-material',
|
||||
label: icon,
|
||||
}),
|
||||
overlays: [
|
||||
buttonDescription,
|
||||
]
|
||||
}),
|
||||
onHover: (button) => {
|
||||
const display = Gdk.Display.get_default();
|
||||
const cursor = Gdk.Cursor.new_from_name(display, 'pointer');
|
||||
button.get_window().set_cursor(cursor);
|
||||
buttonDescription.revealChild = true;
|
||||
const buttonDescription = Widget.Revealer({
|
||||
valign: "end",
|
||||
transitionDuration: 200,
|
||||
transition: "slide_down",
|
||||
revealChild: false,
|
||||
child: Widget.Label({
|
||||
className: "txt-smaller session-button-desc",
|
||||
label: name,
|
||||
}),
|
||||
})
|
||||
return Widget.Button({
|
||||
onClicked: command,
|
||||
className: "session-button",
|
||||
child: Widget.Overlay({
|
||||
className: "session-button-box",
|
||||
child: Widget.Label({
|
||||
vexpand: true,
|
||||
className: "icon-material",
|
||||
label: icon,
|
||||
}),
|
||||
overlays: [buttonDescription],
|
||||
}),
|
||||
onHover: button => {
|
||||
const display = Gdk.Display.get_default()
|
||||
const cursor = Gdk.Cursor.new_from_name(display, "pointer")
|
||||
button.get_window().set_cursor(cursor)
|
||||
buttonDescription.revealChild = true
|
||||
},
|
||||
onHoverLost: button => {
|
||||
const display = Gdk.Display.get_default()
|
||||
const cursor = Gdk.Cursor.new_from_name(display, "default")
|
||||
button.get_window().set_cursor(cursor)
|
||||
buttonDescription.revealChild = false
|
||||
},
|
||||
connections: [
|
||||
[
|
||||
"focus-in-event",
|
||||
self => {
|
||||
buttonDescription.revealChild = true
|
||||
self.toggleClassName("session-button-focused", true)
|
||||
},
|
||||
onHoverLost: (button) => {
|
||||
const display = Gdk.Display.get_default();
|
||||
const cursor = Gdk.Cursor.new_from_name(display, 'default');
|
||||
button.get_window().set_cursor(cursor);
|
||||
buttonDescription.revealChild = false;
|
||||
],
|
||||
[
|
||||
"focus-out-event",
|
||||
self => {
|
||||
buttonDescription.revealChild = false
|
||||
self.toggleClassName("session-button-focused", false)
|
||||
},
|
||||
connections: [
|
||||
['focus-in-event', (self) => {
|
||||
buttonDescription.revealChild = true;
|
||||
self.toggleClassName('session-button-focused', true);
|
||||
}],
|
||||
['focus-out-event', (self) => {
|
||||
buttonDescription.revealChild = false;
|
||||
self.toggleClassName('session-button-focused', false);
|
||||
}],
|
||||
],
|
||||
...props,
|
||||
});
|
||||
],
|
||||
],
|
||||
...props,
|
||||
})
|
||||
}
|
||||
|
||||
export default () => {
|
||||
// lock, logout, sleep
|
||||
const lockButton = SessionButton('Lock', 'lock', () => { App.closeWindow('session'); execAsync('gtklock') });
|
||||
const logoutButton = SessionButton('Logout', 'logout', () => { App.closeWindow('session'); execAsync(['bash', '-c', 'loginctl terminate-user $USER']) });
|
||||
const sleepButton = SessionButton('Sleep', 'sleep', () => { App.closeWindow('session'); execAsync('systemctl suspend') });
|
||||
// hibernate, shutdown, reboot
|
||||
const hibernateButton = SessionButton('Hibernate', 'downloading', () => { App.closeWindow('session'); execAsync('systemctl hibernate') });
|
||||
const shutdownButton = SessionButton('Shutdown', 'power_settings_new', () => { App.closeWindow('session'); execAsync('systemctl poweroff') });
|
||||
const rebootButton = SessionButton('Reboot', 'restart_alt', () => { App.closeWindow('session'); execAsync('systemctl reboot') });
|
||||
const cancelButton = SessionButton('Cancel', 'close', () => App.closeWindow('session'), { className: 'session-button-cancel' });
|
||||
return Widget.Box({
|
||||
className: 'session-bg',
|
||||
style: `
|
||||
// lock, logout, sleep
|
||||
const lockButton = SessionButton("Lock", "lock", () => {
|
||||
App.closeWindow("session")
|
||||
execAsync("gtklock")
|
||||
})
|
||||
const logoutButton = SessionButton("Logout", "logout", () => {
|
||||
App.closeWindow("session")
|
||||
execAsync(["bash", "-c", "loginctl terminate-user $USER"])
|
||||
})
|
||||
const sleepButton = SessionButton("Sleep", "sleep", () => {
|
||||
App.closeWindow("session")
|
||||
execAsync("systemctl suspend")
|
||||
})
|
||||
// hibernate, shutdown, reboot
|
||||
const hibernateButton = SessionButton("Hibernate", "downloading", () => {
|
||||
App.closeWindow("session")
|
||||
execAsync("systemctl hibernate")
|
||||
})
|
||||
const shutdownButton = SessionButton("Shutdown", "power_settings_new", () => {
|
||||
App.closeWindow("session")
|
||||
execAsync("systemctl poweroff")
|
||||
})
|
||||
const rebootButton = SessionButton("Reboot", "restart_alt", () => {
|
||||
App.closeWindow("session")
|
||||
execAsync("systemctl reboot")
|
||||
})
|
||||
const cancelButton = SessionButton("Cancel", "close", () => App.closeWindow("session"), {
|
||||
className: "session-button-cancel",
|
||||
})
|
||||
return Widget.Box({
|
||||
className: "session-bg",
|
||||
style: `
|
||||
min-width: ${SCREEN_WIDTH * 2}px;
|
||||
min-height: ${SCREEN_HEIGHT * 2}px;
|
||||
`, // Hack to draw over reserved bar space
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.EventBox({
|
||||
onPrimaryClick: () => App.closeWindow("session"),
|
||||
onSecondaryClick: () => App.closeWindow("session"),
|
||||
onMiddleClick: () => App.closeWindow("session"),
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: "center",
|
||||
vexpand: true,
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.EventBox({
|
||||
onPrimaryClick: () => App.closeWindow('session'),
|
||||
onSecondaryClick: () => App.closeWindow('session'),
|
||||
onMiddleClick: () => App.closeWindow('session'),
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: 'center',
|
||||
vexpand: true,
|
||||
Widget.Box({
|
||||
valign: "center",
|
||||
vertical: true,
|
||||
className: "spacing-v-15",
|
||||
children: [
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
style: "margin-bottom: 0.682rem;",
|
||||
children: [
|
||||
Widget.Box({
|
||||
valign: 'center',
|
||||
vertical: true,
|
||||
className: 'spacing-v-15',
|
||||
children: [
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
style: 'margin-bottom: 0.682rem;',
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: 'txt-title txt',
|
||||
label: 'Session',
|
||||
}),
|
||||
Widget.Label({
|
||||
justify: Gtk.Justification.CENTER,
|
||||
className: 'txt-small txt',
|
||||
label: 'Use arrow keys to navigate.\nEnter to select, Esc to cancel.'
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: 'center',
|
||||
className: 'spacing-h-15',
|
||||
children: [ // lock, logout, sleep
|
||||
lockButton,
|
||||
logoutButton,
|
||||
sleepButton,
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: 'center',
|
||||
className: 'spacing-h-15',
|
||||
children: [ // hibernate, shutdown, reboot
|
||||
hibernateButton,
|
||||
shutdownButton,
|
||||
rebootButton,
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: 'center',
|
||||
className: 'spacing-h-15',
|
||||
children: [ // hibernate, shutdown, reboot
|
||||
cancelButton,
|
||||
]
|
||||
}),
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
Widget.Label({
|
||||
className: "txt-title txt",
|
||||
label: "Session",
|
||||
}),
|
||||
Widget.Label({
|
||||
justify: Gtk.Justification.CENTER,
|
||||
className: "txt-small txt",
|
||||
label: "Use arrow keys to navigate.\nEnter to select, Esc to cancel.",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: "center",
|
||||
className: "spacing-h-15",
|
||||
children: [
|
||||
// lock, logout, sleep
|
||||
lockButton,
|
||||
logoutButton,
|
||||
sleepButton,
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: "center",
|
||||
className: "spacing-h-15",
|
||||
children: [
|
||||
// hibernate, shutdown, reboot
|
||||
hibernateButton,
|
||||
shutdownButton,
|
||||
rebootButton,
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
halign: "center",
|
||||
className: "spacing-h-15",
|
||||
children: [
|
||||
// hibernate, shutdown, reboot
|
||||
cancelButton,
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
connections: [
|
||||
[App, (_b, name, visible) => {
|
||||
if (visible) lockButton.grab_focus(); // Lock is the default option
|
||||
}],
|
||||
],
|
||||
});
|
||||
}),
|
||||
],
|
||||
connections: [
|
||||
[
|
||||
App,
|
||||
(_b, name, visible) => {
|
||||
if (visible) lockButton.grab_focus() // Lock is the default option
|
||||
},
|
||||
],
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,75 +1,85 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Widget } from '../imports.js';
|
||||
import Applications from 'resource:///com/github/Aylur/ags/service/applications.js';
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
const { Box, EventBox, Button, Label, Scrollable } = Widget;
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
import {App, Service, Utils, Widget} from "../imports.js"
|
||||
import Applications from "resource:///com/github/Aylur/ags/service/applications.js"
|
||||
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js"
|
||||
const {execAsync, exec} = Utils
|
||||
const {Box, EventBox, Button, Label, Scrollable} = Widget
|
||||
|
||||
const CLIPBOARD_SHOWN_ENTRIES = 20;
|
||||
const CLIPBOARD_SHOWN_ENTRIES = 20
|
||||
|
||||
const ClipboardItems = () => {
|
||||
return Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
connections: [
|
||||
[App, (box, name, visible) => {
|
||||
if (name != 'sideleft')
|
||||
return;
|
||||
return Box({
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
connections: [
|
||||
[
|
||||
App,
|
||||
(box, name, visible) => {
|
||||
if (name != "sideleft") return
|
||||
|
||||
let clipboardContents = exec('cliphist list'); // Output is lines like this: 1000 copied text
|
||||
clipboardContents = clipboardContents.split('\n');
|
||||
let clipboardContents = exec("cliphist list") // Output is lines like this: 1000 copied text
|
||||
clipboardContents = clipboardContents.split("\n")
|
||||
|
||||
// console.log(clipboardContents);
|
||||
// console.log(`bash -c 'echo "${clipboardContents[0]}" | sed "s/ /\\t/" | cliphist decode'`);
|
||||
// console.log(exec(`bash -c 'echo "${clipboardContents[0]}" | sed "s/ /\\t/" | cliphist decode'`));
|
||||
// console.log(clipboardContents);
|
||||
// console.log(`bash -c 'echo "${clipboardContents[0]}" | sed "s/ /\\t/" | cliphist decode'`);
|
||||
// console.log(exec(`bash -c 'echo "${clipboardContents[0]}" | sed "s/ /\\t/" | cliphist decode'`));
|
||||
|
||||
box.children = clipboardContents.map((text, i) => {
|
||||
if (i >= CLIPBOARD_SHOWN_ENTRIES) return;
|
||||
return Button({
|
||||
onClicked: () => {
|
||||
print(`bash` + `-c` + `echo "${clipboardContents[i]}" | sed "s/ /\\\t/" | cliphist decode | wl-copy`);
|
||||
execAsync(`bash`, `-c`, `echo "${clipboardContents[i]}" | sed "s/ /\\\t/" | cliphist decode | wl-copy`).catch(print);
|
||||
App.closeWindow('sideleft');
|
||||
},
|
||||
className: 'sidebar-clipboard-item',
|
||||
child: Box({
|
||||
children: [
|
||||
Label({
|
||||
label: text,
|
||||
className: 'txt-small',
|
||||
truncate: 'end',
|
||||
})
|
||||
]
|
||||
})
|
||||
})
|
||||
});
|
||||
}]
|
||||
]
|
||||
});
|
||||
box.children = clipboardContents.map((text, i) => {
|
||||
if (i >= CLIPBOARD_SHOWN_ENTRIES) return
|
||||
return Button({
|
||||
onClicked: () => {
|
||||
print(
|
||||
`bash` +
|
||||
`-c` +
|
||||
`echo "${clipboardContents[i]}" | sed "s/ /\\\t/" | cliphist decode | wl-copy`,
|
||||
)
|
||||
execAsync(
|
||||
`bash`,
|
||||
`-c`,
|
||||
`echo "${clipboardContents[i]}" | sed "s/ /\\\t/" | cliphist decode | wl-copy`,
|
||||
).catch(print)
|
||||
App.closeWindow("sideleft")
|
||||
},
|
||||
className: "sidebar-clipboard-item",
|
||||
child: Box({
|
||||
children: [
|
||||
Label({
|
||||
label: text,
|
||||
className: "txt-small",
|
||||
truncate: "end",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
})
|
||||
},
|
||||
],
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export default () => Box({
|
||||
export default () =>
|
||||
Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
EventBox({
|
||||
onPrimaryClick: () => App.closeWindow('sideleft'),
|
||||
onSecondaryClick: () => App.closeWindow('sideleft'),
|
||||
onMiddleClick: () => App.closeWindow('sideleft'),
|
||||
}),
|
||||
ClipboardItems(),
|
||||
// Box({
|
||||
// vertical: true,
|
||||
// vexpand: true,
|
||||
// className: 'sidebar-left',
|
||||
// children: [
|
||||
// Widget.Box({
|
||||
// className: 'spacing-v-5',
|
||||
// children: [
|
||||
// ClipboardItems(),
|
||||
// ]
|
||||
// })
|
||||
// ],
|
||||
// }),
|
||||
]
|
||||
});
|
||||
|
||||
EventBox({
|
||||
onPrimaryClick: () => App.closeWindow("sideleft"),
|
||||
onSecondaryClick: () => App.closeWindow("sideleft"),
|
||||
onMiddleClick: () => App.closeWindow("sideleft"),
|
||||
}),
|
||||
ClipboardItems(),
|
||||
// Box({
|
||||
// vertical: true,
|
||||
// vexpand: true,
|
||||
// className: 'sidebar-left',
|
||||
// children: [
|
||||
// Widget.Box({
|
||||
// className: 'spacing-v-5',
|
||||
// children: [
|
||||
// ClipboardItems(),
|
||||
// ]
|
||||
// })
|
||||
// ],
|
||||
// }),
|
||||
],
|
||||
})
|
||||
|
||||
@@ -1,109 +1,141 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { Utils, Widget } from '../imports.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
const { Box, EventBox } = Widget;
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
import {Utils, Widget} from "../imports.js"
|
||||
const {execAsync, exec} = Utils
|
||||
const {Box, EventBox} = Widget
|
||||
import {
|
||||
ToggleIconBluetooth, ToggleIconWifi, HyprToggleIcon, ModuleNightLight,
|
||||
ModuleEditIcon, ModuleReloadIcon, ModuleSettingsIcon, ModulePowerIcon
|
||||
} from "./quicktoggles.js";
|
||||
import ModuleNotificationList from "./notificationlist.js";
|
||||
import { ModuleMusicControls } from "./musiccontrols.js";
|
||||
import { ModuleCalendar } from "./calendar.js";
|
||||
ToggleIconBluetooth,
|
||||
ToggleIconWifi,
|
||||
HyprToggleIcon,
|
||||
ModuleNightLight,
|
||||
ModuleEditIcon,
|
||||
ModuleReloadIcon,
|
||||
ModuleSettingsIcon,
|
||||
ModulePowerIcon,
|
||||
} from "./quicktoggles.js"
|
||||
import ModuleNotificationList from "./notificationlist.js"
|
||||
import {ModuleMusicControls} from "./musiccontrols.js"
|
||||
import {ModuleCalendar} from "./calendar.js"
|
||||
|
||||
const NUM_OF_TOGGLES_PER_LINE = 5;
|
||||
const NUM_OF_TOGGLES_PER_LINE = 5
|
||||
|
||||
const togglesFlowBox = Widget({
|
||||
type: Gtk.FlowBox,
|
||||
className: 'sidebar-group spacing-h-10',
|
||||
setup: (self) => {
|
||||
self.set_max_children_per_line(NUM_OF_TOGGLES_PER_LINE);
|
||||
self.add(ToggleIconWifi({ hexpand: 'true' }));
|
||||
self.add(ToggleIconBluetooth({ hexpand: 'true' }));
|
||||
self.add(HyprToggleIcon('mouse', 'Raw input', 'input:force_no_accel', { hexpand: 'true' }));
|
||||
self.add(HyprToggleIcon('front_hand', 'No touchpad while typing', 'input:touchpad:disable_while_typing', { hexpand: 'true' }));
|
||||
self.add(ModuleNightLight({ hexpand: 'true' }));
|
||||
// Setup flowbox rearrange
|
||||
self.connect('child-activated', (self, child) => {
|
||||
if (child.get_index() === 0) {
|
||||
self.reorder_child(child, self.get_children().length - 1);
|
||||
} else {
|
||||
self.reorder_child(child, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
type: Gtk.FlowBox,
|
||||
className: "sidebar-group spacing-h-10",
|
||||
setup: self => {
|
||||
self.set_max_children_per_line(NUM_OF_TOGGLES_PER_LINE)
|
||||
self.add(ToggleIconWifi({hexpand: "true"}))
|
||||
self.add(ToggleIconBluetooth({hexpand: "true"}))
|
||||
self.add(HyprToggleIcon("mouse", "Raw input", "input:force_no_accel", {hexpand: "true"}))
|
||||
self.add(
|
||||
HyprToggleIcon("front_hand", "No touchpad while typing", "input:touchpad:disable_while_typing", {
|
||||
hexpand: "true",
|
||||
}),
|
||||
)
|
||||
self.add(ModuleNightLight({hexpand: "true"}))
|
||||
// Setup flowbox rearrange
|
||||
self.connect("child-activated", (self, child) => {
|
||||
if (child.get_index() === 0) {
|
||||
self.reorder_child(child, self.get_children().length - 1)
|
||||
} else {
|
||||
self.reorder_child(child, 0)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const togglesBox = Widget.Box({
|
||||
className: 'sidebar-group spacing-h-10',
|
||||
children: [
|
||||
ToggleIconWifi({ hexpand: 'true' }),
|
||||
ToggleIconBluetooth({ hexpand: 'true' }),
|
||||
HyprToggleIcon('mouse', 'Raw input', 'input:force_no_accel', { hexpand: 'true' }),
|
||||
HyprToggleIcon('front_hand', 'No touchpad while typing', 'input:touchpad:disable_while_typing', { hexpand: 'true' }),
|
||||
ModuleNightLight({ hexpand: 'true' }),
|
||||
]
|
||||
className: "sidebar-group spacing-h-10",
|
||||
children: [
|
||||
ToggleIconWifi({hexpand: "true"}),
|
||||
ToggleIconBluetooth({hexpand: "true"}),
|
||||
HyprToggleIcon("mouse", "Raw input", "input:force_no_accel", {hexpand: "true"}),
|
||||
HyprToggleIcon("front_hand", "No touchpad while typing", "input:touchpad:disable_while_typing", {
|
||||
hexpand: "true",
|
||||
}),
|
||||
ModuleNightLight({hexpand: "true"}),
|
||||
],
|
||||
})
|
||||
|
||||
export default () => Box({
|
||||
export default () =>
|
||||
Box({
|
||||
// vertical: true,
|
||||
vexpand: true,
|
||||
hexpand: true,
|
||||
children: [
|
||||
EventBox({
|
||||
onPrimaryClick: () => App.closeWindow('sideright'),
|
||||
onSecondaryClick: () => App.closeWindow('sideright'),
|
||||
onMiddleClick: () => App.closeWindow('sideright'),
|
||||
}),
|
||||
Box({
|
||||
EventBox({
|
||||
onPrimaryClick: () => App.closeWindow("sideright"),
|
||||
onSecondaryClick: () => App.closeWindow("sideright"),
|
||||
onMiddleClick: () => App.closeWindow("sideright"),
|
||||
}),
|
||||
Box({
|
||||
vertical: true,
|
||||
vexpand: true,
|
||||
className: "sidebar-right",
|
||||
children: [
|
||||
Box({
|
||||
vertical: true,
|
||||
vexpand: true,
|
||||
className: 'sidebar-right',
|
||||
className: "spacing-v-15",
|
||||
children: [
|
||||
Box({
|
||||
vertical: true,
|
||||
vexpand: true,
|
||||
className: 'spacing-v-15',
|
||||
Box({
|
||||
vertical: true,
|
||||
className: "spacing-v-5",
|
||||
children: [
|
||||
Box({
|
||||
// Header
|
||||
className: "spacing-h-5 sidebar-group-invisible-morehorizpad",
|
||||
children: [
|
||||
Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
children: [
|
||||
Box({ // Header
|
||||
className: 'spacing-h-5 sidebar-group-invisible-morehorizpad',
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: 'txt-title txt',
|
||||
connections: [[5000, label => {
|
||||
execAsync([`date`, "+%H:%M"]).then(timeString => {
|
||||
label.label = timeString;
|
||||
}).catch(print);
|
||||
}]],
|
||||
}),
|
||||
Widget.Label({
|
||||
halign: 'center',
|
||||
className: 'txt-small txt',
|
||||
connections: [[5000, label => {
|
||||
execAsync(['bash', '-c', `uptime -p | sed -e 's/up //;s/ hours,/h/;s/ minutes/m/'`]).then(upTimeString => {
|
||||
label.label = `• uptime ${upTimeString}`;
|
||||
}).catch(print);
|
||||
}]],
|
||||
}),
|
||||
Widget.Box({ hexpand: true }),
|
||||
// ModuleEditIcon({ halign: 'end' }), // TODO: Make this work
|
||||
ModuleReloadIcon({ halign: 'end' }),
|
||||
ModuleSettingsIcon({ halign: 'end' }),
|
||||
ModulePowerIcon({ halign: 'end' }),
|
||||
]
|
||||
}),
|
||||
// togglesFlowBox,
|
||||
togglesBox,
|
||||
]
|
||||
}),
|
||||
ModuleNotificationList({ vexpand: true, }),
|
||||
ModuleCalendar(),
|
||||
]
|
||||
}),
|
||||
Widget.Label({
|
||||
className: "txt-title txt",
|
||||
connections: [
|
||||
[
|
||||
5000,
|
||||
label => {
|
||||
execAsync([`date`, "+%H:%M"])
|
||||
.then(timeString => {
|
||||
label.label = timeString
|
||||
})
|
||||
.catch(print)
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
Widget.Label({
|
||||
halign: "center",
|
||||
className: "txt-small txt",
|
||||
connections: [
|
||||
[
|
||||
5000,
|
||||
label => {
|
||||
execAsync([
|
||||
"bash",
|
||||
"-c",
|
||||
`uptime -p | sed -e 's/up //;s/ hours,/h/;s/ minutes/m/'`,
|
||||
])
|
||||
.then(upTimeString => {
|
||||
label.label = `• uptime ${upTimeString}`
|
||||
})
|
||||
.catch(print)
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
Widget.Box({hexpand: true}),
|
||||
// ModuleEditIcon({ halign: 'end' }), // TODO: Make this work
|
||||
ModuleReloadIcon({halign: "end"}),
|
||||
ModuleSettingsIcon({halign: "end"}),
|
||||
ModulePowerIcon({halign: "end"}),
|
||||
],
|
||||
}),
|
||||
// togglesFlowBox,
|
||||
togglesBox,
|
||||
],
|
||||
}),
|
||||
ModuleNotificationList({vexpand: true}),
|
||||
ModuleCalendar(),
|
||||
],
|
||||
}),
|
||||
]
|
||||
});
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
@@ -1,93 +1,66 @@
|
||||
import { Service, Utils, Widget } from '../imports.js';
|
||||
const { exec, execAsync } = Utils;
|
||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
||||
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
|
||||
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
|
||||
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
// @ts-expect-error missing type defs
|
||||
import Bluetooth from "resource:///com/github/Aylur/ags/service/bluetooth.js"
|
||||
import Network from "resource:///com/github/Aylur/ags/service/network.js"
|
||||
|
||||
export const BluetoothIndicator = () => Widget.Stack({
|
||||
transition: 'slide_up_down',
|
||||
items: [
|
||||
['true', Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth' })],
|
||||
['false', Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth_disabled' })],
|
||||
export function BluetoothIndicator() {
|
||||
return Widget.Icon({
|
||||
binds: [
|
||||
[
|
||||
"icon",
|
||||
Bluetooth,
|
||||
"enabled",
|
||||
(/** @type {boolean} */ enabled) => `bluetooth-${enabled ? "active" : "disabled"}-symbolic`,
|
||||
],
|
||||
],
|
||||
connections: [[Bluetooth, stack => { stack.shown = String(Bluetooth.enabled); }]],
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function WiredIndicator() {
|
||||
return Widget.Icon({
|
||||
binds: [["icon", Network.wired, "icon-name"]],
|
||||
})
|
||||
}
|
||||
|
||||
const NetworkWiredIndicator = () => Widget.Stack({
|
||||
transition: 'slide_up_down',
|
||||
items: [
|
||||
['unknown', Widget.Label({ className: 'txt-norm icon-material', label: 'wifi_off' })],
|
||||
['disconnected', Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' })],
|
||||
['disabled', Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_statusbar_not_connected' })],
|
||||
['connected', Widget.Label({ className: 'txt-norm icon-material', label: 'lan' })],
|
||||
['connecting', Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_0_bar' })],
|
||||
function WifiIndicator() {
|
||||
return Widget.Box({
|
||||
children: [
|
||||
Widget.Icon({
|
||||
binds: [["icon", Network.wifi, "icon-name"]],
|
||||
}),
|
||||
Widget.Label({
|
||||
binds: [["label", Network.wifi, "ssid"]],
|
||||
}),
|
||||
],
|
||||
connections: [[Network, stack => {
|
||||
if (!Network.wired)
|
||||
return;
|
||||
})
|
||||
}
|
||||
|
||||
const { internet } = Network.wired;
|
||||
if (internet === 'connected' || internet === 'connecting')
|
||||
stack.shown = internet;
|
||||
|
||||
if (Network.connectivity !== 'full')
|
||||
stack.shown = 'disconnected';
|
||||
|
||||
stack.shown = 'disabled';
|
||||
}]],
|
||||
});
|
||||
|
||||
const NetworkWifiIndicator = () => Widget.Stack({
|
||||
transition: 'slide_up_down',
|
||||
function NetworkIndicator() {
|
||||
return Widget.Stack({
|
||||
transition: "slide_up_down",
|
||||
items: [
|
||||
['disabled', Widget.Label({ className: 'txt-norm icon-material', label: 'wifi_off' })],
|
||||
['disconnected', Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' })],
|
||||
['connecting', Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_statusbar_not_connected' })],
|
||||
['4', Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_4_bar' })],
|
||||
['3', Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_3_bar' })],
|
||||
['2', Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_2_bar' })],
|
||||
['1', Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_1_bar' })],
|
||||
['0', Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_0_bar' })],
|
||||
["wifi", WifiIndicator()],
|
||||
["wired", WiredIndicator()],
|
||||
],
|
||||
connections: [[Network,
|
||||
stack => {
|
||||
if (!Network.wifi)
|
||||
return;
|
||||
const { internet, enabled, strength } = Network.wifi;
|
||||
binds: [["shown", Network, "primary", primary => primary || "wired"]],
|
||||
})
|
||||
}
|
||||
|
||||
if (internet == 'connected') {
|
||||
stack.shown = String(Math.ceil(strength / 25));
|
||||
}
|
||||
else {
|
||||
stack.shown = 'disconnected'
|
||||
}
|
||||
}
|
||||
]],
|
||||
});
|
||||
|
||||
export const NetworkIndicator = () => Widget.Stack({
|
||||
transition: 'slide_up_down',
|
||||
items: [
|
||||
['wifi', NetworkWifiIndicator()],
|
||||
['wired', NetworkWiredIndicator()],
|
||||
],
|
||||
connections: [[Network, stack => {
|
||||
const primary = Network.primary || 'wired';
|
||||
stack.shown = primary;
|
||||
}]],
|
||||
});
|
||||
|
||||
export const StatusIcons = (props = {}) => Widget.Box({
|
||||
/**
|
||||
* @param [props] {Parameters<Widget.Box>[0]}
|
||||
*/
|
||||
function StatusIcons(props = {}) {
|
||||
return Widget.Box({
|
||||
...props,
|
||||
children: [Widget.EventBox({
|
||||
children: [
|
||||
Widget.EventBox({
|
||||
child: Widget.Box({
|
||||
className: 'spacing-h-15',
|
||||
children: [
|
||||
BluetoothIndicator(),
|
||||
NetworkIndicator(),
|
||||
]
|
||||
})
|
||||
})]
|
||||
});
|
||||
class_name: "spacing-h-15",
|
||||
children: [BluetoothIndicator(), NetworkIndicator()],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export default StatusIcons
|
||||
|
||||
@@ -1,108 +1,121 @@
|
||||
// This is for the cool memory indicator on the sidebar
|
||||
// For the right pill of the bar, see system.js
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
import { App, Service, Utils, Widget } from '../imports.js';
|
||||
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
import { CircularProgress } from "./lib/circularprogress.js";
|
||||
import { MaterialIcon } from "./lib/materialicon.js";
|
||||
const {Gdk, Gtk} = imports.gi
|
||||
const GObject = imports.gi.GObject
|
||||
const Lang = imports.lang
|
||||
import {App, Service, Utils, Widget} from "../imports.js"
|
||||
import Bluetooth from "resource:///com/github/Aylur/ags/service/bluetooth.js"
|
||||
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js"
|
||||
import Network from "resource:///com/github/Aylur/ags/service/network.js"
|
||||
const {execAsync, exec} = Utils
|
||||
import {CircularProgress} from "./lib/circularprogress.js"
|
||||
import {MaterialIcon} from "./lib/materialicon.js"
|
||||
|
||||
let cpuUsageQueue = [];
|
||||
const CPU_HISTORY_LENGTH = 10;
|
||||
let cpuUsageQueue = []
|
||||
const CPU_HISTORY_LENGTH = 10
|
||||
|
||||
export const ModuleSysInfo = (props = {}) => {
|
||||
const swapCircle = Widget({
|
||||
const swapCircle = Widget({
|
||||
type: CircularProgress,
|
||||
className: "sidebar-memory-swap-circprog",
|
||||
valign: "center",
|
||||
})
|
||||
const ramCircle = Widget({
|
||||
type: CircularProgress,
|
||||
className: "sidebar-memory-ram-circprog margin-right-10", // margin right 10 here cuz overlay can't have margins itself
|
||||
valign: "center",
|
||||
})
|
||||
const cpuCircle = Widget.Box({
|
||||
children: [
|
||||
Widget({
|
||||
type: CircularProgress,
|
||||
className: 'sidebar-memory-swap-circprog',
|
||||
valign: 'center',
|
||||
});
|
||||
const ramCircle = Widget({
|
||||
type: CircularProgress,
|
||||
className: 'sidebar-memory-ram-circprog margin-right-10', // margin right 10 here cuz overlay can't have margins itself
|
||||
valign: 'center',
|
||||
});
|
||||
const cpuCircle = Widget.Box({
|
||||
children: [Widget({
|
||||
type: CircularProgress,
|
||||
className: 'sidebar-cpu-circprog margin-right-10', // margin right 10 here cuz overlay can't have margins itself
|
||||
valign: 'center',
|
||||
})]
|
||||
});
|
||||
const memoryCircles = Widget.Box({
|
||||
homogeneous: true,
|
||||
children: [Widget.Overlay({
|
||||
child: ramCircle,
|
||||
overlays: [
|
||||
swapCircle,
|
||||
]
|
||||
})]
|
||||
});
|
||||
const ramText = Widget.Label({
|
||||
halign: 'start', xalign: 0,
|
||||
className: 'txt txt-small',
|
||||
});
|
||||
const swapText = Widget.Label({
|
||||
halign: 'start', xalign: 0,
|
||||
className: 'txt txt-small',
|
||||
});
|
||||
const memoryText = Widget.Box({
|
||||
vertical: true,
|
||||
valign: 'center',
|
||||
className: 'spacing-v--5',
|
||||
className: "sidebar-cpu-circprog margin-right-10", // margin right 10 here cuz overlay can't have margins itself
|
||||
valign: "center",
|
||||
}),
|
||||
],
|
||||
})
|
||||
const memoryCircles = Widget.Box({
|
||||
homogeneous: true,
|
||||
children: [
|
||||
Widget.Overlay({
|
||||
child: ramCircle,
|
||||
overlays: [swapCircle],
|
||||
}),
|
||||
],
|
||||
})
|
||||
const ramText = Widget.Label({
|
||||
halign: "start",
|
||||
xalign: 0,
|
||||
className: "txt txt-small",
|
||||
})
|
||||
const swapText = Widget.Label({
|
||||
halign: "start",
|
||||
xalign: 0,
|
||||
className: "txt txt-small",
|
||||
})
|
||||
const memoryText = Widget.Box({
|
||||
vertical: true,
|
||||
valign: "center",
|
||||
className: "spacing-v--5",
|
||||
children: [
|
||||
Widget.Box({
|
||||
className: "spacing-h-5",
|
||||
children: [
|
||||
Widget.Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
MaterialIcon('memory', 'large', { setup: icon => icon.toggleClassName('txt', true) }),
|
||||
ramText
|
||||
]
|
||||
}),
|
||||
Widget.Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
MaterialIcon('swap_horiz', 'large', { setup: icon => icon.toggleClassName('txt', true) }),
|
||||
swapText
|
||||
]
|
||||
}),
|
||||
]
|
||||
});
|
||||
return Widget.Box({
|
||||
...props,
|
||||
className: 'sidebar-group-nopad',
|
||||
children: [Widget.Scrollable({
|
||||
hexpand: true,
|
||||
vscroll: 'never',
|
||||
hscroll: 'automatic',
|
||||
child: Widget.Box({
|
||||
className: 'sidebar-sysinfo-grouppad spacing-h--5',
|
||||
children: [
|
||||
memoryCircles,
|
||||
memoryText,
|
||||
// cpuCircle,
|
||||
// maybe make cpu a graph?
|
||||
],
|
||||
connections: [
|
||||
[3000, () => {
|
||||
// Get memory info
|
||||
const ramString = exec(`bash -c 'free -h --si | rg "Mem:"'`);
|
||||
const [ramTotal, ramUsed] = ramString.split(/\s+/).slice(1, 3);
|
||||
const ramPerc = Number(exec(`bash -c "printf '%.1f' \\\"$(free -m | rg Mem | awk '{print ($3/$2)*100}')\\\""`));
|
||||
const swapString = exec(`bash -c 'free -h --si | rg "Swap:"'`);
|
||||
const [swapTotal, swapUsed] = swapString.split(/\s+/).slice(1, 3);
|
||||
const swapPerc = Number(exec(`bash -c "printf '%.1f' \\\"$(free -m | rg Swap | awk '{print ($3/$2)*100}')\\\""`));
|
||||
// const cpuPerc = parseFloat(exec(`bash -c "top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}'"`));
|
||||
// Set circular progress (font size cuz hack for anims)
|
||||
ramCircle.style = `font-size: ${ramPerc}px;`
|
||||
swapCircle.style = `font-size: ${swapPerc}px;`
|
||||
ramText.label = `${ramUsed} / ${ramTotal}`;
|
||||
swapText.label = `${swapUsed} / ${swapTotal}`;
|
||||
}]
|
||||
]
|
||||
})
|
||||
})]
|
||||
});
|
||||
};
|
||||
MaterialIcon("memory", "large", {setup: icon => icon.toggleClassName("txt", true)}),
|
||||
ramText,
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
className: "spacing-h-5",
|
||||
children: [
|
||||
MaterialIcon("swap_horiz", "large", {setup: icon => icon.toggleClassName("txt", true)}),
|
||||
swapText,
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
return Widget.Box({
|
||||
...props,
|
||||
className: "sidebar-group-nopad",
|
||||
children: [
|
||||
Widget.Scrollable({
|
||||
hexpand: true,
|
||||
vscroll: "never",
|
||||
hscroll: "automatic",
|
||||
child: Widget.Box({
|
||||
className: "sidebar-sysinfo-grouppad spacing-h--5",
|
||||
children: [
|
||||
memoryCircles,
|
||||
memoryText,
|
||||
// cpuCircle,
|
||||
// maybe make cpu a graph?
|
||||
],
|
||||
connections: [
|
||||
[
|
||||
3000,
|
||||
() => {
|
||||
// Get memory info
|
||||
const ramString = exec(`bash -c 'free -h --si | rg "Mem:"'`)
|
||||
const [ramTotal, ramUsed] = ramString.split(/\s+/).slice(1, 3)
|
||||
const ramPerc = Number(
|
||||
exec(`bash -c "printf '%.1f' \\\"$(free -m | rg Mem | awk '{print ($3/$2)*100}')\\\""`),
|
||||
)
|
||||
const swapString = exec(`bash -c 'free -h --si | rg "Swap:"'`)
|
||||
const [swapTotal, swapUsed] = swapString.split(/\s+/).slice(1, 3)
|
||||
const swapPerc = Number(
|
||||
exec(`bash -c "printf '%.1f' \\\"$(free -m | rg Swap | awk '{print ($3/$2)*100}')\\\""`),
|
||||
)
|
||||
// const cpuPerc = parseFloat(exec(`bash -c "top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}'"`));
|
||||
// Set circular progress (font size cuz hack for anims)
|
||||
ramCircle.style = `font-size: ${ramPerc}px;`
|
||||
swapCircle.style = `font-size: ${swapPerc}px;`
|
||||
ramText.label = `${ramUsed} / ${ramTotal}`
|
||||
swapText.label = `${swapUsed} / ${swapTotal}`
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,89 +1,67 @@
|
||||
// This is for the right pill of the bar.
|
||||
// For the cool memory indicator on the sidebar, see sysinfo.js
|
||||
import { Service, Utils, Widget } from '../imports.js';
|
||||
const { exec, execAsync } = Utils;
|
||||
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
|
||||
import {execAsync} from "resource:///com/github/Aylur/ags/utils.js"
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
|
||||
export const ModuleSystem = () => Widget.EventBox({
|
||||
onScrollUp: () => execAsync('hyprctl dispatch workspace -1'),
|
||||
onScrollDown: () => execAsync('hyprctl dispatch workspace +1'),
|
||||
function Clock() {
|
||||
return Widget.Box({
|
||||
vpack: "center",
|
||||
class_name: "spacing-h-5",
|
||||
children: [
|
||||
Widget.Label({
|
||||
class_name: "bar-clock",
|
||||
connections: [
|
||||
[
|
||||
5000,
|
||||
label => {
|
||||
execAsync([`date`, "+%H:%M"])
|
||||
.then(timeString => {
|
||||
label.label = timeString
|
||||
})
|
||||
.catch(print)
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "txt-norm txt",
|
||||
label: "•",
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "txt-smallie txt",
|
||||
connections: [
|
||||
[
|
||||
5000,
|
||||
label => {
|
||||
execAsync(["date", "+%A, %d/%m"])
|
||||
.then(dateString => {
|
||||
label.label = dateString
|
||||
})
|
||||
.catch(print)
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
function ModuleSystem() {
|
||||
return Widget.EventBox({
|
||||
async on_scroll_up() {
|
||||
await execAsync("hyprctl dispatch workspace -1")
|
||||
},
|
||||
async on_scroll_down() {
|
||||
await execAsync("hyprctl dispatch workspace +1")
|
||||
},
|
||||
child: Widget.Box({
|
||||
className: 'bar-group-margin bar-sides',
|
||||
children: [
|
||||
Widget.Box({
|
||||
className: 'bar-group bar-group-standalone bar-group-pad-system spacing-h-15',
|
||||
children: [
|
||||
Widget.Box({ // Clock
|
||||
valign: 'center',
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: 'bar-clock',
|
||||
connections: [[5000, label => {
|
||||
execAsync([`date`, "+%H:%M"]).then(timeString => {
|
||||
label.label = timeString;
|
||||
}).catch(print);
|
||||
}]],
|
||||
}),
|
||||
Widget.Label({
|
||||
className: 'txt-norm txt',
|
||||
label: '•',
|
||||
}),
|
||||
Widget.Label({
|
||||
className: 'txt-smallie txt',
|
||||
connections: [[5000, label => {
|
||||
execAsync([`date`, "+%A, %d/%m"]).then(dateString => {
|
||||
label.label = dateString;
|
||||
}).catch(print);
|
||||
}]],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
/*Widget.Box({ // Battery
|
||||
valign: 'center',
|
||||
hexpand: true,
|
||||
className: 'spacing-h-5 bar-batt',
|
||||
connections: [[Battery, box => {
|
||||
box.toggleClassName('bar-batt-low', Battery.percent <= 20);
|
||||
box.toggleClassName('bar-batt-full', Battery.charged);
|
||||
}]],
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: 'bar-batt-percentage',
|
||||
connections: [[Battery, label => {
|
||||
label.label = `${Battery.percent}`;
|
||||
}]],
|
||||
}),
|
||||
Widget.ProgressBar({
|
||||
valign: 'center',
|
||||
hexpand: true,
|
||||
className: 'bar-prog-batt',
|
||||
connections: [[Battery, progress => {
|
||||
progress.value = Math.abs(Battery.percent / 100); // battery could be initially negative wtf
|
||||
progress.toggleClassName('bar-prog-batt-low', Battery.percent <= 20);
|
||||
progress.toggleClassName('bar-prog-batt-full', Battery.charged);
|
||||
}]],
|
||||
}),
|
||||
Widget.Revealer({
|
||||
transitionDuration: 150,
|
||||
revealChild: false,
|
||||
transition: 'slide_left',
|
||||
child: Widget.Box({
|
||||
valign: 'center',
|
||||
className: 'bar-batt-chargestate-charging',
|
||||
connections: [[Battery, box => {
|
||||
box.toggleClassName('bar-batt-chargestate-low', Battery.percent <= 20);
|
||||
box.toggleClassName('bar-batt-chargestate-full', Battery.charged);
|
||||
}]],
|
||||
}),
|
||||
connections: [[Battery, revealer => {
|
||||
revealer.revealChild = Battery.charging;
|
||||
}]],
|
||||
}),
|
||||
],
|
||||
}),]*/
|
||||
],
|
||||
}),
|
||||
]
|
||||
})
|
||||
});
|
||||
class_name: "bar-group-margin bar-sides",
|
||||
children: [
|
||||
Widget.Box({
|
||||
class_name: "bar-group bar-group-standalone bar-group-pad-system spacing-h-15",
|
||||
children: [Clock()],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export default ModuleSystem
|
||||
|
||||
@@ -1,71 +1,49 @@
|
||||
import { Service, Widget } from '../imports.js';
|
||||
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
|
||||
const { Box, Icon, Button, Revealer } = Widget;
|
||||
const { Gravity } = imports.gi.Gdk;
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
import SystemTray from "resource:///com/github/Aylur/ags/service/systemtray.js"
|
||||
import Gdk from "gi://Gdk?version=3.0"
|
||||
|
||||
const revealerDuration = 200;
|
||||
const REVEAL_DURATION = 200
|
||||
|
||||
const SysTrayItem = item => Button({
|
||||
className: 'bar-systray-item',
|
||||
child: Icon({
|
||||
halign: 'center',
|
||||
size: 16,
|
||||
binds: [['icon', item, 'icon']]
|
||||
/**
|
||||
* @param item {import('resource:///com/github/Aylur/ags/service/systemtray.js').TrayItem}
|
||||
*/
|
||||
function SysTrayItem(item) {
|
||||
return Widget.Button({
|
||||
class_name: "bar-systray-item",
|
||||
child: Widget.Icon({
|
||||
halign: "center",
|
||||
size: 16,
|
||||
binds: [["icon", item, "icon"]],
|
||||
}),
|
||||
binds: [['tooltipMarkup', item, 'tooltipMarkup']],
|
||||
// setup: btn => {
|
||||
// const id = item.menu.connect('popped-up', menu => {
|
||||
// menu.disconnect(id);
|
||||
// });
|
||||
// },
|
||||
onClicked: btn => item.menu.popup_at_widget(btn, Gravity.SOUTH, Gravity.NORTH, null),
|
||||
onSecondaryClick: btn => item.menu.popup_at_widget(btn, Gravity.SOUTH, Gravity.NORTH, null),
|
||||
});
|
||||
|
||||
export const Tray = (props = {}) => {
|
||||
const trayContent = Box({
|
||||
valign: 'center',
|
||||
className: 'bar-systray bar-group',
|
||||
properties: [
|
||||
['items', new Map()],
|
||||
['onAdded', (box, id) => {
|
||||
const item = SystemTray.getItem(id);
|
||||
if (!item) return;
|
||||
item.menu.className = 'menu';
|
||||
if (box._items.has(id) || !item)
|
||||
return;
|
||||
const widget = SysTrayItem(item);
|
||||
box._items.set(id, widget);
|
||||
box.pack_start(widget, false, false, 0);
|
||||
box.show_all();
|
||||
if (box._items.size === 1)
|
||||
trayRevealer.revealChild = true;
|
||||
}],
|
||||
['onRemoved', (box, id) => {
|
||||
if (!box._items.has(id))
|
||||
return;
|
||||
|
||||
box._items.get(id).destroy();
|
||||
box._items.delete(id);
|
||||
if (box._items.size === 0)
|
||||
trayRevealer.revealChild = false;
|
||||
}],
|
||||
],
|
||||
connections: [
|
||||
[SystemTray, (box, id) => box._onAdded(box, id), 'added'],
|
||||
[SystemTray, (box, id) => box._onRemoved(box, id), 'removed'],
|
||||
],
|
||||
});
|
||||
const trayRevealer = Widget.Revealer({
|
||||
revealChild: false,
|
||||
transition: 'slide_left',
|
||||
transitionDuration: revealerDuration,
|
||||
child: trayContent,
|
||||
});
|
||||
return Box({
|
||||
...props,
|
||||
children: [
|
||||
trayRevealer,
|
||||
]
|
||||
});
|
||||
binds: [["tooltip-markup", item, "tooltip-markup"]],
|
||||
on_clicked(button) {
|
||||
return item.menu.popup_at_widget(button, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null)
|
||||
},
|
||||
on_secondary_click(button) {
|
||||
return item.menu.popup_at_widget(button, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [props] {Parameters<typeof Widget.Box>[0]}
|
||||
*/
|
||||
function Tray(props = {}) {
|
||||
return Widget.Box({
|
||||
...props,
|
||||
children: [
|
||||
Widget.Revealer({
|
||||
reveal_child: false,
|
||||
transition: "slide_left",
|
||||
transition_duration: REVEAL_DURATION,
|
||||
child: Widget.Box({
|
||||
vpack: "center",
|
||||
class_name: "bar-systray bar-group",
|
||||
binds: [["children", SystemTray, "items", i => i.map(SysTrayItem)]],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export default Tray
|
||||
|
||||
@@ -1,76 +1,104 @@
|
||||
import {App, Service, Utils, Widget} from '../imports.js';
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
import {deflisten} from '../scripts/scripts.js';
|
||||
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js"
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js"
|
||||
import {execAsync} from "resource:///com/github/Aylur/ags/utils.js"
|
||||
|
||||
const WORKSPACE_SIDE_PAD = 0.546; // rem
|
||||
const NUM_OF_WORKSPACES = 9;
|
||||
let lastWorkspace = 0;
|
||||
const WORKSPACE_SIDE_PAD = 0.546 // rem
|
||||
const NUM_OF_WORKSPACES = 9
|
||||
|
||||
const activeWorkspaceIndicator = Widget.Box({
|
||||
valign: 'center',
|
||||
halign: 'start',
|
||||
className: 'bar-ws-active-box',
|
||||
connections: [
|
||||
[Hyprland.active.workspace, (box) => {
|
||||
const ws = Hyprland.active.workspace.id;
|
||||
box.setStyle(`
|
||||
margin-left: -${1.772 * (NUM_OF_WORKSPACES - ws + 1) + WORKSPACE_SIDE_PAD / 2 + 0.4}rem;
|
||||
`);
|
||||
lastWorkspace = ws;
|
||||
}],
|
||||
],
|
||||
children: [
|
||||
Widget.Label({
|
||||
valign: 'center',
|
||||
className: 'bar-ws-active',
|
||||
label: `•`,
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
export const ModuleWorkspaces = () => Widget.EventBox({
|
||||
onScrollUp: () => Utils.execAsync(['bash', '-c', 'hyprctl dispatch workspace -1 &']),
|
||||
onScrollDown: () => Utils.execAsync(['bash', '-c', 'hyprctl dispatch workspace +1 &']),
|
||||
onPrimaryClickRelease: () => App.toggleWindow('overview'),
|
||||
onMiddleClickRelease: () => App.toggleWindow('osk'),
|
||||
child: Widget.Box({
|
||||
homogeneous: true,
|
||||
className: 'bar-group-center',
|
||||
function ActiveWorkspaceIndicator() {
|
||||
return Widget.Box({
|
||||
vpack: "center",
|
||||
hpack: "start",
|
||||
class_name: "bar-ws-active-box",
|
||||
connections: [
|
||||
[
|
||||
Hyprland.active.workspace,
|
||||
self => {
|
||||
const ws = Hyprland.active.workspace.id
|
||||
self.set_margin_left(`-${1.772 * (NUM_OF_WORKSPACES - ws + 1) + WORKSPACE_SIDE_PAD / 2 + 0.4}rem`)
|
||||
},
|
||||
],
|
||||
],
|
||||
children: [
|
||||
Widget.Box({
|
||||
style: `padding: 0rem ${WORKSPACE_SIDE_PAD}rem;`,
|
||||
children: [
|
||||
Widget.Box({
|
||||
halign: 'center',
|
||||
children: Array.from({length: NUM_OF_WORKSPACES}, (_, i) => i + 1).map(i => Widget.Button({
|
||||
onSecondaryClick: () => Utils.execAsync(['bash', '-c', `hyprctl dispatch workspace ${i} &`]).catch(print),
|
||||
child: Widget.Label({
|
||||
valign: 'center',
|
||||
label: `${i}`,
|
||||
className: 'bar-ws txt',
|
||||
}),
|
||||
})),
|
||||
connections: [
|
||||
[Hyprland, (box) => { // TODO: connect to the right signal so that it doesn't update too much
|
||||
const kids = box.children;
|
||||
kids.forEach((child, i) => {
|
||||
child.child.toggleClassName('bar-ws-occupied', false);
|
||||
child.child.toggleClassName('bar-ws-occupied-left', false);
|
||||
child.child.toggleClassName('bar-ws-occupied-right', false);
|
||||
child.child.toggleClassName('bar-ws-occupied-left-right', false);
|
||||
});
|
||||
const occupied = Array.from({length: NUM_OF_WORKSPACES}, (_, i) => Hyprland.getWorkspace(i + 1)?.windows > 0);
|
||||
for (let i = 0; i < occupied.length; i++) {
|
||||
if (!occupied[i]) continue;
|
||||
const child = kids[i];
|
||||
child.child.toggleClassName(`bar-ws-occupied${!occupied[i - 1] ? '-left' : ''}${!occupied[i + 1] ? '-right' : ''}`, true);
|
||||
}
|
||||
}],
|
||||
],
|
||||
}),
|
||||
activeWorkspaceIndicator,
|
||||
]
|
||||
})
|
||||
]
|
||||
Widget.Label({
|
||||
justification: "center",
|
||||
class_name: "bar-ws-active",
|
||||
label: `•`,
|
||||
}),
|
||||
],
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function Workspaces() {
|
||||
return Widget.Box({
|
||||
hpack: "center",
|
||||
children: Array.from({length: NUM_OF_WORKSPACES}, (_, i) => i + 1).map(i =>
|
||||
Widget.Button({
|
||||
async on_secondary_click() {
|
||||
await execAsync(["bash", "-c", `hyprctl dispatch workspace ${i} &`]).catch(print)
|
||||
},
|
||||
child: Widget.Label({
|
||||
justification: "center",
|
||||
class_name: "bar-ws txt",
|
||||
label: `${i}`,
|
||||
}),
|
||||
}),
|
||||
),
|
||||
connections: [
|
||||
[
|
||||
Hyprland,
|
||||
box => {
|
||||
// TODO: connect to the right signal so that it doesn't update too much
|
||||
const kids = box.children
|
||||
kids.forEach((child, i) => {
|
||||
child.child.toggleClassName("bar-ws-occupied", false)
|
||||
child.child.toggleClassName("bar-ws-occupied-left", false)
|
||||
child.child.toggleClassName("bar-ws-occupied-right", false)
|
||||
child.child.toggleClassName("bar-ws-occupied-left-right", false)
|
||||
})
|
||||
const occupied = Array.from(
|
||||
{length: NUM_OF_WORKSPACES},
|
||||
(_, i) => Hyprland.getWorkspace(i + 1)?.windows > 0,
|
||||
)
|
||||
for (let i = 0; i < occupied.length; i++) {
|
||||
if (!occupied[i]) continue
|
||||
const child = kids[i]
|
||||
child.child.toggleClassName(
|
||||
`bar-ws-occupied${!occupied[i - 1] ? "-left" : ""}${!occupied[i + 1] ? "-right" : ""}`,
|
||||
true,
|
||||
)
|
||||
}
|
||||
},
|
||||
],
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
function ModuleWorkspaces() {
|
||||
return Widget.EventBox({
|
||||
async on_scroll_up() {
|
||||
await execAsync(["bash", "-c", "hyprctl dispatch workspace -1 &"])
|
||||
},
|
||||
async on_scroll_down() {
|
||||
await execAsync(["bash", "-c", "hyprctl dispatch workspace +1 &"])
|
||||
},
|
||||
on_primary_click_release() {
|
||||
App.toggleWindow("overview")
|
||||
},
|
||||
on_secondary_click_release() {
|
||||
App.toggleWindow("osk")
|
||||
},
|
||||
child: Widget.Box({
|
||||
homogeneous: true,
|
||||
className: "bar-group-center",
|
||||
children: [
|
||||
Widget.Box({
|
||||
css: `padding: 0rem ${WORKSPACE_SIDE_PAD}rem;`,
|
||||
children: [Workspaces(), ActiveWorkspaceIndicator()],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export default ModuleWorkspaces
|
||||
|
||||
1
desktops/hyprland/ags/node_modules/.bin/acorn
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/acorn
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../acorn/bin/acorn
|
||||
1
desktops/hyprland/ags/node_modules/.bin/eslint
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/eslint
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../eslint/bin/eslint.js
|
||||
1
desktops/hyprland/ags/node_modules/.bin/js-yaml
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/js-yaml
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../js-yaml/bin/js-yaml.js
|
||||
1
desktops/hyprland/ags/node_modules/.bin/node-which
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/node-which
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../which/bin/node-which
|
||||
1
desktops/hyprland/ags/node_modules/.bin/prettier
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/prettier
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../prettier/bin/prettier.cjs
|
||||
1
desktops/hyprland/ags/node_modules/.bin/rimraf
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/rimraf
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../rimraf/bin.js
|
||||
1
desktops/hyprland/ags/node_modules/.bin/semver
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/semver
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../semver/bin/semver.js
|
||||
1
desktops/hyprland/ags/node_modules/.bin/tsc
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/tsc
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../typescript/bin/tsc
|
||||
1
desktops/hyprland/ags/node_modules/.bin/tsserver
generated
vendored
Symbolic link
1
desktops/hyprland/ags/node_modules/.bin/tsserver
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../typescript/bin/tsserver
|
||||
2152
desktops/hyprland/ags/node_modules/.package-lock.json
generated
vendored
Normal file
2152
desktops/hyprland/ags/node_modules/.package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
21
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/LICENSE
generated
vendored
Normal file
21
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2016, Jon Schlinkert
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
182
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/README.md
generated
vendored
Normal file
182
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/README.md
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
# word-wrap [](https://www.npmjs.com/package/word-wrap) [](https://npmjs.org/package/word-wrap) [](https://npmjs.org/package/word-wrap) [](https://travis-ci.org/jonschlinkert/word-wrap)
|
||||
|
||||
> Wrap words to a specified length.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save word-wrap
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var wrap = require('word-wrap');
|
||||
|
||||
wrap('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.');
|
||||
```
|
||||
|
||||
Results in:
|
||||
|
||||
```
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing
|
||||
elit, sed do eiusmod tempor incididunt ut labore
|
||||
et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut
|
||||
aliquip ex ea commodo consequat.
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||

|
||||
|
||||
### options.width
|
||||
|
||||
Type: `Number`
|
||||
|
||||
Default: `50`
|
||||
|
||||
The width of the text before wrapping to a new line.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
wrap(str, {width: 60});
|
||||
```
|
||||
|
||||
### options.indent
|
||||
|
||||
Type: `String`
|
||||
|
||||
Default: `` (none)
|
||||
|
||||
The string to use at the beginning of each line.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
wrap(str, {indent: ' '});
|
||||
```
|
||||
|
||||
### options.newline
|
||||
|
||||
Type: `String`
|
||||
|
||||
Default: `\n`
|
||||
|
||||
The string to use at the end of each line.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
wrap(str, {newline: '\n\n'});
|
||||
```
|
||||
|
||||
### options.escape
|
||||
|
||||
Type: `function`
|
||||
|
||||
Default: `function(str){return str;}`
|
||||
|
||||
An escape function to run on each line after splitting them.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
var xmlescape = require('xml-escape');
|
||||
wrap(str, {
|
||||
escape: function(string){
|
||||
return xmlescape(string);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### options.trim
|
||||
|
||||
Type: `Boolean`
|
||||
|
||||
Default: `false`
|
||||
|
||||
Trim trailing whitespace from the returned string. This option is included since `.trim()` would also strip the leading indentation from the first line.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
wrap(str, {trim: true});
|
||||
```
|
||||
|
||||
### options.cut
|
||||
|
||||
Type: `Boolean`
|
||||
|
||||
Default: `false`
|
||||
|
||||
Break a word between any two letters when the word is longer than the specified width.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
wrap(str, {cut: true});
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
### Related projects
|
||||
|
||||
* [common-words](https://www.npmjs.com/package/common-words): Updated list (JSON) of the 100 most common words in the English language. Useful for… [more](https://github.com/jonschlinkert/common-words) | [homepage](https://github.com/jonschlinkert/common-words "Updated list (JSON) of the 100 most common words in the English language. Useful for excluding these words from arrays.")
|
||||
* [shuffle-words](https://www.npmjs.com/package/shuffle-words): Shuffle the words in a string and optionally the letters in each word using the… [more](https://github.com/jonschlinkert/shuffle-words) | [homepage](https://github.com/jonschlinkert/shuffle-words "Shuffle the words in a string and optionally the letters in each word using the Fisher-Yates algorithm. Useful for creating test fixtures, benchmarking samples, etc.")
|
||||
* [unique-words](https://www.npmjs.com/package/unique-words): Return the unique words in a string or array. | [homepage](https://github.com/jonschlinkert/unique-words "Return the unique words in a string or array.")
|
||||
* [wordcount](https://www.npmjs.com/package/wordcount): Count the words in a string. Support for english, CJK and Cyrillic. | [homepage](https://github.com/jonschlinkert/wordcount "Count the words in a string. Support for english, CJK and Cyrillic.")
|
||||
|
||||
### Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 43 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 2 | [lordvlad](https://github.com/lordvlad) |
|
||||
| 2 | [hildjj](https://github.com/hildjj) |
|
||||
| 1 | [danilosampaio](https://github.com/danilosampaio) |
|
||||
| 1 | [2fd](https://github.com/2fd) |
|
||||
| 1 | [toddself](https://github.com/toddself) |
|
||||
| 1 | [wolfgang42](https://github.com/wolfgang42) |
|
||||
| 1 | [zachhale](https://github.com/zachhale) |
|
||||
|
||||
### Building docs
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
### Running tests
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on June 02, 2017._
|
||||
50
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/index.d.ts
generated
vendored
Normal file
50
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Wrap words to a specified length.
|
||||
*/
|
||||
export = wrap;
|
||||
|
||||
declare function wrap(str: string, options?: wrap.IOptions): string;
|
||||
|
||||
declare namespace wrap {
|
||||
export interface IOptions {
|
||||
|
||||
/**
|
||||
* The width of the text before wrapping to a new line.
|
||||
* @default ´50´
|
||||
*/
|
||||
width?: number;
|
||||
|
||||
/**
|
||||
* The string to use at the beginning of each line.
|
||||
* @default ´´ (none)
|
||||
*/
|
||||
indent?: string;
|
||||
|
||||
/**
|
||||
* The string to use at the end of each line.
|
||||
* @default ´\n´
|
||||
*/
|
||||
newline?: string;
|
||||
|
||||
/**
|
||||
* An escape function to run on each line after splitting them.
|
||||
* @default (str: string) => string;
|
||||
*/
|
||||
escape?: (str: string) => string;
|
||||
|
||||
/**
|
||||
* Trim trailing whitespace from the returned string.
|
||||
* This option is included since .trim() would also strip
|
||||
* the leading indentation from the first line.
|
||||
* @default true
|
||||
*/
|
||||
trim?: boolean;
|
||||
|
||||
/**
|
||||
* Break a word between any two letters when the word is longer
|
||||
* than the specified width.
|
||||
* @default false
|
||||
*/
|
||||
cut?: boolean;
|
||||
}
|
||||
}
|
||||
52
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/index.js
generated
vendored
Normal file
52
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/index.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*!
|
||||
* word-wrap <https://github.com/jonschlinkert/word-wrap>
|
||||
*
|
||||
* Copyright (c) 2014-2023, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
function trimTabAndSpaces(str) {
|
||||
const lines = str.split('\n');
|
||||
const trimmedLines = lines.map((line) => line.trimEnd());
|
||||
return trimmedLines.join('\n');
|
||||
}
|
||||
|
||||
module.exports = function(str, options) {
|
||||
options = options || {};
|
||||
if (str == null) {
|
||||
return str;
|
||||
}
|
||||
|
||||
var width = options.width || 50;
|
||||
var indent = (typeof options.indent === 'string')
|
||||
? options.indent
|
||||
: '';
|
||||
|
||||
var newline = options.newline || '\n' + indent;
|
||||
var escape = typeof options.escape === 'function'
|
||||
? options.escape
|
||||
: identity;
|
||||
|
||||
var regexString = '.{1,' + width + '}';
|
||||
if (options.cut !== true) {
|
||||
regexString += '([\\s\u200B]+|$)|[^\\s\u200B]+?([\\s\u200B]+|$)';
|
||||
}
|
||||
|
||||
var re = new RegExp(regexString, 'g');
|
||||
var lines = str.match(re) || [];
|
||||
var result = indent + lines.map(function(line) {
|
||||
if (line.slice(-1) === '\n') {
|
||||
line = line.slice(0, line.length - 1);
|
||||
}
|
||||
return escape(line);
|
||||
}).join(newline);
|
||||
|
||||
if (options.trim === true) {
|
||||
result = trimTabAndSpaces(result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
function identity(str) {
|
||||
return str;
|
||||
}
|
||||
81
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/package.json
generated
vendored
Normal file
81
desktops/hyprland/ags/node_modules/@aashutoshrathi/word-wrap/package.json
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"name": "@aashutoshrathi/word-wrap",
|
||||
"description": "Wrap words to a specified length.",
|
||||
"version": "1.2.6",
|
||||
"homepage": "https://github.com/aashutoshrathi/word-wrap",
|
||||
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
|
||||
"contributors": [
|
||||
"Aashutosh Rathi <aashutoshrathi@gmail.com>",
|
||||
"Danilo Sampaio <danilo.sampaio@gmail.com> (localhost:8080)",
|
||||
"Fede Ramirez <i@2fd.me> (https://2fd.github.io)",
|
||||
"Joe Hildebrand <joe-github@cursive.net> (https://twitter.com/hildjj)",
|
||||
"Jon Schlinkert <jon.schlinkert@sellside.com> (http://twitter.com/jonschlinkert)",
|
||||
"Todd Kennedy (https://tck.io)",
|
||||
"Waldemar Reusch (https://github.com/lordvlad)",
|
||||
"Wolfgang Faust (http://www.linestarve.com)",
|
||||
"Zach Hale <zachhale@gmail.com> (http://zachhale.com)"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/aashutoshrathi/word-wrap.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/aashutoshrathi/word-wrap/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp-format-md": "^0.1.11",
|
||||
"mocha": "^10.2.0"
|
||||
},
|
||||
"keywords": [
|
||||
"break",
|
||||
"carriage",
|
||||
"line",
|
||||
"new-line",
|
||||
"newline",
|
||||
"return",
|
||||
"soft",
|
||||
"text",
|
||||
"word",
|
||||
"word-wrap",
|
||||
"words",
|
||||
"wrap"
|
||||
],
|
||||
"typings": "index.d.ts",
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
},
|
||||
"related": {
|
||||
"list": [
|
||||
"common-words",
|
||||
"shuffle-words",
|
||||
"unique-words",
|
||||
"wordcount"
|
||||
]
|
||||
},
|
||||
"reflinks": [
|
||||
"verb",
|
||||
"verb-generate-readme"
|
||||
]
|
||||
}
|
||||
}
|
||||
21
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/LICENSE
generated
vendored
Normal file
21
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Toru Nagashima
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
37
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/README.md
generated
vendored
Normal file
37
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/README.md
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# @eslint-community/eslint-utils
|
||||
|
||||
[](https://www.npmjs.com/package/@eslint-community/eslint-utils)
|
||||
[](http://www.npmtrends.com/@eslint-community/eslint-utils)
|
||||
[](https://github.com/eslint-community/eslint-utils/actions)
|
||||
[](https://codecov.io/gh/eslint-community/eslint-utils)
|
||||
|
||||
## 🏁 Goal
|
||||
|
||||
This package provides utility functions and classes for make ESLint custom rules.
|
||||
|
||||
For examples:
|
||||
|
||||
- [`getStaticValue`](https://eslint-community.github.io/eslint-utils/api/ast-utils.html#getstaticvalue) evaluates static value on AST.
|
||||
- [`ReferenceTracker`](https://eslint-community.github.io/eslint-utils/api/scope-utils.html#referencetracker-class) checks the members of modules/globals as handling assignments and destructuring.
|
||||
|
||||
## 📖 Usage
|
||||
|
||||
See [documentation](https://eslint-community.github.io/eslint-utils).
|
||||
|
||||
## 📰 Changelog
|
||||
|
||||
See [releases](https://github.com/eslint-community/eslint-utils/releases).
|
||||
|
||||
## ❤️ Contributing
|
||||
|
||||
Welcome contributing!
|
||||
|
||||
Please use GitHub's Issues/PRs.
|
||||
|
||||
### Development Tools
|
||||
|
||||
- `npm test` runs tests and measures coverage.
|
||||
- `npm run clean` removes the coverage result of `npm test` command.
|
||||
- `npm run coverage` shows the coverage result of the last `npm test` command.
|
||||
- `npm run lint` runs ESLint.
|
||||
- `npm run watch` runs tests on each file change.
|
||||
2068
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.js
generated
vendored
Normal file
2068
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.js.map
generated
vendored
Normal file
1
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2027
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.mjs
generated
vendored
Normal file
2027
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.mjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.mjs.map
generated
vendored
Normal file
1
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/index.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
73
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/package.json
generated
vendored
Normal file
73
desktops/hyprland/ags/node_modules/@eslint-community/eslint-utils/package.json
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "@eslint-community/eslint-utils",
|
||||
"version": "4.4.0",
|
||||
"description": "Utilities for ESLint plugins.",
|
||||
"keywords": [
|
||||
"eslint"
|
||||
],
|
||||
"homepage": "https://github.com/eslint-community/eslint-utils#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/eslint-community/eslint-utils/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eslint-community/eslint-utils"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Toru Nagashima",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./index.mjs",
|
||||
"require": "./index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"main": "index",
|
||||
"module": "index.mjs",
|
||||
"files": [
|
||||
"index.*"
|
||||
],
|
||||
"scripts": {
|
||||
"prebuild": "npm run -s clean",
|
||||
"build": "rollup -c",
|
||||
"clean": "rimraf .nyc_output coverage index.*",
|
||||
"coverage": "opener ./coverage/lcov-report/index.html",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:watch": "vitepress dev docs",
|
||||
"format": "npm run -s format:prettier -- --write",
|
||||
"format:prettier": "prettier .",
|
||||
"format:check": "npm run -s format:prettier -- --check",
|
||||
"lint": "eslint .",
|
||||
"test": "c8 mocha --reporter dot \"test/*.mjs\"",
|
||||
"preversion": "npm test && npm run -s build",
|
||||
"postversion": "git push && git push --tags",
|
||||
"prewatch": "npm run -s clean",
|
||||
"watch": "warun \"{src,test}/**/*.mjs\" -- npm run -s test:mocha"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-mysticatea": "^15.2.0",
|
||||
"c8": "^7.12.0",
|
||||
"dot-prop": "^6.0.1",
|
||||
"eslint": "^8.28.0",
|
||||
"mocha": "^9.2.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"opener": "^1.5.2",
|
||||
"prettier": "2.8.4",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"semver": "^7.3.8",
|
||||
"vitepress": "^1.0.0-alpha.40",
|
||||
"warun": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
}
|
||||
21
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/LICENSE
generated
vendored
Normal file
21
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Toru Nagashima
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
177
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/README.md
generated
vendored
Normal file
177
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/README.md
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
# @eslint-community/regexpp
|
||||
|
||||
[](https://www.npmjs.com/package/@eslint-community/regexpp)
|
||||
[](http://www.npmtrends.com/@eslint-community/regexpp)
|
||||
[](https://github.com/eslint-community/regexpp/actions)
|
||||
[](https://codecov.io/gh/eslint-community/regexpp)
|
||||
|
||||
A regular expression parser for ECMAScript.
|
||||
|
||||
## 💿 Installation
|
||||
|
||||
```bash
|
||||
$ npm install @eslint-community/regexpp
|
||||
```
|
||||
|
||||
- require Node@^12.0.0 || ^14.0.0 || >=16.0.0.
|
||||
|
||||
## 📖 Usage
|
||||
|
||||
```ts
|
||||
import {
|
||||
AST,
|
||||
RegExpParser,
|
||||
RegExpValidator,
|
||||
RegExpVisitor,
|
||||
parseRegExpLiteral,
|
||||
validateRegExpLiteral,
|
||||
visitRegExpAST
|
||||
} from "@eslint-community/regexpp"
|
||||
```
|
||||
|
||||
### parseRegExpLiteral(source, options?)
|
||||
|
||||
Parse a given regular expression literal then make AST object.
|
||||
|
||||
This is equivalent to `new RegExpParser(options).parseLiteral(source)`.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string | RegExp`) The source code to parse.
|
||||
- `options?` ([`RegExpParser.Options`]) The options to parse.
|
||||
- **Return:**
|
||||
- The AST of the regular expression.
|
||||
|
||||
### validateRegExpLiteral(source, options?)
|
||||
|
||||
Validate a given regular expression literal.
|
||||
|
||||
This is equivalent to `new RegExpValidator(options).validateLiteral(source)`.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `options?` ([`RegExpValidator.Options`]) The options to validate.
|
||||
|
||||
### visitRegExpAST(ast, handlers)
|
||||
|
||||
Visit each node of a given AST.
|
||||
|
||||
This is equivalent to `new RegExpVisitor(handlers).visit(ast)`.
|
||||
|
||||
- **Parameters:**
|
||||
- `ast` ([`AST.Node`]) The AST to visit.
|
||||
- `handlers` ([`RegExpVisitor.Handlers`]) The callbacks.
|
||||
|
||||
### RegExpParser
|
||||
|
||||
#### new RegExpParser(options?)
|
||||
|
||||
- **Parameters:**
|
||||
- `options?` ([`RegExpParser.Options`]) The options to parse.
|
||||
|
||||
#### parser.parseLiteral(source, start?, end?)
|
||||
|
||||
Parse a regular expression literal.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to parse. E.g. `"/abc/g"`.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- **Return:**
|
||||
- The AST of the regular expression.
|
||||
|
||||
#### parser.parsePattern(source, start?, end?, flags?)
|
||||
|
||||
Parse a regular expression pattern.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to parse. E.g. `"abc"`.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- `flags?` (`{ unicode?: boolean, unicodeSets?: boolean }`) The flags to enable Unicode mode, and Unicode Set mode.
|
||||
- **Return:**
|
||||
- The AST of the regular expression pattern.
|
||||
|
||||
#### parser.parseFlags(source, start?, end?)
|
||||
|
||||
Parse a regular expression flags.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to parse. E.g. `"gim"`.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- **Return:**
|
||||
- The AST of the regular expression flags.
|
||||
|
||||
### RegExpValidator
|
||||
|
||||
#### new RegExpValidator(options)
|
||||
|
||||
- **Parameters:**
|
||||
- `options` ([`RegExpValidator.Options`]) The options to validate.
|
||||
|
||||
#### validator.validateLiteral(source, start, end)
|
||||
|
||||
Validate a regular expression literal.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
|
||||
#### validator.validatePattern(source, start, end, flags)
|
||||
|
||||
Validate a regular expression pattern.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
- `flags?` (`{ unicode?: boolean, unicodeSets?: boolean }`) The flags to enable Unicode mode, and Unicode Set mode.
|
||||
|
||||
#### validator.validateFlags(source, start, end)
|
||||
|
||||
Validate a regular expression flags.
|
||||
|
||||
- **Parameters:**
|
||||
- `source` (`string`) The source code to validate.
|
||||
- `start?` (`number`) The start index in the source code. Default is `0`.
|
||||
- `end?` (`number`) The end index in the source code. Default is `source.length`.
|
||||
|
||||
### RegExpVisitor
|
||||
|
||||
#### new RegExpVisitor(handlers)
|
||||
|
||||
- **Parameters:**
|
||||
- `handlers` ([`RegExpVisitor.Handlers`]) The callbacks.
|
||||
|
||||
#### visitor.visit(ast)
|
||||
|
||||
Validate a regular expression literal.
|
||||
|
||||
- **Parameters:**
|
||||
- `ast` ([`AST.Node`]) The AST to visit.
|
||||
|
||||
## 📰 Changelog
|
||||
|
||||
- [GitHub Releases](https://github.com/eslint-community/regexpp/releases)
|
||||
|
||||
## 🍻 Contributing
|
||||
|
||||
Welcome contributing!
|
||||
|
||||
Please use GitHub's Issues/PRs.
|
||||
|
||||
### Development Tools
|
||||
|
||||
- `npm test` runs tests and measures coverage.
|
||||
- `npm run build` compiles TypeScript source code to `index.js`, `index.js.map`, and `index.d.ts`.
|
||||
- `npm run clean` removes the temporary files which are created by `npm test` and `npm run build`.
|
||||
- `npm run lint` runs ESLint.
|
||||
- `npm run update:test` updates test fixtures.
|
||||
- `npm run update:ids` updates `src/unicode/ids.ts`.
|
||||
- `npm run watch` runs tests with `--watch` option.
|
||||
|
||||
[`AST.Node`]: src/ast.ts#L4
|
||||
[`RegExpParser.Options`]: src/parser.ts#L743
|
||||
[`RegExpValidator.Options`]: src/validator.ts#L220
|
||||
[`RegExpVisitor.Handlers`]: src/visitor.ts#L291
|
||||
1065
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.d.ts
generated
vendored
Normal file
1065
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2747
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.js
generated
vendored
Normal file
2747
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.js.map
generated
vendored
Normal file
1
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2737
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.mjs
generated
vendored
Normal file
2737
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.mjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.mjs.map
generated
vendored
Normal file
1
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/index.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
93
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/package.json
generated
vendored
Normal file
93
desktops/hyprland/ags/node_modules/@eslint-community/regexpp/package.json
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"name": "@eslint-community/regexpp",
|
||||
"version": "4.10.0",
|
||||
"description": "Regular expression parser for ECMAScript.",
|
||||
"keywords": [
|
||||
"regexp",
|
||||
"regular",
|
||||
"expression",
|
||||
"parser",
|
||||
"validator",
|
||||
"ast",
|
||||
"abstract",
|
||||
"syntax",
|
||||
"tree",
|
||||
"ecmascript",
|
||||
"es2015",
|
||||
"es2016",
|
||||
"es2017",
|
||||
"es2018",
|
||||
"es2019",
|
||||
"es2020",
|
||||
"es2021",
|
||||
"annexB"
|
||||
],
|
||||
"homepage": "https://github.com/eslint-community/regexpp#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/eslint-community/regexpp/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eslint-community/regexpp"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Toru Nagashima",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.mjs",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"main": "index",
|
||||
"files": [
|
||||
"index.*"
|
||||
],
|
||||
"scripts": {
|
||||
"prebuild": "npm run -s clean",
|
||||
"build": "run-s build:*",
|
||||
"build:tsc": "tsc --module es2015",
|
||||
"build:rollup": "rollup -c",
|
||||
"build:dts": "npm run -s build:tsc -- --removeComments false && dts-bundle --name @eslint-community/regexpp --main .temp/index.d.ts --out ../index.d.ts && prettier --write index.d.ts",
|
||||
"clean": "rimraf .temp index.*",
|
||||
"lint": "eslint . --ext .ts",
|
||||
"test": "nyc _mocha \"test/*.ts\" --reporter dot --timeout 10000",
|
||||
"debug": "mocha --require ts-node/register/transpile-only \"test/*.ts\" --reporter dot --timeout 10000",
|
||||
"update:test": "ts-node scripts/update-fixtures.ts",
|
||||
"update:unicode": "run-s update:unicode:*",
|
||||
"update:unicode:ids": "ts-node scripts/update-unicode-ids.ts",
|
||||
"update:unicode:props": "ts-node scripts/update-unicode-properties.ts",
|
||||
"update:test262:extract": "ts-node -T scripts/extract-test262.ts",
|
||||
"preversion": "npm test && npm run -s build",
|
||||
"postversion": "git push && git push --tags",
|
||||
"prewatch": "npm run -s clean",
|
||||
"watch": "_mocha \"test/*.ts\" --require ts-node/register --reporter dot --timeout 10000 --watch-extensions ts --watch --growl"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-mysticatea": "^15.5.1",
|
||||
"@rollup/plugin-node-resolve": "^14.1.0",
|
||||
"@types/eslint": "^8.44.3",
|
||||
"@types/jsdom": "^16.2.15",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^12.20.55",
|
||||
"dts-bundle": "^0.7.3",
|
||||
"eslint": "^8.50.0",
|
||||
"js-tokens": "^8.0.2",
|
||||
"jsdom": "^19.0.0",
|
||||
"mocha": "^9.2.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nyc": "^14.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-sourcemaps": "^0.6.3",
|
||||
"test262": "git+https://github.com/tc39/test262.git",
|
||||
"test262-stream": "^1.4.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "~5.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
}
|
||||
19
desktops/hyprland/ags/node_modules/@eslint/eslintrc/LICENSE
generated
vendored
Normal file
19
desktops/hyprland/ags/node_modules/@eslint/eslintrc/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
115
desktops/hyprland/ags/node_modules/@eslint/eslintrc/README.md
generated
vendored
Normal file
115
desktops/hyprland/ags/node_modules/@eslint/eslintrc/README.md
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
# ESLintRC Library
|
||||
|
||||
This repository contains the legacy ESLintRC configuration file format for ESLint. This package is not intended for use outside of the ESLint ecosystem. It is ESLint-specific and not intended for use in other programs.
|
||||
|
||||
**Note:** This package is frozen except for critical bug fixes as ESLint moves to a new config system.
|
||||
|
||||
## Installation
|
||||
|
||||
You can install the package as follows:
|
||||
|
||||
```
|
||||
npm install @eslint/eslintrc --save-dev
|
||||
|
||||
# or
|
||||
|
||||
yarn add @eslint/eslintrc -D
|
||||
```
|
||||
|
||||
## Usage (ESM)
|
||||
|
||||
The primary class in this package is `FlatCompat`, which is a utility to translate ESLintRC-style configs into flat configs. Here's how you use it inside of your `eslint.config.js` file:
|
||||
|
||||
```js
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import js from "@eslint/js";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
// mimic CommonJS variables -- not needed if using CommonJS
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname, // optional; default: process.cwd()
|
||||
resolvePluginsRelativeTo: __dirname, // optional
|
||||
recommendedConfig: js.configs.recommended, // optional
|
||||
allConfig: js.configs.all, // optional
|
||||
});
|
||||
|
||||
export default [
|
||||
|
||||
// mimic ESLintRC-style extends
|
||||
...compat.extends("standard", "example"),
|
||||
|
||||
// mimic environments
|
||||
...compat.env({
|
||||
es2020: true,
|
||||
node: true
|
||||
}),
|
||||
|
||||
// mimic plugins
|
||||
...compat.plugins("airbnb", "react"),
|
||||
|
||||
// translate an entire config
|
||||
...compat.config({
|
||||
plugins: ["airbnb", "react"],
|
||||
extends: "standard",
|
||||
env: {
|
||||
es2020: true,
|
||||
node: true
|
||||
},
|
||||
rules: {
|
||||
semi: "error"
|
||||
}
|
||||
})
|
||||
];
|
||||
```
|
||||
|
||||
## Usage (CommonJS)
|
||||
|
||||
Using `FlatCompat` in CommonJS files is similar to ESM, but you'll use `require()` and `module.exports` instead of `import` and `export`. Here's how you use it inside of your `eslint.config.js` CommonJS file:
|
||||
|
||||
```js
|
||||
const { FlatCompat } = require("@eslint/eslintrc");
|
||||
const js = require("@eslint/js");
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname, // optional; default: process.cwd()
|
||||
resolvePluginsRelativeTo: __dirname, // optional
|
||||
recommendedConfig: js.configs.recommended, // optional
|
||||
allConfig: js.configs.all, // optional
|
||||
});
|
||||
|
||||
module.exports = [
|
||||
|
||||
// mimic ESLintRC-style extends
|
||||
...compat.extends("standard", "example"),
|
||||
|
||||
// mimic environments
|
||||
...compat.env({
|
||||
es2020: true,
|
||||
node: true
|
||||
}),
|
||||
|
||||
// mimic plugins
|
||||
...compat.plugins("airbnb", "react"),
|
||||
|
||||
// translate an entire config
|
||||
...compat.config({
|
||||
plugins: ["airbnb", "react"],
|
||||
extends: "standard",
|
||||
env: {
|
||||
es2020: true,
|
||||
node: true
|
||||
},
|
||||
rules: {
|
||||
semi: "error"
|
||||
}
|
||||
})
|
||||
];
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
79
desktops/hyprland/ags/node_modules/@eslint/eslintrc/conf/config-schema.js
generated
vendored
Normal file
79
desktops/hyprland/ags/node_modules/@eslint/eslintrc/conf/config-schema.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @fileoverview Defines a schema for configs.
|
||||
* @author Sylvan Mably
|
||||
*/
|
||||
|
||||
const baseConfigProperties = {
|
||||
$schema: { type: "string" },
|
||||
env: { type: "object" },
|
||||
extends: { $ref: "#/definitions/stringOrStrings" },
|
||||
globals: { type: "object" },
|
||||
overrides: {
|
||||
type: "array",
|
||||
items: { $ref: "#/definitions/overrideConfig" },
|
||||
additionalItems: false
|
||||
},
|
||||
parser: { type: ["string", "null"] },
|
||||
parserOptions: { type: "object" },
|
||||
plugins: { type: "array" },
|
||||
processor: { type: "string" },
|
||||
rules: { type: "object" },
|
||||
settings: { type: "object" },
|
||||
noInlineConfig: { type: "boolean" },
|
||||
reportUnusedDisableDirectives: { type: "boolean" },
|
||||
|
||||
ecmaFeatures: { type: "object" } // deprecated; logs a warning when used
|
||||
};
|
||||
|
||||
const configSchema = {
|
||||
definitions: {
|
||||
stringOrStrings: {
|
||||
oneOf: [
|
||||
{ type: "string" },
|
||||
{
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
additionalItems: false
|
||||
}
|
||||
]
|
||||
},
|
||||
stringOrStringsRequired: {
|
||||
oneOf: [
|
||||
{ type: "string" },
|
||||
{
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
additionalItems: false,
|
||||
minItems: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// Config at top-level.
|
||||
objectConfig: {
|
||||
type: "object",
|
||||
properties: {
|
||||
root: { type: "boolean" },
|
||||
ignorePatterns: { $ref: "#/definitions/stringOrStrings" },
|
||||
...baseConfigProperties
|
||||
},
|
||||
additionalProperties: false
|
||||
},
|
||||
|
||||
// Config in `overrides`.
|
||||
overrideConfig: {
|
||||
type: "object",
|
||||
properties: {
|
||||
excludedFiles: { $ref: "#/definitions/stringOrStrings" },
|
||||
files: { $ref: "#/definitions/stringOrStringsRequired" },
|
||||
...baseConfigProperties
|
||||
},
|
||||
required: ["files"],
|
||||
additionalProperties: false
|
||||
}
|
||||
},
|
||||
|
||||
$ref: "#/definitions/objectConfig"
|
||||
};
|
||||
|
||||
export default configSchema;
|
||||
215
desktops/hyprland/ags/node_modules/@eslint/eslintrc/conf/environments.js
generated
vendored
Normal file
215
desktops/hyprland/ags/node_modules/@eslint/eslintrc/conf/environments.js
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* @fileoverview Defines environment settings and globals.
|
||||
* @author Elan Shanker
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import globals from "globals";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the object that has difference.
|
||||
* @param {Record<string,boolean>} current The newer object.
|
||||
* @param {Record<string,boolean>} prev The older object.
|
||||
* @returns {Record<string,boolean>} The difference object.
|
||||
*/
|
||||
function getDiff(current, prev) {
|
||||
const retv = {};
|
||||
|
||||
for (const [key, value] of Object.entries(current)) {
|
||||
if (!Object.hasOwnProperty.call(prev, key)) {
|
||||
retv[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
const newGlobals2015 = getDiff(globals.es2015, globals.es5); // 19 variables such as Promise, Map, ...
|
||||
const newGlobals2017 = {
|
||||
Atomics: false,
|
||||
SharedArrayBuffer: false
|
||||
};
|
||||
const newGlobals2020 = {
|
||||
BigInt: false,
|
||||
BigInt64Array: false,
|
||||
BigUint64Array: false,
|
||||
globalThis: false
|
||||
};
|
||||
|
||||
const newGlobals2021 = {
|
||||
AggregateError: false,
|
||||
FinalizationRegistry: false,
|
||||
WeakRef: false
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {Map<string, import("../lib/shared/types").Environment>} */
|
||||
export default new Map(Object.entries({
|
||||
|
||||
// Language
|
||||
builtin: {
|
||||
globals: globals.es5
|
||||
},
|
||||
es6: {
|
||||
globals: newGlobals2015,
|
||||
parserOptions: {
|
||||
ecmaVersion: 6
|
||||
}
|
||||
},
|
||||
es2015: {
|
||||
globals: newGlobals2015,
|
||||
parserOptions: {
|
||||
ecmaVersion: 6
|
||||
}
|
||||
},
|
||||
es2016: {
|
||||
globals: newGlobals2015,
|
||||
parserOptions: {
|
||||
ecmaVersion: 7
|
||||
}
|
||||
},
|
||||
es2017: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 8
|
||||
}
|
||||
},
|
||||
es2018: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 9
|
||||
}
|
||||
},
|
||||
es2019: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 10
|
||||
}
|
||||
},
|
||||
es2020: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 11
|
||||
}
|
||||
},
|
||||
es2021: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 12
|
||||
}
|
||||
},
|
||||
es2022: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 13
|
||||
}
|
||||
},
|
||||
es2023: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 14
|
||||
}
|
||||
},
|
||||
es2024: {
|
||||
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 },
|
||||
parserOptions: {
|
||||
ecmaVersion: 15
|
||||
}
|
||||
},
|
||||
|
||||
// Platforms
|
||||
browser: {
|
||||
globals: globals.browser
|
||||
},
|
||||
node: {
|
||||
globals: globals.node,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
globalReturn: true
|
||||
}
|
||||
}
|
||||
},
|
||||
"shared-node-browser": {
|
||||
globals: globals["shared-node-browser"]
|
||||
},
|
||||
worker: {
|
||||
globals: globals.worker
|
||||
},
|
||||
serviceworker: {
|
||||
globals: globals.serviceworker
|
||||
},
|
||||
|
||||
// Frameworks
|
||||
commonjs: {
|
||||
globals: globals.commonjs,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
globalReturn: true
|
||||
}
|
||||
}
|
||||
},
|
||||
amd: {
|
||||
globals: globals.amd
|
||||
},
|
||||
mocha: {
|
||||
globals: globals.mocha
|
||||
},
|
||||
jasmine: {
|
||||
globals: globals.jasmine
|
||||
},
|
||||
jest: {
|
||||
globals: globals.jest
|
||||
},
|
||||
phantomjs: {
|
||||
globals: globals.phantomjs
|
||||
},
|
||||
jquery: {
|
||||
globals: globals.jquery
|
||||
},
|
||||
qunit: {
|
||||
globals: globals.qunit
|
||||
},
|
||||
prototypejs: {
|
||||
globals: globals.prototypejs
|
||||
},
|
||||
shelljs: {
|
||||
globals: globals.shelljs
|
||||
},
|
||||
meteor: {
|
||||
globals: globals.meteor
|
||||
},
|
||||
mongo: {
|
||||
globals: globals.mongo
|
||||
},
|
||||
protractor: {
|
||||
globals: globals.protractor
|
||||
},
|
||||
applescript: {
|
||||
globals: globals.applescript
|
||||
},
|
||||
nashorn: {
|
||||
globals: globals.nashorn
|
||||
},
|
||||
atomtest: {
|
||||
globals: globals.atomtest
|
||||
},
|
||||
embertest: {
|
||||
globals: globals.embertest
|
||||
},
|
||||
webextensions: {
|
||||
globals: globals.webextensions
|
||||
},
|
||||
greasemonkey: {
|
||||
globals: globals.greasemonkey
|
||||
}
|
||||
}));
|
||||
1104
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs
generated
vendored
Normal file
1104
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs.map
generated
vendored
Normal file
1
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4333
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
generated
vendored
Normal file
4333
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc.cjs.map
generated
vendored
Normal file
1
desktops/hyprland/ags/node_modules/@eslint/eslintrc/dist/eslintrc.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
532
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js
generated
vendored
Normal file
532
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js
generated
vendored
Normal file
@@ -0,0 +1,532 @@
|
||||
/**
|
||||
* @fileoverview `CascadingConfigArrayFactory` class.
|
||||
*
|
||||
* `CascadingConfigArrayFactory` class has a responsibility:
|
||||
*
|
||||
* 1. Handles cascading of config files.
|
||||
*
|
||||
* It provides two methods:
|
||||
*
|
||||
* - `getConfigArrayForFile(filePath)`
|
||||
* Get the corresponded configuration of a given file. This method doesn't
|
||||
* throw even if the given file didn't exist.
|
||||
* - `clearCache()`
|
||||
* Clear the internal cache. You have to call this method when
|
||||
* `additionalPluginPool` was updated if `baseConfig` or `cliConfig` depends
|
||||
* on the additional plugins. (`CLIEngine#addPlugin()` method calls this.)
|
||||
*
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import debugOrig from "debug";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
import { ConfigArrayFactory } from "./config-array-factory.js";
|
||||
import {
|
||||
ConfigArray,
|
||||
ConfigDependency,
|
||||
IgnorePattern
|
||||
} from "./config-array/index.js";
|
||||
import ConfigValidator from "./shared/config-validator.js";
|
||||
import { emitDeprecationWarning } from "./shared/deprecation-warnings.js";
|
||||
|
||||
const debug = debugOrig("eslintrc:cascading-config-array-factory");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Define types for VSCode IntelliSense.
|
||||
/** @typedef {import("./shared/types").ConfigData} ConfigData */
|
||||
/** @typedef {import("./shared/types").Parser} Parser */
|
||||
/** @typedef {import("./shared/types").Plugin} Plugin */
|
||||
/** @typedef {import("./shared/types").Rule} Rule */
|
||||
/** @typedef {ReturnType<ConfigArrayFactory["create"]>} ConfigArray */
|
||||
|
||||
/**
|
||||
* @typedef {Object} CascadingConfigArrayFactoryOptions
|
||||
* @property {Map<string,Plugin>} [additionalPluginPool] The map for additional plugins.
|
||||
* @property {ConfigData} [baseConfig] The config by `baseConfig` option.
|
||||
* @property {ConfigData} [cliConfig] The config by CLI options (`--env`, `--global`, `--ignore-pattern`, `--parser`, `--parser-options`, `--plugin`, and `--rule`). CLI options overwrite the setting in config files.
|
||||
* @property {string} [cwd] The base directory to start lookup.
|
||||
* @property {string} [ignorePath] The path to the alternative file of `.eslintignore`.
|
||||
* @property {string[]} [rulePaths] The value of `--rulesdir` option.
|
||||
* @property {string} [specificConfigPath] The value of `--config` option.
|
||||
* @property {boolean} [useEslintrc] if `false` then it doesn't load config files.
|
||||
* @property {Function} loadRules The function to use to load rules.
|
||||
* @property {Map<string,Rule>} builtInRules The rules that are built in to ESLint.
|
||||
* @property {Object} [resolver=ModuleResolver] The module resolver object.
|
||||
* @property {string} eslintAllPath The path to the definitions for eslint:all.
|
||||
* @property {Function} getEslintAllConfig Returns the config data for eslint:all.
|
||||
* @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended.
|
||||
* @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} CascadingConfigArrayFactoryInternalSlots
|
||||
* @property {ConfigArray} baseConfigArray The config array of `baseConfig` option.
|
||||
* @property {ConfigData} baseConfigData The config data of `baseConfig` option. This is used to reset `baseConfigArray`.
|
||||
* @property {ConfigArray} cliConfigArray The config array of CLI options.
|
||||
* @property {ConfigData} cliConfigData The config data of CLI options. This is used to reset `cliConfigArray`.
|
||||
* @property {ConfigArrayFactory} configArrayFactory The factory for config arrays.
|
||||
* @property {Map<string, ConfigArray>} configCache The cache from directory paths to config arrays.
|
||||
* @property {string} cwd The base directory to start lookup.
|
||||
* @property {WeakMap<ConfigArray, ConfigArray>} finalizeCache The cache from config arrays to finalized config arrays.
|
||||
* @property {string} [ignorePath] The path to the alternative file of `.eslintignore`.
|
||||
* @property {string[]|null} rulePaths The value of `--rulesdir` option. This is used to reset `baseConfigArray`.
|
||||
* @property {string|null} specificConfigPath The value of `--config` option. This is used to reset `cliConfigArray`.
|
||||
* @property {boolean} useEslintrc if `false` then it doesn't load config files.
|
||||
* @property {Function} loadRules The function to use to load rules.
|
||||
* @property {Map<string,Rule>} builtInRules The rules that are built in to ESLint.
|
||||
* @property {Object} [resolver=ModuleResolver] The module resolver object.
|
||||
* @property {string} eslintAllPath The path to the definitions for eslint:all.
|
||||
* @property {Function} getEslintAllConfig Returns the config data for eslint:all.
|
||||
* @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended.
|
||||
* @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended.
|
||||
*/
|
||||
|
||||
/** @type {WeakMap<CascadingConfigArrayFactory, CascadingConfigArrayFactoryInternalSlots>} */
|
||||
const internalSlotsMap = new WeakMap();
|
||||
|
||||
/**
|
||||
* Create the config array from `baseConfig` and `rulePaths`.
|
||||
* @param {CascadingConfigArrayFactoryInternalSlots} slots The slots.
|
||||
* @returns {ConfigArray} The config array of the base configs.
|
||||
*/
|
||||
function createBaseConfigArray({
|
||||
configArrayFactory,
|
||||
baseConfigData,
|
||||
rulePaths,
|
||||
cwd,
|
||||
loadRules
|
||||
}) {
|
||||
const baseConfigArray = configArrayFactory.create(
|
||||
baseConfigData,
|
||||
{ name: "BaseConfig" }
|
||||
);
|
||||
|
||||
/*
|
||||
* Create the config array element for the default ignore patterns.
|
||||
* This element has `ignorePattern` property that ignores the default
|
||||
* patterns in the current working directory.
|
||||
*/
|
||||
baseConfigArray.unshift(configArrayFactory.create(
|
||||
{ ignorePatterns: IgnorePattern.DefaultPatterns },
|
||||
{ name: "DefaultIgnorePattern" }
|
||||
)[0]);
|
||||
|
||||
/*
|
||||
* Load rules `--rulesdir` option as a pseudo plugin.
|
||||
* Use a pseudo plugin to define rules of `--rulesdir`, so we can validate
|
||||
* the rule's options with only information in the config array.
|
||||
*/
|
||||
if (rulePaths && rulePaths.length > 0) {
|
||||
baseConfigArray.push({
|
||||
type: "config",
|
||||
name: "--rulesdir",
|
||||
filePath: "",
|
||||
plugins: {
|
||||
"": new ConfigDependency({
|
||||
definition: {
|
||||
rules: rulePaths.reduce(
|
||||
(map, rulesPath) => Object.assign(
|
||||
map,
|
||||
loadRules(rulesPath, cwd)
|
||||
),
|
||||
{}
|
||||
)
|
||||
},
|
||||
filePath: "",
|
||||
id: "",
|
||||
importerName: "--rulesdir",
|
||||
importerPath: ""
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return baseConfigArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the config array from CLI options.
|
||||
* @param {CascadingConfigArrayFactoryInternalSlots} slots The slots.
|
||||
* @returns {ConfigArray} The config array of the base configs.
|
||||
*/
|
||||
function createCLIConfigArray({
|
||||
cliConfigData,
|
||||
configArrayFactory,
|
||||
cwd,
|
||||
ignorePath,
|
||||
specificConfigPath
|
||||
}) {
|
||||
const cliConfigArray = configArrayFactory.create(
|
||||
cliConfigData,
|
||||
{ name: "CLIOptions" }
|
||||
);
|
||||
|
||||
cliConfigArray.unshift(
|
||||
...(ignorePath
|
||||
? configArrayFactory.loadESLintIgnore(ignorePath)
|
||||
: configArrayFactory.loadDefaultESLintIgnore())
|
||||
);
|
||||
|
||||
if (specificConfigPath) {
|
||||
cliConfigArray.unshift(
|
||||
...configArrayFactory.loadFile(
|
||||
specificConfigPath,
|
||||
{ name: "--config", basePath: cwd }
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return cliConfigArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* The error type when there are files matched by a glob, but all of them have been ignored.
|
||||
*/
|
||||
class ConfigurationNotFoundError extends Error {
|
||||
|
||||
// eslint-disable-next-line jsdoc/require-description
|
||||
/**
|
||||
* @param {string} directoryPath The directory path.
|
||||
*/
|
||||
constructor(directoryPath) {
|
||||
super(`No ESLint configuration found in ${directoryPath}.`);
|
||||
this.messageTemplate = "no-config-found";
|
||||
this.messageData = { directoryPath };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class provides the functionality that enumerates every file which is
|
||||
* matched by given glob patterns and that configuration.
|
||||
*/
|
||||
class CascadingConfigArrayFactory {
|
||||
|
||||
/**
|
||||
* Initialize this enumerator.
|
||||
* @param {CascadingConfigArrayFactoryOptions} options The options.
|
||||
*/
|
||||
constructor({
|
||||
additionalPluginPool = new Map(),
|
||||
baseConfig: baseConfigData = null,
|
||||
cliConfig: cliConfigData = null,
|
||||
cwd = process.cwd(),
|
||||
ignorePath,
|
||||
resolvePluginsRelativeTo,
|
||||
rulePaths = [],
|
||||
specificConfigPath = null,
|
||||
useEslintrc = true,
|
||||
builtInRules = new Map(),
|
||||
loadRules,
|
||||
resolver,
|
||||
eslintRecommendedPath,
|
||||
getEslintRecommendedConfig,
|
||||
eslintAllPath,
|
||||
getEslintAllConfig
|
||||
} = {}) {
|
||||
const configArrayFactory = new ConfigArrayFactory({
|
||||
additionalPluginPool,
|
||||
cwd,
|
||||
resolvePluginsRelativeTo,
|
||||
builtInRules,
|
||||
resolver,
|
||||
eslintRecommendedPath,
|
||||
getEslintRecommendedConfig,
|
||||
eslintAllPath,
|
||||
getEslintAllConfig
|
||||
});
|
||||
|
||||
internalSlotsMap.set(this, {
|
||||
baseConfigArray: createBaseConfigArray({
|
||||
baseConfigData,
|
||||
configArrayFactory,
|
||||
cwd,
|
||||
rulePaths,
|
||||
loadRules
|
||||
}),
|
||||
baseConfigData,
|
||||
cliConfigArray: createCLIConfigArray({
|
||||
cliConfigData,
|
||||
configArrayFactory,
|
||||
cwd,
|
||||
ignorePath,
|
||||
specificConfigPath
|
||||
}),
|
||||
cliConfigData,
|
||||
configArrayFactory,
|
||||
configCache: new Map(),
|
||||
cwd,
|
||||
finalizeCache: new WeakMap(),
|
||||
ignorePath,
|
||||
rulePaths,
|
||||
specificConfigPath,
|
||||
useEslintrc,
|
||||
builtInRules,
|
||||
loadRules
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The path to the current working directory.
|
||||
* This is used by tests.
|
||||
* @type {string}
|
||||
*/
|
||||
get cwd() {
|
||||
const { cwd } = internalSlotsMap.get(this);
|
||||
|
||||
return cwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config array of a given file.
|
||||
* If `filePath` was not given, it returns the config which contains only
|
||||
* `baseConfigData` and `cliConfigData`.
|
||||
* @param {string} [filePath] The file path to a file.
|
||||
* @param {Object} [options] The options.
|
||||
* @param {boolean} [options.ignoreNotFoundError] If `true` then it doesn't throw `ConfigurationNotFoundError`.
|
||||
* @returns {ConfigArray} The config array of the file.
|
||||
*/
|
||||
getConfigArrayForFile(filePath, { ignoreNotFoundError = false } = {}) {
|
||||
const {
|
||||
baseConfigArray,
|
||||
cliConfigArray,
|
||||
cwd
|
||||
} = internalSlotsMap.get(this);
|
||||
|
||||
if (!filePath) {
|
||||
return new ConfigArray(...baseConfigArray, ...cliConfigArray);
|
||||
}
|
||||
|
||||
const directoryPath = path.dirname(path.resolve(cwd, filePath));
|
||||
|
||||
debug(`Load config files for ${directoryPath}.`);
|
||||
|
||||
return this._finalizeConfigArray(
|
||||
this._loadConfigInAncestors(directoryPath),
|
||||
directoryPath,
|
||||
ignoreNotFoundError
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the config data to override all configs.
|
||||
* Require to call `clearCache()` method after this method is called.
|
||||
* @param {ConfigData} configData The config data to override all configs.
|
||||
* @returns {void}
|
||||
*/
|
||||
setOverrideConfig(configData) {
|
||||
const slots = internalSlotsMap.get(this);
|
||||
|
||||
slots.cliConfigData = configData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear config cache.
|
||||
* @returns {void}
|
||||
*/
|
||||
clearCache() {
|
||||
const slots = internalSlotsMap.get(this);
|
||||
|
||||
slots.baseConfigArray = createBaseConfigArray(slots);
|
||||
slots.cliConfigArray = createCLIConfigArray(slots);
|
||||
slots.configCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and normalize config files from the ancestor directories.
|
||||
* @param {string} directoryPath The path to a leaf directory.
|
||||
* @param {boolean} configsExistInSubdirs `true` if configurations exist in subdirectories.
|
||||
* @returns {ConfigArray} The loaded config.
|
||||
* @private
|
||||
*/
|
||||
_loadConfigInAncestors(directoryPath, configsExistInSubdirs = false) {
|
||||
const {
|
||||
baseConfigArray,
|
||||
configArrayFactory,
|
||||
configCache,
|
||||
cwd,
|
||||
useEslintrc
|
||||
} = internalSlotsMap.get(this);
|
||||
|
||||
if (!useEslintrc) {
|
||||
return baseConfigArray;
|
||||
}
|
||||
|
||||
let configArray = configCache.get(directoryPath);
|
||||
|
||||
// Hit cache.
|
||||
if (configArray) {
|
||||
debug(`Cache hit: ${directoryPath}.`);
|
||||
return configArray;
|
||||
}
|
||||
debug(`No cache found: ${directoryPath}.`);
|
||||
|
||||
const homePath = os.homedir();
|
||||
|
||||
// Consider this is root.
|
||||
if (directoryPath === homePath && cwd !== homePath) {
|
||||
debug("Stop traversing because of considered root.");
|
||||
if (configsExistInSubdirs) {
|
||||
const filePath = ConfigArrayFactory.getPathToConfigFileInDirectory(directoryPath);
|
||||
|
||||
if (filePath) {
|
||||
emitDeprecationWarning(
|
||||
filePath,
|
||||
"ESLINT_PERSONAL_CONFIG_SUPPRESS"
|
||||
);
|
||||
}
|
||||
}
|
||||
return this._cacheConfig(directoryPath, baseConfigArray);
|
||||
}
|
||||
|
||||
// Load the config on this directory.
|
||||
try {
|
||||
configArray = configArrayFactory.loadInDirectory(directoryPath);
|
||||
} catch (error) {
|
||||
/* istanbul ignore next */
|
||||
if (error.code === "EACCES") {
|
||||
debug("Stop traversing because of 'EACCES' error.");
|
||||
return this._cacheConfig(directoryPath, baseConfigArray);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (configArray.length > 0 && configArray.isRoot()) {
|
||||
debug("Stop traversing because of 'root:true'.");
|
||||
configArray.unshift(...baseConfigArray);
|
||||
return this._cacheConfig(directoryPath, configArray);
|
||||
}
|
||||
|
||||
// Load from the ancestors and merge it.
|
||||
const parentPath = path.dirname(directoryPath);
|
||||
const parentConfigArray = parentPath && parentPath !== directoryPath
|
||||
? this._loadConfigInAncestors(
|
||||
parentPath,
|
||||
configsExistInSubdirs || configArray.length > 0
|
||||
)
|
||||
: baseConfigArray;
|
||||
|
||||
if (configArray.length > 0) {
|
||||
configArray.unshift(...parentConfigArray);
|
||||
} else {
|
||||
configArray = parentConfigArray;
|
||||
}
|
||||
|
||||
// Cache and return.
|
||||
return this._cacheConfig(directoryPath, configArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Freeze and cache a given config.
|
||||
* @param {string} directoryPath The path to a directory as a cache key.
|
||||
* @param {ConfigArray} configArray The config array as a cache value.
|
||||
* @returns {ConfigArray} The `configArray` (frozen).
|
||||
*/
|
||||
_cacheConfig(directoryPath, configArray) {
|
||||
const { configCache } = internalSlotsMap.get(this);
|
||||
|
||||
Object.freeze(configArray);
|
||||
configCache.set(directoryPath, configArray);
|
||||
|
||||
return configArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize a given config array.
|
||||
* Concatenate `--config` and other CLI options.
|
||||
* @param {ConfigArray} configArray The parent config array.
|
||||
* @param {string} directoryPath The path to the leaf directory to find config files.
|
||||
* @param {boolean} ignoreNotFoundError If `true` then it doesn't throw `ConfigurationNotFoundError`.
|
||||
* @returns {ConfigArray} The loaded config.
|
||||
* @private
|
||||
*/
|
||||
_finalizeConfigArray(configArray, directoryPath, ignoreNotFoundError) {
|
||||
const {
|
||||
cliConfigArray,
|
||||
configArrayFactory,
|
||||
finalizeCache,
|
||||
useEslintrc,
|
||||
builtInRules
|
||||
} = internalSlotsMap.get(this);
|
||||
|
||||
let finalConfigArray = finalizeCache.get(configArray);
|
||||
|
||||
if (!finalConfigArray) {
|
||||
finalConfigArray = configArray;
|
||||
|
||||
// Load the personal config if there are no regular config files.
|
||||
if (
|
||||
useEslintrc &&
|
||||
configArray.every(c => !c.filePath) &&
|
||||
cliConfigArray.every(c => !c.filePath) // `--config` option can be a file.
|
||||
) {
|
||||
const homePath = os.homedir();
|
||||
|
||||
debug("Loading the config file of the home directory:", homePath);
|
||||
|
||||
const personalConfigArray = configArrayFactory.loadInDirectory(
|
||||
homePath,
|
||||
{ name: "PersonalConfig" }
|
||||
);
|
||||
|
||||
if (
|
||||
personalConfigArray.length > 0 &&
|
||||
!directoryPath.startsWith(homePath)
|
||||
) {
|
||||
const lastElement =
|
||||
personalConfigArray[personalConfigArray.length - 1];
|
||||
|
||||
emitDeprecationWarning(
|
||||
lastElement.filePath,
|
||||
"ESLINT_PERSONAL_CONFIG_LOAD"
|
||||
);
|
||||
}
|
||||
|
||||
finalConfigArray = finalConfigArray.concat(personalConfigArray);
|
||||
}
|
||||
|
||||
// Apply CLI options.
|
||||
if (cliConfigArray.length > 0) {
|
||||
finalConfigArray = finalConfigArray.concat(cliConfigArray);
|
||||
}
|
||||
|
||||
// Validate rule settings and environments.
|
||||
const validator = new ConfigValidator({
|
||||
builtInRules
|
||||
});
|
||||
|
||||
validator.validateConfigArray(finalConfigArray);
|
||||
|
||||
// Cache it.
|
||||
Object.freeze(finalConfigArray);
|
||||
finalizeCache.set(configArray, finalConfigArray);
|
||||
|
||||
debug(
|
||||
"Configuration was determined: %o on %s",
|
||||
finalConfigArray,
|
||||
directoryPath
|
||||
);
|
||||
}
|
||||
|
||||
// At least one element (the default ignore patterns) exists.
|
||||
if (!ignoreNotFoundError && useEslintrc && finalConfigArray.length <= 1) {
|
||||
throw new ConfigurationNotFoundError(directoryPath);
|
||||
}
|
||||
|
||||
return finalConfigArray;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export { CascadingConfigArrayFactory };
|
||||
1149
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array-factory.js
generated
vendored
Normal file
1149
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array-factory.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
523
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/config-array.js
generated
vendored
Normal file
523
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/config-array.js
generated
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
/**
|
||||
* @fileoverview `ConfigArray` class.
|
||||
*
|
||||
* `ConfigArray` class expresses the full of a configuration. It has the entry
|
||||
* config file, base config files that were extended, loaded parsers, and loaded
|
||||
* plugins.
|
||||
*
|
||||
* `ConfigArray` class provides three properties and two methods.
|
||||
*
|
||||
* - `pluginEnvironments`
|
||||
* - `pluginProcessors`
|
||||
* - `pluginRules`
|
||||
* The `Map` objects that contain the members of all plugins that this
|
||||
* config array contains. Those map objects don't have mutation methods.
|
||||
* Those keys are the member ID such as `pluginId/memberName`.
|
||||
* - `isRoot()`
|
||||
* If `true` then this configuration has `root:true` property.
|
||||
* - `extractConfig(filePath)`
|
||||
* Extract the final configuration for a given file. This means merging
|
||||
* every config array element which that `criteria` property matched. The
|
||||
* `filePath` argument must be an absolute path.
|
||||
*
|
||||
* `ConfigArrayFactory` provides the loading logic of config files.
|
||||
*
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import { ExtractedConfig } from "./extracted-config.js";
|
||||
import { IgnorePattern } from "./ignore-pattern.js";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Define types for VSCode IntelliSense.
|
||||
/** @typedef {import("../../shared/types").Environment} Environment */
|
||||
/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */
|
||||
/** @typedef {import("../../shared/types").RuleConf} RuleConf */
|
||||
/** @typedef {import("../../shared/types").Rule} Rule */
|
||||
/** @typedef {import("../../shared/types").Plugin} Plugin */
|
||||
/** @typedef {import("../../shared/types").Processor} Processor */
|
||||
/** @typedef {import("./config-dependency").DependentParser} DependentParser */
|
||||
/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */
|
||||
/** @typedef {import("./override-tester")["OverrideTester"]} OverrideTester */
|
||||
|
||||
/**
|
||||
* @typedef {Object} ConfigArrayElement
|
||||
* @property {string} name The name of this config element.
|
||||
* @property {string} filePath The path to the source file of this config element.
|
||||
* @property {InstanceType<OverrideTester>|null} criteria The tester for the `files` and `excludedFiles` of this config element.
|
||||
* @property {Record<string, boolean>|undefined} env The environment settings.
|
||||
* @property {Record<string, GlobalConf>|undefined} globals The global variable settings.
|
||||
* @property {IgnorePattern|undefined} ignorePattern The ignore patterns.
|
||||
* @property {boolean|undefined} noInlineConfig The flag that disables directive comments.
|
||||
* @property {DependentParser|undefined} parser The parser loader.
|
||||
* @property {Object|undefined} parserOptions The parser options.
|
||||
* @property {Record<string, DependentPlugin>|undefined} plugins The plugin loaders.
|
||||
* @property {string|undefined} processor The processor name to refer plugin's processor.
|
||||
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
|
||||
* @property {boolean|undefined} root The flag to express root.
|
||||
* @property {Record<string, RuleConf>|undefined} rules The rule settings
|
||||
* @property {Object|undefined} settings The shared settings.
|
||||
* @property {"config" | "ignore" | "implicit-processor"} type The element type.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ConfigArrayInternalSlots
|
||||
* @property {Map<string, ExtractedConfig>} cache The cache to extract configs.
|
||||
* @property {ReadonlyMap<string, Environment>|null} envMap The map from environment ID to environment definition.
|
||||
* @property {ReadonlyMap<string, Processor>|null} processorMap The map from processor ID to environment definition.
|
||||
* @property {ReadonlyMap<string, Rule>|null} ruleMap The map from rule ID to rule definition.
|
||||
*/
|
||||
|
||||
/** @type {WeakMap<ConfigArray, ConfigArrayInternalSlots>} */
|
||||
const internalSlotsMap = new class extends WeakMap {
|
||||
get(key) {
|
||||
let value = super.get(key);
|
||||
|
||||
if (!value) {
|
||||
value = {
|
||||
cache: new Map(),
|
||||
envMap: null,
|
||||
processorMap: null,
|
||||
ruleMap: null
|
||||
};
|
||||
super.set(key, value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}();
|
||||
|
||||
/**
|
||||
* Get the indices which are matched to a given file.
|
||||
* @param {ConfigArrayElement[]} elements The elements.
|
||||
* @param {string} filePath The path to a target file.
|
||||
* @returns {number[]} The indices.
|
||||
*/
|
||||
function getMatchedIndices(elements, filePath) {
|
||||
const indices = [];
|
||||
|
||||
for (let i = elements.length - 1; i >= 0; --i) {
|
||||
const element = elements[i];
|
||||
|
||||
if (!element.criteria || (filePath && element.criteria.test(filePath))) {
|
||||
indices.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a value is a non-null object.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if the value is a non-null object.
|
||||
*/
|
||||
function isNonNullObject(x) {
|
||||
return typeof x === "object" && x !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two objects.
|
||||
*
|
||||
* Assign every property values of `y` to `x` if `x` doesn't have the property.
|
||||
* If `x`'s property value is an object, it does recursive.
|
||||
* @param {Object} target The destination to merge
|
||||
* @param {Object|undefined} source The source to merge.
|
||||
* @returns {void}
|
||||
*/
|
||||
function mergeWithoutOverwrite(target, source) {
|
||||
if (!isNonNullObject(source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of Object.keys(source)) {
|
||||
if (key === "__proto__") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isNonNullObject(target[key])) {
|
||||
mergeWithoutOverwrite(target[key], source[key]);
|
||||
} else if (target[key] === void 0) {
|
||||
if (isNonNullObject(source[key])) {
|
||||
target[key] = Array.isArray(source[key]) ? [] : {};
|
||||
mergeWithoutOverwrite(target[key], source[key]);
|
||||
} else if (source[key] !== void 0) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The error for plugin conflicts.
|
||||
*/
|
||||
class PluginConflictError extends Error {
|
||||
|
||||
/**
|
||||
* Initialize this error object.
|
||||
* @param {string} pluginId The plugin ID.
|
||||
* @param {{filePath:string, importerName:string}[]} plugins The resolved plugins.
|
||||
*/
|
||||
constructor(pluginId, plugins) {
|
||||
super(`Plugin "${pluginId}" was conflicted between ${plugins.map(p => `"${p.importerName}"`).join(" and ")}.`);
|
||||
this.messageTemplate = "plugin-conflict";
|
||||
this.messageData = { pluginId, plugins };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge plugins.
|
||||
* `target`'s definition is prior to `source`'s.
|
||||
* @param {Record<string, DependentPlugin>} target The destination to merge
|
||||
* @param {Record<string, DependentPlugin>|undefined} source The source to merge.
|
||||
* @returns {void}
|
||||
*/
|
||||
function mergePlugins(target, source) {
|
||||
if (!isNonNullObject(source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of Object.keys(source)) {
|
||||
if (key === "__proto__") {
|
||||
continue;
|
||||
}
|
||||
const targetValue = target[key];
|
||||
const sourceValue = source[key];
|
||||
|
||||
// Adopt the plugin which was found at first.
|
||||
if (targetValue === void 0) {
|
||||
if (sourceValue.error) {
|
||||
throw sourceValue.error;
|
||||
}
|
||||
target[key] = sourceValue;
|
||||
} else if (sourceValue.filePath !== targetValue.filePath) {
|
||||
throw new PluginConflictError(key, [
|
||||
{
|
||||
filePath: targetValue.filePath,
|
||||
importerName: targetValue.importerName
|
||||
},
|
||||
{
|
||||
filePath: sourceValue.filePath,
|
||||
importerName: sourceValue.importerName
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge rule configs.
|
||||
* `target`'s definition is prior to `source`'s.
|
||||
* @param {Record<string, Array>} target The destination to merge
|
||||
* @param {Record<string, RuleConf>|undefined} source The source to merge.
|
||||
* @returns {void}
|
||||
*/
|
||||
function mergeRuleConfigs(target, source) {
|
||||
if (!isNonNullObject(source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of Object.keys(source)) {
|
||||
if (key === "__proto__") {
|
||||
continue;
|
||||
}
|
||||
const targetDef = target[key];
|
||||
const sourceDef = source[key];
|
||||
|
||||
// Adopt the rule config which was found at first.
|
||||
if (targetDef === void 0) {
|
||||
if (Array.isArray(sourceDef)) {
|
||||
target[key] = [...sourceDef];
|
||||
} else {
|
||||
target[key] = [sourceDef];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the first found rule config is severity only and the current rule
|
||||
* config has options, merge the severity and the options.
|
||||
*/
|
||||
} else if (
|
||||
targetDef.length === 1 &&
|
||||
Array.isArray(sourceDef) &&
|
||||
sourceDef.length >= 2
|
||||
) {
|
||||
targetDef.push(...sourceDef.slice(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extracted config.
|
||||
* @param {ConfigArray} instance The config elements.
|
||||
* @param {number[]} indices The indices to use.
|
||||
* @returns {ExtractedConfig} The extracted config.
|
||||
*/
|
||||
function createConfig(instance, indices) {
|
||||
const config = new ExtractedConfig();
|
||||
const ignorePatterns = [];
|
||||
|
||||
// Merge elements.
|
||||
for (const index of indices) {
|
||||
const element = instance[index];
|
||||
|
||||
// Adopt the parser which was found at first.
|
||||
if (!config.parser && element.parser) {
|
||||
if (element.parser.error) {
|
||||
throw element.parser.error;
|
||||
}
|
||||
config.parser = element.parser;
|
||||
}
|
||||
|
||||
// Adopt the processor which was found at first.
|
||||
if (!config.processor && element.processor) {
|
||||
config.processor = element.processor;
|
||||
}
|
||||
|
||||
// Adopt the noInlineConfig which was found at first.
|
||||
if (config.noInlineConfig === void 0 && element.noInlineConfig !== void 0) {
|
||||
config.noInlineConfig = element.noInlineConfig;
|
||||
config.configNameOfNoInlineConfig = element.name;
|
||||
}
|
||||
|
||||
// Adopt the reportUnusedDisableDirectives which was found at first.
|
||||
if (config.reportUnusedDisableDirectives === void 0 && element.reportUnusedDisableDirectives !== void 0) {
|
||||
config.reportUnusedDisableDirectives = element.reportUnusedDisableDirectives;
|
||||
}
|
||||
|
||||
// Collect ignorePatterns
|
||||
if (element.ignorePattern) {
|
||||
ignorePatterns.push(element.ignorePattern);
|
||||
}
|
||||
|
||||
// Merge others.
|
||||
mergeWithoutOverwrite(config.env, element.env);
|
||||
mergeWithoutOverwrite(config.globals, element.globals);
|
||||
mergeWithoutOverwrite(config.parserOptions, element.parserOptions);
|
||||
mergeWithoutOverwrite(config.settings, element.settings);
|
||||
mergePlugins(config.plugins, element.plugins);
|
||||
mergeRuleConfigs(config.rules, element.rules);
|
||||
}
|
||||
|
||||
// Create the predicate function for ignore patterns.
|
||||
if (ignorePatterns.length > 0) {
|
||||
config.ignores = IgnorePattern.createIgnore(ignorePatterns.reverse());
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect definitions.
|
||||
* @template T, U
|
||||
* @param {string} pluginId The plugin ID for prefix.
|
||||
* @param {Record<string,T>} defs The definitions to collect.
|
||||
* @param {Map<string, U>} map The map to output.
|
||||
* @param {function(T): U} [normalize] The normalize function for each value.
|
||||
* @returns {void}
|
||||
*/
|
||||
function collect(pluginId, defs, map, normalize) {
|
||||
if (defs) {
|
||||
const prefix = pluginId && `${pluginId}/`;
|
||||
|
||||
for (const [key, value] of Object.entries(defs)) {
|
||||
map.set(
|
||||
`${prefix}${key}`,
|
||||
normalize ? normalize(value) : value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a rule definition.
|
||||
* @param {Function|Rule} rule The rule definition to normalize.
|
||||
* @returns {Rule} The normalized rule definition.
|
||||
*/
|
||||
function normalizePluginRule(rule) {
|
||||
return typeof rule === "function" ? { create: rule } : rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the mutation methods from a given map.
|
||||
* @param {Map<any, any>} map The map object to delete.
|
||||
* @returns {void}
|
||||
*/
|
||||
function deleteMutationMethods(map) {
|
||||
Object.defineProperties(map, {
|
||||
clear: { configurable: true, value: void 0 },
|
||||
delete: { configurable: true, value: void 0 },
|
||||
set: { configurable: true, value: void 0 }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array.
|
||||
* @param {ConfigArrayElement[]} elements The config elements.
|
||||
* @param {ConfigArrayInternalSlots} slots The internal slots.
|
||||
* @returns {void}
|
||||
*/
|
||||
function initPluginMemberMaps(elements, slots) {
|
||||
const processed = new Set();
|
||||
|
||||
slots.envMap = new Map();
|
||||
slots.processorMap = new Map();
|
||||
slots.ruleMap = new Map();
|
||||
|
||||
for (const element of elements) {
|
||||
if (!element.plugins) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [pluginId, value] of Object.entries(element.plugins)) {
|
||||
const plugin = value.definition;
|
||||
|
||||
if (!plugin || processed.has(pluginId)) {
|
||||
continue;
|
||||
}
|
||||
processed.add(pluginId);
|
||||
|
||||
collect(pluginId, plugin.environments, slots.envMap);
|
||||
collect(pluginId, plugin.processors, slots.processorMap);
|
||||
collect(pluginId, plugin.rules, slots.ruleMap, normalizePluginRule);
|
||||
}
|
||||
}
|
||||
|
||||
deleteMutationMethods(slots.envMap);
|
||||
deleteMutationMethods(slots.processorMap);
|
||||
deleteMutationMethods(slots.ruleMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array.
|
||||
* @param {ConfigArray} instance The config elements.
|
||||
* @returns {ConfigArrayInternalSlots} The extracted config.
|
||||
*/
|
||||
function ensurePluginMemberMaps(instance) {
|
||||
const slots = internalSlotsMap.get(instance);
|
||||
|
||||
if (!slots.ruleMap) {
|
||||
initPluginMemberMaps(instance, slots);
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The Config Array.
|
||||
*
|
||||
* `ConfigArray` instance contains all settings, parsers, and plugins.
|
||||
* You need to call `ConfigArray#extractConfig(filePath)` method in order to
|
||||
* extract, merge and get only the config data which is related to an arbitrary
|
||||
* file.
|
||||
* @extends {Array<ConfigArrayElement>}
|
||||
*/
|
||||
class ConfigArray extends Array {
|
||||
|
||||
/**
|
||||
* Get the plugin environments.
|
||||
* The returned map cannot be mutated.
|
||||
* @type {ReadonlyMap<string, Environment>} The plugin environments.
|
||||
*/
|
||||
get pluginEnvironments() {
|
||||
return ensurePluginMemberMaps(this).envMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin processors.
|
||||
* The returned map cannot be mutated.
|
||||
* @type {ReadonlyMap<string, Processor>} The plugin processors.
|
||||
*/
|
||||
get pluginProcessors() {
|
||||
return ensurePluginMemberMaps(this).processorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin rules.
|
||||
* The returned map cannot be mutated.
|
||||
* @returns {ReadonlyMap<string, Rule>} The plugin rules.
|
||||
*/
|
||||
get pluginRules() {
|
||||
return ensurePluginMemberMaps(this).ruleMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this config has `root` flag.
|
||||
* @returns {boolean} `true` if this config array is root.
|
||||
*/
|
||||
isRoot() {
|
||||
for (let i = this.length - 1; i >= 0; --i) {
|
||||
const root = this[i].root;
|
||||
|
||||
if (typeof root === "boolean") {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the config data which is related to a given file.
|
||||
* @param {string} filePath The absolute path to the target file.
|
||||
* @returns {ExtractedConfig} The extracted config data.
|
||||
*/
|
||||
extractConfig(filePath) {
|
||||
const { cache } = internalSlotsMap.get(this);
|
||||
const indices = getMatchedIndices(this, filePath);
|
||||
const cacheKey = indices.join(",");
|
||||
|
||||
if (!cache.has(cacheKey)) {
|
||||
cache.set(cacheKey, createConfig(this, indices));
|
||||
}
|
||||
|
||||
return cache.get(cacheKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given path is an additional lint target.
|
||||
* @param {string} filePath The absolute path to the target file.
|
||||
* @returns {boolean} `true` if the file is an additional lint target.
|
||||
*/
|
||||
isAdditionalTargetPath(filePath) {
|
||||
for (const { criteria, type } of this) {
|
||||
if (
|
||||
type === "config" &&
|
||||
criteria &&
|
||||
!criteria.endsWithWildcard &&
|
||||
criteria.test(filePath)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the used extracted configs.
|
||||
* CLIEngine will use this method to collect used deprecated rules.
|
||||
* @param {ConfigArray} instance The config array object to get.
|
||||
* @returns {ExtractedConfig[]} The used extracted configs.
|
||||
* @private
|
||||
*/
|
||||
function getUsedExtractedConfigs(instance) {
|
||||
const { cache } = internalSlotsMap.get(instance);
|
||||
|
||||
return Array.from(cache.values());
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
ConfigArray,
|
||||
getUsedExtractedConfigs
|
||||
};
|
||||
115
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/config-dependency.js
generated
vendored
Normal file
115
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/config-dependency.js
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @fileoverview `ConfigDependency` class.
|
||||
*
|
||||
* `ConfigDependency` class expresses a loaded parser or plugin.
|
||||
*
|
||||
* If the parser or plugin was loaded successfully, it has `definition` property
|
||||
* and `filePath` property. Otherwise, it has `error` property.
|
||||
*
|
||||
* When `JSON.stringify()` converted a `ConfigDependency` object to a JSON, it
|
||||
* omits `definition` property.
|
||||
*
|
||||
* `ConfigArrayFactory` creates `ConfigDependency` objects when it loads parsers
|
||||
* or plugins.
|
||||
*
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
import util from "util";
|
||||
|
||||
/**
|
||||
* The class is to store parsers or plugins.
|
||||
* This class hides the loaded object from `JSON.stringify()` and `console.log`.
|
||||
* @template T
|
||||
*/
|
||||
class ConfigDependency {
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
* @param {Object} data The dependency data.
|
||||
* @param {T} [data.definition] The dependency if the loading succeeded.
|
||||
* @param {Error} [data.error] The error object if the loading failed.
|
||||
* @param {string} [data.filePath] The actual path to the dependency if the loading succeeded.
|
||||
* @param {string} data.id The ID of this dependency.
|
||||
* @param {string} data.importerName The name of the config file which loads this dependency.
|
||||
* @param {string} data.importerPath The path to the config file which loads this dependency.
|
||||
*/
|
||||
constructor({
|
||||
definition = null,
|
||||
error = null,
|
||||
filePath = null,
|
||||
id,
|
||||
importerName,
|
||||
importerPath
|
||||
}) {
|
||||
|
||||
/**
|
||||
* The loaded dependency if the loading succeeded.
|
||||
* @type {T|null}
|
||||
*/
|
||||
this.definition = definition;
|
||||
|
||||
/**
|
||||
* The error object if the loading failed.
|
||||
* @type {Error|null}
|
||||
*/
|
||||
this.error = error;
|
||||
|
||||
/**
|
||||
* The loaded dependency if the loading succeeded.
|
||||
* @type {string|null}
|
||||
*/
|
||||
this.filePath = filePath;
|
||||
|
||||
/**
|
||||
* The ID of this dependency.
|
||||
* @type {string}
|
||||
*/
|
||||
this.id = id;
|
||||
|
||||
/**
|
||||
* The name of the config file which loads this dependency.
|
||||
* @type {string}
|
||||
*/
|
||||
this.importerName = importerName;
|
||||
|
||||
/**
|
||||
* The path to the config file which loads this dependency.
|
||||
* @type {string}
|
||||
*/
|
||||
this.importerPath = importerPath;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line jsdoc/require-description
|
||||
/**
|
||||
* @returns {Object} a JSON compatible object.
|
||||
*/
|
||||
toJSON() {
|
||||
const obj = this[util.inspect.custom]();
|
||||
|
||||
// Display `error.message` (`Error#message` is unenumerable).
|
||||
if (obj.error instanceof Error) {
|
||||
obj.error = { ...obj.error, message: obj.error.message };
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line jsdoc/require-description
|
||||
/**
|
||||
* @returns {Object} an object to display by `console.log()`.
|
||||
*/
|
||||
[util.inspect.custom]() {
|
||||
const {
|
||||
definition: _ignore, // eslint-disable-line no-unused-vars
|
||||
...obj
|
||||
} = this;
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
/** @typedef {ConfigDependency<import("../../shared/types").Parser>} DependentParser */
|
||||
/** @typedef {ConfigDependency<import("../../shared/types").Plugin>} DependentPlugin */
|
||||
|
||||
export { ConfigDependency };
|
||||
145
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/extracted-config.js
generated
vendored
Normal file
145
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/extracted-config.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @fileoverview `ExtractedConfig` class.
|
||||
*
|
||||
* `ExtractedConfig` class expresses a final configuration for a specific file.
|
||||
*
|
||||
* It provides one method.
|
||||
*
|
||||
* - `toCompatibleObjectAsConfigFileContent()`
|
||||
* Convert this configuration to the compatible object as the content of
|
||||
* config files. It converts the loaded parser and plugins to strings.
|
||||
* `CLIEngine#getConfigForFile(filePath)` method uses this method.
|
||||
*
|
||||
* `ConfigArray#extractConfig(filePath)` creates a `ExtractedConfig` instance.
|
||||
*
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
import { IgnorePattern } from "./ignore-pattern.js";
|
||||
|
||||
// For VSCode intellisense
|
||||
/** @typedef {import("../../shared/types").ConfigData} ConfigData */
|
||||
/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */
|
||||
/** @typedef {import("../../shared/types").SeverityConf} SeverityConf */
|
||||
/** @typedef {import("./config-dependency").DependentParser} DependentParser */
|
||||
/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */
|
||||
|
||||
/**
|
||||
* Check if `xs` starts with `ys`.
|
||||
* @template T
|
||||
* @param {T[]} xs The array to check.
|
||||
* @param {T[]} ys The array that may be the first part of `xs`.
|
||||
* @returns {boolean} `true` if `xs` starts with `ys`.
|
||||
*/
|
||||
function startsWith(xs, ys) {
|
||||
return xs.length >= ys.length && ys.every((y, i) => y === xs[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The class for extracted config data.
|
||||
*/
|
||||
class ExtractedConfig {
|
||||
constructor() {
|
||||
|
||||
/**
|
||||
* The config name what `noInlineConfig` setting came from.
|
||||
* @type {string}
|
||||
*/
|
||||
this.configNameOfNoInlineConfig = "";
|
||||
|
||||
/**
|
||||
* Environments.
|
||||
* @type {Record<string, boolean>}
|
||||
*/
|
||||
this.env = {};
|
||||
|
||||
/**
|
||||
* Global variables.
|
||||
* @type {Record<string, GlobalConf>}
|
||||
*/
|
||||
this.globals = {};
|
||||
|
||||
/**
|
||||
* The glob patterns that ignore to lint.
|
||||
* @type {(((filePath:string, dot?:boolean) => boolean) & { basePath:string; patterns:string[] }) | undefined}
|
||||
*/
|
||||
this.ignores = void 0;
|
||||
|
||||
/**
|
||||
* The flag that disables directive comments.
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.noInlineConfig = void 0;
|
||||
|
||||
/**
|
||||
* Parser definition.
|
||||
* @type {DependentParser|null}
|
||||
*/
|
||||
this.parser = null;
|
||||
|
||||
/**
|
||||
* Options for the parser.
|
||||
* @type {Object}
|
||||
*/
|
||||
this.parserOptions = {};
|
||||
|
||||
/**
|
||||
* Plugin definitions.
|
||||
* @type {Record<string, DependentPlugin>}
|
||||
*/
|
||||
this.plugins = {};
|
||||
|
||||
/**
|
||||
* Processor ID.
|
||||
* @type {string|null}
|
||||
*/
|
||||
this.processor = null;
|
||||
|
||||
/**
|
||||
* The flag that reports unused `eslint-disable` directive comments.
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.reportUnusedDisableDirectives = void 0;
|
||||
|
||||
/**
|
||||
* Rule settings.
|
||||
* @type {Record<string, [SeverityConf, ...any[]]>}
|
||||
*/
|
||||
this.rules = {};
|
||||
|
||||
/**
|
||||
* Shared settings.
|
||||
* @type {Object}
|
||||
*/
|
||||
this.settings = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this config to the compatible object as a config file content.
|
||||
* @returns {ConfigData} The converted object.
|
||||
*/
|
||||
toCompatibleObjectAsConfigFileContent() {
|
||||
const {
|
||||
/* eslint-disable no-unused-vars */
|
||||
configNameOfNoInlineConfig: _ignore1,
|
||||
processor: _ignore2,
|
||||
/* eslint-enable no-unused-vars */
|
||||
ignores,
|
||||
...config
|
||||
} = this;
|
||||
|
||||
config.parser = config.parser && config.parser.filePath;
|
||||
config.plugins = Object.keys(config.plugins).filter(Boolean).reverse();
|
||||
config.ignorePatterns = ignores ? ignores.patterns : [];
|
||||
|
||||
// Strip the default patterns from `ignorePatterns`.
|
||||
if (startsWith(config.ignorePatterns, IgnorePattern.DefaultPatterns)) {
|
||||
config.ignorePatterns =
|
||||
config.ignorePatterns.slice(IgnorePattern.DefaultPatterns.length);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
export { ExtractedConfig };
|
||||
238
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/ignore-pattern.js
generated
vendored
Normal file
238
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/ignore-pattern.js
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* @fileoverview `IgnorePattern` class.
|
||||
*
|
||||
* `IgnorePattern` class has the set of glob patterns and the base path.
|
||||
*
|
||||
* It provides two static methods.
|
||||
*
|
||||
* - `IgnorePattern.createDefaultIgnore(cwd)`
|
||||
* Create the default predicate function.
|
||||
* - `IgnorePattern.createIgnore(ignorePatterns)`
|
||||
* Create the predicate function from multiple `IgnorePattern` objects.
|
||||
*
|
||||
* It provides two properties and a method.
|
||||
*
|
||||
* - `patterns`
|
||||
* The glob patterns that ignore to lint.
|
||||
* - `basePath`
|
||||
* The base path of the glob patterns. If absolute paths existed in the
|
||||
* glob patterns, those are handled as relative paths to the base path.
|
||||
* - `getPatternsRelativeTo(basePath)`
|
||||
* Get `patterns` as modified for a given base path. It modifies the
|
||||
* absolute paths in the patterns as prepending the difference of two base
|
||||
* paths.
|
||||
*
|
||||
* `ConfigArrayFactory` creates `IgnorePattern` objects when it processes
|
||||
* `ignorePatterns` properties.
|
||||
*
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import assert from "assert";
|
||||
import path from "path";
|
||||
import ignore from "ignore";
|
||||
import debugOrig from "debug";
|
||||
|
||||
const debug = debugOrig("eslintrc:ignore-pattern");
|
||||
|
||||
/** @typedef {ReturnType<import("ignore").default>} Ignore */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the path to the common ancestor directory of given paths.
|
||||
* @param {string[]} sourcePaths The paths to calculate the common ancestor.
|
||||
* @returns {string} The path to the common ancestor directory.
|
||||
*/
|
||||
function getCommonAncestorPath(sourcePaths) {
|
||||
let result = sourcePaths[0];
|
||||
|
||||
for (let i = 1; i < sourcePaths.length; ++i) {
|
||||
const a = result;
|
||||
const b = sourcePaths[i];
|
||||
|
||||
// Set the shorter one (it's the common ancestor if one includes the other).
|
||||
result = a.length < b.length ? a : b;
|
||||
|
||||
// Set the common ancestor.
|
||||
for (let j = 0, lastSepPos = 0; j < a.length && j < b.length; ++j) {
|
||||
if (a[j] !== b[j]) {
|
||||
result = a.slice(0, lastSepPos);
|
||||
break;
|
||||
}
|
||||
if (a[j] === path.sep) {
|
||||
lastSepPos = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let resolvedResult = result || path.sep;
|
||||
|
||||
// if Windows common ancestor is root of drive must have trailing slash to be absolute.
|
||||
if (resolvedResult && resolvedResult.endsWith(":") && process.platform === "win32") {
|
||||
resolvedResult += path.sep;
|
||||
}
|
||||
return resolvedResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make relative path.
|
||||
* @param {string} from The source path to get relative path.
|
||||
* @param {string} to The destination path to get relative path.
|
||||
* @returns {string} The relative path.
|
||||
*/
|
||||
function relative(from, to) {
|
||||
const relPath = path.relative(from, to);
|
||||
|
||||
if (path.sep === "/") {
|
||||
return relPath;
|
||||
}
|
||||
return relPath.split(path.sep).join("/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the trailing slash if existed.
|
||||
* @param {string} filePath The path to check.
|
||||
* @returns {string} The trailing slash if existed.
|
||||
*/
|
||||
function dirSuffix(filePath) {
|
||||
const isDir = (
|
||||
filePath.endsWith(path.sep) ||
|
||||
(process.platform === "win32" && filePath.endsWith("/"))
|
||||
);
|
||||
|
||||
return isDir ? "/" : "";
|
||||
}
|
||||
|
||||
const DefaultPatterns = Object.freeze(["/**/node_modules/*"]);
|
||||
const DotPatterns = Object.freeze([".*", "!.eslintrc.*", "!../"]);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class IgnorePattern {
|
||||
|
||||
/**
|
||||
* The default patterns.
|
||||
* @type {string[]}
|
||||
*/
|
||||
static get DefaultPatterns() {
|
||||
return DefaultPatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the default predicate function.
|
||||
* @param {string} cwd The current working directory.
|
||||
* @returns {((filePath:string, dot:boolean) => boolean) & {basePath:string; patterns:string[]}}
|
||||
* The preficate function.
|
||||
* The first argument is an absolute path that is checked.
|
||||
* The second argument is the flag to not ignore dotfiles.
|
||||
* If the predicate function returned `true`, it means the path should be ignored.
|
||||
*/
|
||||
static createDefaultIgnore(cwd) {
|
||||
return this.createIgnore([new IgnorePattern(DefaultPatterns, cwd)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the predicate function from multiple `IgnorePattern` objects.
|
||||
* @param {IgnorePattern[]} ignorePatterns The list of ignore patterns.
|
||||
* @returns {((filePath:string, dot?:boolean) => boolean) & {basePath:string; patterns:string[]}}
|
||||
* The preficate function.
|
||||
* The first argument is an absolute path that is checked.
|
||||
* The second argument is the flag to not ignore dotfiles.
|
||||
* If the predicate function returned `true`, it means the path should be ignored.
|
||||
*/
|
||||
static createIgnore(ignorePatterns) {
|
||||
debug("Create with: %o", ignorePatterns);
|
||||
|
||||
const basePath = getCommonAncestorPath(ignorePatterns.map(p => p.basePath));
|
||||
const patterns = [].concat(
|
||||
...ignorePatterns.map(p => p.getPatternsRelativeTo(basePath))
|
||||
);
|
||||
const ig = ignore({ allowRelativePaths: true }).add([...DotPatterns, ...patterns]);
|
||||
const dotIg = ignore({ allowRelativePaths: true }).add(patterns);
|
||||
|
||||
debug(" processed: %o", { basePath, patterns });
|
||||
|
||||
return Object.assign(
|
||||
(filePath, dot = false) => {
|
||||
assert(path.isAbsolute(filePath), "'filePath' should be an absolute path.");
|
||||
const relPathRaw = relative(basePath, filePath);
|
||||
const relPath = relPathRaw && (relPathRaw + dirSuffix(filePath));
|
||||
const adoptedIg = dot ? dotIg : ig;
|
||||
const result = relPath !== "" && adoptedIg.ignores(relPath);
|
||||
|
||||
debug("Check", { filePath, dot, relativePath: relPath, result });
|
||||
return result;
|
||||
},
|
||||
{ basePath, patterns }
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a new `IgnorePattern` instance.
|
||||
* @param {string[]} patterns The glob patterns that ignore to lint.
|
||||
* @param {string} basePath The base path of `patterns`.
|
||||
*/
|
||||
constructor(patterns, basePath) {
|
||||
assert(path.isAbsolute(basePath), "'basePath' should be an absolute path.");
|
||||
|
||||
/**
|
||||
* The glob patterns that ignore to lint.
|
||||
* @type {string[]}
|
||||
*/
|
||||
this.patterns = patterns;
|
||||
|
||||
/**
|
||||
* The base path of `patterns`.
|
||||
* @type {string}
|
||||
*/
|
||||
this.basePath = basePath;
|
||||
|
||||
/**
|
||||
* If `true` then patterns which don't start with `/` will match the paths to the outside of `basePath`. Defaults to `false`.
|
||||
*
|
||||
* It's set `true` for `.eslintignore`, `package.json`, and `--ignore-path` for backward compatibility.
|
||||
* It's `false` as-is for `ignorePatterns` property in config files.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.loose = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get `patterns` as modified for a given base path. It modifies the
|
||||
* absolute paths in the patterns as prepending the difference of two base
|
||||
* paths.
|
||||
* @param {string} newBasePath The base path.
|
||||
* @returns {string[]} Modifired patterns.
|
||||
*/
|
||||
getPatternsRelativeTo(newBasePath) {
|
||||
assert(path.isAbsolute(newBasePath), "'newBasePath' should be an absolute path.");
|
||||
const { basePath, loose, patterns } = this;
|
||||
|
||||
if (newBasePath === basePath) {
|
||||
return patterns;
|
||||
}
|
||||
const prefix = `/${relative(newBasePath, basePath)}`;
|
||||
|
||||
return patterns.map(pattern => {
|
||||
const negative = pattern.startsWith("!");
|
||||
const head = negative ? "!" : "";
|
||||
const body = negative ? pattern.slice(1) : pattern;
|
||||
|
||||
if (body.startsWith("/") || body.startsWith("../")) {
|
||||
return `${head}${prefix}${body}`;
|
||||
}
|
||||
return loose ? pattern : `${head}${prefix}/**/${body}`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { IgnorePattern };
|
||||
19
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/index.js
generated
vendored
Normal file
19
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/index.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @fileoverview `ConfigArray` class.
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
import { ConfigArray, getUsedExtractedConfigs } from "./config-array.js";
|
||||
import { ConfigDependency } from "./config-dependency.js";
|
||||
import { ExtractedConfig } from "./extracted-config.js";
|
||||
import { IgnorePattern } from "./ignore-pattern.js";
|
||||
import { OverrideTester } from "./override-tester.js";
|
||||
|
||||
export {
|
||||
ConfigArray,
|
||||
ConfigDependency,
|
||||
ExtractedConfig,
|
||||
IgnorePattern,
|
||||
OverrideTester,
|
||||
getUsedExtractedConfigs
|
||||
};
|
||||
225
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js
generated
vendored
Normal file
225
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* @fileoverview `OverrideTester` class.
|
||||
*
|
||||
* `OverrideTester` class handles `files` property and `excludedFiles` property
|
||||
* of `overrides` config.
|
||||
*
|
||||
* It provides one method.
|
||||
*
|
||||
* - `test(filePath)`
|
||||
* Test if a file path matches the pair of `files` property and
|
||||
* `excludedFiles` property. The `filePath` argument must be an absolute
|
||||
* path.
|
||||
*
|
||||
* `ConfigArrayFactory` creates `OverrideTester` objects when it processes
|
||||
* `overrides` properties.
|
||||
*
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
import assert from "assert";
|
||||
import path from "path";
|
||||
import util from "util";
|
||||
import minimatch from "minimatch";
|
||||
|
||||
const { Minimatch } = minimatch;
|
||||
|
||||
const minimatchOpts = { dot: true, matchBase: true };
|
||||
|
||||
/**
|
||||
* @typedef {Object} Pattern
|
||||
* @property {InstanceType<Minimatch>[] | null} includes The positive matchers.
|
||||
* @property {InstanceType<Minimatch>[] | null} excludes The negative matchers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Normalize a given pattern to an array.
|
||||
* @param {string|string[]|undefined} patterns A glob pattern or an array of glob patterns.
|
||||
* @returns {string[]|null} Normalized patterns.
|
||||
* @private
|
||||
*/
|
||||
function normalizePatterns(patterns) {
|
||||
if (Array.isArray(patterns)) {
|
||||
return patterns.filter(Boolean);
|
||||
}
|
||||
if (typeof patterns === "string" && patterns) {
|
||||
return [patterns];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the matchers of given patterns.
|
||||
* @param {string[]} patterns The patterns.
|
||||
* @returns {InstanceType<Minimatch>[] | null} The matchers.
|
||||
*/
|
||||
function toMatcher(patterns) {
|
||||
if (patterns.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return patterns.map(pattern => {
|
||||
if (/^\.[/\\]/u.test(pattern)) {
|
||||
return new Minimatch(
|
||||
pattern.slice(2),
|
||||
|
||||
// `./*.js` should not match with `subdir/foo.js`
|
||||
{ ...minimatchOpts, matchBase: false }
|
||||
);
|
||||
}
|
||||
return new Minimatch(pattern, minimatchOpts);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a given matcher to string.
|
||||
* @param {Pattern} matchers The matchers.
|
||||
* @returns {string} The string expression of the matcher.
|
||||
*/
|
||||
function patternToJson({ includes, excludes }) {
|
||||
return {
|
||||
includes: includes && includes.map(m => m.pattern),
|
||||
excludes: excludes && excludes.map(m => m.pattern)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The class to test given paths are matched by the patterns.
|
||||
*/
|
||||
class OverrideTester {
|
||||
|
||||
/**
|
||||
* Create a tester with given criteria.
|
||||
* If there are no criteria, returns `null`.
|
||||
* @param {string|string[]} files The glob patterns for included files.
|
||||
* @param {string|string[]} excludedFiles The glob patterns for excluded files.
|
||||
* @param {string} basePath The path to the base directory to test paths.
|
||||
* @returns {OverrideTester|null} The created instance or `null`.
|
||||
*/
|
||||
static create(files, excludedFiles, basePath) {
|
||||
const includePatterns = normalizePatterns(files);
|
||||
const excludePatterns = normalizePatterns(excludedFiles);
|
||||
let endsWithWildcard = false;
|
||||
|
||||
if (includePatterns.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Rejects absolute paths or relative paths to parents.
|
||||
for (const pattern of includePatterns) {
|
||||
if (path.isAbsolute(pattern) || pattern.includes("..")) {
|
||||
throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`);
|
||||
}
|
||||
if (pattern.endsWith("*")) {
|
||||
endsWithWildcard = true;
|
||||
}
|
||||
}
|
||||
for (const pattern of excludePatterns) {
|
||||
if (path.isAbsolute(pattern) || pattern.includes("..")) {
|
||||
throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`);
|
||||
}
|
||||
}
|
||||
|
||||
const includes = toMatcher(includePatterns);
|
||||
const excludes = toMatcher(excludePatterns);
|
||||
|
||||
return new OverrideTester(
|
||||
[{ includes, excludes }],
|
||||
basePath,
|
||||
endsWithWildcard
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine two testers by logical and.
|
||||
* If either of the testers was `null`, returns the other tester.
|
||||
* The `basePath` property of the two must be the same value.
|
||||
* @param {OverrideTester|null} a A tester.
|
||||
* @param {OverrideTester|null} b Another tester.
|
||||
* @returns {OverrideTester|null} Combined tester.
|
||||
*/
|
||||
static and(a, b) {
|
||||
if (!b) {
|
||||
return a && new OverrideTester(
|
||||
a.patterns,
|
||||
a.basePath,
|
||||
a.endsWithWildcard
|
||||
);
|
||||
}
|
||||
if (!a) {
|
||||
return new OverrideTester(
|
||||
b.patterns,
|
||||
b.basePath,
|
||||
b.endsWithWildcard
|
||||
);
|
||||
}
|
||||
|
||||
assert.strictEqual(a.basePath, b.basePath);
|
||||
return new OverrideTester(
|
||||
a.patterns.concat(b.patterns),
|
||||
a.basePath,
|
||||
a.endsWithWildcard || b.endsWithWildcard
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this instance.
|
||||
* @param {Pattern[]} patterns The matchers.
|
||||
* @param {string} basePath The base path.
|
||||
* @param {boolean} endsWithWildcard If `true` then a pattern ends with `*`.
|
||||
*/
|
||||
constructor(patterns, basePath, endsWithWildcard = false) {
|
||||
|
||||
/** @type {Pattern[]} */
|
||||
this.patterns = patterns;
|
||||
|
||||
/** @type {string} */
|
||||
this.basePath = basePath;
|
||||
|
||||
/** @type {boolean} */
|
||||
this.endsWithWildcard = endsWithWildcard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a given path is matched or not.
|
||||
* @param {string} filePath The absolute path to the target file.
|
||||
* @returns {boolean} `true` if the path was matched.
|
||||
*/
|
||||
test(filePath) {
|
||||
if (typeof filePath !== "string" || !path.isAbsolute(filePath)) {
|
||||
throw new Error(`'filePath' should be an absolute path, but got ${filePath}.`);
|
||||
}
|
||||
const relativePath = path.relative(this.basePath, filePath);
|
||||
|
||||
return this.patterns.every(({ includes, excludes }) => (
|
||||
(!includes || includes.some(m => m.match(relativePath))) &&
|
||||
(!excludes || !excludes.some(m => m.match(relativePath)))
|
||||
));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line jsdoc/require-description
|
||||
/**
|
||||
* @returns {Object} a JSON compatible object.
|
||||
*/
|
||||
toJSON() {
|
||||
if (this.patterns.length === 1) {
|
||||
return {
|
||||
...patternToJson(this.patterns[0]),
|
||||
basePath: this.basePath
|
||||
};
|
||||
}
|
||||
return {
|
||||
AND: this.patterns.map(patternToJson),
|
||||
basePath: this.basePath
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line jsdoc/require-description
|
||||
/**
|
||||
* @returns {Object} an object to display by `console.log()`.
|
||||
*/
|
||||
[util.inspect.custom]() {
|
||||
return this.toJSON();
|
||||
}
|
||||
}
|
||||
|
||||
export { OverrideTester };
|
||||
318
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/flat-compat.js
generated
vendored
Normal file
318
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/flat-compat.js
generated
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* @fileoverview Compatibility class for flat config.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
import createDebug from "debug";
|
||||
import path from "path";
|
||||
|
||||
import environments from "../conf/environments.js";
|
||||
import { ConfigArrayFactory } from "./config-array-factory.js";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("../../shared/types").Environment} Environment */
|
||||
/** @typedef {import("../../shared/types").Processor} Processor */
|
||||
|
||||
const debug = createDebug("eslintrc:flat-compat");
|
||||
const cafactory = Symbol("cafactory");
|
||||
|
||||
/**
|
||||
* Translates an ESLintRC-style config object into a flag-config-style config
|
||||
* object.
|
||||
* @param {Object} eslintrcConfig An ESLintRC-style config object.
|
||||
* @param {Object} options Options to help translate the config.
|
||||
* @param {string} options.resolveConfigRelativeTo To the directory to resolve
|
||||
* configs from.
|
||||
* @param {string} options.resolvePluginsRelativeTo The directory to resolve
|
||||
* plugins from.
|
||||
* @param {ReadOnlyMap<string,Environment>} options.pluginEnvironments A map of plugin environment
|
||||
* names to objects.
|
||||
* @param {ReadOnlyMap<string,Processor>} options.pluginProcessors A map of plugin processor
|
||||
* names to objects.
|
||||
* @returns {Object} A flag-config-style config object.
|
||||
*/
|
||||
function translateESLintRC(eslintrcConfig, {
|
||||
resolveConfigRelativeTo,
|
||||
resolvePluginsRelativeTo,
|
||||
pluginEnvironments,
|
||||
pluginProcessors
|
||||
}) {
|
||||
|
||||
const flatConfig = {};
|
||||
const configs = [];
|
||||
const languageOptions = {};
|
||||
const linterOptions = {};
|
||||
const keysToCopy = ["settings", "rules", "processor"];
|
||||
const languageOptionsKeysToCopy = ["globals", "parser", "parserOptions"];
|
||||
const linterOptionsKeysToCopy = ["noInlineConfig", "reportUnusedDisableDirectives"];
|
||||
|
||||
// copy over simple translations
|
||||
for (const key of keysToCopy) {
|
||||
if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") {
|
||||
flatConfig[key] = eslintrcConfig[key];
|
||||
}
|
||||
}
|
||||
|
||||
// copy over languageOptions
|
||||
for (const key of languageOptionsKeysToCopy) {
|
||||
if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") {
|
||||
|
||||
// create the languageOptions key in the flat config
|
||||
flatConfig.languageOptions = languageOptions;
|
||||
|
||||
if (key === "parser") {
|
||||
debug(`Resolving parser '${languageOptions[key]}' relative to ${resolveConfigRelativeTo}`);
|
||||
|
||||
if (eslintrcConfig[key].error) {
|
||||
throw eslintrcConfig[key].error;
|
||||
}
|
||||
|
||||
languageOptions[key] = eslintrcConfig[key].definition;
|
||||
continue;
|
||||
}
|
||||
|
||||
// clone any object values that are in the eslintrc config
|
||||
if (eslintrcConfig[key] && typeof eslintrcConfig[key] === "object") {
|
||||
languageOptions[key] = {
|
||||
...eslintrcConfig[key]
|
||||
};
|
||||
} else {
|
||||
languageOptions[key] = eslintrcConfig[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy over linterOptions
|
||||
for (const key of linterOptionsKeysToCopy) {
|
||||
if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") {
|
||||
flatConfig.linterOptions = linterOptions;
|
||||
linterOptions[key] = eslintrcConfig[key];
|
||||
}
|
||||
}
|
||||
|
||||
// move ecmaVersion a level up
|
||||
if (languageOptions.parserOptions) {
|
||||
|
||||
if ("ecmaVersion" in languageOptions.parserOptions) {
|
||||
languageOptions.ecmaVersion = languageOptions.parserOptions.ecmaVersion;
|
||||
delete languageOptions.parserOptions.ecmaVersion;
|
||||
}
|
||||
|
||||
if ("sourceType" in languageOptions.parserOptions) {
|
||||
languageOptions.sourceType = languageOptions.parserOptions.sourceType;
|
||||
delete languageOptions.parserOptions.sourceType;
|
||||
}
|
||||
|
||||
// check to see if we even need parserOptions anymore and remove it if not
|
||||
if (Object.keys(languageOptions.parserOptions).length === 0) {
|
||||
delete languageOptions.parserOptions;
|
||||
}
|
||||
}
|
||||
|
||||
// overrides
|
||||
if (eslintrcConfig.criteria) {
|
||||
flatConfig.files = [absoluteFilePath => eslintrcConfig.criteria.test(absoluteFilePath)];
|
||||
}
|
||||
|
||||
// translate plugins
|
||||
if (eslintrcConfig.plugins && typeof eslintrcConfig.plugins === "object") {
|
||||
debug(`Translating plugins: ${eslintrcConfig.plugins}`);
|
||||
|
||||
flatConfig.plugins = {};
|
||||
|
||||
for (const pluginName of Object.keys(eslintrcConfig.plugins)) {
|
||||
|
||||
debug(`Translating plugin: ${pluginName}`);
|
||||
debug(`Resolving plugin '${pluginName} relative to ${resolvePluginsRelativeTo}`);
|
||||
|
||||
const { definition: plugin, error } = eslintrcConfig.plugins[pluginName];
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
flatConfig.plugins[pluginName] = plugin;
|
||||
|
||||
// create a config for any processors
|
||||
if (plugin.processors) {
|
||||
for (const processorName of Object.keys(plugin.processors)) {
|
||||
if (processorName.startsWith(".")) {
|
||||
debug(`Assigning processor: ${pluginName}/${processorName}`);
|
||||
|
||||
configs.unshift({
|
||||
files: [`**/*${processorName}`],
|
||||
processor: pluginProcessors.get(`${pluginName}/${processorName}`)
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// translate env - must come after plugins
|
||||
if (eslintrcConfig.env && typeof eslintrcConfig.env === "object") {
|
||||
for (const envName of Object.keys(eslintrcConfig.env)) {
|
||||
|
||||
// only add environments that are true
|
||||
if (eslintrcConfig.env[envName]) {
|
||||
debug(`Translating environment: ${envName}`);
|
||||
|
||||
if (environments.has(envName)) {
|
||||
|
||||
// built-in environments should be defined first
|
||||
configs.unshift(...translateESLintRC({
|
||||
criteria: eslintrcConfig.criteria,
|
||||
...environments.get(envName)
|
||||
}, {
|
||||
resolveConfigRelativeTo,
|
||||
resolvePluginsRelativeTo
|
||||
}));
|
||||
} else if (pluginEnvironments.has(envName)) {
|
||||
|
||||
// if the environment comes from a plugin, it should come after the plugin config
|
||||
configs.push(...translateESLintRC({
|
||||
criteria: eslintrcConfig.criteria,
|
||||
...pluginEnvironments.get(envName)
|
||||
}, {
|
||||
resolveConfigRelativeTo,
|
||||
resolvePluginsRelativeTo
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only add if there are actually keys in the config
|
||||
if (Object.keys(flatConfig).length > 0) {
|
||||
configs.push(flatConfig);
|
||||
}
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A compatibility class for working with configs.
|
||||
*/
|
||||
class FlatCompat {
|
||||
|
||||
constructor({
|
||||
baseDirectory = process.cwd(),
|
||||
resolvePluginsRelativeTo = baseDirectory,
|
||||
recommendedConfig,
|
||||
allConfig
|
||||
} = {}) {
|
||||
this.baseDirectory = baseDirectory;
|
||||
this.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
|
||||
this[cafactory] = new ConfigArrayFactory({
|
||||
cwd: baseDirectory,
|
||||
resolvePluginsRelativeTo,
|
||||
getEslintAllConfig: () => {
|
||||
|
||||
if (!allConfig) {
|
||||
throw new TypeError("Missing parameter 'allConfig' in FlatCompat constructor.");
|
||||
}
|
||||
|
||||
return allConfig;
|
||||
},
|
||||
getEslintRecommendedConfig: () => {
|
||||
|
||||
if (!recommendedConfig) {
|
||||
throw new TypeError("Missing parameter 'recommendedConfig' in FlatCompat constructor.");
|
||||
}
|
||||
|
||||
return recommendedConfig;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates an ESLintRC-style config into a flag-config-style config.
|
||||
* @param {Object} eslintrcConfig The ESLintRC-style config object.
|
||||
* @returns {Object} A flag-config-style config object.
|
||||
*/
|
||||
config(eslintrcConfig) {
|
||||
const eslintrcArray = this[cafactory].create(eslintrcConfig, {
|
||||
basePath: this.baseDirectory
|
||||
});
|
||||
|
||||
const flatArray = [];
|
||||
let hasIgnorePatterns = false;
|
||||
|
||||
eslintrcArray.forEach(configData => {
|
||||
if (configData.type === "config") {
|
||||
hasIgnorePatterns = hasIgnorePatterns || configData.ignorePattern;
|
||||
flatArray.push(...translateESLintRC(configData, {
|
||||
resolveConfigRelativeTo: path.join(this.baseDirectory, "__placeholder.js"),
|
||||
resolvePluginsRelativeTo: path.join(this.resolvePluginsRelativeTo, "__placeholder.js"),
|
||||
pluginEnvironments: eslintrcArray.pluginEnvironments,
|
||||
pluginProcessors: eslintrcArray.pluginProcessors
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
// combine ignorePatterns to emulate ESLintRC behavior better
|
||||
if (hasIgnorePatterns) {
|
||||
flatArray.unshift({
|
||||
ignores: [filePath => {
|
||||
|
||||
// Compute the final config for this file.
|
||||
// This filters config array elements by `files`/`excludedFiles` then merges the elements.
|
||||
const finalConfig = eslintrcArray.extractConfig(filePath);
|
||||
|
||||
// Test the `ignorePattern` properties of the final config.
|
||||
return Boolean(finalConfig.ignores) && finalConfig.ignores(filePath);
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
return flatArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the `env` section of an ESLintRC-style config.
|
||||
* @param {Object} envConfig The `env` section of an ESLintRC config.
|
||||
* @returns {Object[]} An array of flag-config objects representing the environments.
|
||||
*/
|
||||
env(envConfig) {
|
||||
return this.config({
|
||||
env: envConfig
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the `extends` section of an ESLintRC-style config.
|
||||
* @param {...string} configsToExtend The names of the configs to load.
|
||||
* @returns {Object[]} An array of flag-config objects representing the config.
|
||||
*/
|
||||
extends(...configsToExtend) {
|
||||
return this.config({
|
||||
extends: configsToExtend
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the `plugins` section of an ESLintRC-style config.
|
||||
* @param {...string} plugins The names of the plugins to load.
|
||||
* @returns {Object[]} An array of flag-config objects representing the plugins.
|
||||
*/
|
||||
plugins(...plugins) {
|
||||
return this.config({
|
||||
plugins
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { FlatCompat };
|
||||
29
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/index-universal.js
generated
vendored
Normal file
29
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/index-universal.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @fileoverview Package exports for @eslint/eslintrc
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import * as ConfigOps from "./shared/config-ops.js";
|
||||
import ConfigValidator from "./shared/config-validator.js";
|
||||
import * as naming from "./shared/naming.js";
|
||||
import environments from "../conf/environments.js";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const Legacy = {
|
||||
environments,
|
||||
|
||||
// shared
|
||||
ConfigOps,
|
||||
ConfigValidator,
|
||||
naming
|
||||
};
|
||||
|
||||
export {
|
||||
Legacy
|
||||
};
|
||||
56
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/index.js
generated
vendored
Normal file
56
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @fileoverview Package exports for @eslint/eslintrc
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import {
|
||||
ConfigArrayFactory,
|
||||
createContext as createConfigArrayFactoryContext
|
||||
} from "./config-array-factory.js";
|
||||
|
||||
import { CascadingConfigArrayFactory } from "./cascading-config-array-factory.js";
|
||||
import * as ModuleResolver from "./shared/relative-module-resolver.js";
|
||||
import { ConfigArray, getUsedExtractedConfigs } from "./config-array/index.js";
|
||||
import { ConfigDependency } from "./config-array/config-dependency.js";
|
||||
import { ExtractedConfig } from "./config-array/extracted-config.js";
|
||||
import { IgnorePattern } from "./config-array/ignore-pattern.js";
|
||||
import { OverrideTester } from "./config-array/override-tester.js";
|
||||
import * as ConfigOps from "./shared/config-ops.js";
|
||||
import ConfigValidator from "./shared/config-validator.js";
|
||||
import * as naming from "./shared/naming.js";
|
||||
import { FlatCompat } from "./flat-compat.js";
|
||||
import environments from "../conf/environments.js";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const Legacy = {
|
||||
ConfigArray,
|
||||
createConfigArrayFactoryContext,
|
||||
CascadingConfigArrayFactory,
|
||||
ConfigArrayFactory,
|
||||
ConfigDependency,
|
||||
ExtractedConfig,
|
||||
IgnorePattern,
|
||||
OverrideTester,
|
||||
getUsedExtractedConfigs,
|
||||
environments,
|
||||
|
||||
// shared
|
||||
ConfigOps,
|
||||
ConfigValidator,
|
||||
ModuleResolver,
|
||||
naming
|
||||
};
|
||||
|
||||
export {
|
||||
|
||||
Legacy,
|
||||
|
||||
FlatCompat
|
||||
|
||||
};
|
||||
191
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/ajv.js
generated
vendored
Normal file
191
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/ajv.js
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* @fileoverview The instance of Ajv validator.
|
||||
* @author Evgeny Poberezkin
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import Ajv from "ajv";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Copied from ajv/lib/refs/json-schema-draft-04.json
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2015-2017 Evgeny Poberezkin
|
||||
*/
|
||||
const metaSchema = {
|
||||
id: "http://json-schema.org/draft-04/schema#",
|
||||
$schema: "http://json-schema.org/draft-04/schema#",
|
||||
description: "Core schema meta-schema",
|
||||
definitions: {
|
||||
schemaArray: {
|
||||
type: "array",
|
||||
minItems: 1,
|
||||
items: { $ref: "#" }
|
||||
},
|
||||
positiveInteger: {
|
||||
type: "integer",
|
||||
minimum: 0
|
||||
},
|
||||
positiveIntegerDefault0: {
|
||||
allOf: [{ $ref: "#/definitions/positiveInteger" }, { default: 0 }]
|
||||
},
|
||||
simpleTypes: {
|
||||
enum: ["array", "boolean", "integer", "null", "number", "object", "string"]
|
||||
},
|
||||
stringArray: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
minItems: 1,
|
||||
uniqueItems: true
|
||||
}
|
||||
},
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string"
|
||||
},
|
||||
$schema: {
|
||||
type: "string"
|
||||
},
|
||||
title: {
|
||||
type: "string"
|
||||
},
|
||||
description: {
|
||||
type: "string"
|
||||
},
|
||||
default: { },
|
||||
multipleOf: {
|
||||
type: "number",
|
||||
minimum: 0,
|
||||
exclusiveMinimum: true
|
||||
},
|
||||
maximum: {
|
||||
type: "number"
|
||||
},
|
||||
exclusiveMaximum: {
|
||||
type: "boolean",
|
||||
default: false
|
||||
},
|
||||
minimum: {
|
||||
type: "number"
|
||||
},
|
||||
exclusiveMinimum: {
|
||||
type: "boolean",
|
||||
default: false
|
||||
},
|
||||
maxLength: { $ref: "#/definitions/positiveInteger" },
|
||||
minLength: { $ref: "#/definitions/positiveIntegerDefault0" },
|
||||
pattern: {
|
||||
type: "string",
|
||||
format: "regex"
|
||||
},
|
||||
additionalItems: {
|
||||
anyOf: [
|
||||
{ type: "boolean" },
|
||||
{ $ref: "#" }
|
||||
],
|
||||
default: { }
|
||||
},
|
||||
items: {
|
||||
anyOf: [
|
||||
{ $ref: "#" },
|
||||
{ $ref: "#/definitions/schemaArray" }
|
||||
],
|
||||
default: { }
|
||||
},
|
||||
maxItems: { $ref: "#/definitions/positiveInteger" },
|
||||
minItems: { $ref: "#/definitions/positiveIntegerDefault0" },
|
||||
uniqueItems: {
|
||||
type: "boolean",
|
||||
default: false
|
||||
},
|
||||
maxProperties: { $ref: "#/definitions/positiveInteger" },
|
||||
minProperties: { $ref: "#/definitions/positiveIntegerDefault0" },
|
||||
required: { $ref: "#/definitions/stringArray" },
|
||||
additionalProperties: {
|
||||
anyOf: [
|
||||
{ type: "boolean" },
|
||||
{ $ref: "#" }
|
||||
],
|
||||
default: { }
|
||||
},
|
||||
definitions: {
|
||||
type: "object",
|
||||
additionalProperties: { $ref: "#" },
|
||||
default: { }
|
||||
},
|
||||
properties: {
|
||||
type: "object",
|
||||
additionalProperties: { $ref: "#" },
|
||||
default: { }
|
||||
},
|
||||
patternProperties: {
|
||||
type: "object",
|
||||
additionalProperties: { $ref: "#" },
|
||||
default: { }
|
||||
},
|
||||
dependencies: {
|
||||
type: "object",
|
||||
additionalProperties: {
|
||||
anyOf: [
|
||||
{ $ref: "#" },
|
||||
{ $ref: "#/definitions/stringArray" }
|
||||
]
|
||||
}
|
||||
},
|
||||
enum: {
|
||||
type: "array",
|
||||
minItems: 1,
|
||||
uniqueItems: true
|
||||
},
|
||||
type: {
|
||||
anyOf: [
|
||||
{ $ref: "#/definitions/simpleTypes" },
|
||||
{
|
||||
type: "array",
|
||||
items: { $ref: "#/definitions/simpleTypes" },
|
||||
minItems: 1,
|
||||
uniqueItems: true
|
||||
}
|
||||
]
|
||||
},
|
||||
format: { type: "string" },
|
||||
allOf: { $ref: "#/definitions/schemaArray" },
|
||||
anyOf: { $ref: "#/definitions/schemaArray" },
|
||||
oneOf: { $ref: "#/definitions/schemaArray" },
|
||||
not: { $ref: "#" }
|
||||
},
|
||||
dependencies: {
|
||||
exclusiveMaximum: ["maximum"],
|
||||
exclusiveMinimum: ["minimum"]
|
||||
},
|
||||
default: { }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export default (additionalOptions = {}) => {
|
||||
const ajv = new Ajv({
|
||||
meta: false,
|
||||
useDefaults: true,
|
||||
validateSchema: false,
|
||||
missingRefs: "ignore",
|
||||
verbose: true,
|
||||
schemaId: "auto",
|
||||
...additionalOptions
|
||||
});
|
||||
|
||||
ajv.addMetaSchema(metaSchema);
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
ajv._opts.defaultMeta = metaSchema.id;
|
||||
|
||||
return ajv;
|
||||
};
|
||||
135
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/config-ops.js
generated
vendored
Normal file
135
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/config-ops.js
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @fileoverview Config file operations. This file must be usable in the browser,
|
||||
* so no Node-specific code can be here.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const RULE_SEVERITY_STRINGS = ["off", "warn", "error"],
|
||||
RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => {
|
||||
map[value] = index;
|
||||
return map;
|
||||
}, {}),
|
||||
VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Normalizes the severity value of a rule's configuration to a number
|
||||
* @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally
|
||||
* received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0),
|
||||
* the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array
|
||||
* whose first element is one of the above values. Strings are matched case-insensitively.
|
||||
* @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0.
|
||||
*/
|
||||
function getRuleSeverity(ruleConfig) {
|
||||
const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
|
||||
|
||||
if (severityValue === 0 || severityValue === 1 || severityValue === 2) {
|
||||
return severityValue;
|
||||
}
|
||||
|
||||
if (typeof severityValue === "string") {
|
||||
return RULE_SEVERITY[severityValue.toLowerCase()] || 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts old-style severity settings (0, 1, 2) into new-style
|
||||
* severity settings (off, warn, error) for all rules. Assumption is that severity
|
||||
* values have already been validated as correct.
|
||||
* @param {Object} config The config object to normalize.
|
||||
* @returns {void}
|
||||
*/
|
||||
function normalizeToStrings(config) {
|
||||
|
||||
if (config.rules) {
|
||||
Object.keys(config.rules).forEach(ruleId => {
|
||||
const ruleConfig = config.rules[ruleId];
|
||||
|
||||
if (typeof ruleConfig === "number") {
|
||||
config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0];
|
||||
} else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") {
|
||||
ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the severity for the given rule configuration represents an error.
|
||||
* @param {int|string|Array} ruleConfig The configuration for an individual rule.
|
||||
* @returns {boolean} True if the rule represents an error, false if not.
|
||||
*/
|
||||
function isErrorSeverity(ruleConfig) {
|
||||
return getRuleSeverity(ruleConfig) === 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given config has valid severity or not.
|
||||
* @param {number|string|Array} ruleConfig The configuration for an individual rule.
|
||||
* @returns {boolean} `true` if the configuration has valid severity.
|
||||
*/
|
||||
function isValidSeverity(ruleConfig) {
|
||||
let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
|
||||
|
||||
if (typeof severity === "string") {
|
||||
severity = severity.toLowerCase();
|
||||
}
|
||||
return VALID_SEVERITIES.indexOf(severity) !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether every rule of a given config has valid severity or not.
|
||||
* @param {Object} config The configuration for rules.
|
||||
* @returns {boolean} `true` if the configuration has valid severity.
|
||||
*/
|
||||
function isEverySeverityValid(config) {
|
||||
return Object.keys(config).every(ruleId => isValidSeverity(config[ruleId]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a value for a global in a config
|
||||
* @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in
|
||||
* a global directive comment
|
||||
* @returns {("readable"|"writeable"|"off")} The value normalized as a string
|
||||
* @throws Error if global value is invalid
|
||||
*/
|
||||
function normalizeConfigGlobal(configuredValue) {
|
||||
switch (configuredValue) {
|
||||
case "off":
|
||||
return "off";
|
||||
|
||||
case true:
|
||||
case "true":
|
||||
case "writeable":
|
||||
case "writable":
|
||||
return "writable";
|
||||
|
||||
case null:
|
||||
case false:
|
||||
case "false":
|
||||
case "readable":
|
||||
case "readonly":
|
||||
return "readonly";
|
||||
|
||||
default:
|
||||
throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
getRuleSeverity,
|
||||
normalizeToStrings,
|
||||
isErrorSeverity,
|
||||
isValidSeverity,
|
||||
isEverySeverityValid,
|
||||
normalizeConfigGlobal
|
||||
};
|
||||
325
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/config-validator.js
generated
vendored
Normal file
325
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/config-validator.js
generated
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
/**
|
||||
* @fileoverview Validates configs.
|
||||
* @author Brandon Mills
|
||||
*/
|
||||
|
||||
/* eslint class-methods-use-this: "off" */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import util from "util";
|
||||
import * as ConfigOps from "./config-ops.js";
|
||||
import { emitDeprecationWarning } from "./deprecation-warnings.js";
|
||||
import ajvOrig from "./ajv.js";
|
||||
import configSchema from "../../conf/config-schema.js";
|
||||
import BuiltInEnvironments from "../../conf/environments.js";
|
||||
|
||||
const ajv = ajvOrig();
|
||||
|
||||
const ruleValidators = new WeakMap();
|
||||
const noop = Function.prototype;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
let validateSchema;
|
||||
const severityMap = {
|
||||
error: 2,
|
||||
warn: 1,
|
||||
off: 0
|
||||
};
|
||||
|
||||
const validated = new WeakSet();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
export default class ConfigValidator {
|
||||
constructor({ builtInRules = new Map() } = {}) {
|
||||
this.builtInRules = builtInRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a complete options schema for a rule.
|
||||
* @param {{create: Function, schema: (Array|null)}} rule A new-style rule object
|
||||
* @returns {Object} JSON Schema for the rule's options.
|
||||
*/
|
||||
getRuleOptionsSchema(rule) {
|
||||
if (!rule) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const schema = rule.schema || rule.meta && rule.meta.schema;
|
||||
|
||||
// Given a tuple of schemas, insert warning level at the beginning
|
||||
if (Array.isArray(schema)) {
|
||||
if (schema.length) {
|
||||
return {
|
||||
type: "array",
|
||||
items: schema,
|
||||
minItems: 0,
|
||||
maxItems: schema.length
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: "array",
|
||||
minItems: 0,
|
||||
maxItems: 0
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Given a full schema, leave it alone
|
||||
return schema || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid.
|
||||
* @param {options} options The given options for the rule.
|
||||
* @returns {number|string} The rule's severity value
|
||||
*/
|
||||
validateRuleSeverity(options) {
|
||||
const severity = Array.isArray(options) ? options[0] : options;
|
||||
const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity;
|
||||
|
||||
if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) {
|
||||
return normSeverity;
|
||||
}
|
||||
|
||||
throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the non-severity options passed to a rule, based on its schema.
|
||||
* @param {{create: Function}} rule The rule to validate
|
||||
* @param {Array} localOptions The options for the rule, excluding severity
|
||||
* @returns {void}
|
||||
*/
|
||||
validateRuleSchema(rule, localOptions) {
|
||||
if (!ruleValidators.has(rule)) {
|
||||
const schema = this.getRuleOptionsSchema(rule);
|
||||
|
||||
if (schema) {
|
||||
ruleValidators.set(rule, ajv.compile(schema));
|
||||
}
|
||||
}
|
||||
|
||||
const validateRule = ruleValidators.get(rule);
|
||||
|
||||
if (validateRule) {
|
||||
validateRule(localOptions);
|
||||
if (validateRule.errors) {
|
||||
throw new Error(validateRule.errors.map(
|
||||
error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n`
|
||||
).join(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a rule's options against its schema.
|
||||
* @param {{create: Function}|null} rule The rule that the config is being validated for
|
||||
* @param {string} ruleId The rule's unique name.
|
||||
* @param {Array|number} options The given options for the rule.
|
||||
* @param {string|null} source The name of the configuration source to report in any errors. If null or undefined,
|
||||
* no source is prepended to the message.
|
||||
* @returns {void}
|
||||
*/
|
||||
validateRuleOptions(rule, ruleId, options, source = null) {
|
||||
try {
|
||||
const severity = this.validateRuleSeverity(options);
|
||||
|
||||
if (severity !== 0) {
|
||||
this.validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []);
|
||||
}
|
||||
} catch (err) {
|
||||
const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`;
|
||||
|
||||
if (typeof source === "string") {
|
||||
throw new Error(`${source}:\n\t${enhancedMessage}`);
|
||||
} else {
|
||||
throw new Error(enhancedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an environment object
|
||||
* @param {Object} environment The environment config object to validate.
|
||||
* @param {string} source The name of the configuration source to report in any errors.
|
||||
* @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments.
|
||||
* @returns {void}
|
||||
*/
|
||||
validateEnvironment(
|
||||
environment,
|
||||
source,
|
||||
getAdditionalEnv = noop
|
||||
) {
|
||||
|
||||
// not having an environment is ok
|
||||
if (!environment) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.keys(environment).forEach(id => {
|
||||
const env = getAdditionalEnv(id) || BuiltInEnvironments.get(id) || null;
|
||||
|
||||
if (!env) {
|
||||
const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`;
|
||||
|
||||
throw new Error(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a rules config object
|
||||
* @param {Object} rulesConfig The rules config object to validate.
|
||||
* @param {string} source The name of the configuration source to report in any errors.
|
||||
* @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules
|
||||
* @returns {void}
|
||||
*/
|
||||
validateRules(
|
||||
rulesConfig,
|
||||
source,
|
||||
getAdditionalRule = noop
|
||||
) {
|
||||
if (!rulesConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.keys(rulesConfig).forEach(id => {
|
||||
const rule = getAdditionalRule(id) || this.builtInRules.get(id) || null;
|
||||
|
||||
this.validateRuleOptions(rule, id, rulesConfig[id], source);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a `globals` section of a config file
|
||||
* @param {Object} globalsConfig The `globals` section
|
||||
* @param {string|null} source The name of the configuration source to report in the event of an error.
|
||||
* @returns {void}
|
||||
*/
|
||||
validateGlobals(globalsConfig, source = null) {
|
||||
if (!globalsConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.entries(globalsConfig)
|
||||
.forEach(([configuredGlobal, configuredValue]) => {
|
||||
try {
|
||||
ConfigOps.normalizeConfigGlobal(configuredValue);
|
||||
} catch (err) {
|
||||
throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate `processor` configuration.
|
||||
* @param {string|undefined} processorName The processor name.
|
||||
* @param {string} source The name of config file.
|
||||
* @param {function(id:string): Processor} getProcessor The getter of defined processors.
|
||||
* @returns {void}
|
||||
*/
|
||||
validateProcessor(processorName, source, getProcessor) {
|
||||
if (processorName && !getProcessor(processorName)) {
|
||||
throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an array of schema validation errors.
|
||||
* @param {Array} errors An array of error messages to format.
|
||||
* @returns {string} Formatted error message
|
||||
*/
|
||||
formatErrors(errors) {
|
||||
return errors.map(error => {
|
||||
if (error.keyword === "additionalProperties") {
|
||||
const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty;
|
||||
|
||||
return `Unexpected top-level property "${formattedPropertyPath}"`;
|
||||
}
|
||||
if (error.keyword === "type") {
|
||||
const formattedField = error.dataPath.slice(1);
|
||||
const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema;
|
||||
const formattedValue = JSON.stringify(error.data);
|
||||
|
||||
return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`;
|
||||
}
|
||||
|
||||
const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath;
|
||||
|
||||
return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`;
|
||||
}).map(message => `\t- ${message}.\n`).join("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the top level properties of the config object.
|
||||
* @param {Object} config The config object to validate.
|
||||
* @param {string} source The name of the configuration source to report in any errors.
|
||||
* @returns {void}
|
||||
*/
|
||||
validateConfigSchema(config, source = null) {
|
||||
validateSchema = validateSchema || ajv.compile(configSchema);
|
||||
|
||||
if (!validateSchema(config)) {
|
||||
throw new Error(`ESLint configuration in ${source} is invalid:\n${this.formatErrors(validateSchema.errors)}`);
|
||||
}
|
||||
|
||||
if (Object.hasOwnProperty.call(config, "ecmaFeatures")) {
|
||||
emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an entire config object.
|
||||
* @param {Object} config The config object to validate.
|
||||
* @param {string} source The name of the configuration source to report in any errors.
|
||||
* @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules.
|
||||
* @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs.
|
||||
* @returns {void}
|
||||
*/
|
||||
validate(config, source, getAdditionalRule, getAdditionalEnv) {
|
||||
this.validateConfigSchema(config, source);
|
||||
this.validateRules(config.rules, source, getAdditionalRule);
|
||||
this.validateEnvironment(config.env, source, getAdditionalEnv);
|
||||
this.validateGlobals(config.globals, source);
|
||||
|
||||
for (const override of config.overrides || []) {
|
||||
this.validateRules(override.rules, source, getAdditionalRule);
|
||||
this.validateEnvironment(override.env, source, getAdditionalEnv);
|
||||
this.validateGlobals(config.globals, source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate config array object.
|
||||
* @param {ConfigArray} configArray The config array to validate.
|
||||
* @returns {void}
|
||||
*/
|
||||
validateConfigArray(configArray) {
|
||||
const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments);
|
||||
const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors);
|
||||
const getPluginRule = Map.prototype.get.bind(configArray.pluginRules);
|
||||
|
||||
// Validate.
|
||||
for (const element of configArray) {
|
||||
if (validated.has(element)) {
|
||||
continue;
|
||||
}
|
||||
validated.add(element);
|
||||
|
||||
this.validateEnvironment(element.env, element.name, getPluginEnv);
|
||||
this.validateGlobals(element.globals, element.name);
|
||||
this.validateProcessor(element.processor, element.name, getPluginProcessor);
|
||||
this.validateRules(element.rules, element.name, getPluginRule);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
63
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/deprecation-warnings.js
generated
vendored
Normal file
63
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/deprecation-warnings.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @fileoverview Provide the function that emits deprecation warnings.
|
||||
* @author Toru Nagashima <http://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import path from "path";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Defitions for deprecation warnings.
|
||||
const deprecationWarningMessages = {
|
||||
ESLINT_LEGACY_ECMAFEATURES:
|
||||
"The 'ecmaFeatures' config file property is deprecated and has no effect.",
|
||||
ESLINT_PERSONAL_CONFIG_LOAD:
|
||||
"'~/.eslintrc.*' config files have been deprecated. " +
|
||||
"Please use a config file per project or the '--config' option.",
|
||||
ESLINT_PERSONAL_CONFIG_SUPPRESS:
|
||||
"'~/.eslintrc.*' config files have been deprecated. " +
|
||||
"Please remove it or add 'root:true' to the config files in your " +
|
||||
"projects in order to avoid loading '~/.eslintrc.*' accidentally."
|
||||
};
|
||||
|
||||
const sourceFileErrorCache = new Set();
|
||||
|
||||
/**
|
||||
* Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted
|
||||
* for each unique file path, but repeated invocations with the same file path have no effect.
|
||||
* No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active.
|
||||
* @param {string} source The name of the configuration source to report the warning for.
|
||||
* @param {string} errorCode The warning message to show.
|
||||
* @returns {void}
|
||||
*/
|
||||
function emitDeprecationWarning(source, errorCode) {
|
||||
const cacheKey = JSON.stringify({ source, errorCode });
|
||||
|
||||
if (sourceFileErrorCache.has(cacheKey)) {
|
||||
return;
|
||||
}
|
||||
sourceFileErrorCache.add(cacheKey);
|
||||
|
||||
const rel = path.relative(process.cwd(), source);
|
||||
const message = deprecationWarningMessages[errorCode];
|
||||
|
||||
process.emitWarning(
|
||||
`${message} (found in "${rel}")`,
|
||||
"DeprecationWarning",
|
||||
errorCode
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
emitDeprecationWarning
|
||||
};
|
||||
96
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/naming.js
generated
vendored
Normal file
96
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/naming.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @fileoverview Common helpers for naming of plugins, formatters and configs
|
||||
*/
|
||||
|
||||
const NAMESPACE_REGEX = /^@.*\//iu;
|
||||
|
||||
/**
|
||||
* Brings package name to correct format based on prefix
|
||||
* @param {string} name The name of the package.
|
||||
* @param {string} prefix Can be either "eslint-plugin", "eslint-config" or "eslint-formatter"
|
||||
* @returns {string} Normalized name of the package
|
||||
* @private
|
||||
*/
|
||||
function normalizePackageName(name, prefix) {
|
||||
let normalizedName = name;
|
||||
|
||||
/**
|
||||
* On Windows, name can come in with Windows slashes instead of Unix slashes.
|
||||
* Normalize to Unix first to avoid errors later on.
|
||||
* https://github.com/eslint/eslint/issues/5644
|
||||
*/
|
||||
if (normalizedName.includes("\\")) {
|
||||
normalizedName = normalizedName.replace(/\\/gu, "/");
|
||||
}
|
||||
|
||||
if (normalizedName.charAt(0) === "@") {
|
||||
|
||||
/**
|
||||
* it's a scoped package
|
||||
* package name is the prefix, or just a username
|
||||
*/
|
||||
const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`, "u"),
|
||||
scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`, "u");
|
||||
|
||||
if (scopedPackageShortcutRegex.test(normalizedName)) {
|
||||
normalizedName = normalizedName.replace(scopedPackageShortcutRegex, `$1/${prefix}`);
|
||||
} else if (!scopedPackageNameRegex.test(normalizedName.split("/")[1])) {
|
||||
|
||||
/**
|
||||
* for scoped packages, insert the prefix after the first / unless
|
||||
* the path is already @scope/eslint or @scope/eslint-xxx-yyy
|
||||
*/
|
||||
normalizedName = normalizedName.replace(/^@([^/]+)\/(.*)$/u, `@$1/${prefix}-$2`);
|
||||
}
|
||||
} else if (!normalizedName.startsWith(`${prefix}-`)) {
|
||||
normalizedName = `${prefix}-${normalizedName}`;
|
||||
}
|
||||
|
||||
return normalizedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the prefix from a fullname.
|
||||
* @param {string} fullname The term which may have the prefix.
|
||||
* @param {string} prefix The prefix to remove.
|
||||
* @returns {string} The term without prefix.
|
||||
*/
|
||||
function getShorthandName(fullname, prefix) {
|
||||
if (fullname[0] === "@") {
|
||||
let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`, "u").exec(fullname);
|
||||
|
||||
if (matchResult) {
|
||||
return matchResult[1];
|
||||
}
|
||||
|
||||
matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`, "u").exec(fullname);
|
||||
if (matchResult) {
|
||||
return `${matchResult[1]}/${matchResult[2]}`;
|
||||
}
|
||||
} else if (fullname.startsWith(`${prefix}-`)) {
|
||||
return fullname.slice(prefix.length + 1);
|
||||
}
|
||||
|
||||
return fullname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scope (namespace) of a term.
|
||||
* @param {string} term The term which may have the namespace.
|
||||
* @returns {string} The namespace of the term if it has one.
|
||||
*/
|
||||
function getNamespaceFromTerm(term) {
|
||||
const match = term.match(NAMESPACE_REGEX);
|
||||
|
||||
return match ? match[0] : "";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
normalizePackageName,
|
||||
getShorthandName,
|
||||
getNamespaceFromTerm
|
||||
};
|
||||
42
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/relative-module-resolver.js
generated
vendored
Normal file
42
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/relative-module-resolver.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Utility for resolving a module relative to another module
|
||||
* @author Teddy Katz
|
||||
*/
|
||||
|
||||
import Module from "module";
|
||||
|
||||
/*
|
||||
* `Module.createRequire` is added in v12.2.0. It supports URL as well.
|
||||
* We only support the case where the argument is a filepath, not a URL.
|
||||
*/
|
||||
const createRequire = Module.createRequire;
|
||||
|
||||
/**
|
||||
* Resolves a Node module relative to another module
|
||||
* @param {string} moduleName The name of a Node module, or a path to a Node module.
|
||||
* @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be
|
||||
* a file rather than a directory, but the file need not actually exist.
|
||||
* @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath`
|
||||
*/
|
||||
function resolve(moduleName, relativeToPath) {
|
||||
try {
|
||||
return createRequire(relativeToPath).resolve(moduleName);
|
||||
} catch (error) {
|
||||
|
||||
// This `if` block is for older Node.js than 12.0.0. We can remove this block in the future.
|
||||
if (
|
||||
typeof error === "object" &&
|
||||
error !== null &&
|
||||
error.code === "MODULE_NOT_FOUND" &&
|
||||
!error.requireStack &&
|
||||
error.message.includes(moduleName)
|
||||
) {
|
||||
error.message += `\nRequire stack:\n- ${relativeToPath}`;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
resolve
|
||||
};
|
||||
149
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/types.js
generated
vendored
Normal file
149
desktops/hyprland/ags/node_modules/@eslint/eslintrc/lib/shared/types.js
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @fileoverview Define common types for input completion.
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
/** @type {any} */
|
||||
export default {};
|
||||
|
||||
/** @typedef {boolean | "off" | "readable" | "readonly" | "writable" | "writeable"} GlobalConf */
|
||||
/** @typedef {0 | 1 | 2 | "off" | "warn" | "error"} SeverityConf */
|
||||
/** @typedef {SeverityConf | [SeverityConf, ...any[]]} RuleConf */
|
||||
|
||||
/**
|
||||
* @typedef {Object} EcmaFeatures
|
||||
* @property {boolean} [globalReturn] Enabling `return` statements at the top-level.
|
||||
* @property {boolean} [jsx] Enabling JSX syntax.
|
||||
* @property {boolean} [impliedStrict] Enabling strict mode always.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ParserOptions
|
||||
* @property {EcmaFeatures} [ecmaFeatures] The optional features.
|
||||
* @property {3|5|6|7|8|9|10|11|12|2015|2016|2017|2018|2019|2020|2021} [ecmaVersion] The ECMAScript version (or revision number).
|
||||
* @property {"script"|"module"} [sourceType] The source code type.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ConfigData
|
||||
* @property {Record<string, boolean>} [env] The environment settings.
|
||||
* @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
|
||||
* @property {Record<string, GlobalConf>} [globals] The global variable settings.
|
||||
* @property {string | string[]} [ignorePatterns] The glob patterns that ignore to lint.
|
||||
* @property {boolean} [noInlineConfig] The flag that disables directive comments.
|
||||
* @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
|
||||
* @property {string} [parser] The path to a parser or the package name of a parser.
|
||||
* @property {ParserOptions} [parserOptions] The parser options.
|
||||
* @property {string[]} [plugins] The plugin specifiers.
|
||||
* @property {string} [processor] The processor specifier.
|
||||
* @property {boolean} [reportUnusedDisableDirectives] The flag to report unused `eslint-disable` comments.
|
||||
* @property {boolean} [root] The root flag.
|
||||
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
||||
* @property {Object} [settings] The shared settings.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} OverrideConfigData
|
||||
* @property {Record<string, boolean>} [env] The environment settings.
|
||||
* @property {string | string[]} [excludedFiles] The glob pattarns for excluded files.
|
||||
* @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
|
||||
* @property {string | string[]} files The glob patterns for target files.
|
||||
* @property {Record<string, GlobalConf>} [globals] The global variable settings.
|
||||
* @property {boolean} [noInlineConfig] The flag that disables directive comments.
|
||||
* @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
|
||||
* @property {string} [parser] The path to a parser or the package name of a parser.
|
||||
* @property {ParserOptions} [parserOptions] The parser options.
|
||||
* @property {string[]} [plugins] The plugin specifiers.
|
||||
* @property {string} [processor] The processor specifier.
|
||||
* @property {boolean} [reportUnusedDisableDirectives] The flag to report unused `eslint-disable` comments.
|
||||
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
||||
* @property {Object} [settings] The shared settings.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ParseResult
|
||||
* @property {Object} ast The AST.
|
||||
* @property {ScopeManager} [scopeManager] The scope manager of the AST.
|
||||
* @property {Record<string, any>} [services] The services that the parser provides.
|
||||
* @property {Record<string, string[]>} [visitorKeys] The visitor keys of the AST.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Parser
|
||||
* @property {(text:string, options:ParserOptions) => Object} parse The definition of global variables.
|
||||
* @property {(text:string, options:ParserOptions) => ParseResult} [parseForESLint] The parser options that will be enabled under this environment.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Environment
|
||||
* @property {Record<string, GlobalConf>} [globals] The definition of global variables.
|
||||
* @property {ParserOptions} [parserOptions] The parser options that will be enabled under this environment.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} LintMessage
|
||||
* @property {number} column The 1-based column number.
|
||||
* @property {number} [endColumn] The 1-based column number of the end location.
|
||||
* @property {number} [endLine] The 1-based line number of the end location.
|
||||
* @property {boolean} fatal If `true` then this is a fatal error.
|
||||
* @property {{range:[number,number], text:string}} [fix] Information for autofix.
|
||||
* @property {number} line The 1-based line number.
|
||||
* @property {string} message The error message.
|
||||
* @property {string|null} ruleId The ID of the rule which makes this message.
|
||||
* @property {0|1|2} severity The severity of this message.
|
||||
* @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SuggestionResult
|
||||
* @property {string} desc A short description.
|
||||
* @property {string} [messageId] Id referencing a message for the description.
|
||||
* @property {{ text: string, range: number[] }} fix fix result info
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Processor
|
||||
* @property {(text:string, filename:string) => Array<string | { text:string, filename:string }>} [preprocess] The function to extract code blocks.
|
||||
* @property {(messagesList:LintMessage[][], filename:string) => LintMessage[]} [postprocess] The function to merge messages.
|
||||
* @property {boolean} [supportsAutofix] If `true` then it means the processor supports autofix.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RuleMetaDocs
|
||||
* @property {string} category The category of the rule.
|
||||
* @property {string} description The description of the rule.
|
||||
* @property {boolean} recommended If `true` then the rule is included in `eslint:recommended` preset.
|
||||
* @property {string} url The URL of the rule documentation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RuleMeta
|
||||
* @property {boolean} [deprecated] If `true` then the rule has been deprecated.
|
||||
* @property {RuleMetaDocs} docs The document information of the rule.
|
||||
* @property {"code"|"whitespace"} [fixable] The autofix type.
|
||||
* @property {Record<string,string>} [messages] The messages the rule reports.
|
||||
* @property {string[]} [replacedBy] The IDs of the alternative rules.
|
||||
* @property {Array|Object} schema The option schema of the rule.
|
||||
* @property {"problem"|"suggestion"|"layout"} type The rule type.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Rule
|
||||
* @property {Function} create The factory of the rule.
|
||||
* @property {RuleMeta} meta The meta data of the rule.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Plugin
|
||||
* @property {Record<string, ConfigData>} [configs] The definition of plugin configs.
|
||||
* @property {Record<string, Environment>} [environments] The definition of plugin environments.
|
||||
* @property {Record<string, Processor>} [processors] The definition of plugin processors.
|
||||
* @property {Record<string, Function | Rule>} [rules] The definition of plugin rules.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Information of deprecated rules.
|
||||
* @typedef {Object} DeprecatedRuleInfo
|
||||
* @property {string} ruleId The rule ID.
|
||||
* @property {string[]} replacedBy The rule IDs that replace this deprecated rule.
|
||||
*/
|
||||
82
desktops/hyprland/ags/node_modules/@eslint/eslintrc/package.json
generated
vendored
Normal file
82
desktops/hyprland/ags/node_modules/@eslint/eslintrc/package.json
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "@eslint/eslintrc",
|
||||
"version": "2.1.3",
|
||||
"description": "The legacy ESLintRC config file format for ESLint",
|
||||
"type": "module",
|
||||
"main": "./dist/eslintrc.cjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./lib/index.js",
|
||||
"require": "./dist/eslintrc.cjs"
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
"./universal": {
|
||||
"import": "./lib/index-universal.js",
|
||||
"require": "./dist/eslintrc-universal.cjs"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"lib",
|
||||
"conf",
|
||||
"LICENSE",
|
||||
"dist",
|
||||
"universal.js"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"lint": "eslint . --report-unused-disable-directives",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"prepare": "npm run build",
|
||||
"release:generate:latest": "eslint-generate-release",
|
||||
"release:generate:alpha": "eslint-generate-prerelease alpha",
|
||||
"release:generate:beta": "eslint-generate-prerelease beta",
|
||||
"release:generate:rc": "eslint-generate-prerelease rc",
|
||||
"release:publish": "eslint-publish-release",
|
||||
"test": "mocha -R progress -c 'tests/lib/*.cjs' && c8 mocha -R progress -c 'tests/lib/**/*.js'"
|
||||
},
|
||||
"repository": "eslint/eslintrc",
|
||||
"funding": "https://opencollective.com/eslint",
|
||||
"keywords": [
|
||||
"ESLint",
|
||||
"ESLintRC",
|
||||
"Configuration"
|
||||
],
|
||||
"author": "Nicholas C. Zakas",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/eslint/eslintrc/issues"
|
||||
},
|
||||
"homepage": "https://github.com/eslint/eslintrc#readme",
|
||||
"devDependencies": {
|
||||
"c8": "^7.7.3",
|
||||
"chai": "^4.3.4",
|
||||
"eslint": "^7.31.0",
|
||||
"eslint-config-eslint": "^7.0.0",
|
||||
"eslint-plugin-jsdoc": "^35.4.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-release": "^3.2.0",
|
||||
"fs-teardown": "^0.1.3",
|
||||
"mocha": "^9.0.3",
|
||||
"rollup": "^2.70.1",
|
||||
"shelljs": "^0.8.4",
|
||||
"sinon": "^11.1.2",
|
||||
"temp-dir": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.6.0",
|
||||
"globals": "^13.19.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.1.2",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
}
|
||||
9
desktops/hyprland/ags/node_modules/@eslint/eslintrc/universal.js
generated
vendored
Normal file
9
desktops/hyprland/ags/node_modules/@eslint/eslintrc/universal.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// Jest (and probably some other runtimes with custom implementations of
|
||||
// `require`) doesn't support `exports` in `package.json`, so this file is here
|
||||
// to help them load this module. Note that it is also `.js` and not `.cjs` for
|
||||
// the same reason - `cjs` files requires to be loaded with an extension, but
|
||||
// since Jest doesn't respect `module` outside of ESM mode it still works in
|
||||
// this case (and the `require` in _this_ file does specify the extension).
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
module.exports = require("./dist/eslintrc-universal.cjs");
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user