feat(agsV2): migrate GSR
This commit is contained in:
parent
6fe0e49378
commit
29ad4ad55a
1 changed files with 158 additions and 0 deletions
158
nixosModules/ags-v2/config/services/gpu-screen-recorder.ts
Normal file
158
nixosModules/ags-v2/config/services/gpu-screen-recorder.ts
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
import { execAsync, subprocess } from 'astal';
|
||||||
|
import GObject, { register } from 'astal/gobject';
|
||||||
|
|
||||||
|
/* Types */
|
||||||
|
interface NotifyAction {
|
||||||
|
id: string
|
||||||
|
label: string
|
||||||
|
callback: () => void
|
||||||
|
}
|
||||||
|
interface NotifySendProps {
|
||||||
|
actions?: NotifyAction[]
|
||||||
|
appName?: string
|
||||||
|
body?: string
|
||||||
|
category?: string
|
||||||
|
hint?: string
|
||||||
|
iconName: string
|
||||||
|
replaceId?: number
|
||||||
|
title: string
|
||||||
|
urgency?: 'low' | 'normal' | 'critical'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const APP_NAME = 'gpu-screen-recorder';
|
||||||
|
const ICON_NAME = 'nvidia';
|
||||||
|
|
||||||
|
const escapeShellArg = (arg: string): string => `'${arg.replace(/'/g, '\'\\\'\'')}'`;
|
||||||
|
|
||||||
|
const notifySend = ({
|
||||||
|
actions = [],
|
||||||
|
appName,
|
||||||
|
body,
|
||||||
|
category,
|
||||||
|
hint,
|
||||||
|
iconName,
|
||||||
|
replaceId,
|
||||||
|
title,
|
||||||
|
urgency = 'normal',
|
||||||
|
}: NotifySendProps) => new Promise<number>((resolve) => {
|
||||||
|
let printedId = false;
|
||||||
|
|
||||||
|
const cmd = [
|
||||||
|
'notify-send',
|
||||||
|
'--print-id',
|
||||||
|
`--icon=${escapeShellArg(iconName)}`,
|
||||||
|
escapeShellArg(title),
|
||||||
|
escapeShellArg(body ?? ''),
|
||||||
|
// Optional params
|
||||||
|
appName ? `--app-name=${escapeShellArg(appName)}` : '',
|
||||||
|
category ? `--category=${escapeShellArg(category)}` : '',
|
||||||
|
hint ? `--hint=${escapeShellArg(hint)}` : '',
|
||||||
|
replaceId ? `--replace-id=${replaceId.toString()}` : '',
|
||||||
|
`--urgency=${urgency}`,
|
||||||
|
].concat(
|
||||||
|
actions.map(({ id, label }) => `--action=${escapeShellArg(id)}=${escapeShellArg(label)}`),
|
||||||
|
).join(' ');
|
||||||
|
|
||||||
|
subprocess(
|
||||||
|
cmd,
|
||||||
|
(out) => {
|
||||||
|
if (!printedId) {
|
||||||
|
resolve(parseInt(out));
|
||||||
|
printedId = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actions.find((action) => action.id === out)?.callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
console.error(`[Notify] ${err}`);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
@register()
|
||||||
|
class GSR extends GObject.Object {
|
||||||
|
private _lastNotifID: number | undefined;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
subprocess(
|
||||||
|
['gsr-start'],
|
||||||
|
(path) => {
|
||||||
|
if (!this._lastNotifID) {
|
||||||
|
console.error('[GSR] ID of warning notif not found');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this._onSaved(path);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._onSaved(path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => { /**/ },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public saveReplay() {
|
||||||
|
execAsync(['gpu-save-replay'])
|
||||||
|
.then(async() => {
|
||||||
|
this._lastNotifID = await notifySend({
|
||||||
|
appName: APP_NAME,
|
||||||
|
iconName: ICON_NAME,
|
||||||
|
title: 'Saving Replay',
|
||||||
|
body: 'Last 20 minutes',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(`[GSR save-replay] ${err}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onSaved(path: string) {
|
||||||
|
notifySend({
|
||||||
|
appName: APP_NAME,
|
||||||
|
iconName: ICON_NAME,
|
||||||
|
replaceId: this._lastNotifID,
|
||||||
|
|
||||||
|
title: 'Replay Saved',
|
||||||
|
body: `Saved to ${path}`,
|
||||||
|
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
id: 'folder',
|
||||||
|
label: 'Open Folder',
|
||||||
|
|
||||||
|
callback: () => execAsync([
|
||||||
|
'xdg-open',
|
||||||
|
path.substring(0, path.lastIndexOf('/')),
|
||||||
|
]).catch(print),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: 'video',
|
||||||
|
label: 'Open Video',
|
||||||
|
|
||||||
|
callback: () => execAsync(['xdg-open', path]).catch(print),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: 'kdenlive',
|
||||||
|
label: 'Edit in kdenlive',
|
||||||
|
|
||||||
|
callback: () => execAsync([
|
||||||
|
'bash',
|
||||||
|
'-c',
|
||||||
|
`kdenlive -i ${path}`,
|
||||||
|
]).catch(print),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const gsrService = new GSR();
|
||||||
|
|
||||||
|
export default gsrService;
|
Loading…
Reference in a new issue