import { Variable, bind, execAsync } from "astal"; import { App, Astal, Gtk } from "astal/gtk4"; import { hideWindow, limit, skip } from "@lib/utils"; import { SHELL } from "@/settings.json"; import Hyprland from "gi://AstalHyprland"; const hide = () => App.get_window("clipboard")?.hide(); type Entry = { id: string, content: string }; function ClipboardEntry({ id, content }: Entry) { return } async function getClipboardHistory(history: Variable) { try { const ids = await execAsync([SHELL, "-c", "cliphist list | awk '{print $1}'"]) .then(it => it.split("\n")); const contents = await execAsync([SHELL, "-c", "cliphist list | awk '{$1=\"\"; print}'"]) .then(it => it.split("\n")); history.set(ids .map((id, index) => ({ id, content: contents[index] })) .filter(({ content }) => content && content.length > 0)); } catch { history.set([]); } } export default async function Clipboard(_monitor_id: number) { const { TOP, BOTTOM, LEFT, RIGHT } = Astal.WindowAnchor; const hypr = Hyprland.get_default(); const history: Variable = Variable([]); const toSkip = Variable(0); const list = Variable.derive([ bind(history), bind(toSkip) ], (history, count) => limit( skip(history, count), 10 )); const isEmpty = bind(list).as(list => list.length === 0); const onScroll = (dy: number) => { const value = toSkip.get(); if (dy < 0) { if ((value - 10) < 0) return; toSkip.set(value - 10) } else { if ((value + 10) > history.get().length) return; toSkip.set(value + 10) } }; const setup = (self: Gtk.Window) => self.connect('notify::visible', async () => { await getClipboardHistory(history) }) return monitor.id)} name={"clipboard"} cssClasses={["clipboard"]} keymode={Astal.Keymode.EXCLUSIVE} anchor={TOP | BOTTOM | LEFT | RIGHT} onKeyPressed={hideWindow} application={App} setup={setup}> onScroll(dy)}> {bind(list).as(list => list.map(({ id, content }) => ( )))} }