This commit is contained in:
xsghetti 2024-04-11 00:21:35 -04:00
parent 1f8cb3c145
commit 610604e80f
253 changed files with 27055 additions and 44 deletions

View file

@ -0,0 +1,49 @@
import { sh } from "../lib/utils.js"
class Asusctl extends Service {
static {
Service.register(this, {}, {
"profile": ["string", "r"],
"mode": ["string", "r"],
})
}
available = !!Utils.exec("which asusctl")
#profile = "Balanced"
#mode = "Hybrid"
async nextProfile() {
await sh("asusctl profile -n")
const profile = await sh("asusctl profile -p")
const p = profile.split(" ")[3]
this.#profile = p
this.changed("profile")
}
async setProfile(prof) {
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")
this.changed("profile")
}
constructor() {
super()
if (this.available) {
sh("asusctl profile -p").then(p => this.#profile = p.split(" ")[3])
sh("supergfxctl -g").then(m => this.#mode = m)
}
}
get profiles() { return ["Performance", "Balanced", "Quiet"] }
get profile() { return this.#profile }
get mode() { return this.#mode }
}
export default new Asusctl()

View file

@ -0,0 +1,69 @@
import { bash, dependencies, sh } from "../lib/utils.js"
if (!dependencies("brightnessctl"))
App.quit()
const get = (args) => 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()

View file

@ -0,0 +1,21 @@
const { GLib } = imports.gi;
class ClockService extends Service {
static {
Service.register ( this, {}, {
'time': ['gobject']
}
)
}
#time = GLib.DateTime.new_now_local()
get time() { return this.#time; }
constructor() {
super()
Utils.interval(1000, () => {
this.#time = GLib.DateTime.new_now_local()
this.changed("time")
})
}
}
export default new ClockService()

View file

@ -0,0 +1,57 @@
import icons from "../lib/icons.js"
import { bash, dependencies } from "../lib/utils.js"
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) || "[]")
get colors() { return [...this.#colors] }
set colors(colors) {
this.#colors = colors
this.changed("colors")
}
// TODO: doesn't work?
async wlCopy(color) {
if (dependencies("wl-copy"))
bash(`wl-copy ${color}`)
}
async pick() {
if (!dependencies("hyprpicker"))
return
const color = await bash("hyprpicker -a -r")
if (!color)
return
colorpicker.wlCopy(color)
const list = colorpicker.colors
if (!list.includes(color)) {
list.push(color)
if (list.length > MAX_NUM_COLORS)
list.shift()
colorpicker.colors = list
Utils.writeFile(JSON.stringify(list, null, 2), COLORS_CACHE)
}
colorpicker.notifID = await Utils.notify({
id: colorpicker.notifID,
iconName: icons.ui.colorpicker,
summary: color,
})
}
}
const colorpicker = new ColorPicker
export default colorpicker

View file

@ -0,0 +1,43 @@
import options from '../options.js';
// 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) {
[this.#cmd, this.#title] = {
sleep: [options.powermenu.sleep, "Sleep"],
reboot: [options.powermenu.reboot, "Reboot"],
logout: [options.powermenu.logout, "Log Out"],
shutdown: [options.powermenu.shutdown, "Shutdown"],
lock: [options.powermenu.lock, "Lock"],
}[action]
this.notify("cmd")
this.notify("title")
this.emit("changed")
App.closeWindow("powermenu")
App.openWindow("verification")
}
shutdown = () => {
this.action("shutdown")
}
}
const powermenu = new PowerMenu
globalThis["powermenu"] = powermenu
export default powermenu

View file

@ -0,0 +1,93 @@
import GLib from "gi://GLib"
import icons from "../lib/icons.js"
import { dependencies, sh, bash } from "../lib/utils.js"
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)
const wayshot = `wayshot -f ${file} ${full ? "" : `-s "${await sh("slurp")}"`}`
await sh(wayshot)
bash(`wl-copy < ${file}`)
Utils.notify({
image: file,
summary: "Screenshot",
body: this.#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
globalThis["recorder"] = recorder
export default recorder