mirror of
https://github.com/Theaninova/TheaninovOS.git
synced 2026-01-09 01:02:49 +00:00
feat: update system
This commit is contained in:
@@ -7,43 +7,35 @@ import PanelButton from "../PanelButton.js";
|
||||
|
||||
const Indicator = () =>
|
||||
Widget.Stack({
|
||||
items: [
|
||||
["false", Widget.Icon({ binds: [["icon", Battery, "icon-name"]] })],
|
||||
["true", FontIcon(icons.battery.charging)],
|
||||
],
|
||||
binds: [["visible", options.battery.bar.show_icon]],
|
||||
connections: [
|
||||
[
|
||||
Battery,
|
||||
(stack) => {
|
||||
stack.shown = `${Battery.charging || Battery.charged}`;
|
||||
},
|
||||
],
|
||||
],
|
||||
children: {
|
||||
false: Widget.Icon({ icon: Battery.bind("icon_name") }),
|
||||
true: FontIcon(icons.battery.charging),
|
||||
},
|
||||
visible: options.battery.bar.show_icon.bind("value"),
|
||||
setup: (self) =>
|
||||
self.hook(Battery, () => {
|
||||
self.shown = `${Battery.charging || Battery.charged}`;
|
||||
}),
|
||||
});
|
||||
|
||||
const PercentLabel = () =>
|
||||
Widget.Revealer({
|
||||
transition: "slide_right",
|
||||
binds: [["reveal-child", options.battery.show_percentage]],
|
||||
reveal_child: options.battery.show_percentage.bind("value"),
|
||||
child: Widget.Label({
|
||||
binds: [["label", Battery, "percent", (p) => `${p}%`]],
|
||||
label: Battery.bind("percent").transform((p) => `${p}%`),
|
||||
}),
|
||||
});
|
||||
|
||||
const LevelBar = () =>
|
||||
Widget.LevelBar({
|
||||
connections: [
|
||||
[
|
||||
options.battery.bar.full,
|
||||
(self) => {
|
||||
const full = options.battery.bar.full.value;
|
||||
self.vpack = full ? "fill" : "center";
|
||||
self.hpack = full ? "fill" : "center";
|
||||
},
|
||||
],
|
||||
],
|
||||
binds: [["value", Battery, "percent", (p) => p / 100]],
|
||||
value: Battery.bind("percent").transform((p) => p / 100),
|
||||
setup: (self) =>
|
||||
self.hook(options.battery.bar.full, () => {
|
||||
const full = options.battery.bar.full.value;
|
||||
self.vpack = full ? "fill" : "center";
|
||||
self.hpack = full ? "fill" : "center";
|
||||
}),
|
||||
});
|
||||
|
||||
const WholeButton = () =>
|
||||
@@ -57,7 +49,7 @@ const WholeButton = () =>
|
||||
children: [
|
||||
FontIcon({
|
||||
icon: icons.battery.charging,
|
||||
binds: [["visible", Battery, "charging"]],
|
||||
visible: Battery.bind("charging"),
|
||||
}),
|
||||
Widget.Box({
|
||||
hpack: "center",
|
||||
@@ -77,32 +69,21 @@ export default () =>
|
||||
options.battery.show_percentage.value = !v;
|
||||
},
|
||||
content: Widget.Box({
|
||||
connections: [
|
||||
[
|
||||
Battery,
|
||||
(w) => {
|
||||
w.toggleClassName("charging", Battery.charging || Battery.charged);
|
||||
w.toggleClassName(
|
||||
"medium",
|
||||
Battery.percent < options.battery.medium.value,
|
||||
);
|
||||
w.toggleClassName(
|
||||
"low",
|
||||
Battery.percent < options.battery.low.value,
|
||||
);
|
||||
w.toggleClassName("half", Battery.percent < 48);
|
||||
},
|
||||
],
|
||||
],
|
||||
binds: [
|
||||
["visible", Battery, "available"],
|
||||
[
|
||||
"children",
|
||||
options.battery.bar.full,
|
||||
"value",
|
||||
(full) =>
|
||||
full ? [WholeButton()] : [Indicator(), PercentLabel(), LevelBar()],
|
||||
],
|
||||
],
|
||||
visible: Battery.bind("available"),
|
||||
children: options.battery.bar.full
|
||||
.bind("value")
|
||||
.transform((full) =>
|
||||
full ? [WholeButton()] : [Indicator(), PercentLabel(), LevelBar()],
|
||||
),
|
||||
setup: (self) =>
|
||||
self.hook(Battery, (w) => {
|
||||
w.toggleClassName("charging", Battery.charging || Battery.charged);
|
||||
w.toggleClassName(
|
||||
"medium",
|
||||
Battery.percent < options.battery.medium.value,
|
||||
);
|
||||
w.toggleClassName("low", Battery.percent < options.battery.low.value);
|
||||
w.toggleClassName("half", Battery.percent < 48);
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -7,9 +7,8 @@ export default () =>
|
||||
PanelButton({
|
||||
class_name: "color-picker",
|
||||
content: Widget.Icon("color-select-symbolic"),
|
||||
binds: [["tooltip-text", Colors, "colors", (v) => `${v.length} colors`]],
|
||||
tooltip_text: Colors.bind("colors").transform((v) => `${v.length} colors`),
|
||||
on_clicked: () => Colors.pick(),
|
||||
|
||||
on_secondary_click: (btn) => {
|
||||
if (Colors.colors.length === 0) return;
|
||||
|
||||
|
||||
@@ -7,49 +7,38 @@ import { substitute } from "../../utils.js";
|
||||
|
||||
export const ClientLabel = () =>
|
||||
Widget.Label({
|
||||
binds: [
|
||||
[
|
||||
"label",
|
||||
Hyprland.active.client,
|
||||
"class",
|
||||
(c) => {
|
||||
const { titles } = options.substitutions;
|
||||
return substitute(titles, c);
|
||||
},
|
||||
],
|
||||
],
|
||||
label: Hyprland.active.client.bind("class").transform((c) => {
|
||||
const { titles } = options.substitutions;
|
||||
return substitute(titles, c);
|
||||
}),
|
||||
});
|
||||
|
||||
export const ClientIcon = () =>
|
||||
Widget.Icon({
|
||||
connections: [
|
||||
[
|
||||
Hyprland.active.client,
|
||||
(self) => {
|
||||
const { icons } = options.substitutions;
|
||||
const { client } = Hyprland.active;
|
||||
setup: (self) =>
|
||||
self.hook(Hyprland.active.client, () => {
|
||||
const { icons } = options.substitutions;
|
||||
const { client } = Hyprland.active;
|
||||
|
||||
const classIcon = substitute(icons, client.class) + "-symbolic";
|
||||
const titleIcon = substitute(icons, client.class) + "-symbolic";
|
||||
const classIcon = substitute(icons, client.class) + "-symbolic";
|
||||
const titleIcon = substitute(icons, client.class) + "-symbolic";
|
||||
|
||||
const hasTitleIcon = Utils.lookUpIcon(titleIcon);
|
||||
const hasClassIcon = Utils.lookUpIcon(classIcon);
|
||||
const hasTitleIcon = Utils.lookUpIcon(titleIcon);
|
||||
const hasClassIcon = Utils.lookUpIcon(classIcon);
|
||||
|
||||
if (hasClassIcon) self.icon = classIcon;
|
||||
if (hasClassIcon) self.icon = classIcon;
|
||||
|
||||
if (hasTitleIcon) self.icon = titleIcon;
|
||||
if (hasTitleIcon) self.icon = titleIcon;
|
||||
|
||||
self.visible = !!(hasTitleIcon || hasClassIcon);
|
||||
},
|
||||
],
|
||||
],
|
||||
self.visible = !!(hasTitleIcon || hasClassIcon);
|
||||
}),
|
||||
});
|
||||
|
||||
export default () =>
|
||||
PanelButton({
|
||||
class_name: "focused-client",
|
||||
content: Widget.Box({
|
||||
tooltip_text: Hyprland.active.bind("client").transform((c) => c.title),
|
||||
children: [ClientIcon(), ClientLabel()],
|
||||
binds: [["tooltip-text", Hyprland.active, "client", (c) => c.title]],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -26,31 +26,24 @@ const Indicator = ({ player, direction = "right" }) =>
|
||||
vexpand: true,
|
||||
truncate: "end",
|
||||
max_width_chars: 40,
|
||||
connections: [
|
||||
[
|
||||
player,
|
||||
(label) => {
|
||||
label.label = `${player.track_artists.join(", ")} - ${
|
||||
player.track_title
|
||||
}`;
|
||||
},
|
||||
],
|
||||
],
|
||||
label: player
|
||||
.bind("track_title")
|
||||
.transform(
|
||||
() => `${player.track_artists.join(", ")} - ${player.track_title}`,
|
||||
),
|
||||
}),
|
||||
connections: [
|
||||
[
|
||||
player,
|
||||
(revealer) => {
|
||||
if (revealer._current === player.track_title) return;
|
||||
setupRevealer: (self) => {
|
||||
let current = "";
|
||||
self.hook(player, () => {
|
||||
if (current === player.track_title) return;
|
||||
|
||||
revealer._current = player.track_title;
|
||||
revealer.reveal_child = true;
|
||||
Utils.timeout(3000, () => {
|
||||
revealer.reveal_child = false;
|
||||
});
|
||||
},
|
||||
],
|
||||
],
|
||||
current = player.track_title;
|
||||
self.reveal_child = true;
|
||||
Utils.timeout(3000, () => {
|
||||
self.reveal_child = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -75,10 +68,7 @@ export default ({ direction = "right" } = {}) => {
|
||||
box.children = [Indicator({ player, direction })];
|
||||
};
|
||||
|
||||
return Widget.Box({
|
||||
connections: [
|
||||
[options.mpris.preferred, update],
|
||||
[Mpris, update, "notify::players"],
|
||||
],
|
||||
});
|
||||
return Widget.Box()
|
||||
.hook(options.mpris.preferred, update)
|
||||
.hook(Mpris, update, "notify::players");
|
||||
};
|
||||
|
||||
@@ -12,52 +12,39 @@ import HoverRevealer from "../../misc/HoverRevealer.js";
|
||||
export default ({ direction = "left" } = {}) =>
|
||||
HoverRevealer({
|
||||
class_name: "notifications panel-button",
|
||||
eventboxConnections: [
|
||||
["button-press-event", () => App.openWindow("dashboard")],
|
||||
[
|
||||
Notifications,
|
||||
(box) =>
|
||||
(box.visible =
|
||||
Notifications.notifications.length > 0 || Notifications.dnd),
|
||||
],
|
||||
],
|
||||
connections: [
|
||||
[
|
||||
Notifications,
|
||||
(revealer) => {
|
||||
const title = Notifications.notifications[0]?.summary;
|
||||
if (revealer._title === title) return;
|
||||
setupEventBox: (box) =>
|
||||
box
|
||||
.on("button-press-event", () => App.openWindow("dashboard"))
|
||||
.hook(
|
||||
Notifications,
|
||||
() =>
|
||||
(box.visible =
|
||||
Notifications.notifications.length > 0 || Notifications.dnd),
|
||||
),
|
||||
|
||||
revealer._title = title;
|
||||
revealer.reveal_child = true;
|
||||
Utils.timeout(3000, () => {
|
||||
revealer.reveal_child = false;
|
||||
});
|
||||
},
|
||||
],
|
||||
],
|
||||
setupRevealer: (self) =>
|
||||
self.hook(Notifications, () => {
|
||||
let title = "";
|
||||
const summary = Notifications.notifications[0]?.summary;
|
||||
if (title === summary) return;
|
||||
|
||||
title = summary;
|
||||
self.reveal_child = true;
|
||||
Utils.timeout(3000, () => {
|
||||
self.reveal_child = false;
|
||||
});
|
||||
}),
|
||||
direction,
|
||||
indicator: Widget.Icon({
|
||||
binds: [
|
||||
[
|
||||
"icon",
|
||||
Notifications,
|
||||
"dnd",
|
||||
(dnd) =>
|
||||
dnd ? icons.notifications.silent : icons.notifications.noisy,
|
||||
],
|
||||
],
|
||||
icon: Notifications.bind("dnd").transform(
|
||||
(dnd) => icons.notifications[dnd ? "silent" : "noisy"],
|
||||
),
|
||||
}),
|
||||
child: Widget.Label({
|
||||
truncate: "end",
|
||||
max_width_chars: 40,
|
||||
binds: [
|
||||
[
|
||||
"label",
|
||||
Notifications,
|
||||
"notifications",
|
||||
(n) => n.reverse()[0]?.summary || "",
|
||||
],
|
||||
],
|
||||
label: Notifications.bind("notifications").transform(
|
||||
(n) => n.reverse()[0]?.summary || "",
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -10,15 +10,8 @@ export default () =>
|
||||
window: "overview",
|
||||
on_clicked: () => App.toggleWindow("overview"),
|
||||
content: FontIcon({
|
||||
binds: [
|
||||
[
|
||||
"icon",
|
||||
options.bar.icon,
|
||||
"value",
|
||||
(v) => {
|
||||
return v === "distro-icon" ? distroIcon : v;
|
||||
},
|
||||
],
|
||||
],
|
||||
label: options.bar.icon.bind("value").transform((v) => {
|
||||
return v === "distro-icon" ? distroIcon : v;
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -7,23 +7,16 @@ export default () =>
|
||||
PanelButton({
|
||||
class_name: "recorder",
|
||||
on_clicked: () => Recorder.stop(),
|
||||
binds: [["visible", Recorder, "recording"]],
|
||||
visible: Recorder.bind("recording"),
|
||||
content: Widget.Box({
|
||||
children: [
|
||||
Widget.Icon(icons.recorder.recording),
|
||||
Widget.Label({
|
||||
binds: [
|
||||
[
|
||||
"label",
|
||||
Recorder,
|
||||
"timer",
|
||||
(time) => {
|
||||
const sec = time % 60;
|
||||
const min = Math.floor(time / 60);
|
||||
return `${min}:${sec < 10 ? "0" + sec : sec}`;
|
||||
},
|
||||
],
|
||||
],
|
||||
label: Recorder.bind("timer").transform((time) => {
|
||||
const sec = time % 60;
|
||||
const min = Math.floor(time / 60);
|
||||
return `${min}:${sec < 10 ? "0" + sec : sec}`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
||||
@@ -7,7 +7,7 @@ import options from "../../options.js";
|
||||
/**
|
||||
* @param {import('types/widgets/revealer').default} revealer
|
||||
* @param {'left' | 'right' | 'up' | 'down'} direction
|
||||
* @param {import('types/variable').Variable} items
|
||||
* @param {import('types/variable').Variable<number>} items
|
||||
*/
|
||||
const Arrow = (revealer, direction, items) => {
|
||||
let deg = 0;
|
||||
@@ -29,14 +29,7 @@ const Arrow = (revealer, direction, items) => {
|
||||
|
||||
return Widget.Button({
|
||||
class_name: "panel-button sub-menu",
|
||||
connections: [
|
||||
[
|
||||
items,
|
||||
(btn) => {
|
||||
btn.tooltip_text = `${items.value} Items`;
|
||||
},
|
||||
],
|
||||
],
|
||||
tooltip_text: items.bind().transform((v) => `${v} Items`),
|
||||
on_clicked: () => {
|
||||
animate();
|
||||
revealer.reveal_child = !revealer.reveal_child;
|
||||
|
||||
@@ -13,23 +13,16 @@ const System = (type) => {
|
||||
const progress = Widget.Box({
|
||||
class_name: "progress",
|
||||
child: Widget.CircularProgress({
|
||||
binds: [["value", variables[type]]],
|
||||
value: variables[type].bind(),
|
||||
}),
|
||||
});
|
||||
|
||||
const revealer = Widget.Revealer({
|
||||
transition: "slide_right",
|
||||
child: Widget.Label({
|
||||
binds: [
|
||||
[
|
||||
"label",
|
||||
variables[type],
|
||||
"value",
|
||||
(v) => {
|
||||
return ` ${type}: ${Math.round(v * 100)}%`;
|
||||
},
|
||||
],
|
||||
],
|
||||
label: variables[type].bind("value").transform((v) => {
|
||||
return ` ${type}: ${Math.round(v * 100)}%`;
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ const MicrophoneIndicator = () =>
|
||||
if (!Audio.microphone) return;
|
||||
|
||||
const { muted, low, medium, high } = icons.audio.mic;
|
||||
if (Audio.microphone.is_muted) return (icon.icon = muted);
|
||||
|
||||
/** @type {Array<[number, string]>} */
|
||||
const cons = [
|
||||
@@ -42,7 +41,7 @@ const MicrophoneIndicator = () =>
|
||||
|
||||
icon.visible = Audio.recorders.length > 0 || Audio.microphone.is_muted;
|
||||
},
|
||||
"speaker-changed",
|
||||
"microphone-changed",
|
||||
);
|
||||
|
||||
const DNDIndicator = () =>
|
||||
|
||||
@@ -26,9 +26,6 @@ const setChildren = (box) =>
|
||||
}));
|
||||
|
||||
export default () =>
|
||||
Widget.Box({
|
||||
connections: [
|
||||
[Hyprland, setChildren, "notify::clients"],
|
||||
[Hyprland, setChildren, "notify::active"],
|
||||
],
|
||||
});
|
||||
Widget.Box()
|
||||
.hook(Hyprland, setChildren, "notify::clients")
|
||||
.hook(Hyprland, setChildren, "notify::active");
|
||||
|
||||
@@ -12,40 +12,34 @@ const Workspaces = () => {
|
||||
return Widget.Box({
|
||||
children: range(ws || 20).map((i) =>
|
||||
Widget.Button({
|
||||
setup: (btn) => (btn.id = i),
|
||||
attribute: i,
|
||||
on_clicked: () => dispatch(i),
|
||||
child: Widget.Label({
|
||||
label: `${i}`,
|
||||
class_name: "indicator",
|
||||
vpack: "center",
|
||||
}),
|
||||
connections: [
|
||||
[
|
||||
Hyprland,
|
||||
(btn) => {
|
||||
btn.toggleClassName("active", Hyprland.active.workspace.id === i);
|
||||
btn.toggleClassName(
|
||||
"occupied",
|
||||
Hyprland.getWorkspace(i)?.windows > 0,
|
||||
);
|
||||
},
|
||||
],
|
||||
],
|
||||
setup: (self) =>
|
||||
self.hook(Hyprland, () => {
|
||||
self.toggleClassName("active", Hyprland.active.workspace.id === i);
|
||||
self.toggleClassName(
|
||||
"occupied",
|
||||
(Hyprland.getWorkspace(i)?.windows || 0) > 0,
|
||||
);
|
||||
}),
|
||||
}),
|
||||
),
|
||||
connections: ws
|
||||
? []
|
||||
: [
|
||||
[
|
||||
Hyprland.active.workspace,
|
||||
(box) =>
|
||||
box.children.map((btn) => {
|
||||
btn.visible = Hyprland.workspaces.some(
|
||||
(ws) => ws.id === btn.id,
|
||||
);
|
||||
}),
|
||||
],
|
||||
],
|
||||
setup: (box) => {
|
||||
if (ws === 0) {
|
||||
box.hook(Hyprland.active.workspace, () =>
|
||||
box.children.map((btn) => {
|
||||
btn.visible = Hyprland.workspaces.some(
|
||||
(ws) => ws.id === btn.attribute,
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -58,7 +52,7 @@ export default () =>
|
||||
on_scroll_up: () => dispatch("m+1"),
|
||||
on_scroll_down: () => dispatch("m-1"),
|
||||
class_name: "eventbox",
|
||||
binds: [["child", options.workspaces, "value", Workspaces]],
|
||||
child: options.workspaces.bind("value").transform(Workspaces),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user