feat(ags): transfer remaining bar stuff from v1
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
f0704cba04
commit
7d64a1fe25
8 changed files with 177 additions and 264 deletions
|
@ -20,6 +20,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.bluetooth icon,
|
&.bluetooth icon,
|
||||||
|
&.heart-toggle label,
|
||||||
|
&.keyboard icon,
|
||||||
&.network icon,
|
&.network icon,
|
||||||
&.tablet-mode icon {
|
&.tablet-mode icon {
|
||||||
min-width: 30px;
|
min-width: 30px;
|
||||||
|
|
29
modules/ags/config/widgets/bar/items/heart.tsx
Normal file
29
modules/ags/config/widgets/bar/items/heart.tsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { Variable } from 'astal';
|
||||||
|
|
||||||
|
import Persist from '../../misc/persist';
|
||||||
|
|
||||||
|
const HeartState = Variable('');
|
||||||
|
|
||||||
|
Persist({
|
||||||
|
name: 'heart',
|
||||||
|
variable: HeartState,
|
||||||
|
condition: '',
|
||||||
|
whenFalse: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<button
|
||||||
|
className="bar-item heart-toggle"
|
||||||
|
cursor="pointer"
|
||||||
|
|
||||||
|
onButtonReleaseEvent={() => {
|
||||||
|
HeartState.set(HeartState.get() === '' ? '' : '');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
label={HeartState()}
|
||||||
|
css="margin-left: -6px; margin-right: 4px; font-size: 28px;"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
87
modules/ags/config/widgets/bar/items/keyboard-layout.tsx
Normal file
87
modules/ags/config/widgets/bar/items/keyboard-layout.tsx
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
import { Variable } from 'astal';
|
||||||
|
import { Label } from 'astal/gtk3/widget';
|
||||||
|
|
||||||
|
import AstalHyprland from 'gi://AstalHyprland';
|
||||||
|
|
||||||
|
import { hyprMessage } from '../../../lib';
|
||||||
|
import { Gtk } from 'astal/gtk3';
|
||||||
|
|
||||||
|
/* Types */
|
||||||
|
interface Keyboard {
|
||||||
|
address: string
|
||||||
|
name: string
|
||||||
|
rules: string
|
||||||
|
model: string
|
||||||
|
layout: string
|
||||||
|
variant: string
|
||||||
|
options: string
|
||||||
|
active_keymap: string
|
||||||
|
main: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const DEFAULT_KB = 'at-translated-set-2-keyboard';
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const Hovered = Variable(false);
|
||||||
|
|
||||||
|
const hyprland = AstalHyprland.get_default();
|
||||||
|
|
||||||
|
const getKbdLayout = (self: Label, _: string, layout?: string) => {
|
||||||
|
if (layout) {
|
||||||
|
if (layout === 'error') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const shortName = layout.match(/\(([A-Za-z]+)\)/);
|
||||||
|
|
||||||
|
self.label = shortName ? shortName[1] : layout;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// At launch, kb layout is undefined
|
||||||
|
hyprMessage('j/devices').then((obj) => {
|
||||||
|
const keyboards = Array.from(JSON.parse(obj)
|
||||||
|
.keyboards) as Keyboard[];
|
||||||
|
const kb = keyboards.find((v) => v.name === DEFAULT_KB);
|
||||||
|
|
||||||
|
if (kb) {
|
||||||
|
layout = kb.active_keymap;
|
||||||
|
|
||||||
|
const shortName = layout
|
||||||
|
.match(/\(([A-Za-z]+)\)/);
|
||||||
|
|
||||||
|
self.label = shortName ? shortName[1] : layout;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.label = 'None';
|
||||||
|
}
|
||||||
|
}).catch(print);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="bar-item keyboard"
|
||||||
|
cursor="pointer"
|
||||||
|
|
||||||
|
onHover={() => Hovered.set(true)}
|
||||||
|
onHoverLost={() => Hovered.set(false)}
|
||||||
|
>
|
||||||
|
<box>
|
||||||
|
<icon icon="input-keyboard-symbolic" />
|
||||||
|
|
||||||
|
<revealer
|
||||||
|
revealChild={Hovered()}
|
||||||
|
transitionType={Gtk.RevealerTransitionType.SLIDE_LEFT}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
setup={(self) => {
|
||||||
|
self.hook(hyprland, 'keyboard-layout', getKbdLayout);
|
||||||
|
getKbdLayout(self, '');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</revealer>
|
||||||
|
</box>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
|
@ -7,6 +7,8 @@ import Bluetooth from './items/bluetooth';
|
||||||
import Brightness from './items/brightness';
|
import Brightness from './items/brightness';
|
||||||
import Clock from './items/clock';
|
import Clock from './items/clock';
|
||||||
import CurrentClient from './items/current-client';
|
import CurrentClient from './items/current-client';
|
||||||
|
import Heart from './items/heart';
|
||||||
|
import Keyboard from './items/keyboard-layout';
|
||||||
import Network from './items/network';
|
import Network from './items/network';
|
||||||
import NotifButton from './items/notif-button';
|
import NotifButton from './items/notif-button';
|
||||||
import SysTray from './items/tray';
|
import SysTray from './items/tray';
|
||||||
|
@ -52,6 +54,10 @@ export default () => (
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<Separator size={8} />
|
||||||
|
|
||||||
|
<Heart />
|
||||||
|
|
||||||
<CurrentClient />
|
<CurrentClient />
|
||||||
|
|
||||||
<Separator size={8} />
|
<Separator size={8} />
|
||||||
|
@ -70,6 +76,10 @@ export default () => (
|
||||||
|
|
||||||
<Separator size={8} />
|
<Separator size={8} />
|
||||||
|
|
||||||
|
<Keyboard />
|
||||||
|
|
||||||
|
<Separator size={8} />
|
||||||
|
|
||||||
<NotifButton />
|
<NotifButton />
|
||||||
|
|
||||||
<Separator size={8} />
|
<Separator size={8} />
|
||||||
|
|
49
modules/ags/config/widgets/misc/persist.ts
Normal file
49
modules/ags/config/widgets/misc/persist.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import { execAsync, readFileAsync, timeout, GLib, type Variable } from 'astal';
|
||||||
|
|
||||||
|
const { get_home_dir } = GLib;
|
||||||
|
|
||||||
|
|
||||||
|
export default <T>({
|
||||||
|
name,
|
||||||
|
variable,
|
||||||
|
condition = true,
|
||||||
|
whenTrue = condition,
|
||||||
|
whenFalse = false,
|
||||||
|
}: {
|
||||||
|
name: string
|
||||||
|
variable: Variable<T>
|
||||||
|
condition?: boolean | string
|
||||||
|
whenTrue?: boolean | string
|
||||||
|
whenFalse?: boolean | string
|
||||||
|
}) => {
|
||||||
|
const cacheFile = `${get_home_dir()}/.cache/ags/.${name}`;
|
||||||
|
|
||||||
|
const stateCmd = () => ['bash', '-c',
|
||||||
|
`echo ${variable.get() === condition} > ${cacheFile}`];
|
||||||
|
|
||||||
|
const monitorState = () => {
|
||||||
|
variable.subscribe(() => {
|
||||||
|
execAsync(stateCmd()).catch(print);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
readFileAsync(cacheFile)
|
||||||
|
.then((content) => {
|
||||||
|
// JSON.parse was the only way I found to reliably
|
||||||
|
// convert a string of 'true' or 'false' into a bool
|
||||||
|
const value = (JSON.parse(content) ? whenTrue : whenFalse) as T;
|
||||||
|
|
||||||
|
variable.set(value);
|
||||||
|
|
||||||
|
timeout(1000, () => {
|
||||||
|
monitorState();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
execAsync(stateCmd())
|
||||||
|
.then(() => {
|
||||||
|
monitorState();
|
||||||
|
})
|
||||||
|
.catch(print);
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,184 +0,0 @@
|
||||||
.quick-settings {
|
|
||||||
font-size: 30px;
|
|
||||||
min-width: 500px;
|
|
||||||
padding: 0;
|
|
||||||
background-color: $bg;
|
|
||||||
border-radius: 30px 0 30px 30px;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 22px;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-label {
|
|
||||||
font-size: 30px;
|
|
||||||
margin-left: 15px;
|
|
||||||
margin-right: 10px;
|
|
||||||
min-width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrolled-indicator {
|
|
||||||
margin: 5px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
margin: 10px;
|
|
||||||
padding: 0;
|
|
||||||
border: 1.5px solid $contrast-bg;
|
|
||||||
border-radius: 10px;
|
|
||||||
font-size: 12px;
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
row {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item {
|
|
||||||
margin: 5px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 16px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-label {
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 3px;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
border-radius: 10px 20px 20px 10px;
|
|
||||||
min-width: 106px;
|
|
||||||
background: #1b1b1b;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-chev {
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 12px;
|
|
||||||
font-size: 25px;
|
|
||||||
|
|
||||||
transition: -gtk-icon-transform 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-grid {
|
|
||||||
font-size: 10px;
|
|
||||||
min-width: 440px;
|
|
||||||
background-color: $bgfull;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 10px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-button {
|
|
||||||
min-height: 65px;
|
|
||||||
min-width: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-part {
|
|
||||||
background: #1b1b1b;
|
|
||||||
border-top-left-radius: 15px;
|
|
||||||
border-bottom-left-radius: 15px;
|
|
||||||
border-left: 2px solid $contrast-bg;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-part {
|
|
||||||
background: #1b1b1b;
|
|
||||||
border-top-right-radius: 30px;
|
|
||||||
border-bottom-right-radius: 30px;
|
|
||||||
border-right: 2px solid $contrast-bg;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-part:hover,
|
|
||||||
.right-part:active {
|
|
||||||
color: $contrast-bg;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
border-top-left-radius: 7px;
|
|
||||||
border-bottom-left-radius: 7px;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-part:hover,
|
|
||||||
.left-part:active {
|
|
||||||
color: $contrast-bg;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
border-top-right-radius: 7px;
|
|
||||||
border-bottom-right-radius: 7px;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.player {
|
|
||||||
margin-top: 6px;
|
|
||||||
min-height: 220px;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider-box {
|
|
||||||
min-height: 100px;
|
|
||||||
min-width: 470px;
|
|
||||||
background-color: $bgfull;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
border-radius: 15px;
|
|
||||||
margin-top: 30px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.slider-label {
|
|
||||||
font-size: 30px;
|
|
||||||
min-width: 40px;
|
|
||||||
margin-right: -20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider {
|
|
||||||
min-height: 55px;
|
|
||||||
margin-right: -15px;
|
|
||||||
|
|
||||||
scale {
|
|
||||||
min-width: 400px;
|
|
||||||
margin-left: 18px;
|
|
||||||
margin-right: 20px;
|
|
||||||
|
|
||||||
highlight {
|
|
||||||
margin: 0;
|
|
||||||
background-color: #79659f;
|
|
||||||
border-radius: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
trough {
|
|
||||||
background-color: #363847;
|
|
||||||
border-radius: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
slider {
|
|
||||||
margin: -4px;
|
|
||||||
min-width: 20px;
|
|
||||||
min-height: 20px;
|
|
||||||
background: #3e4153;
|
|
||||||
border-radius: 100%;
|
|
||||||
transition: background-color 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
slider:hover {
|
|
||||||
background-color: #303240;
|
|
||||||
transition: background-color 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
const { Label } = Widget;
|
|
||||||
|
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
import Persist from '../../misc/persist.ts';
|
|
||||||
|
|
||||||
const HeartState = Variable('');
|
|
||||||
|
|
||||||
Persist({
|
|
||||||
name: 'heart',
|
|
||||||
gobject: HeartState,
|
|
||||||
prop: 'value',
|
|
||||||
condition: '',
|
|
||||||
whenFalse: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default () => CursorBox({
|
|
||||||
on_primary_click_release: () => {
|
|
||||||
HeartState.setValue(HeartState.value === '' ? '' : '');
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Label({
|
|
||||||
class_name: 'heart-toggle',
|
|
||||||
label: HeartState.bind(),
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -1,54 +0,0 @@
|
||||||
const Hyprland = await Service.import('hyprland');
|
|
||||||
const { Icon, Label } = Widget;
|
|
||||||
|
|
||||||
import HoverRevealer from './hover-revealer.ts';
|
|
||||||
|
|
||||||
const DEFAULT_KB = 'at-translated-set-2-keyboard';
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { Keyboard, LabelGeneric } from 'global-types';
|
|
||||||
|
|
||||||
|
|
||||||
const getKbdLayout = (self: LabelGeneric, _: string, layout: string) => {
|
|
||||||
if (layout) {
|
|
||||||
if (layout === 'error') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const shortName = layout.match(/\(([A-Za-z]+)\)/);
|
|
||||||
|
|
||||||
self.label = shortName ? shortName[1] : layout;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// At launch, kb layout is undefined
|
|
||||||
Hyprland.messageAsync('j/devices').then((obj) => {
|
|
||||||
const keyboards = Array.from(JSON.parse(obj)
|
|
||||||
.keyboards) as Keyboard[];
|
|
||||||
const kb = keyboards.find((v) => v.name === DEFAULT_KB);
|
|
||||||
|
|
||||||
if (kb) {
|
|
||||||
layout = kb.active_keymap;
|
|
||||||
|
|
||||||
const shortName = layout
|
|
||||||
.match(/\(([A-Za-z]+)\)/);
|
|
||||||
|
|
||||||
self.label = shortName ? shortName[1] : layout;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.label = 'None';
|
|
||||||
}
|
|
||||||
}).catch(print);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default () => HoverRevealer({
|
|
||||||
class_name: 'keyboard',
|
|
||||||
spacing: 4,
|
|
||||||
|
|
||||||
icon: Icon({
|
|
||||||
icon: 'input-keyboard-symbolic',
|
|
||||||
size: 20,
|
|
||||||
}),
|
|
||||||
label: Label({ css: 'font-size: 20px;' })
|
|
||||||
.hook(Hyprland, getKbdLayout, 'keyboard-layout'),
|
|
||||||
});
|
|
Loading…
Add table
Reference in a new issue