diff --git a/app.ts b/app.ts index ad2f598..a214edc 100644 --- a/app.ts +++ b/app.ts @@ -1,6 +1,6 @@ import { App } from "astal/gtk4"; import style from "./style.scss"; -import Bar from "./widget/Bar"; +import Bar from "@/widget/Bar"; App.start({ css: style, diff --git a/flake.nix b/flake.nix index 4fd569c..559b4a1 100644 --- a/flake.nix +++ b/flake.nix @@ -31,6 +31,8 @@ network tray wireplumber + pkgs.brightnessctl + matcha.packages.${pkgs.system}.default ]; in { packages.${system} = { diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..260b2b6 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,19 @@ +import { execAsync } from "astal"; + +// https://github.com/andre-brandao/hyprshell/blob/bb26e6a1f9afa924b3bb4acfbf822e8fed37221e/src/lib/utils.ts +/** + * @returns true if all of the `bins` are found + */ +export function dependencies(...bins: string[]) { + const missing = bins.filter((bin) => { + execAsync(`which ${bin}`) + .then(() => true) + .catch(() => false); + }); + + if (missing.length > 0) { + console.warn(Error(`missing dependencies: ${missing.join(", ")}`)); + } + + return missing.length === 0; +} diff --git a/service/brightness.ts b/src/service/brightness.ts similarity index 100% rename from service/brightness.ts rename to src/service/brightness.ts diff --git a/widget/Bar.tsx b/src/widget/Bar.tsx similarity index 86% rename from widget/Bar.tsx rename to src/widget/Bar.tsx index 85bf6f0..52109ad 100644 --- a/widget/Bar.tsx +++ b/src/widget/Bar.tsx @@ -1,11 +1,12 @@ import { Astal, Gtk, Gdk } from "astal/gtk4"; -import { Variable, GLib, bind, execAsync, exec } from "astal"; +import { Variable, GLib, bind, exec } from "astal"; import Battery from "gi://AstalBattery"; import Bluetooth from "gi://AstalBluetooth"; import Wp from "gi://AstalWp"; import Network from "gi://AstalNetwork"; import Hyprland from "gi://AstalHyprland"; -import Brightness from "../service/brightness"; +import Brightness from "@/service/brightness"; +import { dependencies } from "@/lib/utils"; const network = Network.get_default(); const wifi = bind(network, "wifi"); @@ -102,25 +103,41 @@ function Time({ format = "%H:%M - %A %e." }) { ); } -function IdleInhibitor() { - const icon = Variable(getIcon()); +type IdleState = "active" | "inactive" | "unknown"; - function getIcon() { - const state = exec("matcha --status"); - const enabled = state.match(/on/g); - return enabled ? "my-caffeine-on-symbolic" : "my-caffeine-off-symbolic"; +function IdleInhibitor() { + /* + * matcha needs additional checking to ensure the daemon is properly running + */ + function isDaemonRunning() { + try { + exec("matcha --status"); + return true; + } catch { + return false; + } } + if (!dependencies("matcha") || !isDaemonRunning()) return <>; + + const state = Variable("unknown"); + function toggle() { exec("matcha --toggle"); - icon.set(getIcon()); + const response = exec("matcha --status"); + const enabled = response.match(/on/g); + state.set(enabled ? "active" : "inactive"); } return (