2024-01-30 11:29:07 -05:00
|
|
|
const Applications = await Service.import('applications');
|
|
|
|
const { Box, Entry, Icon, Label, ListBox, Revealer, Scrollable } = Widget;
|
|
|
|
|
2024-03-19 15:10:18 -04:00
|
|
|
import { Fzf, FzfResultItem } from 'fzf';
|
2023-10-31 08:32:40 -04:00
|
|
|
|
2024-01-13 23:38:31 -05:00
|
|
|
import PopupWindow from '../misc/popup.ts';
|
|
|
|
import AppItem from './app-item.ts';
|
2023-09-29 03:36:48 -04:00
|
|
|
|
2024-01-13 11:15:08 -05:00
|
|
|
// Types
|
2024-01-22 10:23:32 -05:00
|
|
|
import { ListBoxRow } from 'types/@girs/gtk-3.0/gtk-3.0.cjs';
|
2024-01-29 18:54:07 -05:00
|
|
|
import { Application } from 'types/service/applications.ts';
|
|
|
|
import { AgsAppItem } from 'global-types';
|
2023-12-20 03:45:05 -05:00
|
|
|
|
2023-09-29 03:36:48 -04:00
|
|
|
|
2024-01-10 20:10:14 -05:00
|
|
|
const Applauncher = (window_name = 'applauncher') => {
|
2024-01-29 18:54:07 -05:00
|
|
|
let fzfResults: FzfResultItem<Application>[];
|
2024-01-22 10:23:32 -05:00
|
|
|
const list = ListBox();
|
2023-12-09 12:12:43 -05:00
|
|
|
|
2024-01-13 11:15:08 -05:00
|
|
|
const setSort = (text: string) => {
|
2023-12-07 01:18:47 -05:00
|
|
|
const fzf = new Fzf(Applications.list, {
|
2024-03-19 15:10:18 -04:00
|
|
|
selector: (app) => app.name + app.executable,
|
|
|
|
|
2023-12-20 03:45:05 -05:00
|
|
|
tiebreakers: [
|
2024-03-19 15:10:18 -04:00
|
|
|
(a, b) => b.item.frequency - a.item.frequency,
|
2023-12-20 03:45:05 -05:00
|
|
|
],
|
2023-12-07 01:18:47 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
fzfResults = fzf.find(text);
|
2024-01-29 18:54:07 -05:00
|
|
|
list.set_sort_func((a, b) => {
|
|
|
|
const row1 = (a.get_children()[0] as AgsAppItem).attribute.app.name;
|
|
|
|
const row2 = (b.get_children()[0] as AgsAppItem).attribute.app.name;
|
2023-12-07 01:18:47 -05:00
|
|
|
|
2024-03-19 15:26:40 -04:00
|
|
|
const s1 = fzfResults.find((r) => r.item.name === row1)?.score ?? 0;
|
|
|
|
const s2 = fzfResults.find((r) => r.item.name === row2)?.score ?? 0;
|
2024-03-19 15:10:18 -04:00
|
|
|
|
2024-03-19 15:26:40 -04:00
|
|
|
return s1 - s2;
|
2024-01-29 18:54:07 -05:00
|
|
|
});
|
2023-12-07 01:18:47 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
const makeNewChildren = () => {
|
2024-01-29 18:54:07 -05:00
|
|
|
const rows = list.get_children() as ListBoxRow[];
|
2023-12-20 03:45:05 -05:00
|
|
|
|
|
|
|
rows.forEach((ch) => {
|
2023-12-07 01:18:47 -05:00
|
|
|
ch.destroy();
|
|
|
|
});
|
|
|
|
|
2023-12-09 12:12:43 -05:00
|
|
|
const children = Applications.query('')
|
|
|
|
.flatMap((app) => AppItem(app));
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-12-09 12:12:43 -05:00
|
|
|
children.forEach((ch) => {
|
|
|
|
list.add(ch);
|
|
|
|
});
|
|
|
|
list.show_all();
|
2023-12-07 01:18:47 -05:00
|
|
|
};
|
2023-09-29 03:36:48 -04:00
|
|
|
|
2023-12-07 01:18:47 -05:00
|
|
|
makeNewChildren();
|
2023-11-13 15:19:49 -05:00
|
|
|
|
2023-12-18 20:23:09 -05:00
|
|
|
const placeholder = Revealer({
|
|
|
|
child: Label({
|
|
|
|
label: " Couldn't find a match",
|
|
|
|
class_name: 'placeholder',
|
|
|
|
}),
|
2023-11-21 01:29:46 -05:00
|
|
|
});
|
|
|
|
|
2023-10-20 23:11:21 -04:00
|
|
|
const entry = Entry({
|
2023-11-21 01:29:46 -05:00
|
|
|
// Set some text so on-change works the first time
|
|
|
|
text: '-',
|
2023-10-20 23:11:21 -04:00
|
|
|
hexpand: true,
|
2023-11-13 15:19:49 -05:00
|
|
|
|
|
|
|
on_accept: ({ text }) => {
|
2023-11-21 01:29:46 -05:00
|
|
|
const appList = Applications.query(text || '');
|
|
|
|
|
|
|
|
if (appList[0]) {
|
2024-04-07 14:29:12 -04:00
|
|
|
App.closeWindow(`win-${window_name}`);
|
2023-12-21 01:25:59 -05:00
|
|
|
appList[0].launch();
|
2023-10-20 23:11:21 -04:00
|
|
|
}
|
|
|
|
},
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-11-13 15:19:49 -05:00
|
|
|
on_change: ({ text }) => {
|
2023-12-18 23:20:32 -05:00
|
|
|
if (text === null) {
|
2023-12-18 18:00:30 -05:00
|
|
|
return;
|
|
|
|
}
|
2023-12-07 01:18:47 -05:00
|
|
|
setSort(text);
|
2023-11-13 15:19:49 -05:00
|
|
|
let visibleApps = 0;
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2024-01-29 18:54:07 -05:00
|
|
|
const rows = list.get_children() as ListBoxRow[];
|
2023-12-20 03:45:05 -05:00
|
|
|
|
|
|
|
rows.forEach((row) => {
|
2023-12-07 01:18:47 -05:00
|
|
|
row.changed();
|
|
|
|
|
2024-01-29 18:54:07 -05:00
|
|
|
const item = (row.get_children()[0] as AgsAppItem);
|
2023-12-07 01:18:47 -05:00
|
|
|
|
2024-01-29 18:54:07 -05:00
|
|
|
if (item.attribute.app) {
|
2024-03-19 15:10:18 -04:00
|
|
|
const isMatching = fzfResults.some((r) => {
|
2023-12-18 18:00:30 -05:00
|
|
|
return r.item.name === item.attribute.app.name;
|
2023-12-07 01:18:47 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
row.visible = isMatching;
|
2023-09-29 03:36:48 -04:00
|
|
|
|
2023-12-07 01:18:47 -05:00
|
|
|
if (isMatching) {
|
2023-11-13 15:19:49 -05:00
|
|
|
++visibleApps;
|
2023-11-21 01:29:46 -05:00
|
|
|
}
|
2023-11-13 15:19:49 -05:00
|
|
|
}
|
|
|
|
});
|
2023-12-18 20:23:09 -05:00
|
|
|
placeholder.reveal_child = visibleApps <= 0;
|
2023-10-20 23:11:21 -04:00
|
|
|
},
|
|
|
|
});
|
2023-09-29 03:36:48 -04:00
|
|
|
|
2023-10-20 23:11:21 -04:00
|
|
|
return Box({
|
2023-12-18 18:00:30 -05:00
|
|
|
class_name: 'applauncher',
|
2023-10-20 23:11:21 -04:00
|
|
|
vertical: true,
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-12-17 00:01:58 -05:00
|
|
|
setup: (self) => {
|
|
|
|
self.hook(App, (_, name, visible) => {
|
2024-04-07 14:29:12 -04:00
|
|
|
if (name !== `win-${window_name}`) {
|
2023-12-17 00:01:58 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
entry.text = '';
|
|
|
|
|
|
|
|
if (visible) {
|
|
|
|
entry.grab_focus();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
makeNewChildren();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2023-09-29 03:36:48 -04:00
|
|
|
children: [
|
2023-10-20 23:11:21 -04:00
|
|
|
Box({
|
2023-12-18 18:00:30 -05:00
|
|
|
class_name: 'header',
|
2023-10-20 23:11:21 -04:00
|
|
|
children: [
|
2023-11-13 15:19:49 -05:00
|
|
|
Icon('preferences-system-search-symbolic'),
|
2023-10-20 23:11:21 -04:00
|
|
|
entry,
|
|
|
|
],
|
|
|
|
}),
|
2023-11-13 15:19:49 -05:00
|
|
|
|
2023-10-20 23:11:21 -04:00
|
|
|
Scrollable({
|
|
|
|
hscroll: 'never',
|
2023-12-12 23:15:13 -05:00
|
|
|
vscroll: 'automatic',
|
2023-10-20 23:11:21 -04:00
|
|
|
child: Box({
|
|
|
|
vertical: true,
|
|
|
|
children: [list, placeholder],
|
|
|
|
}),
|
|
|
|
}),
|
2023-09-29 03:36:48 -04:00
|
|
|
],
|
2023-10-20 23:11:21 -04:00
|
|
|
});
|
2023-09-29 03:36:48 -04:00
|
|
|
};
|
|
|
|
|
2023-10-16 18:11:19 -04:00
|
|
|
export default () => PopupWindow({
|
2023-10-20 23:11:21 -04:00
|
|
|
name: 'applauncher',
|
2024-04-07 14:29:12 -04:00
|
|
|
transition: 'slide top',
|
2024-01-27 17:11:30 -05:00
|
|
|
keymode: 'on-demand',
|
2024-01-29 18:54:07 -05:00
|
|
|
content: Applauncher(),
|
2023-09-29 03:36:48 -04:00
|
|
|
});
|