nixos-configs/nixosModules/ags/config/ts/screenshot/main.ts
matt1432 24aa4b9842
All checks were successful
Discord / discord commits (push) Has been skipped
refactor: make modules independant and exposed in the flake for outside use
2024-08-02 22:32:29 -04:00

183 lines
5 KiB
TypeScript

const Applications = await Service.import('applications');
const Hyprland = await Service.import('hyprland');
const { Box, Icon, Label, Scrollable, Stack } = Widget;
const { execAsync, timeout } = Utils;
import PopupWindow from '../misc/popup.ts';
import CursorBox from '../misc/cursorbox.ts';
import { Client } from 'types/service/hyprland';
const takeScreenshot = (selector: string, delay = 1000): void => {
App.closeWindow('win-screenshot');
timeout(delay, () => {
execAsync(['bash', '-c', `grim ${selector} - | satty -f -`])
.catch(console.error);
});
};
export default () => {
const windowList = Box({
vertical: true,
});
const updateWindows = async() => {
if (!App.getWindow('win-screenshot')?.visible) {
return;
}
windowList.children = (JSON.parse(
await Hyprland.messageAsync('j/clients'),
) as Client[])
.filter((client) => client.workspace.id === Hyprland.active.workspace.id)
.map((client) => CursorBox({
class_name: 'item-btn',
on_primary_click_release: () => {
takeScreenshot(`-w ${client.address}`);
},
child: Box({
hpack: 'center',
children: [
Icon(Applications
.query(client.class)[0]?.app.get_string('Icon') ?? ''),
Label({
label: client.title,
truncate: 'end',
max_width_chars: 50,
}),
],
}),
}));
};
const stack = Stack({
transition: 'slide_left_right',
children: {
monitors: Scrollable({
child: Box({
vertical: true,
}).hook(Hyprland, (self) => {
self.children = Hyprland.monitors.map((monitor) => CursorBox({
class_name: 'item-btn',
on_primary_click_release: () => {
takeScreenshot(`-o ${monitor.name}`);
},
child: Label({
label: `${monitor.name}: ${monitor.description}`,
truncate: 'end',
max_width_chars: 50,
}),
}));
}, 'notify::monitors'),
}),
windows: Scrollable({
child: windowList
.hook(Hyprland, updateWindows, 'notify::clients')
.hook(Hyprland.active.workspace, updateWindows),
}),
},
});
// TODO: highlight monitor when hovered
const monitorsButton = CursorBox({
class_name: 'header-btn',
on_primary_click_release: () => {
stack.shown = 'monitors';
},
child: Box({
hpack: 'center',
children: [
Icon('display-symbolic'),
Label('monitors'),
],
}),
});
const windowsButton = CursorBox({
class_name: 'header-btn',
on_primary_click_release: () => {
stack.shown = 'windows';
},
child: Box({
hpack: 'center',
children: [
Icon('window-symbolic'),
Label('windows'),
],
}),
});
const regionButton = CursorBox({
class_name: 'header-btn',
on_primary_click_release: () => {
takeScreenshot('-g "$(slurp)"', 0);
},
child: Box({
hpack: 'center',
children: [
Icon('tool-pencil-symbolic'),
Label('region'),
],
}),
});
return PopupWindow({
name: 'screenshot',
on_open: () => {
updateWindows();
},
child: Box({
class_name: 'screenshot',
vertical: true,
children: [
Box({
class_name: 'header',
homogeneous: true,
children: [
monitorsButton,
windowsButton,
regionButton,
],
}).hook(stack, () => {
switch (stack.shown) {
case 'monitors':
monitorsButton.toggleClassName('active', true);
windowsButton.toggleClassName('active', false);
break;
case 'windows':
monitorsButton.toggleClassName('active', false);
windowsButton.toggleClassName('active', true);
break;
default:
break;
}
}, 'notify::shown'),
stack,
],
}),
});
};