feat(ags): cleanup sorted list and hide not matching clips
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
3e4486dc33
commit
1928a74e90
3 changed files with 74 additions and 75 deletions
|
@ -8,13 +8,12 @@ import AppItem from './app-item.ts';
|
||||||
import { launchApp } from './launch.ts';
|
import { launchApp } from './launch.ts';
|
||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
import { ListBoxRow } from 'types/@girs/gtk-3.0/gtk-3.0.cjs';
|
|
||||||
import { Application } from 'types/service/applications.ts';
|
import { Application } from 'types/service/applications.ts';
|
||||||
import { AgsAppItem } from 'global-types';
|
import { AgsAppItem } from 'global-types';
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
let fzfResults: FzfResultItem<Application>[];
|
let fzfResults = [] as FzfResultItem<Application>[];
|
||||||
|
|
||||||
return SortedList({
|
return SortedList({
|
||||||
name: 'applauncher',
|
name: 'applauncher',
|
||||||
|
@ -26,23 +25,38 @@ export default () => {
|
||||||
launchApp((r.get_child() as AgsAppItem).attribute.app);
|
launchApp((r.get_child() as AgsAppItem).attribute.app);
|
||||||
},
|
},
|
||||||
|
|
||||||
init_rows: (list) => {
|
setup_list: (list, entry) => {
|
||||||
const rows = list.get_children() as ListBoxRow[];
|
Applications.query('')
|
||||||
|
.flatMap((app) => AppItem(app))
|
||||||
|
.forEach((ch) => {
|
||||||
|
list.add(ch);
|
||||||
|
});
|
||||||
|
|
||||||
rows.forEach((ch) => {
|
|
||||||
ch.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
const children = Applications.query('')
|
|
||||||
.flatMap((app) => AppItem(app));
|
|
||||||
|
|
||||||
children.forEach((ch) => {
|
|
||||||
list.add(ch);
|
|
||||||
});
|
|
||||||
list.show_all();
|
list.show_all();
|
||||||
|
|
||||||
|
list.set_sort_func((a, b) => {
|
||||||
|
const row1 = (a.get_children()[0] as AgsAppItem).attribute.app;
|
||||||
|
const row2 = (b.get_children()[0] as AgsAppItem).attribute.app;
|
||||||
|
|
||||||
|
if (entry.text === '' || entry.text === '-') {
|
||||||
|
a.set_visible(true);
|
||||||
|
b.set_visible(true);
|
||||||
|
|
||||||
|
return row2.frequency - row1.frequency;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const s1 = fzfResults.find((r) => r.item.name === row1.name)?.score ?? 0;
|
||||||
|
const s2 = fzfResults.find((r) => r.item.name === row2.name)?.score ?? 0;
|
||||||
|
|
||||||
|
a.set_visible(s1 !== 0);
|
||||||
|
b.set_visible(s2 !== 0);
|
||||||
|
|
||||||
|
return s2 - s1;
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
set_sort: (text, list, placeholder) => {
|
on_text_change: (text, list, placeholder) => {
|
||||||
const fzf = new Fzf(Applications.list, {
|
const fzf = new Fzf(Applications.list, {
|
||||||
selector: (app) => app.name + app.executable,
|
selector: (app) => app.name + app.executable,
|
||||||
|
|
||||||
|
@ -52,37 +66,10 @@ export default () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
fzfResults = fzf.find(text);
|
fzfResults = fzf.find(text);
|
||||||
list.set_sort_func((a, b) => {
|
list.invalidate_sort();
|
||||||
const row1 = (a.get_children()[0] as AgsAppItem).attribute.app.name;
|
|
||||||
const row2 = (b.get_children()[0] as AgsAppItem).attribute.app.name;
|
|
||||||
|
|
||||||
const s1 = fzfResults.find((r) => r.item.name === row1)?.score ?? 0;
|
const visibleApps = list.get_children().filter((row) => row.visible).length;
|
||||||
const s2 = fzfResults.find((r) => r.item.name === row2)?.score ?? 0;
|
|
||||||
|
|
||||||
return s2 - s1;
|
|
||||||
});
|
|
||||||
|
|
||||||
let visibleApps = 0;
|
|
||||||
|
|
||||||
const rows = list.get_children() as ListBoxRow[];
|
|
||||||
|
|
||||||
rows.forEach((row) => {
|
|
||||||
row.changed();
|
|
||||||
|
|
||||||
const item = row.get_children()[0] as AgsAppItem;
|
|
||||||
|
|
||||||
if (item.attribute.app) {
|
|
||||||
const isMatching = fzfResults.some((r) => {
|
|
||||||
return r.item.name === item.attribute.app.name;
|
|
||||||
});
|
|
||||||
|
|
||||||
row.visible = isMatching;
|
|
||||||
|
|
||||||
if (isMatching) {
|
|
||||||
++visibleApps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
placeholder.reveal_child = visibleApps <= 0;
|
placeholder.reveal_child = visibleApps <= 0;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,10 +9,6 @@ import SortedList from '../misc/sorted-list.ts';
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
let fzfResults: FzfResultItem<[number, { clip: string, isImage: boolean }]>[];
|
|
||||||
|
|
||||||
const getKey = (r: Gtk.ListBoxRow): number => parseInt(r.get_child()?.name ?? '0');
|
|
||||||
|
|
||||||
const makeItem = (
|
const makeItem = (
|
||||||
list: Gtk.ListBox,
|
list: Gtk.ListBox,
|
||||||
key: number,
|
key: number,
|
||||||
|
@ -49,6 +45,10 @@ export default () => {
|
||||||
widget.show_all();
|
widget.show_all();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fzfResults = [] as FzfResultItem<[number, { clip: string, isImage: boolean }]>[];
|
||||||
|
|
||||||
|
const getKey = (r: Gtk.ListBoxRow): number => parseInt(r.get_child()?.name ?? '0');
|
||||||
|
|
||||||
|
|
||||||
return SortedList({
|
return SortedList({
|
||||||
name: 'clipboard',
|
name: 'clipboard',
|
||||||
|
@ -60,7 +60,7 @@ export default () => {
|
||||||
App.closeWindow('win-clipboard');
|
App.closeWindow('win-clipboard');
|
||||||
},
|
},
|
||||||
|
|
||||||
setup_list: (list) => {
|
setup_list: (list, entry) => {
|
||||||
const CONNECT_ID = Clipboard.connect('history-searched', () => {
|
const CONNECT_ID = Clipboard.connect('history-searched', () => {
|
||||||
// Do every clip that existed before this widget
|
// Do every clip that existed before this widget
|
||||||
list.get_children().forEach((row) => {
|
list.get_children().forEach((row) => {
|
||||||
|
@ -75,29 +75,41 @@ export default () => {
|
||||||
makeItem(list, key, clip.clip, clip.isImage);
|
makeItem(list, key, clip.clip, clip.isImage);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
list.set_sort_func((a, b) => {
|
||||||
|
if (entry.text === '' || entry.text === '-') {
|
||||||
|
a.set_visible(true);
|
||||||
|
b.set_visible(true);
|
||||||
|
|
||||||
|
return getKey(b) - getKey(a);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const ROW_1 = fzfResults.find((f) => f.item[0] === getKey(a))?.score ?? 0;
|
||||||
|
const ROW_2 = fzfResults.find((f) => f.item[0] === getKey(b))?.score ?? 0;
|
||||||
|
|
||||||
|
a.set_visible(ROW_1 !== 0);
|
||||||
|
b.set_visible(ROW_2 !== 0);
|
||||||
|
|
||||||
|
return ROW_2 - ROW_1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Clipboard.disconnect(CONNECT_ID);
|
Clipboard.disconnect(CONNECT_ID);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
set_sort: (text, list) => {
|
on_text_change: (text, list, placeholder) => {
|
||||||
if (text === '' || text === '-') {
|
const fzf = new Fzf([...Clipboard.clips.entries()], {
|
||||||
list.set_sort_func((row1, row2) => getKey(row2) - getKey(row1));
|
selector: ([_key, { clip }]) => clip,
|
||||||
}
|
|
||||||
else {
|
|
||||||
const fzf = new Fzf([...Clipboard.clips.entries()], {
|
|
||||||
selector: ([_key, { clip }]) => clip,
|
|
||||||
|
|
||||||
tiebreakers: [(a, b) => b[0] - a[0]],
|
tiebreakers: [(a, b) => b[0] - a[0]],
|
||||||
});
|
});
|
||||||
|
|
||||||
fzfResults = fzf.find(text);
|
fzfResults = fzf.find(text);
|
||||||
list.set_sort_func((a, b) => {
|
list.invalidate_sort();
|
||||||
const ROW_1 = fzfResults.find((f) => f.item[0] === getKey(a))?.score ?? 0;
|
|
||||||
const ROW_2 = fzfResults.find((f) => f.item[0] === getKey(b))?.score ?? 0;
|
|
||||||
|
|
||||||
return ROW_2 - ROW_1;
|
const visibleApps = list.get_children().filter((row) => row.visible).length;
|
||||||
});
|
|
||||||
}
|
placeholder.reveal_child = visibleApps <= 0;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,14 +17,14 @@ type MakeChild = ReturnType<typeof makeChild>;
|
||||||
|
|
||||||
type SortedListProps<Attr = unknown, Self = SortedList<Attr>> =
|
type SortedListProps<Attr = unknown, Self = SortedList<Attr>> =
|
||||||
PopupWindowProps<MakeChild['child'], Attr, Self> & {
|
PopupWindowProps<MakeChild['child'], Attr, Self> & {
|
||||||
on_select: (row: ListBoxRow) => void
|
on_select?: (row: ListBoxRow) => void
|
||||||
init_rows?: (list: MakeChild['list']) => void
|
init_rows?: (list: MakeChild['list']) => void
|
||||||
set_sort: (
|
on_text_change?: (
|
||||||
text: string,
|
text: string,
|
||||||
list: MakeChild['list'],
|
list: MakeChild['list'],
|
||||||
placeholder: MakeChild['placeholder'],
|
placeholder: MakeChild['placeholder'],
|
||||||
) => void
|
) => void
|
||||||
setup_list?: (list: MakeChild['list']) => void
|
setup_list?: (list: MakeChild['list'], entry: MakeChild['entry']) => void
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ export class SortedList<
|
||||||
private _scrollable: MakeChild['scrollable'];
|
private _scrollable: MakeChild['scrollable'];
|
||||||
private _on_select: (row: ListBoxRow) => void;
|
private _on_select: (row: ListBoxRow) => void;
|
||||||
private _init_rows: (list: MakeChild['list']) => void;
|
private _init_rows: (list: MakeChild['list']) => void;
|
||||||
private _set_sort: (
|
private _on_text_change: (
|
||||||
text: string,
|
text: string,
|
||||||
list: MakeChild['list'],
|
list: MakeChild['list'],
|
||||||
placeholder: MakeChild['placeholder'],
|
placeholder: MakeChild['placeholder'],
|
||||||
|
@ -148,9 +148,9 @@ export class SortedList<
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
on_select,
|
on_select = () => { /**/ },
|
||||||
init_rows = () => { /**/ },
|
init_rows = () => { /**/ },
|
||||||
set_sort,
|
on_text_change = () => { /**/ },
|
||||||
setup_list = () => { /**/ },
|
setup_list = () => { /**/ },
|
||||||
on_open = () => { /**/ },
|
on_open = () => { /**/ },
|
||||||
class_name = '',
|
class_name = '',
|
||||||
|
@ -171,7 +171,7 @@ export class SortedList<
|
||||||
// SortedList
|
// SortedList
|
||||||
this._on_select = on_select;
|
this._on_select = on_select;
|
||||||
this._init_rows = init_rows;
|
this._init_rows = init_rows;
|
||||||
this._set_sort = set_sort;
|
this._on_text_change = on_text_change;
|
||||||
|
|
||||||
this._placeholder = makeChildResult.placeholder;
|
this._placeholder = makeChildResult.placeholder;
|
||||||
this._scrollable = makeChildResult.scrollable;
|
this._scrollable = makeChildResult.scrollable;
|
||||||
|
@ -185,14 +185,14 @@ export class SortedList<
|
||||||
|
|
||||||
this._entry.on_change = ({ text }) => {
|
this._entry.on_change = ({ text }) => {
|
||||||
if (text !== null || typeof text === 'string') {
|
if (text !== null || typeof text === 'string') {
|
||||||
this._set_sort(text, this._list, this._placeholder);
|
this._on_text_change(text, this._list, this._placeholder);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// TODO: add on_accept where it just selects the first visible one
|
// TODO: add on_accept where it just selects the first visible one
|
||||||
|
|
||||||
setup_list(this._list);
|
setup_list(this._list, this._entry);
|
||||||
this._init_rows(this._list);
|
this._init_rows(this._list);
|
||||||
this._set_sort('', this._list, this._placeholder);
|
this._on_text_change('', this._list, this._placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue