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 /.config/ags/widget/launcher | |
| parent | 5928998af5404ae2be84c6cecc10ebf84bd3f3ed (diff) | |
| download | dotfiles-19120d4f9761c67d99ed1ce3da6084b83f5a49c9.tar.gz dotfiles-19120d4f9761c67d99ed1ce3da6084b83f5a49c9.zip | |
Linux-specific dotfiles
Diffstat (limited to '.config/ags/widget/launcher')
| -rw-r--r-- | .config/ags/widget/launcher/AppLauncher.ts | 125 | ||||
| -rw-r--r-- | .config/ags/widget/launcher/Launcher.ts | 134 | ||||
| -rw-r--r-- | .config/ags/widget/launcher/NixRun.ts | 118 | ||||
| -rw-r--r-- | .config/ags/widget/launcher/ShRun.ts | 89 | ||||
| -rw-r--r-- | .config/ags/widget/launcher/launcher.scss | 143 |
5 files changed, 0 insertions, 609 deletions
diff --git a/.config/ags/widget/launcher/AppLauncher.ts b/.config/ags/widget/launcher/AppLauncher.ts deleted file mode 100644 index 08258de..0000000 --- a/.config/ags/widget/launcher/AppLauncher.ts +++ /dev/null @@ -1,125 +0,0 @@ -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); - }, - }); -} diff --git a/.config/ags/widget/launcher/Launcher.ts b/.config/ags/widget/launcher/Launcher.ts deleted file mode 100644 index 90b4d58..0000000 --- a/.config/ags/widget/launcher/Launcher.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { type Binding } from 'lib/utils'; -import PopupWindow, { Padding } from 'widget/PopupWindow'; -import icons from 'lib/icons'; -import options from 'options'; -import nix from 'service/nix'; -import * as AppLauncher from './AppLauncher'; -import * as NixRun from './NixRun'; -import * as ShRun from './ShRun'; - -const { width, margin } = options.launcher; -const isnix = nix.available; - -function Launcher() { - const favs = AppLauncher.Favorites(); - const applauncher = AppLauncher.Launcher(); - const sh = ShRun.ShRun(); - const shicon = ShRun.Icon(); - const nix = NixRun.NixRun(); - const nixload = NixRun.Spinner(); - - function HelpButton(cmd: string, desc: string | Binding<string>) { - return Widget.Box( - { vertical: true }, - Widget.Separator(), - Widget.Button( - { - class_name: 'help', - on_clicked: () => { - entry.grab_focus(); - entry.text = `:${cmd} `; - entry.set_position(-1); - }, - }, - Widget.Box([ - Widget.Label({ - class_name: 'name', - label: `:${cmd}`, - }), - Widget.Label({ - hexpand: true, - hpack: 'end', - class_name: 'description', - label: desc, - }), - ]), - ), - ); - } - - const help = Widget.Revealer({ - child: Widget.Box( - { vertical: true }, - HelpButton('sh', 'run a binary'), - isnix - ? HelpButton( - 'nx', - options.launcher.nix.pkgs.bind().as(pkg => `run a nix package from ${pkg}`), - ) - : Widget.Box(), - ), - }); - - const entry = Widget.Entry({ - hexpand: true, - primary_icon_name: icons.ui.search, - on_accept: ({ text }) => { - if (text?.startsWith(':nx')) nix.run(text.substring(3)); - else if (text?.startsWith(':sh')) sh.run(text.substring(3)); - else applauncher.launchFirst(); - - App.toggleWindow('launcher'); - entry.text = ''; - }, - on_change: ({ text }) => { - text ||= ''; - favs.reveal_child = text === ''; - help.reveal_child = text.split(' ').length === 1 && text?.startsWith(':'); - - if (text?.startsWith(':nx')) nix.filter(text.substring(3)); - else nix.filter(''); - - if (text?.startsWith(':sh')) sh.filter(text.substring(3)); - else sh.filter(''); - - if (!text?.startsWith(':')) applauncher.filter(text); - }, - }); - - function focus() { - entry.text = ''; - entry.set_position(-1); - entry.select_region(0, -1); - entry.grab_focus(); - favs.reveal_child = true; - } - - const layout = Widget.Box({ - css: width.bind().as(v => `min-width: ${v}pt;`), - class_name: 'launcher', - vertical: true, - vpack: 'start', - setup: self => - self.hook(App, (_, win, visible) => { - if (win !== 'launcher') return; - - entry.text = ''; - if (visible) focus(); - }), - children: [ - Widget.Box([entry, nixload, shicon]), - favs, - help, - applauncher, - //nix, - sh, - ], - }); - - return Widget.Box( - { vertical: true, css: 'padding: 1px' }, - Padding('applauncher', { - css: margin.bind().as(v => `min-height: ${v}pt;`), - vexpand: false, - }), - layout, - ); -} - -export default () => - PopupWindow({ - name: 'launcher', - layout: 'top', - child: Launcher(), - }); diff --git a/.config/ags/widget/launcher/NixRun.ts b/.config/ags/widget/launcher/NixRun.ts deleted file mode 100644 index cec9e09..0000000 --- a/.config/ags/widget/launcher/NixRun.ts +++ /dev/null @@ -1,118 +0,0 @@ -import icons from "lib/icons" -import nix, { type Nixpkg } from "service/nix" - -const iconVisible = Variable(false) - -function Item(pkg: Nixpkg) { - const name = Widget.Label({ - class_name: "name", - label: pkg.name.split(".").at(-1), - }) - - const subpkg = pkg.name.includes(".") ? Widget.Label({ - class_name: "description", - hpack: "end", - hexpand: true, - label: ` ${pkg.name.split(".").slice(0, -1).join(".")}`, - }) : null - - const version = Widget.Label({ - class_name: "version", - label: pkg.version, - hexpand: true, - hpack: "end", - }) - - const description = pkg.description ? Widget.Label({ - class_name: "description", - label: pkg.description, - justification: "left", - wrap: true, - hpack: "start", - max_width_chars: 40, - }) : null - - return Widget.Box( - { - attribute: { name: pkg.name }, - vertical: true, - }, - Widget.Separator(), - Widget.Button( - { - class_name: "nix-item", - on_clicked: () => { - nix.run(pkg.name) - App.closeWindow("launcher") - }, - }, - Widget.Box( - { vertical: true }, - Widget.Box([name, version]), - Widget.Box([ - description as ReturnType<typeof Widget.Label>, - subpkg as ReturnType<typeof Widget.Label>, - ]), - ), - ), - ) -} - -export function Spinner() { - const icon = Widget.Icon({ - icon: icons.nix.nix, - class_name: "spinner", - css: ` - @keyframes spin { - to { -gtk-icon-transform: rotate(1turn); } - } - - image.spinning { - animation-name: spin; - animation-duration: 1s; - animation-timing-function: linear; - animation-iteration-count: infinite; - } - `, - setup: self => self.hook(nix, () => { - self.toggleClassName("spinning", !nix.ready) - }), - }) - - return Widget.Revealer({ - transition: "slide_left", - child: icon, - reveal_child: Utils.merge([ - nix.bind("ready"), - iconVisible.bind(), - ], (ready, show) => !ready || show), - }) -} - -export function NixRun() { - const list = Widget.Box<ReturnType<typeof Item>>({ - vertical: true, - }) - - const revealer = Widget.Revealer({ - child: list, - }) - - async function filter(term: string) { - iconVisible.value = Boolean(term) - - if (!term) - revealer.reveal_child = false - - if (term.trim()) { - const found = await nix.query(term) - list.children = found.map(k => Item(nix.db[k])) - revealer.reveal_child = true - } - } - - return Object.assign(revealer, { - filter, - run: nix.run, - }) -} diff --git a/.config/ags/widget/launcher/ShRun.ts b/.config/ags/widget/launcher/ShRun.ts deleted file mode 100644 index c4215ef..0000000 --- a/.config/ags/widget/launcher/ShRun.ts +++ /dev/null @@ -1,89 +0,0 @@ -import icons from "lib/icons" -import options from "options" -import { bash, dependencies } from "lib/utils" - -const iconVisible = Variable(false) - -const MAX = options.launcher.sh.max -const BINS = `${Utils.CACHE_DIR}/binaries` -bash("{ IFS=:; ls -H $PATH; } | sort ") - .then(bins => Utils.writeFile(bins, BINS)) - -async function query(filter: string) { - if (!dependencies("fzf")) - return [] as string[] - - return bash(`cat ${BINS} | fzf -f ${filter} | head -n ${MAX}`) - .then(str => Array.from(new Set(str.split("\n").filter(i => i)).values())) - .catch(err => { print(err); return [] }) -} - -function run(args: string) { - Utils.execAsync(args) - .then(out => { - print(`:sh ${args.trim()}:`) - print(out) - }) - .catch(err => { - Utils.notify("ShRun Error", err, icons.app.terminal) - }) -} - -function Item(bin: string) { - return Widget.Box( - { - attribute: { bin }, - vertical: true, - }, - Widget.Separator(), - Widget.Button({ - child: Widget.Label({ - label: bin, - hpack: "start", - }), - class_name: "sh-item", - on_clicked: () => { - Utils.execAsync(bin) - App.closeWindow("launcher") - }, - }), - ) -} - -export function Icon() { - const icon = Widget.Icon({ - icon: icons.app.terminal, - class_name: "spinner", - }) - - return Widget.Revealer({ - transition: "slide_left", - child: icon, - reveal_child: iconVisible.bind(), - }) -} - -export function ShRun() { - const list = Widget.Box<ReturnType<typeof Item>>({ - vertical: true, - }) - - const revealer = Widget.Revealer({ - child: list, - }) - - async function filter(term: string) { - iconVisible.value = Boolean(term) - - if (!term) - revealer.reveal_child = false - - if (term.trim()) { - const found = await query(term) - list.children = found.map(Item) - revealer.reveal_child = true - } - } - - return Object.assign(revealer, { filter, run }) -} diff --git a/.config/ags/widget/launcher/launcher.scss b/.config/ags/widget/launcher/launcher.scss deleted file mode 100644 index 926abc3..0000000 --- a/.config/ags/widget/launcher/launcher.scss +++ /dev/null @@ -1,143 +0,0 @@ -@use "sass:math"; -@use "sass:color"; - -window#launcher .launcher { - @include floating_widget; - - .quicklaunch { - @include spacing; - - button { - @include button($flat: true); - padding: $padding; - } - } - - entry { - @include button; - padding: $padding; - margin: $spacing; - - selection { - color: color.mix($fg, $bg, 50%); - background-color: transparent; - } - - label, - image { - color: $fg; - } - } - - image.spinner { - color: $primary-bg; - margin-right: $spacing; - } - - separator { - margin: 4pt 0; - background-color: $popover-border-color; - } - - button.app-item { - @include button($flat: true, $reactive: false); - - >box { - @include spacing(0.5); - } - - transition: $transition; - padding: $padding; - - label { - transition: $transition; - - &.title { - color: $fg; - } - - &.description { - color: transparentize($fg, 0.3); - } - } - - image { - transition: $transition; - } - - &:hover, - &:focus { - .title { - color: $primary-bg; - } - - .description { - color: transparentize($primary-bg, .4); - } - - image { - -gtk-icon-shadow: 2px 2px $primary-bg; - } - } - - &:active { - background-color: transparentize($primary-bg, 0.5); - border-radius: $radius; - box-shadow: inset 0 0 0 $border-width $border-color; - - .title { - color: $fg; - } - } - } - - button.help, - button.nix-item { - @include button($flat: true, $reactive: false); - padding: 0 ($padding * .5); - - label { - transition: $transition; - color: $fg; - } - - .name { - font-size: 1.2em; - font-weight: bold; - } - - .description { - color: transparentize($fg, .3) - } - - &:hover, - &:focus { - label { - text-shadow: $text-shadow; - } - - .name, - .version { - color: $primary-bg; - } - - .description { - color: transparentize($primary-bg, .3) - } - } - } - - button.sh-item { - @include button($flat: true, $reactive: false); - padding: 0 ($padding * .5); - - transition: $transition; - color: $fg; - - &:hover, - &:focus { - color: $primary-bg; - text-shadow: $text-shadow; - } - } -} |
