import { Fzf, FzfResultItem } from 'fzf'; import Gtk from 'gi://Gtk?version=3.0'; import Clipboard from '../../services/clipboard.ts'; import SortedList from '../misc/sorted-list.ts'; import ClipWidget from './clip.ts'; const getKey = (r: Gtk.ListBoxRow): number => parseInt(r.get_child()?.name ?? '0'); export default () => { let fzfResults = [] as FzfResultItem<[number, { clip: string, isImage: boolean }]>[]; return SortedList({ name: 'clipboard', class_name: 'clipboard', transition: 'slide top', on_select: (r) => { Clipboard.copyOldItem(getKey(r)); App.closeWindow('win-clipboard'); }, setup_list: (list, entry) => { list.cursor = 'pointer'; const CONNECT_ID = Clipboard.connect('history-searched', () => { // Do every clip that existed before this widget Clipboard.clips.forEach((clip, key) => { const widget = ClipWidget({ key, isImage: clip.isImage, val: clip.clip }); list.add(widget); widget.show_all(); }); // Setup connection for new clips Clipboard.connect('clip-added', (_, [key, clip]) => { const widget = ClipWidget({ key, isImage: clip.isImage, val: clip.clip }); list.add(widget); widget.show_all(); }); 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; } }); // Trigger on_text_change after init entry.text = '-'; Clipboard.disconnect(CONNECT_ID); }); }, on_text_change: (text, list, placeholder) => { const fzf = new Fzf([...Clipboard.clips.entries()], { selector: ([_key, { clip }]) => clip, tiebreakers: [(a, b) => b[0] - a[0]], }); fzfResults = fzf.find(text); list.invalidate_sort(); const visibleApps = list.get_children().filter((row) => row.visible).length; placeholder.reveal_child = visibleApps <= 0; }, }); };