import { App, Astal, Gtk, Widget } from 'astal/gtk3'; import { idle } from 'astal'; import AstalApps from 'gi://AstalApps'; import { Fzf, FzfResultItem } from 'fzf'; import PopupWindow from '../misc/popup-window'; import { centerCursor } from '../../lib'; import AppItemWidget, { AppItem } from './app-item'; import { launchApp } from './launch'; export default () => { let Applications: AstalApps.Application[] = []; let fzfResults = [] as FzfResultItem[]; const list = new Gtk.ListBox({ selectionMode: Gtk.SelectionMode.SINGLE, }); list.connect('row-activated', (_, row) => { const app = (row.get_children()[0] as AppItem).app; launchApp(app); App.get_window('win-applauncher')?.set_visible(false); }); const placeholder = ( ) as Widget.Revealer; const on_text_change = (text: string) => { const fzf = new Fzf(Applications, { selector: (app) => app.name + app.executable, tiebreakers: [ (a, b) => b.item.frequency - a.item.frequency, ], }); fzfResults = fzf.find(text); list.invalidate_sort(); const visibleApplications = list.get_children().filter((row) => row.visible).length; placeholder.reveal_child = visibleApplications <= 0; }; const entry = ( on_text_change(self.text)} hexpand /> ) as Widget.Entry; list.set_sort_func((a, b) => { const row1 = (a.get_children()[0] as AppItem).app; const row2 = (b.get_children()[0] as AppItem).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; } }); const refreshApplications = () => idle(() => { (list.get_children() as Gtk.ListBoxRow[]) .forEach((child) => { child.destroy(); }); Applications = AstalApps.Apps.new().get_list(); Applications .flatMap((app) => AppItemWidget({ app })) .forEach((child) => { list.add(child); }); list.show_all(); on_text_change(''); }); refreshApplications(); return ( { entry.text = ''; centerCursor(); }} > {entry} {list} {placeholder} ); };