mirror of
https://github.com/Theaninova/TheaninovOS.git
synced 2025-12-12 11:36:20 +00:00
131 lines
3.5 KiB
TypeScript
131 lines
3.5 KiB
TypeScript
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)
|
|
},
|
|
})
|
|
}
|