diff options
Diffstat (limited to '.config/ags/service')
| -rw-r--r-- | .config/ags/service/asusctl.ts | 52 | ||||
| -rw-r--r-- | .config/ags/service/brightness.ts | 69 | ||||
| -rw-r--r-- | .config/ags/service/colorpicker.ts | 56 | ||||
| -rw-r--r-- | .config/ags/service/nix.ts | 109 | ||||
| -rw-r--r-- | .config/ags/service/powermenu.ts | 43 | ||||
| -rw-r--r-- | .config/ags/service/screenrecord.ts | 102 | ||||
| -rw-r--r-- | .config/ags/service/wallpaper.ts | 127 | ||||
| -rw-r--r-- | .config/ags/service/weather.ts | 59 |
8 files changed, 0 insertions, 617 deletions
diff --git a/.config/ags/service/asusctl.ts b/.config/ags/service/asusctl.ts deleted file mode 100644 index 16acbd7..0000000 --- a/.config/ags/service/asusctl.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { sh } from "lib/utils" - -type Profile = "Performance" | "Balanced" | "Quiet" -type Mode = "Hybrid" | "Integrated" - -class Asusctl extends Service { - static { - Service.register(this, {}, { - "profile": ["string", "r"], - "mode": ["string", "r"], - }) - } - - available = !!Utils.exec("which asusctl") - #profile: Profile = "Balanced" - #mode: Mode = "Hybrid" - - async nextProfile() { - await sh("asusctl profile -n") - const profile = await sh("asusctl profile -p") - const p = profile.split(" ")[3] as Profile - this.#profile = p - this.changed("profile") - } - - async setProfile(prof: Profile) { - await sh(`asusctl profile --profile-set ${prof}`) - this.#profile = prof - this.changed("profile") - } - - async nextMode() { - await sh(`supergfxctl -m ${this.#mode === "Hybrid" ? "Integrated" : "Hybrid"}`) - this.#mode = await sh("supergfxctl -g") as Mode - this.changed("profile") - } - - constructor() { - super() - - if (this.available) { - sh("asusctl profile -p").then(p => this.#profile = p.split(" ")[3] as Profile) - sh("supergfxctl -g").then(m => this.#mode = m as Mode) - } - } - - get profiles(): Profile[] { return ["Performance", "Balanced", "Quiet"] } - get profile() { return this.#profile } - get mode() { return this.#mode } -} - -export default new Asusctl diff --git a/.config/ags/service/brightness.ts b/.config/ags/service/brightness.ts deleted file mode 100644 index a0b8eb5..0000000 --- a/.config/ags/service/brightness.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { bash, dependencies, sh } from "lib/utils" - -if (!dependencies("brightnessctl")) - App.quit() - -const get = (args: string) => Number(Utils.exec(`brightnessctl ${args}`)) -const screen = await bash`ls -w1 /sys/class/backlight | head -1` -const kbd = await bash`ls -w1 /sys/class/leds | head -1` - -class Brightness extends Service { - static { - Service.register(this, {}, { - "screen": ["float", "rw"], - "kbd": ["int", "rw"], - }) - } - - #kbdMax = get(`--device ${kbd} max`) - #kbd = get(`--device ${kbd} get`) - #screenMax = get("max") - #screen = get("get") / get("max") - - get kbd() { return this.#kbd } - get screen() { return this.#screen } - - set kbd(value) { - if (value < 0 || value > this.#kbdMax) - return - - sh(`brightnessctl -d ${kbd} s ${value} -q`).then(() => { - this.#kbd = value - this.changed("kbd") - }) - } - - set screen(percent) { - if (percent < 0) - percent = 0 - - if (percent > 1) - percent = 1 - - sh(`brightnessctl set ${Math.floor(percent * 100)}% -q`).then(() => { - this.#screen = percent - this.changed("screen") - }) - } - - constructor() { - super() - - const screenPath = `/sys/class/backlight/${screen}/brightness` - const kbdPath = `/sys/class/leds/${kbd}/brightness` - - Utils.monitorFile(screenPath, async f => { - const v = await Utils.readFileAsync(f) - this.#screen = Number(v) / this.#screenMax - this.changed("screen") - }) - - Utils.monitorFile(kbdPath, async f => { - const v = await Utils.readFileAsync(f) - this.#kbd = Number(v) / this.#kbdMax - this.changed("kbd") - }) - } -} - -export default new Brightness diff --git a/.config/ags/service/colorpicker.ts b/.config/ags/service/colorpicker.ts deleted file mode 100644 index 5918f31..0000000 --- a/.config/ags/service/colorpicker.ts +++ /dev/null @@ -1,56 +0,0 @@ -import icons from "lib/icons" -import { bash, dependencies } from "lib/utils" - -const COLORS_CACHE = Utils.CACHE_DIR + "/colorpicker.json" -const MAX_NUM_COLORS = 10 - -class ColorPicker extends Service { - static { - Service.register(this, {}, { - "colors": ["jsobject"], - }) - } - - #notifID = 0 - #colors = JSON.parse(Utils.readFile(COLORS_CACHE) || "[]") as string[] - - get colors() { return [...this.#colors] } - set colors(colors) { - this.#colors = colors - this.changed("colors") - } - - // TODO: doesn't work? - async wlCopy(color: string) { - if (dependencies("wl-copy")) - bash(`wl-copy ${color}`) - } - - readonly pick = async () => { - if (!dependencies("hyprpicker")) - return - - const color = await bash("hyprpicker -a -r") - if (!color) - return - - this.wlCopy(color) - const list = this.colors - if (!list.includes(color)) { - list.push(color) - if (list.length > MAX_NUM_COLORS) - list.shift() - - this.colors = list - Utils.writeFile(JSON.stringify(list, null, 2), COLORS_CACHE) - } - - this.#notifID = await Utils.notify({ - id: this.#notifID, - iconName: icons.ui.colorpicker, - summary: color, - }) - } -} - -export default new ColorPicker diff --git a/.config/ags/service/nix.ts b/.config/ags/service/nix.ts deleted file mode 100644 index 3bde9fc..0000000 --- a/.config/ags/service/nix.ts +++ /dev/null @@ -1,109 +0,0 @@ -import icons from "lib/icons" -import { bash, dependencies } from "lib/utils" -import options from "options" - -const CACHE = `${Utils.CACHE_DIR}/nixpkgs` -const PREFIX = "legacyPackages.x86_64-linux." -const MAX = options.launcher.nix.max -const nixpkgs = options.launcher.nix.pkgs - -export type Nixpkg = { - name: string - description: string - pname: string - version: string -} - -class Nix extends Service { - static { - Service.register(this, {}, { - "available": ["boolean", "r"], - "ready": ["boolean", "rw"], - }) - } - - #db: { [name: string]: Nixpkg } = {} - #ready = true - - private set ready(r: boolean) { - this.#ready = r - this.changed("ready") - } - - get db() { return this.#db } - get ready() { return this.#ready } - get available() { return Utils.exec("which nix") } - - constructor() { - super() - if (!this.available) - return this - - this.#updateList() - nixpkgs.connect("changed", this.#updateList) - } - - query = async (filter: string) => { - if (!dependencies("fzf", "nix") || !this.#ready) - return [] as string[] - - return bash(`cat ${CACHE} | fzf -f ${filter} -e | head -n ${MAX} `) - .then(str => str.split("\n").filter(i => i)) - } - - nix(cmd: string, bin: string, args: string) { - return Utils.execAsync(`nix ${cmd} ${nixpkgs}#${bin} --impure ${args}`) - } - - run = async (input: string) => { - if (!dependencies("nix")) - return - - try { - const [bin, ...args] = input.trim().split(/\s+/) - - this.ready = false - await this.nix("shell", bin, "--command sh -c 'exit'") - this.ready = true - - this.nix("run", bin, ["--", ...args].join(" ")) - } catch (err) { - if (typeof err === "string") - Utils.notify("NixRun Error", err, icons.nix.nix) - else - logError(err) - } finally { - this.ready = true - } - } - - #updateList = async () => { - if (!dependencies("nix")) - return - - this.ready = false - this.#db = {} - - // const search = await bash(`nix search ${nixpkgs} --json`) - const search = "" - if (!search) { - this.ready = true - return - } - - const json = Object.entries(JSON.parse(search) as { - [name: string]: Nixpkg - }) - - for (const [pkg, info] of json) { - const name = pkg.replace(PREFIX, "") - this.#db[name] = { ...info, name } - } - - const list = Object.keys(this.#db).join("\n") - await Utils.writeFile(list, CACHE) - this.ready = true - } -} - -export default new Nix diff --git a/.config/ags/service/powermenu.ts b/.config/ags/service/powermenu.ts deleted file mode 100644 index fd16bc1..0000000 --- a/.config/ags/service/powermenu.ts +++ /dev/null @@ -1,43 +0,0 @@ -import options from "options" - -const { sleep, reboot, logout, shutdown } = options.powermenu - -export type Action = "sleep" | "reboot" | "logout" | "shutdown" - -class PowerMenu extends Service { - static { - Service.register(this, {}, { - "title": ["string"], - "cmd": ["string"], - }) - } - - #title = "" - #cmd = "" - - get title() { return this.#title } - get cmd() { return this.#cmd } - - action(action: Action) { - [this.#cmd, this.#title] = { - sleep: [sleep.value, "Sleep"], - reboot: [reboot.value, "Reboot"], - logout: [logout.value, "Log Out"], - shutdown: [shutdown.value, "Shutdown"], - }[action] - - this.notify("cmd") - this.notify("title") - this.emit("changed") - App.closeWindow("powermenu") - App.openWindow("verification") - } - - readonly shutdown = () => { - this.action("shutdown") - } -} - -const powermenu = new PowerMenu -Object.assign(globalThis, { powermenu }) -export default powermenu diff --git a/.config/ags/service/screenrecord.ts b/.config/ags/service/screenrecord.ts deleted file mode 100644 index 58721d2..0000000 --- a/.config/ags/service/screenrecord.ts +++ /dev/null @@ -1,102 +0,0 @@ -import GLib from "gi://GLib" -import icons from "lib/icons" -import { dependencies, sh, bash } from "lib/utils" - -const now = () => GLib.DateTime.new_now_local().format("%Y-%m-%d_%H-%M-%S") - -class Recorder extends Service { - static { - Service.register(this, {}, { - "timer": ["int"], - "recording": ["boolean"], - }) - } - - #recordings = Utils.HOME + "/Videos/Screencasting" - #screenshots = Utils.HOME + "/Pictures/Screenshots" - #file = "" - #interval = 0 - - recording = false - timer = 0 - - async start() { - if (!dependencies("slurp", "wf-recorder")) - return - - if (this.recording) - return - - Utils.ensureDirectory(this.#recordings) - this.#file = `${this.#recordings}/${now()}.mp4` - sh(`wf-recorder -g "${await sh("slurp")}" -f ${this.#file} --pixel-format yuv420p`) - - this.recording = true - this.changed("recording") - - this.timer = 0 - this.#interval = Utils.interval(1000, () => { - this.changed("timer") - this.timer++ - }) - } - - async stop() { - if (!this.recording) - return - - await bash("killall -INT wf-recorder") - this.recording = false - this.changed("recording") - GLib.source_remove(this.#interval) - - Utils.notify({ - iconName: icons.fallback.video, - summary: "Screenrecord", - body: this.#file, - actions: { - "Show in Files": () => sh(`xdg-open ${this.#recordings}`), - "View": () => sh(`xdg-open ${this.#file}`), - }, - }) - } - - async screenshot(full = false) { - if (!dependencies("slurp", "wayshot")) - return - - const file = `${this.#screenshots}/${now()}.png` - Utils.ensureDirectory(this.#screenshots) - - if (full) { - await sh(`wayshot -f ${file}`) - } - else { - const size = await sh("slurp") - if (!size) - return - - await sh(`wayshot -f ${file} -s "${size}"`) - } - - bash(`wl-copy < ${file}`) - - Utils.notify({ - image: file, - summary: "Screenshot", - body: file, - actions: { - "Show in Files": () => sh(`xdg-open ${this.#screenshots}`), - "View": () => sh(`xdg-open ${file}`), - "Edit": () => { - if (dependencies("swappy")) - sh(`swappy -f ${file}`) - }, - }, - }) - } -} - -const recorder = new Recorder -Object.assign(globalThis, { recorder }) -export default recorder diff --git a/.config/ags/service/wallpaper.ts b/.config/ags/service/wallpaper.ts deleted file mode 100644 index 865c6d9..0000000 --- a/.config/ags/service/wallpaper.ts +++ /dev/null @@ -1,127 +0,0 @@ -import options from 'options'; -import { dependencies, sh } from 'lib/utils'; - -export type Resolution = 1920 | 1366 | 3840; -export type Market = 'random' | 'en-US' | 'ja-JP' | 'en-AU' | 'en-GB' | 'de-DE' | 'en-NZ' | 'en-CA'; - -const WP = `${Utils.HOME}/pictures/wallpapers`; -const Cache = `${Utils.HOME}/Pictures/Wallpapers/Bing`; - -class Wallpaper extends Service { - static { - Service.register( - this, - {}, - { - wallpaper: ['string'], - }, - ); - } - - #blockMonitor = false; - - #wallpaper() { - if (!dependencies('swww')) return; - - sh('hyprctl cursorpos').then(pos => { - sh(['swww', 'img', '--transition-type', 'grow', '--transition-pos', pos.replace(' ', ''), WP]).then(() => { - this.changed('wallpaper'); - }); - }); - } - - async #setWallpaper(path: string) { - this.#blockMonitor = true; - - await sh(`cp "${path}" "${WP}"`); - this.#wallpaper(); - - this.#blockMonitor = false; - } - - async #fetchBing() { - // Check if wallpaper functionality is enabled - if (!options.wallpaper.enable.value) { - console.log('Wallpaper functionality is disabled.'); - return; - } - - try { - const res = await Utils.fetch('https://bing.biturl.top/', { - params: { - resolution: options.wallpaper.resolution.value, - format: 'json', - image_format: 'jpg', - index: 'random', - mkt: options.wallpaper.market.value, - }, - }); - - if (!res.ok) { - console.warn('Failed to fetch from Bing:', res.statusText); - return; - } - - const data = await res.json(); - const { url } = data; - - if (!url) { - console.warn('No URL found in Bing response:', data); - return; - } - - const file = `${Cache}/${url.replace('https://www.bing.com/th?id=', '')}`; - - Utils.ensureDirectory(Cache); - - if (!(await Utils.fileExists(file))) { - await sh(`curl "${url}" --output "${file}"`); - await this.#setWallpaper(file); - } else { - console.log(`Wallpaper already exists: ${file}`); - } - } catch (error) { - console.error('Error fetching wallpaper:', error); - } - } - - readonly random = () => { - // Check if wallpaper functionality is enabled - if (!options.wallpaper.enable.value) { - console.log('Wallpaper functionality is disabled.'); - return; - } - this.#fetchBing(); - }; - - readonly set = (path: string) => { - this.#setWallpaper(path); - }; - - get wallpaper() { - return WP; - } - constructor() { - super(); - - // Respect wallpaper.enable option - if (!options.wallpaper.enable.value) { - console.log('Wallpaper functionality is disabled, not starting swww-daemon.'); - return; - } - - if (!dependencies('swww')) return; - - // Monitor and set wallpaper if enabled - Utils.monitorFile(WP, () => { - if (!this.#blockMonitor) this.#wallpaper(); - }); - - // Start swww-daemon only when wallpaper is enabled - Utils.execAsync('swww-daemon') - .then(this.#wallpaper) - .catch(() => null); - } -} - -export default new Wallpaper(); diff --git a/.config/ags/service/weather.ts b/.config/ags/service/weather.ts deleted file mode 100644 index 14f2df2..0000000 --- a/.config/ags/service/weather.ts +++ /dev/null @@ -1,59 +0,0 @@ -import options from "options" - -const { interval, key, cities, unit } = options.datemenu.weather - -class Weather extends Service { - static { - Service.register(this, {}, { - "forecasts": ["jsobject"], - }) - } - - #forecasts: Forecast[] = [] - get forecasts() { return this.#forecasts } - - async #fetch(placeid: number) { - const url = "https://api.openweathermap.org/data/2.5/forecast" - const res = await Utils.fetch(url, { - params: { - id: placeid, - appid: key.value, - untis: unit.value, - }, - }) - return await res.json() - } - - constructor() { - super() - if (!key.value) - return this - - Utils.interval(interval.value, () => { - Promise.all(cities.value.map(this.#fetch)).then(forecasts => { - this.#forecasts = forecasts as Forecast[] - this.changed("forecasts") - }) - }) - } -} - -export default new Weather - -type Forecast = { - city: { - name: string, - } - list: Array<{ - dt: number - main: { - temp: number - feels_like: number - }, - weather: Array<{ - main: string, - description: string, - icon: string, - }> - }> -} |
