launcher modes + player controls IPC
This commit is contained in:
parent
824ebda7c8
commit
a313624734
6 changed files with 735 additions and 52 deletions
5
app.tsx
5
app.tsx
|
|
@ -4,6 +4,7 @@ import AstalHyprland from "gi://AstalHyprland";
|
|||
import Bar from "./modules/bar";
|
||||
import Launcher from "./modules/launcher";
|
||||
import NotifPopups from "./modules/notifpopups";
|
||||
import Players from "./services/players";
|
||||
import { PopupWindow } from "./utils/widgets";
|
||||
|
||||
const loadStyleAsync = async () => {
|
||||
|
|
@ -29,6 +30,10 @@ App.start({
|
|||
let log = true;
|
||||
|
||||
if (request === "reload css") loadStyleAsync().catch(console.error);
|
||||
else if (request === "media play pause") Players.get_default().lastPlayer?.play_pause();
|
||||
else if (request === "media next") Players.get_default().lastPlayer?.next();
|
||||
else if (request === "media previous") Players.get_default().lastPlayer?.previous();
|
||||
else if (request === "media stop") Players.get_default().lastPlayer?.stop();
|
||||
else if (request.startsWith("toggle")) {
|
||||
const window = App.get_window(request.slice(7));
|
||||
if (window instanceof PopupWindow) window.toggle();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
import { bind, Gio, timeout, Variable } from "astal";
|
||||
import { bind, execAsync, Gio, register, timeout, Variable } from "astal";
|
||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
||||
import fuzzysort from "fuzzysort";
|
||||
import type AstalApps from "gi://AstalApps";
|
||||
import AstalHyprland from "gi://AstalHyprland";
|
||||
import Mexp from "math-expression-evaluator";
|
||||
import { Apps } from "../services/apps";
|
||||
import { getAppCategoryIcon } from "../utils/icons";
|
||||
import { launch } from "../utils/system";
|
||||
import { PopupWindow, setupCustomTooltip, TransitionType } from "../utils/widgets";
|
||||
|
||||
type Mode = "apps" | "files" | "math";
|
||||
|
||||
interface Subcommand {
|
||||
icon: string;
|
||||
name: string;
|
||||
description: string;
|
||||
command: (...args: string[]) => void;
|
||||
}
|
||||
|
||||
const maxSearchResults = 15;
|
||||
|
||||
const browser = [
|
||||
|
|
@ -23,6 +34,17 @@ const files = ["thunar", "nemo", "nautilus"];
|
|||
const ide = ["codium", "code", "clion", "intellij-idea-ultimate-edition"];
|
||||
const music = ["spotify-adblock", "spotify", "audacious", "elisa"];
|
||||
|
||||
const getIconFromMode = (mode: Mode) => {
|
||||
switch (mode) {
|
||||
case "apps":
|
||||
return "apps";
|
||||
case "files":
|
||||
return "folder";
|
||||
case "math":
|
||||
return "calculate";
|
||||
}
|
||||
};
|
||||
|
||||
const launchAndClose = (self: JSX.Element, astalApp: AstalApps.Application) => {
|
||||
const toplevel = self.get_toplevel();
|
||||
if (toplevel instanceof Widget.Window) toplevel.hide();
|
||||
|
|
@ -45,7 +67,7 @@ const PinnedApp = ({ names }: { names: string[] }) => {
|
|||
|
||||
return app ? (
|
||||
<button
|
||||
className="app"
|
||||
className="pinned-app result"
|
||||
cursor="pointer"
|
||||
onClicked={self => launchAndClose(self, astalApp!)}
|
||||
setup={self => setupCustomTooltip(self, app.get_display_name())}
|
||||
|
|
@ -56,7 +78,7 @@ const PinnedApp = ({ names }: { names: string[] }) => {
|
|||
};
|
||||
|
||||
const PinnedApps = () => (
|
||||
<box homogeneous className="pinned">
|
||||
<box homogeneous>
|
||||
<PinnedApp names={browser} />
|
||||
<PinnedApp names={terminal} />
|
||||
<PinnedApp names={files} />
|
||||
|
|
@ -82,21 +104,72 @@ const SearchEntry = ({ entry }: { entry: Widget.Entry }) => (
|
|||
</stack>
|
||||
);
|
||||
|
||||
const Result = ({ app }: { app: AstalApps.Application }) => (
|
||||
<button className="app" cursor="pointer" onClicked={self => launchAndClose(self, app)}>
|
||||
// TODO: description field
|
||||
const Result = ({
|
||||
icon,
|
||||
materialIcon,
|
||||
label,
|
||||
sublabel,
|
||||
onClicked,
|
||||
}: {
|
||||
icon?: string;
|
||||
materialIcon?: string;
|
||||
label: string;
|
||||
sublabel?: string;
|
||||
onClicked: (self: Widget.Button) => void;
|
||||
}) => (
|
||||
<button className="result" cursor="pointer" onClicked={onClicked}>
|
||||
<box>
|
||||
{Astal.Icon.lookup_icon(app.iconName) ? (
|
||||
<icon className="icon" icon={app.iconName} />
|
||||
{icon && Astal.Icon.lookup_icon(icon) ? (
|
||||
<icon className="icon" icon={icon} />
|
||||
) : (
|
||||
<label className="icon" label={getAppCategoryIcon(app)} />
|
||||
<label className="icon" label={materialIcon} />
|
||||
)}
|
||||
{sublabel ? (
|
||||
<box vertical valign={Gtk.Align.CENTER} className="has-sublabel">
|
||||
<label xalign={0} label={label} />
|
||||
<label hexpand truncate maxWidthChars={1} className="sublabel" xalign={0} label={sublabel} />
|
||||
</box>
|
||||
) : (
|
||||
<label xalign={0} label={label} />
|
||||
)}
|
||||
<label xalign={0} label={app.name} />
|
||||
</box>
|
||||
</button>
|
||||
);
|
||||
|
||||
const Results = ({ entry }: { entry: Widget.Entry }) => {
|
||||
const SubcommandResult = ({
|
||||
entry,
|
||||
subcommand,
|
||||
args,
|
||||
}: {
|
||||
entry: Widget.Entry;
|
||||
subcommand: Subcommand;
|
||||
args: string[];
|
||||
}) => (
|
||||
<Result
|
||||
materialIcon={subcommand.icon}
|
||||
label={subcommand.name}
|
||||
sublabel={subcommand.description}
|
||||
onClicked={() => {
|
||||
subcommand.command(...args);
|
||||
entry.set_text("");
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const AppResult = ({ app }: { app: AstalApps.Application }) => (
|
||||
<Result
|
||||
icon={app.iconName}
|
||||
materialIcon={getAppCategoryIcon(app)}
|
||||
label={app.name}
|
||||
sublabel={app.description}
|
||||
onClicked={self => launchAndClose(self, app)}
|
||||
/>
|
||||
);
|
||||
|
||||
const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable<Mode> }) => {
|
||||
const empty = Variable(true);
|
||||
|
||||
return (
|
||||
<stack
|
||||
className="results"
|
||||
|
|
@ -112,17 +185,82 @@ const Results = ({ entry }: { entry: Widget.Entry }) => {
|
|||
vertical
|
||||
name="list"
|
||||
setup={self => {
|
||||
let apps: AstalApps.Application[] = [];
|
||||
self.hook(entry, "activate", () => {
|
||||
if (entry.text && apps[0]) launchAndClose(self, apps[0]);
|
||||
});
|
||||
const subcommands: Record<string, Subcommand> = {
|
||||
apps: {
|
||||
icon: "apps",
|
||||
name: "Apps",
|
||||
description: "Search for apps",
|
||||
command: () => mode.set("apps"),
|
||||
},
|
||||
files: {
|
||||
icon: "folder",
|
||||
name: "Files",
|
||||
description: "Search for files",
|
||||
command: () => mode.set("files"),
|
||||
},
|
||||
calc: {
|
||||
icon: "calculate",
|
||||
name: "Calculator",
|
||||
description: "A calculator...",
|
||||
command: () => mode.set("math"),
|
||||
},
|
||||
todo: {
|
||||
icon: "checklist",
|
||||
name: "Todo",
|
||||
description: "Create a todo in <INSERT_TODO_APP>",
|
||||
command: (...args) => {
|
||||
// TODO: todo service or maybe use external app
|
||||
},
|
||||
},
|
||||
};
|
||||
const subcommandList = Object.keys(subcommands);
|
||||
const mexp = new Mexp();
|
||||
|
||||
const appSearch = () => {
|
||||
const apps = Apps.fuzzy_query(entry.text);
|
||||
empty.set(apps.length === 0);
|
||||
if (apps.length > maxSearchResults) apps.length = maxSearchResults;
|
||||
for (const app of apps) self.add(<AppResult app={app} />);
|
||||
};
|
||||
|
||||
const calculate = () => {
|
||||
// TODO: allow defs, history
|
||||
let math = null;
|
||||
try {
|
||||
math = mexp.eval(entry.text);
|
||||
} catch (e) {
|
||||
// Ignore
|
||||
}
|
||||
if (math !== null)
|
||||
self.add(
|
||||
<Result
|
||||
materialIcon="calculate"
|
||||
label={entry.text}
|
||||
sublabel={String(math)}
|
||||
onClicked={() => execAsync(`wl-copy -- ${math}`).catch(console.error)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
self.hook(entry, "activate", () => entry.text && self.get_children()[0].activate());
|
||||
self.hook(entry, "changed", () => {
|
||||
if (!entry.text) return;
|
||||
self.foreach(ch => ch.destroy());
|
||||
apps = Apps.fuzzy_query(entry.text);
|
||||
empty.set(apps.length === 0);
|
||||
if (apps.length > maxSearchResults) apps.length = maxSearchResults;
|
||||
for (const app of apps) self.add(<Result app={app} />);
|
||||
|
||||
if (entry.text.startsWith(">")) {
|
||||
const args = entry.text.split(" ");
|
||||
for (const { target } of fuzzysort.go(args[0].slice(1), subcommandList, { all: true }))
|
||||
self.add(
|
||||
<SubcommandResult
|
||||
entry={entry}
|
||||
subcommand={subcommands[target]}
|
||||
args={args.slice(1)}
|
||||
/>
|
||||
);
|
||||
} else if (mode.get() === "apps") appSearch();
|
||||
else if (mode.get() === "math") calculate();
|
||||
|
||||
empty.set(self.get_children().length === 0);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
|
@ -130,16 +268,16 @@ const Results = ({ entry }: { entry: Widget.Entry }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const Launcher = ({ entry }: { entry: Widget.Entry }) => (
|
||||
const LauncherContent = ({ mode, entry }: { mode: Variable<Mode>; entry: Widget.Entry }) => (
|
||||
<box
|
||||
vertical
|
||||
className="launcher"
|
||||
className={bind(mode).as(m => `launcher ${m}`)}
|
||||
css={bind(AstalHyprland.get_default(), "focusedMonitor").as(m => `margin-top: ${m.height / 4}px;`)}
|
||||
>
|
||||
<box className="search-bar">
|
||||
<label className="icon" label="search" />
|
||||
<SearchEntry entry={entry} />
|
||||
<label className="icon" label="apps" />
|
||||
<label className="icon" label={bind(mode).as(getIconFromMode)} />
|
||||
</box>
|
||||
<revealer
|
||||
revealChild={bind(entry, "textLength").as(t => t === 0)}
|
||||
|
|
@ -153,20 +291,24 @@ const Launcher = ({ entry }: { entry: Widget.Entry }) => (
|
|||
transitionType={Gtk.RevealerTransitionType.SLIDE_UP}
|
||||
transitionDuration={150}
|
||||
>
|
||||
<Results entry={entry} />
|
||||
<Results entry={entry} mode={mode} />
|
||||
</revealer>
|
||||
</box>
|
||||
);
|
||||
|
||||
export default () => {
|
||||
const entry = (<entry name="entry" />) as Widget.Entry;
|
||||
@register()
|
||||
export default class Launcher extends PopupWindow {
|
||||
readonly mode: Variable<Mode>;
|
||||
|
||||
return (
|
||||
<PopupWindow
|
||||
name="launcher"
|
||||
keymode={Astal.Keymode.EXCLUSIVE}
|
||||
exclusivity={Astal.Exclusivity.IGNORE}
|
||||
onKeyPressEvent={(_, event) => {
|
||||
constructor() {
|
||||
const entry = (<entry name="entry" />) as Widget.Entry;
|
||||
const mode = Variable<Mode>("apps");
|
||||
|
||||
super({
|
||||
name: "launcher",
|
||||
keymode: Astal.Keymode.EXCLUSIVE,
|
||||
exclusivity: Astal.Exclusivity.IGNORE,
|
||||
onKeyPressEvent(_, event) {
|
||||
const keyval = event.get_keyval()[1];
|
||||
// Focus entry on typing
|
||||
if (!entry.isFocus && keyval >= 32 && keyval <= 126) {
|
||||
|
|
@ -177,14 +319,20 @@ export default () => {
|
|||
// Consume event, if not consumed it will duplicate character in entry
|
||||
return true;
|
||||
}
|
||||
}}
|
||||
// Clear entry text on hide
|
||||
setup={self => self.connect("hide", () => entry.set_text(""))}
|
||||
transitionType={TransitionType.SLIDE_DOWN}
|
||||
halign={Gtk.Align.CENTER}
|
||||
valign={Gtk.Align.START}
|
||||
>
|
||||
<Launcher entry={entry} />
|
||||
</PopupWindow>
|
||||
);
|
||||
};
|
||||
},
|
||||
transitionType: TransitionType.SLIDE_DOWN,
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.START,
|
||||
child: <LauncherContent mode={mode} entry={entry} />,
|
||||
});
|
||||
|
||||
this.mode = mode;
|
||||
|
||||
this.connect("hide", () => entry.set_text(""));
|
||||
}
|
||||
|
||||
open(mode: Mode) {
|
||||
this.mode.set(mode);
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
494
package-lock.json
generated
Normal file
494
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,494 @@
|
|||
{
|
||||
"name": "caelestia",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"fuzzysort": "^3.1.0",
|
||||
"math-expression-evaluator": "^2.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "0.24.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
|
||||
"integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
|
||||
"integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
|
||||
"integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
|
||||
"integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
|
||||
"integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
|
||||
"integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
|
||||
"integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
|
||||
"integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
|
||||
"integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
|
||||
"integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
|
||||
"integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
|
||||
"integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
|
||||
"integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.24.2",
|
||||
"@esbuild/android-arm": "0.24.2",
|
||||
"@esbuild/android-arm64": "0.24.2",
|
||||
"@esbuild/android-x64": "0.24.2",
|
||||
"@esbuild/darwin-arm64": "0.24.2",
|
||||
"@esbuild/darwin-x64": "0.24.2",
|
||||
"@esbuild/freebsd-arm64": "0.24.2",
|
||||
"@esbuild/freebsd-x64": "0.24.2",
|
||||
"@esbuild/linux-arm": "0.24.2",
|
||||
"@esbuild/linux-arm64": "0.24.2",
|
||||
"@esbuild/linux-ia32": "0.24.2",
|
||||
"@esbuild/linux-loong64": "0.24.2",
|
||||
"@esbuild/linux-mips64el": "0.24.2",
|
||||
"@esbuild/linux-ppc64": "0.24.2",
|
||||
"@esbuild/linux-riscv64": "0.24.2",
|
||||
"@esbuild/linux-s390x": "0.24.2",
|
||||
"@esbuild/linux-x64": "0.24.2",
|
||||
"@esbuild/netbsd-arm64": "0.24.2",
|
||||
"@esbuild/netbsd-x64": "0.24.2",
|
||||
"@esbuild/openbsd-arm64": "0.24.2",
|
||||
"@esbuild/openbsd-x64": "0.24.2",
|
||||
"@esbuild/sunos-x64": "0.24.2",
|
||||
"@esbuild/win32-arm64": "0.24.2",
|
||||
"@esbuild/win32-ia32": "0.24.2",
|
||||
"@esbuild/win32-x64": "0.24.2"
|
||||
}
|
||||
},
|
||||
"node_modules/fuzzysort": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-3.1.0.tgz",
|
||||
"integrity": "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/math-expression-evaluator": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-2.0.6.tgz",
|
||||
"integrity": "sha512-DRung1qNcKbgkhFeQ0fBPUFB6voRUMY7KyRyp1TRQ2v95Rp2egC823xLRooM1mDx1rmbkY7ym6ZWmpaE/VimOA==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
package.json
Normal file
9
package.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"fuzzysort": "^3.1.0",
|
||||
"math-expression-evaluator": "^2.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "0.24.2"
|
||||
}
|
||||
}
|
||||
11
run.fish
Executable file
11
run.fish
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/fish
|
||||
|
||||
cd (dirname (status filename)) || exit 1
|
||||
|
||||
set -q XDG_RUNTIME_DIR && set bundle_dir $XDG_RUNTIME_DIR || set bundle_dir /tmp
|
||||
|
||||
./node_modules/.bin/esbuild app.tsx --bundle --outfile=$bundle_dir/caelestia.js \
|
||||
--external:console --external:system --external:cairo --external:gettext --external:'file://*' --external:'gi://*' --external:'resource://*' \
|
||||
--define:SRC=\"(pwd)\" --format=esm --platform=neutral --main-fields=module,main
|
||||
|
||||
gjs -m $bundle_dir/caelestia.js
|
||||
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
.icon {
|
||||
font-size: lib.s(18);
|
||||
color: scheme.$sapphire;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
|
|
@ -37,7 +36,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.app {
|
||||
.result {
|
||||
@include lib.element-decel;
|
||||
|
||||
padding: lib.s(5) lib.s(10);
|
||||
|
|
@ -52,35 +51,52 @@
|
|||
}
|
||||
}
|
||||
|
||||
.pinned .app {
|
||||
.pinned-app {
|
||||
@include lib.rounded(5);
|
||||
|
||||
font-size: lib.s(64);
|
||||
}
|
||||
|
||||
.results {
|
||||
.icon {
|
||||
font-size: lib.s(32);
|
||||
}
|
||||
|
||||
.empty {
|
||||
color: scheme.$subtext0;
|
||||
|
||||
@include lib.spacing;
|
||||
|
||||
.icon {
|
||||
font-size: lib.s(32);
|
||||
}
|
||||
}
|
||||
|
||||
.app {
|
||||
.result {
|
||||
@include lib.rounded(10);
|
||||
|
||||
font-size: lib.s(18);
|
||||
|
||||
& > * {
|
||||
@include lib.spacing;
|
||||
@include lib.spacing(8);
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: lib.s(32);
|
||||
.has-sublabel {
|
||||
font-size: lib.s(16);
|
||||
|
||||
.sublabel {
|
||||
color: scheme.$subtext0;
|
||||
font-size: lib.s(14);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.apps label.icon {
|
||||
color: scheme.$sapphire;
|
||||
}
|
||||
|
||||
&.files label.icon {
|
||||
color: scheme.$peach;
|
||||
}
|
||||
|
||||
&.math label.icon {
|
||||
color: scheme.$green;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue