Add QuickCss toggle; add settings listener api
This commit is contained in:
parent
8a8c6a4b52
commit
113f47ca7f
|
@ -1,6 +1,7 @@
|
||||||
export * as Plugins from "./plugins";
|
export * as Plugins from "./plugins";
|
||||||
export * as Webpack from "./webpack";
|
export * as Webpack from "./webpack";
|
||||||
export * as Api from "./api";
|
export * as Api from "./api";
|
||||||
|
export { Settings } from "./api/settings";
|
||||||
|
|
||||||
import "./utils/patchWebpack";
|
import "./utils/patchWebpack";
|
||||||
import "./utils/quickCss";
|
import "./utils/quickCss";
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { mergeDefaults } from '../utils/misc';
|
||||||
|
|
||||||
interface Settings {
|
interface Settings {
|
||||||
unsafeRequire: boolean;
|
unsafeRequire: boolean;
|
||||||
|
useQuickCss: boolean;
|
||||||
plugins: {
|
plugins: {
|
||||||
[plugin: string]: {
|
[plugin: string]: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
@ -15,8 +16,9 @@ interface Settings {
|
||||||
|
|
||||||
const DefaultSettings: Settings = {
|
const DefaultSettings: Settings = {
|
||||||
unsafeRequire: false,
|
unsafeRequire: false,
|
||||||
|
useQuickCss: true,
|
||||||
plugins: {}
|
plugins: {}
|
||||||
};
|
} as any;
|
||||||
|
|
||||||
for (const plugin in plugins) {
|
for (const plugin in plugins) {
|
||||||
DefaultSettings.plugins[plugin] = {
|
DefaultSettings.plugins[plugin] = {
|
||||||
|
@ -35,21 +37,26 @@ try {
|
||||||
var settings = mergeDefaults({} as Settings, DefaultSettings);
|
var settings = mergeDefaults({} as Settings, DefaultSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
const subscriptions = new Set<() => void>();
|
type SubscriptionCallback = ((newValue: any) => void) & { _path?: string; };
|
||||||
|
const subscriptions = new Set<SubscriptionCallback>();
|
||||||
|
|
||||||
function makeProxy(settings: Settings, root = settings): Settings {
|
function makeProxy(settings: Settings, root = settings, path = ""): Settings {
|
||||||
return new Proxy(settings, {
|
return new Proxy(settings, {
|
||||||
get(target, p) {
|
get(target, p: string) {
|
||||||
const v = target[p];
|
const v = target[p];
|
||||||
if (typeof v === "object" && !Array.isArray(v)) return makeProxy(v, root);
|
if (typeof v === "object" && !Array.isArray(v))
|
||||||
|
return makeProxy(v, root, `${path}${path && "."}${p}`);
|
||||||
return v;
|
return v;
|
||||||
},
|
},
|
||||||
set(target, p, v) {
|
set(target, p: string, v) {
|
||||||
if (target[p] === v) return true;
|
if (target[p] === v) return true;
|
||||||
|
|
||||||
target[p] = v;
|
target[p] = v;
|
||||||
|
const setPath = `${path}${path && "."}${p}`;
|
||||||
for (const subscription of subscriptions) {
|
for (const subscription of subscriptions) {
|
||||||
subscription();
|
if (!subscription._path || subscription._path === setPath) {
|
||||||
|
subscription(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
VencordNative.ipc.invoke(IpcEvents.SET_SETTINGS, JSON.stringify(root, null, 4));
|
VencordNative.ipc.invoke(IpcEvents.SET_SETTINGS, JSON.stringify(root, null, 4));
|
||||||
return true;
|
return true;
|
||||||
|
@ -79,3 +86,15 @@ export function useSettings() {
|
||||||
|
|
||||||
return Settings;
|
return Settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolves a possibly nested prop in the form of "some.nested.prop" to type of T.some.nested.prop
|
||||||
|
type ResolvePropDeep<T, P> = P extends "" ? T :
|
||||||
|
P extends `${infer Pre}.${infer Suf}` ?
|
||||||
|
Pre extends keyof T ? ResolvePropDeep<T[Pre], Suf> : never : P extends keyof T ? T[P] : never;
|
||||||
|
|
||||||
|
export function addSettingsListener<Path extends keyof Settings>(path: Path, onUpdate: (newValue: Settings[Path]) => void): void;
|
||||||
|
export function addSettingsListener<Path extends string>(path: Path, onUpdate: (newValue: ResolvePropDeep<Settings, Path>) => void): void;
|
||||||
|
export function addSettingsListener(path: string, onUpdate: (newValue: any) => void) {
|
||||||
|
(onUpdate as SubscriptionCallback)._path = path;
|
||||||
|
subscriptions.add(onUpdate);
|
||||||
|
}
|
|
@ -26,6 +26,8 @@ export default ErrorBoundary.wrap(function Settings(props) {
|
||||||
return o;
|
return o;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const sortedPlugins = React.useMemo(() => Object.values(Plugins).sort((a, b) => a.name.localeCompare(b.name)), []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Forms.FormSection tag="h1" title="Vencord">
|
<Forms.FormSection tag="h1" title="Vencord">
|
||||||
<Forms.FormText>SettingsDir: {settingsDir}</Forms.FormText>
|
<Forms.FormText>SettingsDir: {settingsDir}</Forms.FormText>
|
||||||
|
@ -50,16 +52,23 @@ export default ErrorBoundary.wrap(function Settings(props) {
|
||||||
</Flex.Child>
|
</Flex.Child>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Forms.FormTitle tag="h5">Settings</Forms.FormTitle>
|
<Forms.FormTitle tag="h5">Settings</Forms.FormTitle>
|
||||||
|
<Switch
|
||||||
|
value={settings.useQuickCss}
|
||||||
|
onChange={v => settings.useQuickCss = v}
|
||||||
|
note="Enable QuickCss"
|
||||||
|
>
|
||||||
|
Use QuickCss
|
||||||
|
</Switch>
|
||||||
<Switch
|
<Switch
|
||||||
value={settings.unsafeRequire}
|
value={settings.unsafeRequire}
|
||||||
onChange={v => settings.unsafeRequire = v}
|
onChange={v => settings.unsafeRequire = v}
|
||||||
note="Enables VencordNative.require. Useful for testing, very bad for security. Leave this off unless you need it."
|
note="Enables VencordNative.require. Useful for testing, very bad for security. Leave this off unless you need it."
|
||||||
>
|
>
|
||||||
Enable Ensafe Require
|
Enable Unsafe Require
|
||||||
</Switch>
|
</Switch>
|
||||||
<Forms.FormDivider />
|
<Forms.FormDivider />
|
||||||
<Forms.FormTitle tag="h5">Plugins</Forms.FormTitle>
|
<Forms.FormTitle tag="h5">Plugins</Forms.FormTitle>
|
||||||
{Object.values(Plugins).map(p => {
|
{sortedPlugins.map(p => {
|
||||||
const enabledDependants = depMap[p.name]?.filter(d => settings.plugins[d].enabled);
|
const enabledDependants = depMap[p.name]?.filter(d => settings.plugins[d].enabled);
|
||||||
const dependency = enabledDependants?.length;
|
const dependency = enabledDependants?.length;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,21 @@
|
||||||
|
import { addSettingsListener, Settings } from "../api/settings";
|
||||||
import IpcEvents from "./IpcEvents";
|
import IpcEvents from "./IpcEvents";
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
let style: HTMLStyleElement;
|
||||||
const style = document.createElement("style");
|
|
||||||
document.head.appendChild(style);
|
export async function toggle(isEnabled: boolean) {
|
||||||
VencordNative.ipc.on(IpcEvents.QUICK_CSS_UPDATE, (_, css: string) => style.innerText = css);
|
if (!style) {
|
||||||
style.innerText = await VencordNative.ipc.invoke(IpcEvents.GET_QUICK_CSS);
|
if (isEnabled) {
|
||||||
|
style = document.createElement("style");
|
||||||
|
style.id = "vencord-custom-css";
|
||||||
|
document.head.appendChild(style);
|
||||||
|
VencordNative.ipc.on(IpcEvents.QUICK_CSS_UPDATE, (_, css: string) => style.innerText = css);
|
||||||
|
style.innerText = await VencordNative.ipc.invoke(IpcEvents.GET_QUICK_CSS);
|
||||||
|
}
|
||||||
|
} else style.disabled = !isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
toggle(Settings.useQuickCss);
|
||||||
|
addSettingsListener("useQuickCss", toggle);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue