ags: lot of stuff lmao
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { timeout, Variable } from "astal";
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
|
||||
const empty = new Widget.Box();
|
||||
const page = new Variable<Gtk.Widget>(empty);
|
||||
let connectionId: (number|undefined);
|
||||
|
||||
export const PagesWidget: Widget.Revealer = new Widget.Revealer({
|
||||
revealChild: false,
|
||||
transitionType: Gtk.RevealerTransitionType.SLIDE_DOWN,
|
||||
transitionDuration: 250,
|
||||
child: page()
|
||||
} as Widget.RevealerProps);
|
||||
|
||||
export function showPages(child: Gtk.Widget, onShow?: (self: Widget.Revealer) => void): void {
|
||||
page.set(child);
|
||||
PagesWidget.set_reveal_child(true);
|
||||
connectionId !== undefined && PagesWidget.disconnect(connectionId);
|
||||
connectionId = PagesWidget.connect("show", (_) =>
|
||||
onShow && onShow(_));
|
||||
}
|
||||
|
||||
export function getPage(): (Gtk.Widget|null) {
|
||||
return page.get();
|
||||
}
|
||||
|
||||
export function togglePage(page: Gtk.Widget): void {
|
||||
PagesWidget.revealChild ?
|
||||
hidePages()
|
||||
: showPages(page);
|
||||
}
|
||||
|
||||
export function hidePages(onHide?: () => void) {
|
||||
PagesWidget.set_reveal_child(false);
|
||||
console.log("heyyyyy");
|
||||
timeout(300, () => {
|
||||
page.set(empty);
|
||||
onHide && onHide();
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Process, Variable } from "astal";
|
||||
import { execAsync, Process, Variable } from "astal";
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
import AstalHyprland from "gi://AstalHyprland";
|
||||
|
||||
@@ -53,10 +53,7 @@ function LogoutButton(): Widget.Button {
|
||||
return new Widget.Button({
|
||||
className: "nf",
|
||||
label: "",
|
||||
onClick: () => Process.exec_async(
|
||||
"bash -c 'wlogout -b 5'",
|
||||
() => {}
|
||||
)
|
||||
onClick: () => execAsync("astal open logout-menu")
|
||||
} as Widget.ButtonProps);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
import { TileInternet } from "./tiles/Internet";
|
||||
import { TileBluetooth } from "./tiles/Bluetooth";
|
||||
|
||||
export const tileList: Array<Gtk.Widget> = [];
|
||||
export const tileList: Array<any> = [
|
||||
TileInternet,
|
||||
TileBluetooth
|
||||
];
|
||||
|
||||
export function TilesWidget(): Gtk.Widget {
|
||||
const tilesFlowBox: Gtk.FlowBox = new Gtk.FlowBox({
|
||||
visible: true,
|
||||
noShowAll: false,
|
||||
orientation: Gtk.Orientation.HORIZONTAL
|
||||
} as Gtk.Grid.ConstructorProps);
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
rowSpacing: 6,
|
||||
columnSpacing: 6,
|
||||
minChildrenPerLine: 2,
|
||||
maxChildrenPerLine: 2,
|
||||
expand: true,
|
||||
homogeneous: true,
|
||||
} as Gtk.FlowBox.ConstructorProps);
|
||||
|
||||
tileList.map((item: Gtk.Widget) =>
|
||||
tileList.map((item: Gtk.Widget) =>
|
||||
tilesFlowBox.insert(item, -1));
|
||||
|
||||
return new Widget.Box({
|
||||
children: [
|
||||
tilesFlowBox
|
||||
]
|
||||
className: "tiles-container",
|
||||
child: tilesFlowBox
|
||||
} as Widget.BoxProps);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import { bind, timeout } from "astal";
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
import AstalBluetooth from "gi://AstalBluetooth?version=0.1";
|
||||
|
||||
let watchingDevices: boolean = false;
|
||||
|
||||
export function BluetoothPage() {
|
||||
watchNewDevices();
|
||||
|
||||
return new Widget.Box({
|
||||
className: "page bluetooth container",
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
hexpand: true,
|
||||
children: [
|
||||
new Widget.Box({
|
||||
className: "header",
|
||||
children: [
|
||||
new Widget.Label({
|
||||
hexpand: true,
|
||||
className: "title",
|
||||
label: "Bluetooth",
|
||||
halign: Gtk.Align.START
|
||||
} as Widget.LabelProps),
|
||||
]
|
||||
} as Widget.BoxProps),
|
||||
new Widget.Box({
|
||||
className: "connections",
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
expand: true,
|
||||
children: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) =>
|
||||
devices.filter((device: AstalBluetooth.Device) => device.connected
|
||||
).map((dev: AstalBluetooth.Device) =>
|
||||
new Widget.Button({
|
||||
onClick: () => dev.connected ? dev.disconnect_device(null) : dev.connect_device(null),
|
||||
child: new Widget.Box({
|
||||
className: "device",
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
expand: true,
|
||||
children: [
|
||||
new Widget.Label({
|
||||
className: "alias",
|
||||
halign: Gtk.Align.START,
|
||||
label: bind(dev, "alias")
|
||||
} as Widget.LabelProps),
|
||||
new Widget.Label({
|
||||
className: "battery",
|
||||
halign: Gtk.Align.END,
|
||||
label: bind(dev, "batteryPercentage").as(String)
|
||||
} as Widget.LabelProps)
|
||||
]
|
||||
} as Widget.BoxProps)
|
||||
} as Widget.ButtonProps)).concat(
|
||||
devices.filter((device: AstalBluetooth.Device) => !device.connected
|
||||
).map((dev: AstalBluetooth.Device) =>
|
||||
new Widget.Button({
|
||||
onClick: () => dev.connect_device(() => {}),
|
||||
child: new Widget.Box({
|
||||
className: "device",
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
expand: true,
|
||||
children: [
|
||||
new Widget.Label({
|
||||
className: "alias",
|
||||
halign: Gtk.Align.START,
|
||||
label: bind(dev, "alias")
|
||||
} as Widget.LabelProps),
|
||||
new Widget.Label({
|
||||
className: "battery",
|
||||
halign: Gtk.Align.END,
|
||||
label: bind(dev, "batteryPercentage").as(String)
|
||||
} as Widget.LabelProps)
|
||||
]
|
||||
} as Widget.BoxProps)
|
||||
} as Widget.ButtonProps))
|
||||
)
|
||||
)
|
||||
} as Widget.BoxProps)
|
||||
]
|
||||
} as Widget.BoxProps)
|
||||
}
|
||||
|
||||
function watchNewDevices(): void {
|
||||
if(watchingDevices) {
|
||||
timeout(10000, () => {
|
||||
reloadDevicesList();
|
||||
watchNewDevices();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function stopDeviceWatch(): void {
|
||||
watchingDevices = false;
|
||||
}
|
||||
|
||||
function reloadDevicesList(): void {
|
||||
AstalBluetooth.get_default().adapter.start_discovery();
|
||||
timeout(5000, () => AstalBluetooth.get_default().adapter.stop_discovery());
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { bind } from "astal";
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
import AstalBluetooth from "gi://AstalBluetooth";
|
||||
|
||||
export function WifiPage() {
|
||||
return new Widget.Box({
|
||||
className: "page bluetooth container",
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
hexpand: true,
|
||||
children: [
|
||||
new Widget.Box({
|
||||
className: "connections",
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
expand: true,
|
||||
children: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) =>
|
||||
devices && devices.filter((device: AstalBluetooth.Device) => device.connected
|
||||
).map((dev: AstalBluetooth.Device) =>
|
||||
new Widget.Box({
|
||||
className: "device",
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
expand: true,
|
||||
children: [
|
||||
new Widget.Label({
|
||||
className: "alias",
|
||||
halign: Gtk.Align.START,
|
||||
label: bind(dev, "alias")
|
||||
} as Widget.LabelProps),
|
||||
new Widget.Label({
|
||||
className: "battery",
|
||||
halign: Gtk.Align.END,
|
||||
} as Widget.LabelProps)
|
||||
]
|
||||
} as Widget.BoxProps)
|
||||
))
|
||||
} as Widget.BoxProps)
|
||||
]
|
||||
} as Widget.BoxProps);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { bind } from "astal";
|
||||
import { Tile, TileProps } from "./Tile";
|
||||
import AstalBluetooth from "gi://AstalBluetooth";
|
||||
import { togglePage } from "../Pages";
|
||||
import { BluetoothPage } from "../pages/Bluetooth";
|
||||
|
||||
export const TileBluetooth = Tile({
|
||||
title: "Bluetooth",
|
||||
description: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) => {
|
||||
const connected: Array<AstalBluetooth.Device> = devices.filter(
|
||||
(dev: AstalBluetooth.Device) => dev.connected);
|
||||
|
||||
return connected[0] ? connected[0].get_alias() : undefined;
|
||||
}),
|
||||
onToggledOn: () => AstalBluetooth.get_default().adapter.set_powered(true),
|
||||
onToggledOff: () => AstalBluetooth.get_default().adapter.set_powered(false),
|
||||
onClickMore: () => togglePage(BluetoothPage()),
|
||||
icon: "",
|
||||
iconSize: 16,
|
||||
toggleState: bind(AstalBluetooth.get_default().adapter, "powered")
|
||||
} as TileProps);
|
||||
@@ -1,8 +1,26 @@
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
import { bind, execAsync } from "astal";
|
||||
import { Tile, TileProps } from "./Tile";
|
||||
import AstalNetwork from "gi://AstalNetwork";
|
||||
import { Widget } from "astal/gtk3";
|
||||
|
||||
export const TileInternet = new Widget.Box({
|
||||
className: "tile more internet",
|
||||
children: [
|
||||
toggleButton
|
||||
]
|
||||
child: bind(AstalNetwork.get_default(), "wired").as((wired: AstalNetwork.Wired) => Tile({
|
||||
title: "Wired",
|
||||
description: bind(wired, "internet").as((internet: AstalNetwork.Internet) => {
|
||||
switch(internet) {
|
||||
case AstalNetwork.Internet.CONNECTED:
|
||||
return "Connected";
|
||||
case AstalNetwork.Internet.DISCONNECTED:
|
||||
return "Disconnected";
|
||||
case AstalNetwork.Internet.CONNECTING:
|
||||
return "Connecting...";
|
||||
}
|
||||
}),
|
||||
onToggledOn: () => execAsync("nmcli n on"),
|
||||
onToggledOff: () => execAsync("nmcli n off"),
|
||||
icon: "",
|
||||
iconSize: 16,
|
||||
toggleState: bind(wired, "internet").as((internet: AstalNetwork.Internet) =>
|
||||
internet === AstalNetwork.Internet.CONNECTING || internet === AstalNetwork.Internet.CONNECTED)
|
||||
} as TileProps))
|
||||
} as Widget.BoxProps);
|
||||
|
||||
@@ -1,39 +1,94 @@
|
||||
import { Binding } from "astal";
|
||||
import { Binding, Variable } from "astal";
|
||||
import { Gtk, Widget } from "astal/gtk3";
|
||||
|
||||
export type TileProps = {
|
||||
className?: string | Binding<string | undefined>;
|
||||
iconName?: string | Binding<string | undefined>;
|
||||
icon?: string | Binding<string | undefined>;
|
||||
visible?: boolean | Binding<boolean | undefined>;
|
||||
iconSize?: number | Binding<number | undefined>;
|
||||
title: string | Binding<string>;
|
||||
title: string | Binding<string | undefined>;
|
||||
description?: string | Binding<string | undefined>;
|
||||
defaultToggleState?: boolean;
|
||||
toggleState?: boolean | Binding<boolean | undefined>;
|
||||
onToggledOn: () => void;
|
||||
onToggledOff: () => void;
|
||||
onClickMore?: () => void;
|
||||
}
|
||||
|
||||
export function Tile(props: TileProps): Widget.Box {
|
||||
export function Tile(props: TileProps): Widget.EventBox {
|
||||
const toggled = new Variable<boolean>(props.toggleState instanceof Binding ?
|
||||
(props.toggleState.get() || false) : (props.toggleState || false));
|
||||
|
||||
const toggleButton = new Gtk.ToggleButton();
|
||||
toggleButton.set_active(props.defaultToggleState || false);
|
||||
if(props?.toggleState instanceof Binding)
|
||||
props.toggleState.subscribe(val => toggled.set(val || false))();
|
||||
|
||||
const moreButton = new Widget.Button({
|
||||
className: "more",
|
||||
visible: props.onClickMore
|
||||
});
|
||||
return new Widget.EventBox({
|
||||
className: toggled().as((state: boolean) =>
|
||||
state ? "tile-eventbox toggled" : "tile-eventbox"),
|
||||
expand: true,
|
||||
onClick: () => {
|
||||
if(toggled.get()) {
|
||||
toggled.set(false);
|
||||
console.log(toggled.get());
|
||||
props.onToggledOff && props.onToggledOff();
|
||||
return;
|
||||
}
|
||||
|
||||
return new Widget.Box({
|
||||
className: (typeof Binding<string | undefined>) === (typeof props.className) ?
|
||||
(props.className as Binding<string | undefined>).as((clsName: (string|undefined)) =>
|
||||
`tile ${clsName || ""}`)
|
||||
:
|
||||
props.className,
|
||||
visible: props.visible,
|
||||
children: [
|
||||
toggleButton,
|
||||
moreButton
|
||||
]
|
||||
})
|
||||
toggled.set(true);
|
||||
props.onToggledOn && props.onToggledOn();
|
||||
},
|
||||
child: new Widget.Box({
|
||||
className: (props.className instanceof Binding) ?
|
||||
props.className.as((clsName: (string|undefined)) =>
|
||||
`tile ${clsName || ""}`)
|
||||
: `tile ${props.className || ""}`,
|
||||
visible: props.visible,
|
||||
expand: true,
|
||||
hexpand: true,
|
||||
children: [
|
||||
new Widget.Box({
|
||||
className: "content",
|
||||
expand: true,
|
||||
children: [
|
||||
new Widget.Label({
|
||||
className: "icon nf",
|
||||
label: props.icon || "icon",
|
||||
css: `.icon { font-size: ${props.iconSize || "12px"} }`
|
||||
} as Widget.LabelProps),
|
||||
new Widget.Box({
|
||||
className: "text",
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
vexpand: true,
|
||||
valign: Gtk.Align.CENTER,
|
||||
children: [
|
||||
new Widget.Label({
|
||||
className: "title",
|
||||
xalign: 0,
|
||||
truncate: true,
|
||||
label: props.title
|
||||
} as Widget.LabelProps),
|
||||
new Widget.Label({
|
||||
className: "description",
|
||||
visible: props.description,
|
||||
truncate: true,
|
||||
xalign: 0,
|
||||
label: props.description
|
||||
} as Widget.LabelProps)
|
||||
]
|
||||
} as Widget.BoxProps)
|
||||
]
|
||||
} as Widget.BoxProps),
|
||||
new Widget.Button({
|
||||
className: "more icon",
|
||||
visible: props.onClickMore !== undefined,
|
||||
halign: Gtk.Align.END,
|
||||
image: new Widget.Icon({
|
||||
icon: "go-next-symbolic",
|
||||
css: "icon { font-size: 16px; }"
|
||||
}),
|
||||
onClick: () => props.onClickMore && props?.onClickMore(),
|
||||
widthRequest: 32
|
||||
})
|
||||
]
|
||||
})
|
||||
} as Widget.EventBoxProps)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user