2024-07-25 18:42:25 -04:00
|
|
|
const { execAsync, subprocess } = Utils;
|
2024-07-10 15:14:44 -04:00
|
|
|
|
|
|
|
|
|
|
|
class Clipboard extends Service {
|
|
|
|
static {
|
|
|
|
Service.register(this, {
|
2024-07-25 18:42:25 -04:00
|
|
|
'clip-added': ['jsobject'],
|
2024-07-10 15:14:44 -04:00
|
|
|
'history-searched': [],
|
|
|
|
}, {
|
|
|
|
clips: ['jsobject'],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-07-25 18:42:25 -04:00
|
|
|
private static _MAX_CLIPS = 100;
|
|
|
|
|
|
|
|
// Class Attributes
|
2024-07-10 15:14:44 -04:00
|
|
|
private _clips_left = 0;
|
2024-07-25 18:42:25 -04:00
|
|
|
|
2024-08-01 12:54:32 -04:00
|
|
|
private _clips = new Map<number, { clip: string, isImage: boolean }>();
|
2024-07-10 15:14:44 -04:00
|
|
|
|
|
|
|
get clips() {
|
|
|
|
return this._clips;
|
|
|
|
}
|
|
|
|
|
2024-07-25 18:42:25 -04:00
|
|
|
constructor() {
|
|
|
|
super();
|
2024-07-10 15:14:44 -04:00
|
|
|
|
2024-07-25 18:42:25 -04:00
|
|
|
this._getHistory();
|
|
|
|
this._watchClipboard();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Public Class Methods
|
|
|
|
public copyOldItem(key: string | number): void {
|
|
|
|
execAsync([
|
2024-08-01 21:09:38 -04:00
|
|
|
'bash', '-c', `cliphist list | grep '^${key}' | cliphist decode | wl-copy`,
|
2024-07-25 18:42:25 -04:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Private Class Methods
|
2024-07-10 15:14:44 -04:00
|
|
|
private _decrementClipsLeft() {
|
|
|
|
if (--this._clips_left === 0) {
|
|
|
|
this.emit('history-searched');
|
|
|
|
// FIXME: this is necessary when not putting a cap on clip amount
|
|
|
|
// exec(`prlimit --pid ${exec('pgrep ags')} --nofile=1024:`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private async _decodeItem(index: string): Promise<string | null> {
|
|
|
|
try {
|
|
|
|
const decodedItem = await execAsync([
|
2024-08-01 13:44:49 -04:00
|
|
|
'bash', '-c', `cliphist list | grep -a ${index} | cliphist decode`,
|
2024-07-10 15:14:44 -04:00
|
|
|
]);
|
|
|
|
|
|
|
|
this._decrementClipsLeft();
|
|
|
|
|
|
|
|
return decodedItem;
|
|
|
|
}
|
|
|
|
catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
this._decrementClipsLeft();
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-01 21:09:38 -04:00
|
|
|
private _addClip(newClip: [number, { clip: string, isImage: boolean }]) {
|
|
|
|
if (
|
|
|
|
![...this.clips.values()]
|
|
|
|
.map((c) => c.clip)
|
|
|
|
.includes(newClip[1].clip)
|
|
|
|
) {
|
|
|
|
this._clips.set(...newClip);
|
|
|
|
this.emit('clip-added', newClip);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const oldClip = [...this.clips.entries()]
|
|
|
|
.find(([_, { clip }]) => clip === newClip[1].clip);
|
|
|
|
|
|
|
|
if (oldClip && oldClip[0] < newClip[0]) {
|
|
|
|
this.clips.delete(oldClip[0]);
|
|
|
|
this._clips.set(...newClip);
|
|
|
|
this.emit('clip-added', newClip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-07-10 15:14:44 -04:00
|
|
|
|
2024-08-01 21:09:38 -04:00
|
|
|
private _getHistory(n = Clipboard._MAX_CLIPS) {
|
2024-07-10 15:14:44 -04:00
|
|
|
// FIXME: this is necessary when not putting a cap on clip amount
|
|
|
|
// exec(`prlimit --pid ${exec('pgrep ags')} --nofile=10024:`);
|
|
|
|
|
|
|
|
// This command comes from '../../clipboard/script.sh'
|
2024-07-25 18:42:25 -04:00
|
|
|
execAsync('clipboard-manager').then((out) => {
|
|
|
|
const rawClips = out.split('\n');
|
|
|
|
|
|
|
|
this._clips_left = Math.min(rawClips.length - 1, n);
|
|
|
|
|
2024-08-01 12:54:32 -04:00
|
|
|
rawClips.forEach(async(clip, i) => {
|
2024-07-25 18:42:25 -04:00
|
|
|
if (i > n) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (clip.includes('img')) {
|
|
|
|
this._decrementClipsLeft();
|
|
|
|
|
2024-08-01 12:54:32 -04:00
|
|
|
const newClip: [number, { clip: string, isImage: boolean }] = [
|
2024-07-25 18:42:25 -04:00
|
|
|
parseInt((clip.match('[0-9]+') ?? [''])[0]),
|
|
|
|
{
|
|
|
|
clip,
|
|
|
|
isImage: true,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2024-08-01 21:09:38 -04:00
|
|
|
this._addClip(newClip);
|
2024-07-25 18:42:25 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
const decodedClip = await this._decodeItem(clip);
|
|
|
|
|
|
|
|
if (decodedClip) {
|
2024-08-01 12:54:32 -04:00
|
|
|
const newClip: [number, { clip: string, isImage: boolean }] = [
|
2024-07-25 18:42:25 -04:00
|
|
|
parseInt(clip),
|
2024-07-10 15:14:44 -04:00
|
|
|
{
|
2024-07-25 18:42:25 -04:00
|
|
|
clip: decodedClip,
|
|
|
|
isImage: false,
|
2024-07-10 15:14:44 -04:00
|
|
|
},
|
2024-07-25 18:42:25 -04:00
|
|
|
];
|
|
|
|
|
2024-08-01 21:09:38 -04:00
|
|
|
this._addClip(newClip);
|
2024-07-10 15:14:44 -04:00
|
|
|
}
|
2024-07-25 18:42:25 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}).catch((error) => console.error(error));
|
|
|
|
}
|
|
|
|
|
|
|
|
private _watchClipboard() {
|
|
|
|
subprocess(
|
|
|
|
['wl-paste', '--watch', 'echo'],
|
|
|
|
() => {
|
|
|
|
this._getHistory(1);
|
|
|
|
},
|
2024-08-01 12:54:32 -04:00
|
|
|
() => { /**/ },
|
2024-07-25 18:42:25 -04:00
|
|
|
);
|
2024-07-10 15:14:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const clipboard = new Clipboard();
|
|
|
|
|
|
|
|
export default clipboard;
|