mirror of
https://github.com/Theaninova/TheaninovOS.git
synced 2026-01-08 08:42:49 +00:00
feat: update system
This commit is contained in:
@@ -8,10 +8,10 @@ export const ProfileToggle = () =>
|
||||
ArrowToggleButton({
|
||||
name: "asusctl-profile",
|
||||
icon: Widget.Icon({
|
||||
binds: [["icon", Asusctl, "profile", (p) => icons.asusctl.profile[p]]],
|
||||
icon: Asusctl.bind("profile").transform((p) => icons.asusctl.profile[p]),
|
||||
}),
|
||||
label: Widget.Label({
|
||||
binds: [["label", Asusctl, "profile"]],
|
||||
label: Asusctl.bind("profile"),
|
||||
}),
|
||||
connection: [Asusctl, () => Asusctl.profile !== "Balanced"],
|
||||
activate: () => Asusctl.setProfile("Quiet"),
|
||||
@@ -23,7 +23,7 @@ export const ProfileSelector = () =>
|
||||
Menu({
|
||||
name: "asusctl-profile",
|
||||
icon: Widget.Icon({
|
||||
binds: [["icon", Asusctl, "profile", (p) => icons.asusctl.profile[p]]],
|
||||
icon: Asusctl.bind("profile").transform((p) => icons.asusctl.profile[p]),
|
||||
}),
|
||||
title: Widget.Label("Profile Selector"),
|
||||
content: [
|
||||
|
||||
@@ -7,41 +7,31 @@ export const BluetoothToggle = () =>
|
||||
ArrowToggleButton({
|
||||
name: "bluetooth",
|
||||
icon: Widget.Icon({
|
||||
connections: [
|
||||
[
|
||||
Bluetooth,
|
||||
(icon) => {
|
||||
icon.icon = Bluetooth.enabled
|
||||
? icons.bluetooth.enabled
|
||||
: icons.bluetooth.disabled;
|
||||
},
|
||||
],
|
||||
],
|
||||
icon: Bluetooth.bind("enabled").transform(
|
||||
(p) => icons.bluetooth[p ? "enabled" : "disabled"],
|
||||
),
|
||||
}),
|
||||
label: Widget.Label({
|
||||
truncate: "end",
|
||||
connections: [
|
||||
[
|
||||
Bluetooth,
|
||||
(label) => {
|
||||
if (!Bluetooth.enabled) return (label.label = "Disabled");
|
||||
setup: (self) =>
|
||||
self.hook(Bluetooth, () => {
|
||||
if (!Bluetooth.enabled) return (self.label = "Disabled");
|
||||
|
||||
if (Bluetooth.connectedDevices.length === 0)
|
||||
return (label.label = "Not Connected");
|
||||
if (Bluetooth.connected_devices.length === 0)
|
||||
return (self.label = "Not Connected");
|
||||
|
||||
if (Bluetooth.connectedDevices.length === 1)
|
||||
return (label.label = Bluetooth.connectedDevices[0].alias);
|
||||
if (Bluetooth.connected_devices.length === 1)
|
||||
return (self.label = Bluetooth.connected_devices[0].alias);
|
||||
|
||||
label.label = `${Bluetooth.connectedDevices.length} Connected`;
|
||||
},
|
||||
],
|
||||
],
|
||||
self.label = `${Bluetooth.connected_devices.length} Connected`;
|
||||
}),
|
||||
}),
|
||||
connection: [Bluetooth, () => Bluetooth.enabled],
|
||||
deactivate: () => (Bluetooth.enabled = false),
|
||||
activate: () => (Bluetooth.enabled = true),
|
||||
});
|
||||
|
||||
/** @param {import('types/service/bluetooth').BluetoothDevice} device */
|
||||
const DeviceItem = (device) =>
|
||||
Widget.Box({
|
||||
children: [
|
||||
@@ -49,26 +39,20 @@ const DeviceItem = (device) =>
|
||||
Widget.Label(device.name),
|
||||
Widget.Label({
|
||||
label: `${device.battery_percentage}%`,
|
||||
binds: [["visible", device, "battery-percentage", (p) => p > 0]],
|
||||
visible: device.bind("battery_percentage").transform((p) => p > 0),
|
||||
}),
|
||||
Widget.Box({ hexpand: true }),
|
||||
Widget.Spinner({
|
||||
binds: [
|
||||
["active", device, "connecting"],
|
||||
["visible", device, "connecting"],
|
||||
],
|
||||
active: device.bind("connecting"),
|
||||
visible: device.bind("connecting"),
|
||||
}),
|
||||
Widget.Switch({
|
||||
active: device.connected,
|
||||
binds: [["visible", device, "connecting", (c) => !c]],
|
||||
connections: [
|
||||
[
|
||||
"notify::active",
|
||||
({ active }) => {
|
||||
device.setConnection(active);
|
||||
},
|
||||
],
|
||||
],
|
||||
visible: device.bind("connecting").transform((p) => !p),
|
||||
setup: (self) =>
|
||||
self.on("notify::active", () => {
|
||||
device.setConnection(self.active);
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -82,14 +66,9 @@ export const BluetoothDevices = () =>
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
binds: [
|
||||
[
|
||||
"children",
|
||||
Bluetooth,
|
||||
"devices",
|
||||
(ds) => ds.filter((d) => d.name).map(DeviceItem),
|
||||
],
|
||||
],
|
||||
children: Bluetooth.bind("devices").transform((ds) =>
|
||||
ds.filter((d) => d.name).map(DeviceItem),
|
||||
),
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js";
|
||||
import icons from "../../icons.js";
|
||||
import Brightness from "../../services/brightness.js";
|
||||
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
|
||||
|
||||
const CanSupportBrightness = () => Utils.exec("which gbmonctl");
|
||||
|
||||
const BrightnessSlider = () =>
|
||||
Widget.Slider({
|
||||
draw_value: false,
|
||||
hexpand: true,
|
||||
binds: [["value", Brightness, "screen"]],
|
||||
value: Brightness.bind("screen"),
|
||||
on_change: ({ value }) => (Brightness.screen = value),
|
||||
});
|
||||
|
||||
@@ -18,14 +15,9 @@ export default () =>
|
||||
children: [
|
||||
Widget.Button({
|
||||
child: Widget.Icon(icons.brightness.indicator),
|
||||
binds: [
|
||||
[
|
||||
"tooltip-text",
|
||||
Brightness,
|
||||
"screen",
|
||||
(v) => `Screen Brightness: ${Math.floor(v * 100)}%`,
|
||||
],
|
||||
],
|
||||
tooltip_text: Brightness.bind("screen").transform(
|
||||
(v) => `Screen Brightness: ${Math.floor(v * 100)}%`,
|
||||
),
|
||||
}),
|
||||
BrightnessSlider(),
|
||||
],
|
||||
|
||||
@@ -6,17 +6,9 @@ import { SimpleToggleButton } from "../ToggleButton.js";
|
||||
export default () =>
|
||||
SimpleToggleButton({
|
||||
icon: Widget.Icon({
|
||||
connections: [
|
||||
[
|
||||
Notifications,
|
||||
(icon) => {
|
||||
icon.icon = Notifications.dnd
|
||||
? icons.notifications.silent
|
||||
: icons.notifications.noisy;
|
||||
},
|
||||
"notify::dnd",
|
||||
],
|
||||
],
|
||||
icon: Notifications.bind("dnd").transform(
|
||||
(dnd) => icons.notifications[dnd ? "silent" : "noisy"],
|
||||
),
|
||||
}),
|
||||
toggle: () => (Notifications.dnd = !Notifications.dnd),
|
||||
connection: [Notifications, () => Notifications.dnd],
|
||||
|
||||
@@ -6,6 +6,7 @@ import Avatar from "../../misc/Avatar.js";
|
||||
import icons from "../../icons.js";
|
||||
import { openSettings } from "../../settings/theme.js";
|
||||
import { uptime } from "../../variables.js";
|
||||
import DND from "./DND.js";
|
||||
|
||||
export default () =>
|
||||
Widget.Box({
|
||||
@@ -20,16 +21,17 @@ export default () =>
|
||||
/*Widget.Box({
|
||||
class_name: "battery horizontal",
|
||||
children: [
|
||||
Widget.Icon({ binds: [["icon", Battery, "icon-name"]] }),
|
||||
Widget.Icon({ icon: Battery.bind("icon_name") }),
|
||||
Widget.Label({
|
||||
binds: [["label", Battery, "percent", (p) => `${p}%`]],
|
||||
label: Battery.bind("percent").transform((p) => `${p}%`),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),*/
|
||||
DND(),
|
||||
Widget.Label({
|
||||
class_name: "uptime",
|
||||
binds: [["label", uptime, "value", (v) => `up: ${v}`]],
|
||||
}),*/
|
||||
label: uptime.bind().transform((v) => `up: ${v}`),
|
||||
}),
|
||||
Widget.Button({
|
||||
on_clicked: openSettings,
|
||||
child: Widget.Icon(icons.ui.settings),
|
||||
|
||||
@@ -7,31 +7,29 @@ import options from "../../options.js";
|
||||
const Footer = (player) =>
|
||||
Widget.CenterBox({
|
||||
class_name: "footer-box",
|
||||
children: [
|
||||
Widget.Box({
|
||||
class_name: "position",
|
||||
children: [
|
||||
mpris.PositionLabel(player),
|
||||
mpris.Slash(player),
|
||||
mpris.LengthLabel(player),
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
class_name: "controls",
|
||||
children: [
|
||||
mpris.ShuffleButton(player),
|
||||
mpris.PreviousButton(player),
|
||||
mpris.PlayPauseButton(player),
|
||||
mpris.NextButton(player),
|
||||
mpris.LoopButton(player),
|
||||
],
|
||||
}),
|
||||
mpris.PlayerIcon(player, {
|
||||
symbolic: false,
|
||||
hexpand: true,
|
||||
hpack: "end",
|
||||
}),
|
||||
],
|
||||
start_widget: Widget.Box({
|
||||
class_name: "position",
|
||||
children: [
|
||||
mpris.PositionLabel(player),
|
||||
mpris.Slash(player),
|
||||
mpris.LengthLabel(player),
|
||||
],
|
||||
}),
|
||||
center_widget: Widget.Box({
|
||||
class_name: "controls",
|
||||
children: [
|
||||
mpris.ShuffleButton(player),
|
||||
mpris.PreviousButton(player),
|
||||
mpris.PlayPauseButton(player),
|
||||
mpris.NextButton(player),
|
||||
mpris.LoopButton(player),
|
||||
],
|
||||
}),
|
||||
end_widget: mpris.PlayerIcon(player, {
|
||||
symbolic: false,
|
||||
hexpand: true,
|
||||
hpack: "end",
|
||||
}),
|
||||
});
|
||||
|
||||
/** @param {import('types/service/mpris').MprisPlayer} player */
|
||||
@@ -84,23 +82,10 @@ export default () =>
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
class_name: "media vertical",
|
||||
connections: [
|
||||
[
|
||||
"draw",
|
||||
(self) => {
|
||||
self.visible = Mpris.players.length > 0;
|
||||
},
|
||||
],
|
||||
],
|
||||
binds: [
|
||||
[
|
||||
"children",
|
||||
Mpris,
|
||||
"players",
|
||||
(ps) =>
|
||||
ps
|
||||
.filter((p) => !options.mpris.black_list.value.includes(p.identity))
|
||||
.map(PlayerBox),
|
||||
],
|
||||
],
|
||||
visible: Mpris.bind("players").transform((p) => p.length > 0),
|
||||
children: Mpris.bind("players").transform((ps) =>
|
||||
ps
|
||||
.filter((p) => !options.mpris.black_list.value.includes(p.identity))
|
||||
.map(PlayerBox),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -5,19 +5,15 @@ import { SimpleToggleButton } from "../ToggleButton.js";
|
||||
|
||||
export default () =>
|
||||
SimpleToggleButton({
|
||||
icon: Widget.Icon({
|
||||
connections: [
|
||||
[
|
||||
Audio,
|
||||
(icon) => {
|
||||
icon.icon = Audio.microphone?.is_muted
|
||||
? icons.audio.mic.muted
|
||||
: icons.audio.mic.high;
|
||||
},
|
||||
"microphone-changed",
|
||||
],
|
||||
],
|
||||
}),
|
||||
icon: Widget.Icon().hook(
|
||||
Audio,
|
||||
(self) => {
|
||||
self.icon = Audio.microphone?.is_muted
|
||||
? icons.audio.mic.muted
|
||||
: icons.audio.mic.high;
|
||||
},
|
||||
"microphone-changed",
|
||||
),
|
||||
toggle: () => (Audio.microphone.is_muted = !Audio.microphone.is_muted),
|
||||
connection: [Audio, () => Audio.microphone?.is_muted],
|
||||
connection: [Audio, () => Audio.microphone?.is_muted || false],
|
||||
});
|
||||
|
||||
@@ -9,25 +9,13 @@ export const NetworkToggle = () =>
|
||||
ArrowToggleButton({
|
||||
name: "network",
|
||||
icon: Widget.Icon({
|
||||
connections: [
|
||||
[
|
||||
Network,
|
||||
(icon) => {
|
||||
icon.icon = Network.wifi.icon_name || "";
|
||||
},
|
||||
],
|
||||
],
|
||||
icon: Network.wifi.bind("icon_name"),
|
||||
}),
|
||||
label: Widget.Label({
|
||||
truncate: "end",
|
||||
connections: [
|
||||
[
|
||||
Network,
|
||||
(label) => {
|
||||
label.label = Network.wifi.ssid || "Not Connected";
|
||||
},
|
||||
],
|
||||
],
|
||||
label: Network.wifi
|
||||
.bind("ssid")
|
||||
.transform((ssid) => ssid || "Not Connected"),
|
||||
}),
|
||||
connection: [Network, () => Network.wifi.enabled],
|
||||
deactivate: () => (Network.wifi.enabled = false),
|
||||
@@ -41,24 +29,17 @@ export const WifiSelection = () =>
|
||||
Menu({
|
||||
name: "network",
|
||||
icon: Widget.Icon({
|
||||
connections: [
|
||||
[
|
||||
Network,
|
||||
(icon) => {
|
||||
icon.icon = Network.wifi.icon_name;
|
||||
},
|
||||
],
|
||||
],
|
||||
icon: Network.wifi.bind("icon_name"),
|
||||
}),
|
||||
title: Widget.Label("Wifi Selection"),
|
||||
content: [
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
connections: [
|
||||
[
|
||||
setup: (self) =>
|
||||
self.hook(
|
||||
Network,
|
||||
(box) =>
|
||||
(box.children = Network.wifi?.access_points.map((ap) =>
|
||||
() =>
|
||||
(self.children = Network.wifi?.access_points.map((ap) =>
|
||||
Widget.Button({
|
||||
on_clicked: () =>
|
||||
Utils.execAsync(`nmcli device wifi connect ${ap.bssid}`),
|
||||
@@ -76,8 +57,7 @@ export const WifiSelection = () =>
|
||||
}),
|
||||
}),
|
||||
)),
|
||||
],
|
||||
],
|
||||
),
|
||||
}),
|
||||
Widget.Separator(),
|
||||
Widget.Button({
|
||||
|
||||
@@ -8,8 +8,8 @@ import { setTheme, openSettings } from "../../settings/theme.js";
|
||||
export const ThemeToggle = () =>
|
||||
ArrowToggleButton({
|
||||
name: "theme",
|
||||
icon: Widget.Label({ binds: [["label", options.theme.icon]] }),
|
||||
label: Widget.Label({ binds: [["label", options.theme.name]] }),
|
||||
icon: Widget.Label().bind("label", options.theme.icon),
|
||||
label: Widget.Label().bind("label", options.theme.name),
|
||||
connection: [opened, () => opened.value === "theme"],
|
||||
activate: () => opened.setValue("theme"),
|
||||
activateOnArrow: false,
|
||||
@@ -19,9 +19,7 @@ export const ThemeToggle = () =>
|
||||
export const ThemeSelector = () =>
|
||||
Menu({
|
||||
name: "theme",
|
||||
icon: Widget.Label({
|
||||
binds: [["label", options.theme.icon]],
|
||||
}),
|
||||
icon: Widget.Label().bind("label", options.theme.icon),
|
||||
title: Widget.Label("Theme Selector"),
|
||||
content: [
|
||||
...themes.map(({ name, icon }) =>
|
||||
@@ -35,9 +33,9 @@ export const ThemeSelector = () =>
|
||||
icon: icons.ui.tick,
|
||||
hexpand: true,
|
||||
hpack: "end",
|
||||
binds: [
|
||||
["visible", options.theme.name, "value", (v) => v === name],
|
||||
],
|
||||
visible: options.theme.name
|
||||
.bind("value")
|
||||
.transform((v) => v === name),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
||||
@@ -11,25 +11,13 @@ import { Menu } from "../ToggleButton.js";
|
||||
const VolumeIndicator = (type = "speaker") =>
|
||||
Widget.Button({
|
||||
on_clicked: () => (Audio[type].is_muted = !Audio[type].is_muted),
|
||||
child: Widget.Icon({
|
||||
connections: [
|
||||
[
|
||||
Audio,
|
||||
(icon) => {
|
||||
if (!Audio[type]) return;
|
||||
child: Widget.Icon().hook(Audio[type], (icon) => {
|
||||
icon.icon =
|
||||
type === "speaker"
|
||||
? getAudioTypeIcon(Audio[type].icon_name || "")
|
||||
: icons.audio.mic.high;
|
||||
|
||||
icon.icon =
|
||||
type === "speaker"
|
||||
? getAudioTypeIcon(Audio[type].icon_name || "")
|
||||
: icons.audio.mic.high;
|
||||
|
||||
icon.tooltip_text = `Volume ${Math.floor(
|
||||
Audio[type].volume * 100,
|
||||
)}%`;
|
||||
},
|
||||
`${type}-changed`,
|
||||
],
|
||||
],
|
||||
icon.tooltip_text = `Volume ${Math.floor(Audio[type].volume * 100)}%`;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -39,15 +27,10 @@ const VolumeSlider = (type = "speaker") =>
|
||||
hexpand: true,
|
||||
draw_value: false,
|
||||
on_change: ({ value }) => (Audio[type].volume = value),
|
||||
connections: [
|
||||
[
|
||||
Audio,
|
||||
(slider) => {
|
||||
slider.value = Audio[type]?.volume;
|
||||
},
|
||||
`${type}-changed`,
|
||||
],
|
||||
],
|
||||
setup: (self) =>
|
||||
self.hook(Audio[type], () => {
|
||||
self.value = Audio[type].volume || 0;
|
||||
}),
|
||||
});
|
||||
|
||||
export const Volume = () =>
|
||||
@@ -62,14 +45,7 @@ export const Volume = () =>
|
||||
Widget.Box({
|
||||
vpack: "center",
|
||||
child: Arrow("app-mixer"),
|
||||
connections: [
|
||||
[
|
||||
Audio,
|
||||
(box) => {
|
||||
box.visible = Audio.apps.length > 0;
|
||||
},
|
||||
],
|
||||
],
|
||||
visible: Audio.bind("apps").transform((a) => a.length > 0),
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -77,7 +53,7 @@ export const Volume = () =>
|
||||
export const Microhone = () =>
|
||||
Widget.Box({
|
||||
class_name: "slider horizontal",
|
||||
binds: [["visible", Audio, "recorders", (r) => r.length > 0]],
|
||||
visible: Audio.bind("recorders").transform((a) => a.length > 0),
|
||||
children: [VolumeIndicator("microphone"), VolumeSlider("microphone")],
|
||||
});
|
||||
|
||||
@@ -88,17 +64,10 @@ const MixerItem = (stream) =>
|
||||
class_name: "mixer-item horizontal",
|
||||
children: [
|
||||
Widget.Icon({
|
||||
binds: [["tooltipText", stream, "name"]],
|
||||
connections: [
|
||||
[
|
||||
stream,
|
||||
(icon) => {
|
||||
icon.icon = Utils.lookUpIcon(stream.name || "")
|
||||
? stream.name || ""
|
||||
: icons.mpris.fallback;
|
||||
},
|
||||
],
|
||||
],
|
||||
tooltip_text: stream.bind("name").transform((n) => n || ""),
|
||||
icon: stream.bind("name").transform((n) => {
|
||||
return Utils.lookUpIcon(n || "") ? n || "" : icons.mpris.fallback;
|
||||
}),
|
||||
}),
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
@@ -106,26 +75,19 @@ const MixerItem = (stream) =>
|
||||
Widget.Label({
|
||||
xalign: 0,
|
||||
truncate: "end",
|
||||
binds: [["label", stream, "description"]],
|
||||
label: stream.bind("description").transform((d) => d || ""),
|
||||
}),
|
||||
Widget.Slider({
|
||||
hexpand: true,
|
||||
draw_value: false,
|
||||
binds: [["value", stream, "volume"]],
|
||||
value: stream.bind("volume"),
|
||||
on_change: ({ value }) => (stream.volume = value),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Label({
|
||||
xalign: 1,
|
||||
connections: [
|
||||
[
|
||||
stream,
|
||||
(l) => {
|
||||
l.label = `${Math.floor(stream.volume * 100)}%`;
|
||||
},
|
||||
],
|
||||
],
|
||||
label: stream.bind("volume").transform((v) => `${Math.floor(v * 100)}`),
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -148,7 +110,9 @@ const SinkItem = (stream) =>
|
||||
icon: icons.ui.tick,
|
||||
hexpand: true,
|
||||
hpack: "end",
|
||||
binds: [["visible", Audio, "speaker", (s) => s === stream]],
|
||||
visible: Audio.speaker
|
||||
.bind("stream")
|
||||
.transform((s) => s === stream.stream),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
@@ -171,7 +135,7 @@ export const AppMixer = () =>
|
||||
content: [
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
binds: [["children", Audio, "apps", (a) => a.map(MixerItem)]],
|
||||
children: Audio.bind("apps").transform((a) => a.map(MixerItem)),
|
||||
}),
|
||||
Widget.Separator(),
|
||||
SettingsButton(),
|
||||
@@ -186,7 +150,7 @@ export const SinkSelector = () =>
|
||||
content: [
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
binds: [["children", Audio, "speakers", (s) => s.map(SinkItem)]],
|
||||
children: Audio.bind("speakers").transform((a) => a.map(SinkItem)),
|
||||
}),
|
||||
Widget.Separator(),
|
||||
SettingsButton(),
|
||||
|
||||
Reference in New Issue
Block a user