diff options
| author | srdusr <trevorgray@srdusr.com> | 2025-08-30 19:22:59 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2025-08-30 19:22:59 +0200 |
| commit | 19120d4f9761c67d99ed1ce3da6084b83f5a49c9 (patch) | |
| tree | f234cad1bdad88114a63c9702144da487024967a /linux/home/.config/ags/widget/launcher/AppLauncher.ts | |
| parent | 5928998af5404ae2be84c6cecc10ebf84bd3f3ed (diff) | |
| download | dotfiles-19120d4f9761c67d99ed1ce3da6084b83f5a49c9.tar.gz dotfiles-19120d4f9761c67d99ed1ce3da6084b83f5a49c9.zip | |
Linux-specific dotfiles
Diffstat (limited to 'linux/home/.config/ags/widget/launcher/AppLauncher.ts')
| -rw-r--r-- | linux/home/.config/ags/widget/launcher/AppLauncher.ts | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/linux/home/.config/ags/widget/launcher/AppLauncher.ts b/linux/home/.config/ags/widget/launcher/AppLauncher.ts new file mode 100644 index 0000000..08258de --- /dev/null +++ b/linux/home/.config/ags/widget/launcher/AppLauncher.ts @@ -0,0 +1,125 @@ +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); + }, + }); +} |
