aboutsummaryrefslogtreecommitdiff
path: root/.config/ags/widget/launcher/AppLauncher.ts
diff options
context:
space:
mode:
Diffstat (limited to '.config/ags/widget/launcher/AppLauncher.ts')
-rw-r--r--.config/ags/widget/launcher/AppLauncher.ts130
1 files changed, 130 insertions, 0 deletions
diff --git a/.config/ags/widget/launcher/AppLauncher.ts b/.config/ags/widget/launcher/AppLauncher.ts
new file mode 100644
index 0000000..4d7ca73
--- /dev/null
+++ b/.config/ags/widget/launcher/AppLauncher.ts
@@ -0,0 +1,130 @@
+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)
+ },
+ })
+}