mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-05 19:24:39 +00:00
feat: add more callback listeners to the theme system
This commit is contained in:
@@ -43,6 +43,7 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
|
|||||||
const storageKey = `plugin.${plugin.id}.settings`;
|
const storageKey = `plugin.${plugin.id}.settings`;
|
||||||
const listeners = new Map<keyof T, Set<(value: any) => void>>();
|
const listeners = new Map<keyof T, Set<(value: any) => void>>();
|
||||||
let settings: { [K in keyof T]: T[K]['default'] };
|
let settings: { [K in keyof T]: T[K]['default'] };
|
||||||
|
const storageListeners = new Set<(changes: { [key: string]: any }, area: string) => void>();
|
||||||
|
|
||||||
// Initialize settings with defaults
|
// Initialize settings with defaults
|
||||||
settings = Object.entries(plugin.settings).reduce((acc, [key, setting]) => {
|
settings = Object.entries(plugin.settings).reduce((acc, [key, setting]) => {
|
||||||
@@ -69,7 +70,7 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
// Listen for storage changes
|
// Listen for storage changes
|
||||||
browser.storage.onChanged.addListener((changes, area) => {
|
const handleStorageChange = (changes: { [key: string]: any }, area: string) => {
|
||||||
if (area === 'local' && changes[storageKey]) {
|
if (area === 'local' && changes[storageKey]) {
|
||||||
const newValue = changes[storageKey].newValue;
|
const newValue = changes[storageKey].newValue;
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
@@ -80,7 +81,9 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
browser.storage.onChanged.addListener(handleStorageChange);
|
||||||
|
storageListeners.add(handleStorageChange);
|
||||||
|
|
||||||
// Create a proxy to handle direct property access
|
// Create a proxy to handle direct property access
|
||||||
const proxy = new Proxy(settings, {
|
const proxy = new Proxy(settings, {
|
||||||
@@ -91,11 +94,11 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
|
|||||||
listeners.set(key, new Set());
|
listeners.set(key, new Set());
|
||||||
}
|
}
|
||||||
listeners.get(key)!.add(callback);
|
listeners.get(key)!.add(callback);
|
||||||
};
|
return {
|
||||||
}
|
unregister: () => {
|
||||||
if (prop === 'offChange') {
|
listeners.get(key)?.delete(callback);
|
||||||
return (key: keyof T, callback: (value: any) => void) => {
|
}
|
||||||
listeners.get(key)?.delete(callback);
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (prop === 'loaded') {
|
if (prop === 'loaded') {
|
||||||
@@ -125,6 +128,7 @@ function createStorageAPI<T = any>(pluginId: string): StorageAPI<T> & { [K in ke
|
|||||||
const prefix = `plugin.${pluginId}.storage.`;
|
const prefix = `plugin.${pluginId}.storage.`;
|
||||||
const cache: Record<string, any> = {};
|
const cache: Record<string, any> = {};
|
||||||
const listeners = new Map<string, Set<(value: any) => void>>();
|
const listeners = new Map<string, Set<(value: any) => void>>();
|
||||||
|
const storageListeners = new Set<(changes: { [key: string]: any }, area: string) => void>();
|
||||||
|
|
||||||
// Load all existing storage values for this plugin
|
// Load all existing storage values for this plugin
|
||||||
const loadStoragePromise = (async () => {
|
const loadStoragePromise = (async () => {
|
||||||
@@ -144,7 +148,7 @@ function createStorageAPI<T = any>(pluginId: string): StorageAPI<T> & { [K in ke
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
// Listen for storage changes
|
// Listen for storage changes
|
||||||
browser.storage.onChanged.addListener((changes, area) => {
|
const handleStorageChange = (changes: { [key: string]: any }, area: string) => {
|
||||||
if (area === 'local') {
|
if (area === 'local') {
|
||||||
Object.entries(changes).forEach(([key, change]) => {
|
Object.entries(changes).forEach(([key, change]) => {
|
||||||
if (key.startsWith(prefix)) {
|
if (key.startsWith(prefix)) {
|
||||||
@@ -156,7 +160,9 @@ function createStorageAPI<T = any>(pluginId: string): StorageAPI<T> & { [K in ke
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
browser.storage.onChanged.addListener(handleStorageChange);
|
||||||
|
storageListeners.add(handleStorageChange);
|
||||||
|
|
||||||
// Create the proxy for direct property access
|
// Create the proxy for direct property access
|
||||||
return new Proxy(cache, {
|
return new Proxy(cache, {
|
||||||
@@ -167,6 +173,11 @@ function createStorageAPI<T = any>(pluginId: string): StorageAPI<T> & { [K in ke
|
|||||||
listeners.set(key as string, new Set());
|
listeners.set(key as string, new Set());
|
||||||
}
|
}
|
||||||
listeners.get(key as string)!.add(callback);
|
listeners.get(key as string)!.add(callback);
|
||||||
|
return {
|
||||||
|
unregister: () => {
|
||||||
|
listeners.get(key as string)?.delete(callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (prop === 'offChange') {
|
if (prop === 'offChange') {
|
||||||
@@ -200,12 +211,28 @@ function createStorageAPI<T = any>(pluginId: string): StorageAPI<T> & { [K in ke
|
|||||||
|
|
||||||
function createEventsAPI(pluginId: string): EventsAPI {
|
function createEventsAPI(pluginId: string): EventsAPI {
|
||||||
const prefix = `plugin.${pluginId}.`;
|
const prefix = `plugin.${pluginId}.`;
|
||||||
|
const eventListeners = new Map<string, Set<{ callback: (...args: any[]) => void, listener: EventListener }>>();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
on: (event, callback) => {
|
on: (event, callback) => {
|
||||||
document.addEventListener(prefix + event, ((e: CustomEvent) => {
|
const fullEventName = prefix + event;
|
||||||
|
const listener = ((e: CustomEvent) => {
|
||||||
callback(...(e.detail || []));
|
callback(...(e.detail || []));
|
||||||
}) as EventListener);
|
}) as EventListener;
|
||||||
|
|
||||||
|
document.addEventListener(fullEventName, listener);
|
||||||
|
|
||||||
|
if (!eventListeners.has(event)) {
|
||||||
|
eventListeners.set(event, new Set());
|
||||||
|
}
|
||||||
|
eventListeners.get(event)!.add({ callback, listener });
|
||||||
|
|
||||||
|
return {
|
||||||
|
unregister: () => {
|
||||||
|
document.removeEventListener(fullEventName, listener);
|
||||||
|
eventListeners.get(event)?.delete({ callback, listener });
|
||||||
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
emit: (event, ...args) => {
|
emit: (event, ...args) => {
|
||||||
document.dispatchEvent(
|
document.dispatchEvent(
|
||||||
|
|||||||
@@ -66,12 +66,7 @@ export interface StorageAPI<T = any> {
|
|||||||
/**
|
/**
|
||||||
* Register a callback to be called when a storage value changes
|
* Register a callback to be called when a storage value changes
|
||||||
*/
|
*/
|
||||||
onChange: <K extends keyof T>(key: K, callback: (value: T[K]) => void) => void;
|
onChange: <K extends keyof T>(key: K, callback: (value: T[K]) => void) => { unregister: () => void };
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a previously registered callback
|
|
||||||
*/
|
|
||||||
offChange: <K extends keyof T>(key: K, callback: (value: T[K]) => void) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Promise that resolves when storage values are loaded
|
* Promise that resolves when storage values are loaded
|
||||||
@@ -84,7 +79,7 @@ export type TypedStorageAPI<T> = StorageAPI<T> & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface EventsAPI {
|
export interface EventsAPI {
|
||||||
on: (event: string, callback: (...args: any[]) => void) => void;
|
on: (event: string, callback: (...args: any[]) => void) => { unregister: () => void };
|
||||||
emit: (event: string, ...args: any[]) => void;
|
emit: (event: string, ...args: any[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user