feat: non-exact settings subscriptions for live recompile
This commit is contained in:
parent
64848b2fbf
commit
51059c29e7
3 changed files with 18 additions and 9 deletions
|
@ -117,7 +117,7 @@ const saveSettingsOnFrequentAction = debounce(async () => {
|
|||
}
|
||||
}, 60_000);
|
||||
|
||||
type SubscriptionCallback = ((newValue: any, path: string) => void) & { _paths?: Array<string>; };
|
||||
type SubscriptionCallback = ((newValue: any, path: string) => void) & { _paths?: Array<string>; _exact?: boolean; };
|
||||
const subscriptions = new Set<SubscriptionCallback>();
|
||||
|
||||
const proxyCache = {} as Record<string, any>;
|
||||
|
@ -174,7 +174,12 @@ function makeProxy(settings: any, root = settings, path = ""): Settings {
|
|||
const setPath = `${path}${path && "."}${p}`;
|
||||
delete proxyCache[setPath];
|
||||
for (const subscription of subscriptions) {
|
||||
if (!subscription._paths || subscription._paths.includes(setPath)) {
|
||||
if (
|
||||
!subscription._paths ||
|
||||
(subscription._exact
|
||||
? subscription._paths.includes(setPath)
|
||||
: subscription._paths.some(p => setPath.startsWith(p)))
|
||||
) {
|
||||
subscription(v, setPath);
|
||||
}
|
||||
}
|
||||
|
@ -212,11 +217,14 @@ export const Settings = makeProxy(settings);
|
|||
* @returns Settings
|
||||
*/
|
||||
// TODO: Representing paths as essentially "string[].join('.')" wont allow dots in paths, change to "paths?: string[][]" later
|
||||
export function useSettings(paths?: UseSettings<Settings>[]) {
|
||||
export function useSettings(paths?: UseSettings<Settings>[], exact = true) {
|
||||
const [, forceUpdate] = React.useReducer(() => ({}), {});
|
||||
|
||||
const onUpdate: SubscriptionCallback = paths
|
||||
? (value, path) => paths.includes(path as UseSettings<Settings>) && forceUpdate()
|
||||
? (value, path) =>
|
||||
(exact
|
||||
? paths.includes(path as UseSettings<Settings>)
|
||||
: paths.some(p => path.startsWith(p))) && forceUpdate()
|
||||
: forceUpdate;
|
||||
|
||||
React.useEffect(() => {
|
||||
|
@ -242,10 +250,11 @@ type ResolvePropDeep<T, P> = P extends "" ? T :
|
|||
* @example addSettingsListener("", (newValue, path) => console.log(`${path} is now ${newValue}`))
|
||||
* addSettingsListener("plugins.Unindent.enabled", v => console.log("Unindent is now", v ? "enabled" : "disabled"))
|
||||
*/
|
||||
export function addSettingsListener<Path extends keyof Settings>(path: Path, onUpdate: (newValue: Settings[Path], path: Path) => void): void;
|
||||
export function addSettingsListener<Path extends string>(path: Path, onUpdate: (newValue: Path extends "" ? any : ResolvePropDeep<Settings, Path>, path: Path extends "" ? string : Path) => void): void;
|
||||
export function addSettingsListener(path: string, onUpdate: (newValue: any, path: string) => void) {
|
||||
export function addSettingsListener<Path extends keyof Settings>(path: Path, onUpdate: (newValue: Settings[Path], path: Path) => void, exact?: boolean): void;
|
||||
export function addSettingsListener<Path extends string>(path: Path, onUpdate: (newValue: Path extends "" ? any : ResolvePropDeep<Settings, Path>, path: Path extends "" ? string : Path) => void, exact?: boolean): void;
|
||||
export function addSettingsListener(path: string, onUpdate: (newValue: any, path: string) => void, exact = true) {
|
||||
((onUpdate as SubscriptionCallback)._paths ??= []).push(path);
|
||||
(onUpdate as SubscriptionCallback)._exact = exact;
|
||||
subscriptions.add(onUpdate);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ interface UserCSSSettingsModalProps {
|
|||
|
||||
function UserCSSSettingsModal({ modalProps, theme }: UserCSSSettingsModalProps) {
|
||||
// @ts-expect-error UseSettings<> can't determine this is a valid key
|
||||
const themeSettings = useSettings(["userCssVars"]).userCssVars[theme.id];
|
||||
const themeSettings = useSettings(["userCssVars"], false).userCssVars[theme.id];
|
||||
|
||||
const controls: ReactNode[] = [];
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||
|
||||
addSettingsListener("themeLinks", initThemes);
|
||||
addSettingsListener("enabledThemes", initThemes);
|
||||
addSettingsListener("userCssVars", initThemes);
|
||||
addSettingsListener("userCssVars", initThemes, false);
|
||||
|
||||
if (!IS_WEB)
|
||||
VencordNative.quickCss.addThemeChangeListener(initThemes);
|
||||
|
|
Loading…
Reference in a new issue