mirror of
https://github.com/SupertigerDev/waybar-online.git
synced 2026-03-24 08:06:37 +00:00
huge changes
This commit is contained in:
@@ -4,10 +4,13 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link href="/fontawesome/css/fontawesome.min.css" rel="stylesheet" />
|
||||||
|
<link href="/fontawesome/css/solid.min.css" rel="stylesheet" />
|
||||||
<title>Vite + TS</title>
|
<title>Vite + TS</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -11,5 +11,10 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "~5.8.3",
|
"typescript": "~5.8.3",
|
||||||
"vite": "^7.0.4"
|
"vite": "^7.0.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@adobe/css-tools": "^4.4.3",
|
||||||
|
"@tbela99/css-parser": "^1.1.1",
|
||||||
|
"jsonc-parser": "^3.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
147
pnpm-lock.yaml
generated
147
pnpm-lock.yaml
generated
@@ -7,16 +7,29 @@ settings:
|
|||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@adobe/css-tools':
|
||||||
|
specifier: ^4.4.3
|
||||||
|
version: 4.4.3
|
||||||
|
'@tbela99/css-parser':
|
||||||
|
specifier: ^1.1.1
|
||||||
|
version: 1.1.1
|
||||||
|
jsonc-parser:
|
||||||
|
specifier: ^3.3.1
|
||||||
|
version: 3.3.1
|
||||||
devDependencies:
|
devDependencies:
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ~5.8.3
|
specifier: ~5.8.3
|
||||||
version: 5.8.3
|
version: 5.8.3
|
||||||
vite:
|
vite:
|
||||||
specifier: ^7.0.4
|
specifier: ^7.0.4
|
||||||
version: 7.0.6
|
version: 7.0.6(lightningcss@1.30.1)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
'@adobe/css-tools@4.4.3':
|
||||||
|
resolution: {integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.8':
|
'@esbuild/aix-ppc64@0.25.8':
|
||||||
resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==}
|
resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -273,9 +286,16 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
|
'@tbela99/css-parser@1.1.1':
|
||||||
|
resolution: {integrity: sha512-LYHrxZ//mJlsb1R43dYIZNgN917LCh9OtPJi+02T2jYSXvPmVFAFOHu38HF6XPFeIr3ws8BhcoGi9XvD5Jdi9g==}
|
||||||
|
|
||||||
'@types/estree@1.0.8':
|
'@types/estree@1.0.8':
|
||||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||||
|
|
||||||
|
detect-libc@2.0.4:
|
||||||
|
resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
esbuild@0.25.8:
|
esbuild@0.25.8:
|
||||||
resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==}
|
resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -294,6 +314,73 @@ packages:
|
|||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
|
jsonc-parser@3.3.1:
|
||||||
|
resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
|
||||||
|
|
||||||
|
lightningcss-darwin-arm64@1.30.1:
|
||||||
|
resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
lightningcss-darwin-x64@1.30.1:
|
||||||
|
resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
lightningcss-freebsd-x64@1.30.1:
|
||||||
|
resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [freebsd]
|
||||||
|
|
||||||
|
lightningcss-linux-arm-gnueabihf@1.30.1:
|
||||||
|
resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-gnu@1.30.1:
|
||||||
|
resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-musl@1.30.1:
|
||||||
|
resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-x64-gnu@1.30.1:
|
||||||
|
resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-linux-x64-musl@1.30.1:
|
||||||
|
resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
lightningcss-win32-arm64-msvc@1.30.1:
|
||||||
|
resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
lightningcss-win32-x64-msvc@1.30.1:
|
||||||
|
resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
lightningcss@1.30.1:
|
||||||
|
resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==}
|
||||||
|
engines: {node: '>= 12.0.0'}
|
||||||
|
|
||||||
nanoid@3.3.11:
|
nanoid@3.3.11:
|
||||||
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
@@ -370,6 +457,8 @@ packages:
|
|||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
|
'@adobe/css-tools@4.4.3': {}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.8':
|
'@esbuild/aix-ppc64@0.25.8':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -508,8 +597,13 @@ snapshots:
|
|||||||
'@rollup/rollup-win32-x64-msvc@4.46.2':
|
'@rollup/rollup-win32-x64-msvc@4.46.2':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@tbela99/css-parser@1.1.1': {}
|
||||||
|
|
||||||
'@types/estree@1.0.8': {}
|
'@types/estree@1.0.8': {}
|
||||||
|
|
||||||
|
detect-libc@2.0.4:
|
||||||
|
optional: true
|
||||||
|
|
||||||
esbuild@0.25.8:
|
esbuild@0.25.8:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@esbuild/aix-ppc64': 0.25.8
|
'@esbuild/aix-ppc64': 0.25.8
|
||||||
@@ -546,6 +640,54 @@ snapshots:
|
|||||||
fsevents@2.3.3:
|
fsevents@2.3.3:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
jsonc-parser@3.3.1: {}
|
||||||
|
|
||||||
|
lightningcss-darwin-arm64@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-darwin-x64@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-freebsd-x64@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-arm-gnueabihf@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-gnu@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-arm64-musl@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-x64-gnu@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-linux-x64-musl@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-win32-arm64-msvc@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss-win32-x64-msvc@1.30.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
lightningcss@1.30.1:
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 2.0.4
|
||||||
|
optionalDependencies:
|
||||||
|
lightningcss-darwin-arm64: 1.30.1
|
||||||
|
lightningcss-darwin-x64: 1.30.1
|
||||||
|
lightningcss-freebsd-x64: 1.30.1
|
||||||
|
lightningcss-linux-arm-gnueabihf: 1.30.1
|
||||||
|
lightningcss-linux-arm64-gnu: 1.30.1
|
||||||
|
lightningcss-linux-arm64-musl: 1.30.1
|
||||||
|
lightningcss-linux-x64-gnu: 1.30.1
|
||||||
|
lightningcss-linux-x64-musl: 1.30.1
|
||||||
|
lightningcss-win32-arm64-msvc: 1.30.1
|
||||||
|
lightningcss-win32-x64-msvc: 1.30.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
nanoid@3.3.11: {}
|
nanoid@3.3.11: {}
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
@@ -593,7 +735,7 @@ snapshots:
|
|||||||
|
|
||||||
typescript@5.8.3: {}
|
typescript@5.8.3: {}
|
||||||
|
|
||||||
vite@7.0.6:
|
vite@7.0.6(lightningcss@1.30.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.25.8
|
esbuild: 0.25.8
|
||||||
fdir: 6.4.6(picomatch@4.0.3)
|
fdir: 6.4.6(picomatch@4.0.3)
|
||||||
@@ -603,3 +745,4 @@ snapshots:
|
|||||||
tinyglobby: 0.2.14
|
tinyglobby: 0.2.14
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
lightningcss: 1.30.1
|
||||||
|
|||||||
BIN
public/bg.avif
Normal file
BIN
public/bg.avif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 394 KiB |
8349
public/fontawesome/css/fontawesome.css
vendored
Normal file
8349
public/fontawesome/css/fontawesome.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
public/fontawesome/css/fontawesome.min.css
vendored
Normal file
8
public/fontawesome/css/fontawesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
32
public/fontawesome/css/solid.css
vendored
Normal file
32
public/fontawesome/css/solid.css
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:root,
|
||||||
|
:host {
|
||||||
|
--fa-family-classic: "Font Awesome 7 Free";
|
||||||
|
--fa-font-solid: normal 900 1em/1 var(--fa-family-classic);
|
||||||
|
/* deprecated: this older custom property will be removed next major release */
|
||||||
|
--fa-style-family-classic: var(--fa-family-classic);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Font Awesome 7 Free";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: block;
|
||||||
|
src: url("../webfonts/fa-solid-900.woff2");
|
||||||
|
}
|
||||||
|
.fas {
|
||||||
|
--fa-family: var(--fa-family-classic);
|
||||||
|
--fa-style: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-classic {
|
||||||
|
--fa-family: var(--fa-family-classic);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-solid {
|
||||||
|
--fa-style: 900;
|
||||||
|
}
|
||||||
6
public/fontawesome/css/solid.min.css
vendored
Normal file
6
public/fontawesome/css/solid.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:host,:root{--fa-family-classic:"Font Awesome 7 Free";--fa-font-solid:normal 900 1em/1 var(--fa-family-classic);--fa-style-family-classic:var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2)}.fas{--fa-style:900}.fa-classic,.fas{--fa-family:var(--fa-family-classic)}.fa-solid{--fa-style:900}
|
||||||
BIN
public/fontawesome/webfonts/fa-solid-900.woff2
Normal file
BIN
public/fontawesome/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
219
public/resources/config.jsonc
Normal file
219
public/resources/config.jsonc
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
// -*- mode: jsonc -*-
|
||||||
|
{
|
||||||
|
// "layer": "top", // Waybar at top layer
|
||||||
|
// "position": "bottom", // Waybar position (top|bottom|left|right)
|
||||||
|
"height": 30, // Waybar height (to be removed for auto height)
|
||||||
|
// "width": 1280, // Waybar width
|
||||||
|
"spacing": 4, // Gaps between modules (4px)
|
||||||
|
// Choose the order of the modules
|
||||||
|
"modules-left": [
|
||||||
|
"sway/workspaces",
|
||||||
|
"sway/mode",
|
||||||
|
"sway/scratchpad",
|
||||||
|
"custom/media"
|
||||||
|
],
|
||||||
|
"modules-center": [
|
||||||
|
"sway/window"
|
||||||
|
],
|
||||||
|
"modules-right": [
|
||||||
|
"mpd",
|
||||||
|
"idle_inhibitor",
|
||||||
|
"pulseaudio",
|
||||||
|
"network",
|
||||||
|
"power-profiles-daemon",
|
||||||
|
"cpu",
|
||||||
|
"memory",
|
||||||
|
"temperature",
|
||||||
|
"backlight",
|
||||||
|
"keyboard-state",
|
||||||
|
"sway/language",
|
||||||
|
"battery",
|
||||||
|
"battery#bat2",
|
||||||
|
"clock",
|
||||||
|
"tray",
|
||||||
|
"custom/power"
|
||||||
|
],
|
||||||
|
// Modules configuration
|
||||||
|
// "sway/workspaces": {
|
||||||
|
// "disable-scroll": true,
|
||||||
|
// "all-outputs": true,
|
||||||
|
// "warp-on-scroll": false,
|
||||||
|
// "format": "{name}: {icon}",
|
||||||
|
// "format-icons": {
|
||||||
|
// "1": "",
|
||||||
|
// "2": "",
|
||||||
|
// "3": "",
|
||||||
|
// "4": "",
|
||||||
|
// "5": "",
|
||||||
|
// "urgent": "",
|
||||||
|
// "focused": "",
|
||||||
|
// "default": ""
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
"keyboard-state": {
|
||||||
|
"numlock": true,
|
||||||
|
"capslock": true,
|
||||||
|
"format": "{name} {icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"locked": "",
|
||||||
|
"unlocked": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sway/mode": {
|
||||||
|
"format": "<span style=\"italic\">{}</span>"
|
||||||
|
},
|
||||||
|
"sway/scratchpad": {
|
||||||
|
"format": "{icon} {count}",
|
||||||
|
"show-empty": false,
|
||||||
|
"format-icons": ["", ""],
|
||||||
|
"tooltip": true,
|
||||||
|
"tooltip-format": "{app}: {title}"
|
||||||
|
},
|
||||||
|
"mpd": {
|
||||||
|
"format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ",
|
||||||
|
"format-disconnected": "Disconnected ",
|
||||||
|
"format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ",
|
||||||
|
"unknown-tag": "N/A",
|
||||||
|
"interval": 5,
|
||||||
|
"consume-icons": {
|
||||||
|
"on": " "
|
||||||
|
},
|
||||||
|
"random-icons": {
|
||||||
|
"off": "<span color=\"#f53c3c\"></span> ",
|
||||||
|
"on": " "
|
||||||
|
},
|
||||||
|
"repeat-icons": {
|
||||||
|
"on": " "
|
||||||
|
},
|
||||||
|
"single-icons": {
|
||||||
|
"on": "1 "
|
||||||
|
},
|
||||||
|
"state-icons": {
|
||||||
|
"paused": "",
|
||||||
|
"playing": ""
|
||||||
|
},
|
||||||
|
"tooltip-format": "MPD (connected)",
|
||||||
|
"tooltip-format-disconnected": "MPD (disconnected)"
|
||||||
|
},
|
||||||
|
"idle_inhibitor": {
|
||||||
|
"format": "{icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"activated": "",
|
||||||
|
"deactivated": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tray": {
|
||||||
|
// "icon-size": 21,
|
||||||
|
"spacing": 10,
|
||||||
|
// "icons": {
|
||||||
|
// "blueman": "bluetooth",
|
||||||
|
// "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png"
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
"clock": {
|
||||||
|
// "timezone": "America/New_York",
|
||||||
|
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
|
||||||
|
"format-alt": "{:%Y-%m-%d}"
|
||||||
|
},
|
||||||
|
"cpu": {
|
||||||
|
"format": "{usage}% ",
|
||||||
|
"tooltip": false
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
"format": "{}% "
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
// "thermal-zone": 2,
|
||||||
|
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
|
||||||
|
"critical-threshold": 80,
|
||||||
|
// "format-critical": "{temperatureC}°C {icon}",
|
||||||
|
"format": "{temperatureC}°C {icon}",
|
||||||
|
"format-icons": ["", "", ""]
|
||||||
|
},
|
||||||
|
"backlight": {
|
||||||
|
// "device": "acpi_video1",
|
||||||
|
"format": "{percent}% {icon}",
|
||||||
|
"format-icons": ["", "", "", "", "", "", "", "", ""]
|
||||||
|
},
|
||||||
|
"battery": {
|
||||||
|
"states": {
|
||||||
|
// "good": 95,
|
||||||
|
"warning": 30,
|
||||||
|
"critical": 15
|
||||||
|
},
|
||||||
|
"format": "{capacity}% {icon}",
|
||||||
|
"format-full": "{capacity}% {icon}",
|
||||||
|
"format-charging": "{capacity}% ",
|
||||||
|
"format-plugged": "{capacity}% ",
|
||||||
|
"format-alt": "{time} {icon}",
|
||||||
|
// "format-good": "", // An empty format will hide the module
|
||||||
|
// "format-full": "",
|
||||||
|
"format-icons": ["", "", "", "", ""]
|
||||||
|
},
|
||||||
|
"battery#bat2": {
|
||||||
|
"bat": "BAT2"
|
||||||
|
},
|
||||||
|
"power-profiles-daemon": {
|
||||||
|
"format": "{icon}",
|
||||||
|
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
|
||||||
|
"tooltip": true,
|
||||||
|
"format-icons": {
|
||||||
|
"default": "",
|
||||||
|
"performance": "",
|
||||||
|
"balanced": "",
|
||||||
|
"power-saver": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
// "interface": "wlp2*", // (Optional) To force the use of this interface
|
||||||
|
"format-wifi": "{essid} ({signalStrength}%) ",
|
||||||
|
"format-ethernet": "{ipaddr}/{cidr} ",
|
||||||
|
"tooltip-format": "{ifname} via {gwaddr} ",
|
||||||
|
"format-linked": "{ifname} (No IP) ",
|
||||||
|
"format-disconnected": "Disconnected ⚠",
|
||||||
|
"format-alt": "{ifname}: {ipaddr}/{cidr}"
|
||||||
|
},
|
||||||
|
"pulseaudio": {
|
||||||
|
// "scroll-step": 1, // %, can be a float
|
||||||
|
"format": "{volume}% {icon} {format_source}",
|
||||||
|
"format-bluetooth": "{volume}% {icon} {format_source}",
|
||||||
|
"format-bluetooth-muted": " {icon} {format_source}",
|
||||||
|
"format-muted": " {format_source}",
|
||||||
|
"format-source": "{volume}% ",
|
||||||
|
"format-source-muted": "",
|
||||||
|
"format-icons": {
|
||||||
|
"headphone": "",
|
||||||
|
"hands-free": "",
|
||||||
|
"headset": "",
|
||||||
|
"phone": "",
|
||||||
|
"portable": "",
|
||||||
|
"car": "",
|
||||||
|
"default": ["", "", ""]
|
||||||
|
},
|
||||||
|
"on-click": "pavucontrol"
|
||||||
|
},
|
||||||
|
"custom/media": {
|
||||||
|
"format": "{icon} {text}",
|
||||||
|
"return-type": "json",
|
||||||
|
"max-length": 40,
|
||||||
|
"format-icons": {
|
||||||
|
"spotify": "",
|
||||||
|
"default": "🎜"
|
||||||
|
},
|
||||||
|
"escape": true,
|
||||||
|
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
|
||||||
|
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
|
||||||
|
},
|
||||||
|
"custom/power": {
|
||||||
|
"format" : "⏻ ",
|
||||||
|
"tooltip": false,
|
||||||
|
"menu": "on-click",
|
||||||
|
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
|
||||||
|
"menu-actions": {
|
||||||
|
"shutdown": "shutdown",
|
||||||
|
"reboot": "reboot",
|
||||||
|
"suspend": "systemctl suspend",
|
||||||
|
"hibernate": "systemctl hibernate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
327
public/resources/style.css
Normal file
327
public/resources/style.css
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
* {
|
||||||
|
/* `otf-font-awesome` is required to be installed for icons */
|
||||||
|
font-family: FontAwesome, Roboto, Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar {
|
||||||
|
background-color: rgba(43, 48, 59, 0.5);
|
||||||
|
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
||||||
|
color: #ffffff;
|
||||||
|
transition-property: background-color;
|
||||||
|
transition-duration: .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar.hidden {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
window#waybar.empty {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
window#waybar.solo {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
window#waybar.termite {
|
||||||
|
background-color: #3F3F3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar.chromium {
|
||||||
|
background-color: #000000;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
/* Use box-shadow instead of border so the text isn't offset */
|
||||||
|
box-shadow: inset 0 -3px transparent;
|
||||||
|
/* Avoid rounded borders under each button name */
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||||
|
button:hover {
|
||||||
|
background: inherit;
|
||||||
|
box-shadow: inset 0 -3px #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* you can set a style on hover for any module like this */
|
||||||
|
#pulseaudio:hover {
|
||||||
|
background-color: #a37800;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button {
|
||||||
|
padding: 0 5px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.focused {
|
||||||
|
background-color: #64727D;
|
||||||
|
box-shadow: inset 0 -3px #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.urgent {
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mode {
|
||||||
|
background-color: #64727D;
|
||||||
|
box-shadow: inset 0 -3px #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock,
|
||||||
|
#battery,
|
||||||
|
#cpu,
|
||||||
|
#memory,
|
||||||
|
#disk,
|
||||||
|
#temperature,
|
||||||
|
#backlight,
|
||||||
|
#network,
|
||||||
|
#pulseaudio,
|
||||||
|
#wireplumber,
|
||||||
|
#custom-media,
|
||||||
|
#tray,
|
||||||
|
#mode,
|
||||||
|
#idle_inhibitor,
|
||||||
|
#scratchpad,
|
||||||
|
#power-profiles-daemon,
|
||||||
|
#mpd {
|
||||||
|
padding: 0 10px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#window,
|
||||||
|
#workspaces {
|
||||||
|
margin: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If workspaces is the leftmost module, omit left margin */
|
||||||
|
.modules-left > widget:first-child > #workspaces {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If workspaces is the rightmost module, omit right margin */
|
||||||
|
.modules-right > widget:last-child > #workspaces {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock {
|
||||||
|
background-color: #64727D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.charging, #battery.plugged {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #26A65B;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
to {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Using steps() instead of linear as a timing function to limit cpu usage */
|
||||||
|
#battery.critical:not(.charging) {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
color: #ffffff;
|
||||||
|
animation-name: blink;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-timing-function: steps(12);
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
#power-profiles-daemon {
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#power-profiles-daemon.performance {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#power-profiles-daemon.balanced {
|
||||||
|
background-color: #2980b9;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#power-profiles-daemon.power-saver {
|
||||||
|
background-color: #2ecc71;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
label:focus {
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cpu {
|
||||||
|
background-color: #2ecc71;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#memory {
|
||||||
|
background-color: #9b59b6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#disk {
|
||||||
|
background-color: #964B00;
|
||||||
|
}
|
||||||
|
|
||||||
|
#backlight {
|
||||||
|
background-color: #90b1b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network {
|
||||||
|
background-color: #2980b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.disconnected {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio {
|
||||||
|
background-color: #f1c40f;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio.muted {
|
||||||
|
background-color: #90b1b1;
|
||||||
|
color: #2a5c45;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wireplumber {
|
||||||
|
background-color: #fff0f5;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wireplumber.muted {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media {
|
||||||
|
background-color: #66cc99;
|
||||||
|
color: #2a5c45;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media.custom-spotify {
|
||||||
|
background-color: #66cc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media.custom-vlc {
|
||||||
|
background-color: #ffa000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature {
|
||||||
|
background-color: #f0932b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature.critical {
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray {
|
||||||
|
background-color: #2980b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray > .passive {
|
||||||
|
-gtk-icon-effect: dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray > .needs-attention {
|
||||||
|
-gtk-icon-effect: highlight;
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor {
|
||||||
|
background-color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor.activated {
|
||||||
|
background-color: #ecf0f1;
|
||||||
|
color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd {
|
||||||
|
background-color: #66cc99;
|
||||||
|
color: #2a5c45;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.disconnected {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.stopped {
|
||||||
|
background-color: #90b1b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.paused {
|
||||||
|
background-color: #51a37a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#language {
|
||||||
|
background: #00b093;
|
||||||
|
color: #740864;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin: 0 5px;
|
||||||
|
min-width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state {
|
||||||
|
background: #97e1ad;
|
||||||
|
color: #000000;
|
||||||
|
padding: 0 0px;
|
||||||
|
margin: 0 5px;
|
||||||
|
min-width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state > label {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state > label.locked {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#scratchpad {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#scratchpad.empty {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privacy {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privacy-item {
|
||||||
|
padding: 0 5px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privacy-item.screenshare {
|
||||||
|
background-color: #cf5700;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privacy-item.audio-in {
|
||||||
|
background-color: #1ca000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privacy-item.audio-out {
|
||||||
|
background-color: #0069d4;
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
import { createRootPage } from "./routes/root";
|
|
||||||
import { createWaybarPage } from "./routes/waybar";
|
|
||||||
|
|
||||||
if (location.pathname === "/waybar") {
|
if (location.pathname === "/waybar") {
|
||||||
createWaybarPage();
|
import("./routes/waybar/waybar").then(({ createWaybarPage }) =>
|
||||||
|
createWaybarPage()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location.pathname === "/") {
|
if (location.pathname === "/") {
|
||||||
createRootPage();
|
import("./routes/root/root").then(({ createRootPage }) => createRootPage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
const appElement = document.getElementById("app")!;
|
|
||||||
|
|
||||||
export const createRootPage = async () => {
|
|
||||||
appElement.innerHTML = "test";
|
|
||||||
};
|
|
||||||
14
src/routes/root/root.css
Normal file
14
src/routes/root/root.css
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
body {
|
||||||
|
background: url(/bg.avif) no-repeat center center fixed;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#waybar-iframe {
|
||||||
|
width: 100vw;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
8
src/routes/root/root.ts
Normal file
8
src/routes/root/root.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import "./root.css";
|
||||||
|
const appElement = document.getElementById("app")!;
|
||||||
|
|
||||||
|
export const createRootPage = async () => {
|
||||||
|
appElement.innerHTML = `
|
||||||
|
<iframe id="waybar-iframe" src="/waybar"></iframe>
|
||||||
|
`;
|
||||||
|
};
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
const appElement = document.getElementById("app")!;
|
|
||||||
|
|
||||||
export const createWaybarPage = async () => {
|
|
||||||
appElement.innerHTML = "test";
|
|
||||||
};
|
|
||||||
61
src/routes/waybar/Label.ts
Normal file
61
src/routes/waybar/Label.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { clamp, replaceTextWithUnicode } from "./utils";
|
||||||
|
|
||||||
|
interface LabelOpts {
|
||||||
|
config?: {
|
||||||
|
[key: string]: any;
|
||||||
|
format?: string;
|
||||||
|
"format-icons"?: string[];
|
||||||
|
};
|
||||||
|
interval?: number;
|
||||||
|
update: () => void;
|
||||||
|
}
|
||||||
|
export const createLabel = (opts: LabelOpts) => {
|
||||||
|
let format = "";
|
||||||
|
|
||||||
|
const getMarkup = () => {
|
||||||
|
if (!opts.config) return undefined;
|
||||||
|
if (!format) {
|
||||||
|
return opts.config?.format || undefined;
|
||||||
|
}
|
||||||
|
return opts.config["format-" + format] || undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const element = document.createElement("span");
|
||||||
|
if (opts.interval && opts.update) {
|
||||||
|
setInterval(opts.update, opts.interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
const set = (data: Record<string, any>) => {
|
||||||
|
const markup = getMarkup() as string | undefined;
|
||||||
|
if (!markup) {
|
||||||
|
console.error("No format found");
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
const result = markup.replace(/\{(\w+)\}/g, (match, key) => {
|
||||||
|
return data[key] !== undefined ? data[key] : match;
|
||||||
|
});
|
||||||
|
|
||||||
|
element.innerHTML = replaceTextWithUnicode(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getIcon = (percentage: number, icon?: string, max: number = 0) => {
|
||||||
|
const icons = opts.config?.["format-icons"];
|
||||||
|
const iconCount = icons?.length || 0;
|
||||||
|
const index = clamp(
|
||||||
|
percentage / ((max == 0 ? 100 : max) / iconCount),
|
||||||
|
0,
|
||||||
|
iconCount - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
const resIcon = icons?.[Math.round(index)];
|
||||||
|
if (!resIcon) return "";
|
||||||
|
|
||||||
|
return resIcon;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
element,
|
||||||
|
set,
|
||||||
|
getIcon,
|
||||||
|
};
|
||||||
|
};
|
||||||
288
src/routes/waybar/configParser.ts
Normal file
288
src/routes/waybar/configParser.ts
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
import { parse } from "jsonc-parser";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A general interface for icon mappings, where a key maps to a single icon string or an array of icon strings.
|
||||||
|
*/
|
||||||
|
interface IconMap {
|
||||||
|
[key: string]: string | string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common configuration properties for many Waybar modules.
|
||||||
|
*/
|
||||||
|
interface BaseModule {
|
||||||
|
format?: string;
|
||||||
|
"format-icons"?: IconMap;
|
||||||
|
tooltip?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the states and icons for a module.
|
||||||
|
*/
|
||||||
|
interface ModuleWithStates extends BaseModule {
|
||||||
|
states?: {
|
||||||
|
[state: string]: number;
|
||||||
|
};
|
||||||
|
"format-critical"?: string;
|
||||||
|
"format-alt"?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `sway/workspaces` module.
|
||||||
|
* Note: This module is commented out in the original JSON, but the interface is included for completeness.
|
||||||
|
*/
|
||||||
|
interface SwayWorkspacesModule extends BaseModule {
|
||||||
|
"disable-scroll"?: boolean;
|
||||||
|
"all-outputs"?: boolean;
|
||||||
|
"warp-on-scroll"?: boolean;
|
||||||
|
"format-icons"?: {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `keyboard-state` module.
|
||||||
|
*/
|
||||||
|
interface KeyboardStateModule extends BaseModule {
|
||||||
|
numlock?: boolean;
|
||||||
|
capslock?: boolean;
|
||||||
|
"format-icons"?: {
|
||||||
|
locked: string;
|
||||||
|
unlocked: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `sway/mode` module.
|
||||||
|
*/
|
||||||
|
interface SwayModeModule {
|
||||||
|
format?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `sway/scratchpad` module.
|
||||||
|
*/
|
||||||
|
interface SwayScratchpadModule extends BaseModule {
|
||||||
|
"show-empty"?: boolean;
|
||||||
|
"format-icons"?: string[];
|
||||||
|
"tooltip-format"?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `mpd` module.
|
||||||
|
*/
|
||||||
|
interface MpdModule extends BaseModule {
|
||||||
|
"format-disconnected"?: string;
|
||||||
|
"format-stopped"?: string;
|
||||||
|
"unknown-tag"?: string;
|
||||||
|
interval?: number;
|
||||||
|
"consume-icons"?: {
|
||||||
|
on: string;
|
||||||
|
};
|
||||||
|
"random-icons"?: {
|
||||||
|
on: string;
|
||||||
|
off: string;
|
||||||
|
};
|
||||||
|
"repeat-icons"?: {
|
||||||
|
on: string;
|
||||||
|
};
|
||||||
|
"single-icons"?: {
|
||||||
|
on: string;
|
||||||
|
};
|
||||||
|
"state-icons"?: {
|
||||||
|
paused: string;
|
||||||
|
playing: string;
|
||||||
|
};
|
||||||
|
"tooltip-format"?: string;
|
||||||
|
"tooltip-format-disconnected"?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `idle_inhibitor` module.
|
||||||
|
*/
|
||||||
|
interface IdleInhibitorModule extends BaseModule {
|
||||||
|
"format-icons"?: {
|
||||||
|
activated: string;
|
||||||
|
deactivated: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `tray` module.
|
||||||
|
*/
|
||||||
|
interface TrayModule {
|
||||||
|
"icon-size"?: number;
|
||||||
|
spacing?: number;
|
||||||
|
icons?: {
|
||||||
|
[appName: string]: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `clock` module.
|
||||||
|
*/
|
||||||
|
interface ClockModule {
|
||||||
|
timezone?: string;
|
||||||
|
"tooltip-format"?: string;
|
||||||
|
"format-alt"?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `cpu` module.
|
||||||
|
*/
|
||||||
|
interface CpuModule extends BaseModule {
|
||||||
|
tooltip?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `memory` module.
|
||||||
|
*/
|
||||||
|
interface MemoryModule extends BaseModule {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `temperature` module.
|
||||||
|
*/
|
||||||
|
interface TemperatureModule extends ModuleWithStates {
|
||||||
|
"thermal-zone"?: number;
|
||||||
|
"hwmon-path"?: string;
|
||||||
|
"critical-threshold"?: number;
|
||||||
|
"format-icons"?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `backlight` module.
|
||||||
|
*/
|
||||||
|
interface BacklightModule extends BaseModule {
|
||||||
|
device?: string;
|
||||||
|
"format-icons"?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `battery` module.
|
||||||
|
*/
|
||||||
|
interface BatteryModule extends ModuleWithStates {
|
||||||
|
bat?: string; // Used for battery#bat2
|
||||||
|
"format-full"?: string;
|
||||||
|
"format-charging"?: string;
|
||||||
|
"format-plugged"?: string;
|
||||||
|
"format-good"?: string;
|
||||||
|
"format-icons"?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `power-profiles-daemon` module.
|
||||||
|
*/
|
||||||
|
interface PowerProfilesDaemonModule extends BaseModule {
|
||||||
|
tooltip?: boolean;
|
||||||
|
"tooltip-format"?: string;
|
||||||
|
"format-icons"?: {
|
||||||
|
default: string;
|
||||||
|
performance: string;
|
||||||
|
balanced: string;
|
||||||
|
"power-saver": string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `network` module.
|
||||||
|
*/
|
||||||
|
interface NetworkModule {
|
||||||
|
interface?: string;
|
||||||
|
"format-wifi"?: string;
|
||||||
|
"format-ethernet"?: string;
|
||||||
|
"tooltip-format"?: string;
|
||||||
|
"format-linked"?: string;
|
||||||
|
"format-disconnected"?: string;
|
||||||
|
"format-alt"?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `pulseaudio` module.
|
||||||
|
*/
|
||||||
|
interface PulseaudioModule extends BaseModule {
|
||||||
|
"scroll-step"?: number;
|
||||||
|
"format-bluetooth"?: string;
|
||||||
|
"format-bluetooth-muted"?: string;
|
||||||
|
"format-muted"?: string;
|
||||||
|
"format-source"?: string;
|
||||||
|
"format-source-muted"?: string;
|
||||||
|
"format-icons"?: {
|
||||||
|
headphone: string;
|
||||||
|
"hands-free": string;
|
||||||
|
headset: string;
|
||||||
|
phone: string;
|
||||||
|
portable: string;
|
||||||
|
car: string;
|
||||||
|
default: string[];
|
||||||
|
};
|
||||||
|
"on-click"?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `custom/media` module.
|
||||||
|
*/
|
||||||
|
interface CustomMediaModule extends BaseModule {
|
||||||
|
"return-type"?: "json" | "text";
|
||||||
|
"max-length"?: number;
|
||||||
|
"format-icons"?: {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
escape?: boolean;
|
||||||
|
exec?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the `custom/power` module.
|
||||||
|
*/
|
||||||
|
interface CustomPowerModule extends BaseModule {
|
||||||
|
menu?: string;
|
||||||
|
"menu-file"?: string;
|
||||||
|
"menu-actions"?: {
|
||||||
|
shutdown: string;
|
||||||
|
reboot: string;
|
||||||
|
suspend: string;
|
||||||
|
hibernate: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main interface for the entire Waybar configuration file.
|
||||||
|
* It combines the main settings with a generic index signature for module configurations.
|
||||||
|
*/
|
||||||
|
export interface WaybarConfig {
|
||||||
|
layer?: "top" | "bottom" | "overlay";
|
||||||
|
position?: "top" | "bottom" | "left" | "right";
|
||||||
|
height?: number;
|
||||||
|
width?: number;
|
||||||
|
spacing?: number;
|
||||||
|
"modules-left"?: string[];
|
||||||
|
"modules-center"?: string[];
|
||||||
|
"modules-right"?: string[];
|
||||||
|
|
||||||
|
// Module-specific configurations
|
||||||
|
"sway/workspaces"?: SwayWorkspacesModule;
|
||||||
|
"sway/mode"?: SwayModeModule;
|
||||||
|
"sway/scratchpad"?: SwayScratchpadModule;
|
||||||
|
"keyboard-state"?: KeyboardStateModule;
|
||||||
|
mpd?: MpdModule;
|
||||||
|
idle_inhibitor?: IdleInhibitorModule;
|
||||||
|
tray?: TrayModule;
|
||||||
|
clock?: ClockModule;
|
||||||
|
cpu?: CpuModule;
|
||||||
|
memory?: MemoryModule;
|
||||||
|
temperature?: TemperatureModule;
|
||||||
|
backlight?: BacklightModule;
|
||||||
|
battery?: BatteryModule;
|
||||||
|
"battery#bat2"?: BatteryModule;
|
||||||
|
"power-profiles-daemon"?: PowerProfilesDaemonModule;
|
||||||
|
network?: NetworkModule;
|
||||||
|
pulseaudio?: PulseaudioModule;
|
||||||
|
"custom/media"?: CustomMediaModule;
|
||||||
|
"custom/power"?: CustomPowerModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const parseConfig = async () => {
|
||||||
|
const response = await fetch("/resources/config.jsonc");
|
||||||
|
const jsoncString = await response.text();
|
||||||
|
return parse(jsoncString) as WaybarConfig;
|
||||||
|
};
|
||||||
11
src/routes/waybar/createModule.ts
Normal file
11
src/routes/waybar/createModule.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export type Module = ReturnType<typeof createModule>;
|
||||||
|
|
||||||
|
export const createModule = (name: string) => {
|
||||||
|
const element = document.createElement("div");
|
||||||
|
element.id = name;
|
||||||
|
element.className = "module";
|
||||||
|
|
||||||
|
return {
|
||||||
|
element,
|
||||||
|
};
|
||||||
|
};
|
||||||
13
src/routes/waybar/modules.ts
Normal file
13
src/routes/waybar/modules.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export type Modules = keyof typeof modules;
|
||||||
|
export type ModuleArray = Array<keyof typeof modules>;
|
||||||
|
|
||||||
|
export const modules = {
|
||||||
|
clock: () =>
|
||||||
|
import("./modules/clock").then(
|
||||||
|
({ createClockModule }) => createClockModule
|
||||||
|
),
|
||||||
|
battery: () =>
|
||||||
|
import("./modules/battery").then(
|
||||||
|
({ createBatteryModule }) => createBatteryModule
|
||||||
|
),
|
||||||
|
};
|
||||||
50
src/routes/waybar/modules/battery.ts
Normal file
50
src/routes/waybar/modules/battery.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import type { WaybarConfig } from "../configParser";
|
||||||
|
import type { Module } from "../createModule";
|
||||||
|
import { createLabel } from "../Label";
|
||||||
|
|
||||||
|
export const createBatteryModule = (
|
||||||
|
module: Module,
|
||||||
|
config: WaybarConfig["battery"]
|
||||||
|
) => {
|
||||||
|
const label = createLabel({
|
||||||
|
interval: 1000,
|
||||||
|
update: () => update(),
|
||||||
|
config: config!,
|
||||||
|
});
|
||||||
|
|
||||||
|
module.element.appendChild(label.element);
|
||||||
|
|
||||||
|
const update = async () => {
|
||||||
|
// const battery = await navigator.getBattery();
|
||||||
|
|
||||||
|
const battery = {
|
||||||
|
level: Math.random(),
|
||||||
|
charging: Math.random() > 0.5,
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = "Unknown";
|
||||||
|
|
||||||
|
if (battery.charging && battery.level < 1) {
|
||||||
|
state = "Charging";
|
||||||
|
}
|
||||||
|
if (battery.charging && battery.level === 1) {
|
||||||
|
state = "Full";
|
||||||
|
}
|
||||||
|
|
||||||
|
const charging = battery.charging;
|
||||||
|
const batteryPercent = Math.round(battery.level * 100);
|
||||||
|
|
||||||
|
if (charging) {
|
||||||
|
module.element.classList.add("charging");
|
||||||
|
} else {
|
||||||
|
module.element.classList.remove("charging");
|
||||||
|
}
|
||||||
|
|
||||||
|
label.set({
|
||||||
|
capacity: batteryPercent,
|
||||||
|
icon: label.getIcon(batteryPercent),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
update();
|
||||||
|
};
|
||||||
14
src/routes/waybar/modules/clock.ts
Normal file
14
src/routes/waybar/modules/clock.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import type { Module } from "../createModule";
|
||||||
|
|
||||||
|
export const createClockModule = (module: Module) => {
|
||||||
|
const update = () => {
|
||||||
|
const date = new Date();
|
||||||
|
|
||||||
|
const hours = date.getHours().toString().padStart(2, "0");
|
||||||
|
const minutes = date.getMinutes().toString().padStart(2, "0");
|
||||||
|
module.element.innerHTML = `${hours}:${minutes}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
update();
|
||||||
|
setInterval(update, 1000);
|
||||||
|
};
|
||||||
60
src/routes/waybar/utils.ts
Normal file
60
src/routes/waybar/utils.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { CssTypes, parse, stringify } from "@adobe/css-tools";
|
||||||
|
|
||||||
|
export const clamp = (val: number, min: number, max: number) =>
|
||||||
|
Math.min(Math.max(val, min), max);
|
||||||
|
|
||||||
|
const fetchFontAwesomeStylesheet = async () => {
|
||||||
|
const raw = await fetch("/fontawesome/css/fontawesome.min.css").then((res) =>
|
||||||
|
res.text()
|
||||||
|
);
|
||||||
|
return raw;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const tryCatch = (tryTo: () => string, ifCatch: string) => {
|
||||||
|
try {
|
||||||
|
return tryTo();
|
||||||
|
} catch (e) {
|
||||||
|
return ifCatch;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const css = await fetchFontAwesomeStylesheet();
|
||||||
|
|
||||||
|
function unicodeToHexMap() {
|
||||||
|
const map = new Map<string, string>();
|
||||||
|
|
||||||
|
const parsed = parse(css);
|
||||||
|
parsed.stylesheet.rules.forEach((rule) => {
|
||||||
|
if (rule.type === CssTypes.rule) {
|
||||||
|
const declaration = rule.declarations[0];
|
||||||
|
if (declaration.type === CssTypes.declaration) {
|
||||||
|
if (declaration.property !== "--fa") return;
|
||||||
|
const selector = rule.selectors[0];
|
||||||
|
const value = declaration.value.slice(1, -1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const unicodeChar = String.fromCodePoint(
|
||||||
|
parseInt(value.slice(1), 16)
|
||||||
|
);
|
||||||
|
if (!Number.isNaN(parseInt(unicodeChar))) return;
|
||||||
|
map.set(unicodeChar, value);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
const unicodeArray = [...unicodeToHexMap().keys()];
|
||||||
|
|
||||||
|
const unicodeRegex = new RegExp(
|
||||||
|
unicodeArray.map((x) => `\\${x}`).join("|"),
|
||||||
|
"g"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const replaceTextWithUnicode = (text: string) => {
|
||||||
|
let newText = text.replace(
|
||||||
|
unicodeRegex,
|
||||||
|
(char) => `<span class="fa">${char}</span>`
|
||||||
|
);
|
||||||
|
return newText;
|
||||||
|
};
|
||||||
26
src/routes/waybar/waybar.css
Normal file
26
src/routes/waybar/waybar.css
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#waybar {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modules {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
#modules-left {
|
||||||
|
}
|
||||||
|
#modules-center {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
#modules-right {
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
56
src/routes/waybar/waybar.ts
Normal file
56
src/routes/waybar/waybar.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { parseConfig } from "./configParser";
|
||||||
|
import { createModule } from "./createModule";
|
||||||
|
import { modules, type ModuleArray, type Modules } from "./modules";
|
||||||
|
|
||||||
|
import "./waybar.css";
|
||||||
|
|
||||||
|
const appElement = document.getElementById("app")!;
|
||||||
|
|
||||||
|
export const createWaybarPage = async () => {
|
||||||
|
const styleElement = document.createElement("link");
|
||||||
|
styleElement.rel = "stylesheet";
|
||||||
|
styleElement.href = "/resources/style.css";
|
||||||
|
document.head.appendChild(styleElement);
|
||||||
|
|
||||||
|
const config = await parseConfig();
|
||||||
|
|
||||||
|
appElement.innerHTML = `
|
||||||
|
<window id="waybar" style="height: ${config.height}px;">
|
||||||
|
<div class="modules" id="modules-left" style="gap: ${config.spacing}px;"></div>
|
||||||
|
<div class="modules" id="modules-center" style="gap: ${config.spacing}px;"></div>
|
||||||
|
<div class="modules" id="modules-right" style="gap: ${config.spacing}px;"></div>
|
||||||
|
</window>`;
|
||||||
|
|
||||||
|
const modulesLeftElement = document.getElementById("modules-left")!;
|
||||||
|
const modulesCenterElement = document.getElementById("modules-center")!;
|
||||||
|
const modulesRightElement = document.getElementById("modules-right")!;
|
||||||
|
|
||||||
|
const moduleLeft = (config["modules-left"] as ModuleArray) || [];
|
||||||
|
const moduleCenter = (config["modules-center"] as ModuleArray) || [];
|
||||||
|
const moduleRight = (config["modules-right"] as ModuleArray) || [];
|
||||||
|
|
||||||
|
const loadModules = async (
|
||||||
|
enabledModules: ModuleArray,
|
||||||
|
modulesElement: HTMLElement
|
||||||
|
) => {
|
||||||
|
enabledModules.forEach(async (moduleName) => {
|
||||||
|
if (moduleName === "battery") {
|
||||||
|
console.log(moduleName);
|
||||||
|
const module = createModule("battery");
|
||||||
|
modulesElement.appendChild(module.element);
|
||||||
|
const createBatteryModule = await modules.battery();
|
||||||
|
createBatteryModule(module, config.battery);
|
||||||
|
}
|
||||||
|
if (moduleName === "clock") {
|
||||||
|
console.log(moduleName);
|
||||||
|
const module = createModule("clock");
|
||||||
|
modulesElement.appendChild(module.element);
|
||||||
|
const createClockModule = await modules.clock();
|
||||||
|
createClockModule(module, config.clock);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
loadModules(moduleLeft, modulesLeftElement);
|
||||||
|
loadModules(moduleCenter, modulesCenterElement);
|
||||||
|
loadModules(moduleRight, modulesRightElement);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user