import { type Application } from 'types/service/applications'; import { launchApp, icon } from 'lib/utils'; import options from 'options'; import icons from 'lib/icons'; const apps = await Service.import('applications'); const { query } = apps; const { iconSize } = options.launcher.apps; const QuickAppButton = (app: Application) => Widget.Button({ hexpand: true, tooltip_text: app.name, on_clicked: () => { App.closeWindow('launcher'); launchApp(app); }, child: Widget.Icon({ size: iconSize.bind(), icon: icon(app.icon_name, icons.fallback.executable), }), }); const AppItem = (app: Application) => { const title = Widget.Label({ class_name: 'title', label: app.name, hexpand: true, xalign: 0, vpack: 'center', truncate: 'end', }); const description = Widget.Label({ class_name: 'description', label: app.description || '', hexpand: true, wrap: true, max_width_chars: 30, xalign: 0, justification: 'left', vpack: 'center', }); const appicon = Widget.Icon({ icon: icon(app.icon_name, icons.fallback.executable), size: iconSize.bind(), }); const textBox = Widget.Box({ vertical: true, vpack: 'center', children: app.description ? [title, description] : [title], }); return Widget.Button({ class_name: 'app-item', attribute: { app }, child: Widget.Box({ children: [appicon, textBox], }), on_clicked: () => { App.closeWindow('launcher'); launchApp(app); }, }); }; export function Favorites() { const favs = options.launcher.apps.favorites.bind(); return Widget.Revealer({ visible: favs.as(f => f.length > 0), child: Widget.Box({ vertical: true, children: favs.as(favs => favs.flatMap(fs => [ Widget.Separator(), Widget.Box({ class_name: 'quicklaunch horizontal', children: fs .map(f => query(f)?.[0]) .filter(f => f) .map(QuickAppButton), }), ]), ), }), }); } export function Launcher() { const applist = Variable(query('')); const max = options.launcher.apps.max; let first = applist.value[0]; function SeparatedAppItem(app: Application) { return Widget.Revealer({ attribute: { app } }, Widget.Box({ vertical: true }, Widget.Separator(), AppItem(app))); } const list = Widget.Box({ vertical: true, children: applist.bind().as(list => list.map(SeparatedAppItem)), setup: self => self.hook(apps, () => (applist.value = query('')), 'notify::frequents'), }); return Object.assign(list, { filter(text: string | null) { first = query(text || '')[0]; list.children.reduce((i, item) => { if (!text || i >= max.value) { item.reveal_child = false; return i; } if (item.attribute.app.match(text)) { item.reveal_child = true; return ++i; } item.reveal_child = false; return i; }, 0); }, launchFirst() { launchApp(first); }, }); }