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,
|
||||
&.heart-toggle label,
|
||||
&.keyboard icon,
|
||||
&.network icon,
|
||||
&.tablet-mode icon {
|
||||
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 Clock from './items/clock';
|
||||
import CurrentClient from './items/current-client';
|
||||
import Heart from './items/heart';
|
||||
import Keyboard from './items/keyboard-layout';
|
||||
import Network from './items/network';
|
||||
import NotifButton from './items/notif-button';
|
||||
import SysTray from './items/tray';
|
||||
|
@ -52,6 +54,10 @@ export default () => (
|
|||
/>
|
||||
</button>
|
||||
|
||||
<Separator size={8} />
|
||||
|
||||
<Heart />
|
||||
|
||||
<CurrentClient />
|
||||
|
||||
<Separator size={8} />
|
||||
|
@ -70,6 +76,10 @@ export default () => (
|
|||
|
||||
<Separator size={8} />
|
||||
|
||||
<Keyboard />
|
||||
|
||||
<Separator size={8} />
|
||||
|
||||
<NotifButton />
|
||||
|
||||
<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