nosignal-shell/config.ts
2 * r + 2 * t cf55e26133 config: use config file
Config file at ~/.config/caelestia/shell.json
2025-02-22 19:58:07 +11:00

166 lines
5 KiB
TypeScript

import { GLib, monitorFile, readFileAsync, Variable } from "astal";
import { Astal } from "astal/gtk3";
import { loadStyleAsync } from "./app";
const CONFIG = `${GLib.get_user_config_dir()}/caelestia/shell.json`;
const s = <T>(v: T): Variable<T> => Variable(v);
const warn = (e: Error) => console.warn(`Invalid config: ${e}`);
const updateSection = (from: { [k: string]: any }, to: { [k: string]: any }, path: string) => {
for (const [k, v] of Object.entries(from)) {
if (to.hasOwnProperty(k)) {
if (typeof v === "object" && v !== null && !Array.isArray(v)) updateSection(v, to[k], `${path}.${k}`);
else if (typeof v === typeof to[k].get()) to[k].set(v);
else console.warn(`Invalid type for ${path}.${k}: ${typeof v} != ${typeof to[k].get()}`);
} else console.warn(`Unknown config key: ${path}.${k}`);
}
};
export const updateConfig = async () => {
const conf: { [k: string]: any } = JSON.parse(await readFileAsync(CONFIG));
for (const [k, v] of Object.entries(conf)) {
if (config.hasOwnProperty(k)) updateSection(v, config[k as keyof typeof config], k);
else console.warn(`Unknown config key: ${k}`);
}
loadStyleAsync().catch(console.error);
};
export const initConfig = () => {
monitorFile(CONFIG, () => updateConfig().catch(warn));
updateConfig().catch(warn);
};
const config = {
// Modules
bar: {
vertical: s(true),
modules: {
osIcon: {
enabled: s(true),
},
activeWindow: {
enabled: s(true),
},
mediaPlaying: {
enabled: s(true),
},
workspaces: {
enabled: s(true),
shown: s(5),
},
tray: {
enabled: s(true),
},
statusIcons: {
enabled: s(true),
},
pkgUpdates: {
enabled: s(true),
},
notifCount: {
enabled: s(true),
},
battery: {
enabled: s(true),
},
dateTime: {
enabled: s(true),
format: s("%d/%m/%y %R"),
detailedFormat: s("%c"),
},
power: {
enabled: s(true),
},
},
},
launcher: {
maxResults: s(15), // Max shown results at one time (i.e. max height of the launcher)
apps: {
maxResults: s(30), // Actual max results, -1 for infinite
pins: s([
["zen", "firefox", "waterfox", "google-chrome", "chromium", "brave-browser"],
["foot", "alacritty", "kitty", "wezterm"],
["thunar", "nemo", "nautilus"],
["codium", "code", "clion", "intellij-idea-ultimate-edition"],
["spotify-adblock", "spotify", "audacious", "elisa"],
]),
},
files: {
maxResults: s(40), // Actual max results, -1 for infinite
fdOpts: s(["-a", "-t", "f"]), // Options to pass to `fd`
},
math: {
maxResults: s(40), // Actual max results, -1 for infinite
},
windows: {
maxResults: s(-1), // Actual max results, -1 for infinite
weights: {
// Weights for fuzzy sort
title: s(1),
class: s(1),
initialTitle: s(0.5),
initialClass: s(0.5),
},
},
todo: {
notify: s(true),
},
},
notifpopups: {
maxPopups: s(-1),
expire: s(false),
agoTime: s(true), // Whether to show time in ago format, e.g. 10 mins ago, or raw time, e.g. 10:42
},
osds: {
volume: {
position: s(Astal.WindowAnchor.RIGHT),
margin: s(20),
hideDelay: s(1500),
showValue: s(true),
},
brightness: {
position: s(Astal.WindowAnchor.LEFT),
margin: s(20),
hideDelay: s(1500),
showValue: s(true),
},
lock: {
spacing: s(5),
caps: {
hideDelay: s(1000),
},
num: {
hideDelay: s(1000),
},
},
},
// Services
math: {
maxHistory: 100,
},
updates: {
interval: 900000,
},
weather: {
interval: 600000,
key: "assets/weather-api-key.txt", // Path to file containing api key relative to the base directory. To get a key, visit https://weatherapi.com/
location: "", // Location as a string or empty to autodetect
imperial: false,
},
cpu: {
interval: 2000,
},
gpu: {
interval: 2000,
},
memory: {
interval: 5000,
},
storage: {
interval: 5000,
},
};
export const { bar, launcher, notifpopups, osds, math, updates, weather, cpu, gpu, memory, storage } = config;