Refonte complete du rice. Palette 100% originale (Mitsuri Kanroji inspired), zero emprunt Dracula/Catppuccin. 50 fichiers, 3200+ lignes. Palette v2: - palette.sh source de verite unique (dark + light) - 5 accents (magenta, lilac, mitsuri, lavande, champagne) - 4 semantiques derivees, 4 niveaux texte, 6 fonds - Gradient signature: magenta → lilac → lavande → mitsuri - Variante Light: fonds lavande, accents assombris WCAG Terminal: - kitty (remplace COSMIC Term comme principal) - Maple Mono NF (cursive italics, ligatures) - Cursor trail magenta, splits/layouts tiling, undercurl - Vi-mode zsh avec cursor shape adaptatif Shell: - starship 3 lignes (palette nommee, brain_name, battery, sudo) - zshrc v2 (nouveaux outils, fzf pimp, shell functions, vi-mode) - Commandes custom: proj, glog, fkill, colors, hotkeys, weather, y Desktop: - AGS config (bar 3-pills, OSD gradient, launcher, notifications) - COSMIC Dark + Light v2 (7 fichiers RON chacun) - COSMIC Term v2 (color schemes dark/light, Maple Mono NF) - GTK3/GTK4 dark + light css - Vivaldi theme v2 Outils: - +kitty +dust +procs +tokei +sd +hyperfine +gping +Maple Mono NF - Propagation palette sur: bat, btop, cava, yazi, lazygit, rofi, delta, fastfetch, atuin, ls-colors, vivaldi - Claude Code statusline brain-aware Docs: - README v2 complet (palette, structure, raccourcis, commandes) - help.md v2 (reference exhaustive)
100 lines
3.0 KiB
JavaScript
100 lines
3.0 KiB
JavaScript
// ── violet-chaton v2 — Launcher widget ──────────────────────────────────────
|
|
// App launcher avec recherche fuzzy
|
|
|
|
const applications = await Service.import("applications");
|
|
|
|
const AppItem = (app) => Widget.Button({
|
|
className: "app-item",
|
|
onClicked: () => {
|
|
app.launch();
|
|
App.closeWindow("launcher");
|
|
},
|
|
child: Widget.Box({
|
|
children: [
|
|
Widget.Icon({ icon: app.iconName || "application-x-executable", size: 24 }),
|
|
Widget.Box({
|
|
vertical: true,
|
|
children: [
|
|
Widget.Label({
|
|
label: app.name,
|
|
xalign: 0,
|
|
truncate: "end",
|
|
}),
|
|
Widget.Label({
|
|
label: app.description || "",
|
|
xalign: 0,
|
|
truncate: "end",
|
|
className: "description",
|
|
css: "color: #716686; font-size: 11px; font-weight: normal;",
|
|
}),
|
|
],
|
|
}),
|
|
],
|
|
}),
|
|
});
|
|
|
|
export const Launcher = (monitor) => {
|
|
let apps = applications.list;
|
|
|
|
const list = Widget.Box({
|
|
vertical: true,
|
|
spacing: 2,
|
|
});
|
|
|
|
const entry = Widget.Entry({
|
|
className: "search",
|
|
placeholderText: "Rechercher...",
|
|
onAccept: () => {
|
|
const first = apps[0];
|
|
if (first) {
|
|
first.launch();
|
|
App.closeWindow("launcher");
|
|
}
|
|
},
|
|
onChange: ({ text }) => {
|
|
apps = applications.query(text || "");
|
|
list.children = apps.slice(0, 12).map(AppItem);
|
|
|
|
if (apps.length === 0) {
|
|
list.children = [Widget.Label({
|
|
className: "no-results",
|
|
label: "Aucun resultat",
|
|
})];
|
|
}
|
|
},
|
|
});
|
|
|
|
return Widget.Window({
|
|
name: "launcher",
|
|
monitor,
|
|
anchor: ["top"],
|
|
layer: "overlay",
|
|
visible: false,
|
|
keymode: "exclusive",
|
|
setup: (self) => {
|
|
self.keybind("Escape", () => App.closeWindow("launcher"));
|
|
self.hook(App, (_, name, visible) => {
|
|
if (name === "launcher" && visible) {
|
|
entry.text = "";
|
|
apps = applications.list;
|
|
list.children = apps.slice(0, 12).map(AppItem);
|
|
entry.grab_focus();
|
|
}
|
|
});
|
|
},
|
|
child: Widget.Box({
|
|
className: "launcher",
|
|
vertical: true,
|
|
children: [
|
|
Widget.Scrollable({
|
|
hscroll: "never",
|
|
vscroll: "automatic",
|
|
css: "min-height: 400px;",
|
|
child: list,
|
|
}),
|
|
entry,
|
|
],
|
|
}),
|
|
});
|
|
};
|