config: refactor
This commit is contained in:
parent
9fb35c544f
commit
1ffd7e1d54
6 changed files with 77 additions and 70 deletions
3
app.tsx
3
app.tsx
|
|
@ -12,7 +12,8 @@ import Wallpapers from "@/services/wallpapers";
|
||||||
import type PopupWindow from "@/widgets/popupwindow";
|
import type PopupWindow from "@/widgets/popupwindow";
|
||||||
import { execAsync, idle, timeout, writeFileAsync } from "astal";
|
import { execAsync, idle, timeout, writeFileAsync } from "astal";
|
||||||
import { App } from "astal/gtk3";
|
import { App } from "astal/gtk3";
|
||||||
import { initConfig, style, updateConfig } from "config";
|
import { style } from "config";
|
||||||
|
import { initConfig, updateConfig } from "config/funcs";
|
||||||
|
|
||||||
const shouldBeTransparent = (name: string) =>
|
const shouldBeTransparent = (name: string) =>
|
||||||
name === "base" ||
|
name === "base" ||
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,6 @@
|
||||||
import { GLib, monitorFile, readFileAsync, Variable } from "astal";
|
|
||||||
import { Astal } from "astal/gtk3";
|
import { Astal } from "astal/gtk3";
|
||||||
import { loadStyleAsync } from "./app";
|
|
||||||
|
|
||||||
type Settings<T> = { [P in keyof T]: T[P] extends object & { length?: never } ? Settings<T[P]> : Variable<T[P]> };
|
export default {
|
||||||
|
|
||||||
const CONFIG = `${GLib.get_user_config_dir()}/caelestia/shell.json`;
|
|
||||||
|
|
||||||
const isObject = (o: any) => typeof o === "object" && o !== null && !Array.isArray(o);
|
|
||||||
|
|
||||||
const deepMerge = <T extends object, U extends object>(a: T, b: U, path = ""): T & U => {
|
|
||||||
const merged: { [k: string]: any } = { ...b };
|
|
||||||
for (const [k, v] of Object.entries(a)) {
|
|
||||||
if (b.hasOwnProperty(k)) {
|
|
||||||
const bv = b[k as keyof U];
|
|
||||||
if (isObject(v) && isObject(bv)) merged[k] = deepMerge(v, bv as object, `${path}${k}.`);
|
|
||||||
else if (typeof v !== typeof bv) {
|
|
||||||
console.warn(`Invalid type for ${path}${k}: ${typeof v} != ${typeof bv}`);
|
|
||||||
merged[k] = v;
|
|
||||||
}
|
|
||||||
} else merged[k] = v;
|
|
||||||
}
|
|
||||||
return merged as any;
|
|
||||||
};
|
|
||||||
|
|
||||||
const convertSettings = <T extends object>(obj: T): Settings<T> =>
|
|
||||||
Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, isObject(v) ? convertSettings(v) : Variable(v)])) as any;
|
|
||||||
|
|
||||||
const updateSection = (from: { [k: string]: any }, to: { [k: string]: any }, path = "") => {
|
|
||||||
for (const [k, v] of Object.entries(from)) {
|
|
||||||
if (to.hasOwnProperty(k)) {
|
|
||||||
if (isObject(v)) updateSection(v, to[k], `${path}${k}.`);
|
|
||||||
else to[k].set(v);
|
|
||||||
} else console.warn(`Unknown config key: ${path}${k}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateConfig = async () => {
|
|
||||||
updateSection(deepMerge(DEFAULTS, JSON.parse(await readFileAsync(CONFIG))), config);
|
|
||||||
loadStyleAsync().catch(console.error);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const initConfig = () => {
|
|
||||||
monitorFile(CONFIG, () => updateConfig().catch(e => console.warn(`Invalid config: ${e}`)));
|
|
||||||
updateConfig().catch(e => console.warn(`Invalid config: ${e}`));
|
|
||||||
};
|
|
||||||
|
|
||||||
const DEFAULTS = {
|
|
||||||
style: {
|
style: {
|
||||||
transparency: "normal", // One of "off", "normal", "high"
|
transparency: "normal", // One of "off", "normal", "high"
|
||||||
vibrant: false, // Extra saturation
|
vibrant: false, // Extra saturation
|
||||||
|
|
@ -120,13 +75,13 @@ const DEFAULTS = {
|
||||||
},
|
},
|
||||||
osds: {
|
osds: {
|
||||||
volume: {
|
volume: {
|
||||||
position: Astal.WindowAnchor.RIGHT,
|
position: Astal.WindowAnchor.RIGHT, // Top = 2, Right = 4, Left = 8, Bottom = 16
|
||||||
margin: 20,
|
margin: 20,
|
||||||
hideDelay: 1500,
|
hideDelay: 1500,
|
||||||
showValue: true,
|
showValue: true,
|
||||||
},
|
},
|
||||||
brightness: {
|
brightness: {
|
||||||
position: Astal.WindowAnchor.LEFT,
|
position: Astal.WindowAnchor.LEFT, // Top = 2, Right = 4, Left = 8, Bottom = 16
|
||||||
margin: 20,
|
margin: 20,
|
||||||
hideDelay: 1500,
|
hideDelay: 1500,
|
||||||
showValue: true,
|
showValue: true,
|
||||||
|
|
@ -189,22 +144,3 @@ const DEFAULTS = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = convertSettings(DEFAULTS);
|
|
||||||
|
|
||||||
export const {
|
|
||||||
style,
|
|
||||||
bar,
|
|
||||||
launcher,
|
|
||||||
notifpopups,
|
|
||||||
osds,
|
|
||||||
sideleft,
|
|
||||||
math,
|
|
||||||
updates,
|
|
||||||
weather,
|
|
||||||
cpu,
|
|
||||||
gpu,
|
|
||||||
memory,
|
|
||||||
storage,
|
|
||||||
wallpapers,
|
|
||||||
} = config;
|
|
||||||
47
src/config/funcs.ts
Normal file
47
src/config/funcs.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { GLib, monitorFile, readFileAsync, Variable } from "astal";
|
||||||
|
import config from ".";
|
||||||
|
import { loadStyleAsync } from "../../app";
|
||||||
|
import defaults from "./defaults";
|
||||||
|
|
||||||
|
type Settings<T> = { [P in keyof T]: T[P] extends object & { length?: never } ? Settings<T[P]> : Variable<T[P]> };
|
||||||
|
|
||||||
|
const CONFIG = `${GLib.get_user_config_dir()}/caelestia/shell.json`;
|
||||||
|
|
||||||
|
const isObject = (o: any) => typeof o === "object" && o !== null && !Array.isArray(o);
|
||||||
|
|
||||||
|
const deepMerge = <T extends object, U extends object>(a: T, b: U, path = ""): T & U => {
|
||||||
|
const merged: { [k: string]: any } = { ...b };
|
||||||
|
for (const [k, v] of Object.entries(a)) {
|
||||||
|
if (b.hasOwnProperty(k)) {
|
||||||
|
const bv = b[k as keyof U];
|
||||||
|
if (isObject(v) && isObject(bv)) merged[k] = deepMerge(v, bv as object, `${path}${k}.`);
|
||||||
|
else if (typeof v !== typeof bv) {
|
||||||
|
console.warn(`Invalid type for ${path}${k}: ${typeof v} != ${typeof bv}`);
|
||||||
|
merged[k] = v;
|
||||||
|
}
|
||||||
|
} else merged[k] = v;
|
||||||
|
}
|
||||||
|
return merged as any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertSettings = <T extends object>(obj: T): Settings<T> =>
|
||||||
|
Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, isObject(v) ? convertSettings(v) : Variable(v)])) as any;
|
||||||
|
|
||||||
|
const updateSection = (from: { [k: string]: any }, to: { [k: string]: any }, path = "") => {
|
||||||
|
for (const [k, v] of Object.entries(from)) {
|
||||||
|
if (to.hasOwnProperty(k)) {
|
||||||
|
if (isObject(v)) updateSection(v, to[k], `${path}${k}.`);
|
||||||
|
else to[k].set(v);
|
||||||
|
} else console.warn(`Unknown config key: ${path}${k}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateConfig = async () => {
|
||||||
|
updateSection(deepMerge(defaults, JSON.parse(await readFileAsync(CONFIG))), config);
|
||||||
|
loadStyleAsync().catch(console.error);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initConfig = () => {
|
||||||
|
monitorFile(CONFIG, () => updateConfig().catch(e => console.warn(`Invalid config: ${e}`)));
|
||||||
|
updateConfig().catch(e => console.warn(`Invalid config: ${e}`));
|
||||||
|
};
|
||||||
22
src/config/index.ts
Normal file
22
src/config/index.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import defaults from "./defaults";
|
||||||
|
import { convertSettings } from "./funcs";
|
||||||
|
|
||||||
|
const config = convertSettings(defaults);
|
||||||
|
|
||||||
|
export const {
|
||||||
|
style,
|
||||||
|
bar,
|
||||||
|
launcher,
|
||||||
|
notifpopups,
|
||||||
|
osds,
|
||||||
|
sideleft,
|
||||||
|
math,
|
||||||
|
updates,
|
||||||
|
weather,
|
||||||
|
cpu,
|
||||||
|
gpu,
|
||||||
|
memory,
|
||||||
|
storage,
|
||||||
|
wallpapers,
|
||||||
|
} = config;
|
||||||
|
export default config;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { App, Astal, Gtk } from "astal/gtk3";
|
import { App, Astal, Gtk } from "astal/gtk3";
|
||||||
|
import { notifpopups as config } from "config";
|
||||||
import AstalNotifd from "gi://AstalNotifd";
|
import AstalNotifd from "gi://AstalNotifd";
|
||||||
import { notifpopups as config } from "../../config";
|
|
||||||
import { setupChildClickthrough } from "../utils/widgets";
|
import { setupChildClickthrough } from "../utils/widgets";
|
||||||
import Notification from "../widgets/notification";
|
import Notification from "../widgets/notification";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
"paths": {
|
"paths": {
|
||||||
"astal": ["/usr/share/astal/gjs"],
|
"astal": ["/usr/share/astal/gjs"],
|
||||||
"astal/*": ["/usr/share/astal/gjs/*"],
|
"astal/*": ["/usr/share/astal/gjs/*"],
|
||||||
"config": ["./config"],
|
"config": ["./src/config/index"],
|
||||||
|
"config/*": ["./src/config/*"],
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue