Add darkmode toggle

This commit is contained in:
2024-07-07 23:33:00 +07:00
parent 7db26e31eb
commit dead1213af
3 changed files with 91 additions and 92 deletions
+5 -11
View File
@@ -3,7 +3,7 @@ import * as audio from "../modules/audio.js";
import * as brightness from "../modules/brightness.js";
import * as network from "../modules/network.js";
import * as bluetooth from "../modules/bluetooth.js";
// import * as darkmode from "../modules/darkmode.js";
import * as darkmode from "../modules/darkmode.js";
// import * as nightmode from "../modules/nightmode.js";
import * as mpris from "../modules/mpris.js";
import PopupWindow from "../misc/popup.js";
@@ -20,7 +20,6 @@ const Row = (toggles = [], menus = []) =>
children: [
Widget.Box({
homogeneous: true,
class_name: "row horizontal",
children: toggles,
}),
...menus,
@@ -45,18 +44,13 @@ export const Quicksettings = () =>
[network.Toggle({}), bluetooth.Toggle({})],
[network.Selection({}), bluetooth.Selection({})],
),
// Box({
// children: [darkmode.DarkToggle(), nightmode.NightToggle()],
// }),
Widget.Box({
homogeneous: true,
children: [darkmode.Toggle(), darkmode.Toggle()],
}),
// Box({
// children: [audio.AppMixerToggle(), audio.MuteToggle()],
// }),
// Submenu({
// menuName: "app-mixer",
// icon: FontIcon({ icon: "" }),
// title: "App Mixer",
// contentType: audio.AppMixer,
// }),
Widget.Box({
children: mprisService
.bind("players")
+41
View File
@@ -88,6 +88,47 @@ export const ArrowToggleButton = ({
],
});
/**
* @typedef {{
* icon: Gtk.Widget,
* label: Gtk.Widget,
* activate: () => void
* deactivate: () => void
* connection: [GObject.Object, () => boolean]
* } & import("types/widgets/box").BoxProps} SimpleToggleButtonProps
* @param {SimpleToggleButtonProps} props
*/
export const SimpleToggleButton = ({
icon,
label,
activate,
deactivate,
connection: [service, condition],
}) =>
Widget.Box({
className: "qs-button surface",
setup: (self) =>
self.hook(service, () => {
self.toggleClassName("accent", condition());
}),
children: [
Widget.Button({
child: Widget.Box({
hexpand: true,
children: [icon, label],
}),
onClicked: () => {
if (condition()) {
deactivate();
} else {
activate();
}
},
}),
],
});
/**
* @typedef {{
* name: string,
+45 -81
View File
@@ -1,87 +1,51 @@
import GLib from 'gi://GLib';
import Gio from "gi://Gio";
import GLib from "gi://GLib?version=2.0";
import Service from 'resource:///com/github/Aylur/ags/service.js'
import { exec, execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
import { Icon, Label, Button, Box, Stack } from 'resource:///com/github/Aylur/ags/widget.js';
import { SimpleToggleButton } from "../misc/menu.js";
class ThemeService extends Service {
static {
Service.register(this);
}
const theme = Variable(/** @type {"light" | "dark"} */ ("light"));
_dark = false;
get dark() {
return this._dark;
}
set dark(value) {
this._dark = value;
execAsync(`gsettings set org.gnome.desktop.interface color-scheme prefer-${this._dark ? "dark" : "light"}`).catch(
print
);
execAsync(`gsettings set org.gnome.desktop.interface gtk-theme adw-gtk3${this._dark ? "-dark" : ""}`).catch(
print
);
const conf = GLib.get_user_config_dir();
execAsync(`ln -sf ${conf}/kitty/${this._dark ? "dark" : "light"}.conf ${conf}/kitty/theme.conf`).catch(
print
);
execAsync("pkill -USR1 kitty").catch(print);
this.emit("changed");
}
toggle() {
this.dark = !this.dark;
}
constructor() {
super();
this._dark = exec(`gsettings get org.gnome.desktop.interface color-scheme`) === "'prefer-dark'";
// Ensure that the gtk theme is in sync with the theme.
this._dark = this._dark;
}
}
const Theme = new ThemeService();
export const Indicator = ({ ...props } = {}) =>
Stack({
items: [
["light", Icon("weather-clear-symbolic")],
["dark", Icon("weather-clear-night-symbolic")],
],
...props,
connections: [
[
Theme,
(stack) => {
stack.shown = Theme.dark ? "dark" : "light";
},
],
],
});
export const ThemeLabel = () =>
Label({
connections: [
[
Theme,
(label) => {
label.label = Theme.dark ? "Dark Theme" : "Light Theme";
},
],
],
});
export const DarkToggle = ({ ...props } = {}) =>
Button({
className: "qs-button surface",
hexpand: true,
onClicked: () => Theme.toggle(),
child: Box({
children: [Indicator({ className: "qs-icon" }), ThemeLabel()],
/** @param {Partial<import("../misc/menu.js").SimpleToggleButtonProps>} props */
export const Toggle = ({ ...props } = {}) =>
SimpleToggleButton({
icon: Widget.Icon({
className: "qs-icon",
icon: theme
.bind()
.as((x) =>
x === "light"
? "weather-clear-symbolic"
: "weather-clear-night-symbolic",
),
}),
connections: [[Theme, (button) => button.toggleClassName("accent", Theme.dark)]],
label: Widget.Label({
label: theme.bind().as((x) => (x === "light" ? "Light" : "Dark")),
}),
activate: () => theme.setValue("dark"),
deactivate: () => theme.setValue("light"),
connection: [theme, () => theme.value === "dark"],
...props,
});
function init() {
const settings = new Gio.Settings({
schema: "org.gnome.desktop.interface",
});
const initial = /** @type {"prefer-light" | "prefer-dark"}} */ (
settings.get_value("color-scheme").get_string()[0]
);
theme.setValue(/** @type {any}} */ (initial.substring("prefer-".length)));
theme.connect("changed", () => {
settings.set_string("color-scheme", `prefer-${theme.value}`);
settings.set_string(
"gtk-theme",
`adw-gtk3${theme.value === "dark" ? "-dark" : ""}`,
);
const conf = GLib.get_user_config_dir();
Utils.execAsync(
`bash -c 'ln -sf ${conf}/kitty/${theme.value}.conf ${conf}/kitty/theme.conf && pkill -USR1 kitty'`,
).catch(print);
});
}
init();