fix: update props and types for General Settings page

This commit is contained in:
sethburkart123
2024-09-04 13:18:48 +10:00
parent c008b32efa
commit 19102f9bcd
6 changed files with 52 additions and 93 deletions
@@ -1,5 +1,6 @@
import browser from 'webextension-polyfill'; import browser from 'webextension-polyfill';
import type { SettingsState } from '@/types/storage'; import type { SettingsState } from '@/types/storage';
import type { Subscriber, Unsubscriber } from 'svelte/store';
type ChangeListener = (newValue: any, oldValue: any) => void; type ChangeListener = (newValue: any, oldValue: any) => void;
type GlobalChangeListener = (newValue: any, oldValue: any, key: string) => void; type GlobalChangeListener = (newValue: any, oldValue: any, key: string) => void;
@@ -9,6 +10,7 @@ class StorageManager {
private data: SettingsState; private data: SettingsState;
private listeners: { [key: string]: ChangeListener[] }; private listeners: { [key: string]: ChangeListener[] };
private globalListeners: GlobalChangeListener[]; private globalListeners: GlobalChangeListener[];
private subscribers: Set<Subscriber<SettingsState>> = new Set();
private constructor() { private constructor() {
this.data = {} as SettingsState; this.data = {} as SettingsState;
@@ -73,6 +75,7 @@ class StorageManager {
private async saveToStorage(): Promise<void> { private async saveToStorage(): Promise<void> {
await browser.storage.local.set(this.data); await browser.storage.local.set(this.data);
this.notifySubscribers();
} }
private async removeFromStorage(key: string): Promise<void> { private async removeFromStorage(key: string): Promise<void> {
@@ -128,6 +131,20 @@ class StorageManager {
public getAll(): SettingsState { public getAll(): SettingsState {
return this.data; return this.data;
} }
public subscribe(run: Subscriber<SettingsState>): Unsubscriber {
this.subscribers.add(run);
run(this.data);
return () => {
this.subscribers.delete(run);
};
}
private notifySubscribers(): void {
for (const subscriber of this.subscribers) {
subscriber(this.data);
}
}
} }
export const settingsState = StorageManager.getInstance(); export const settingsState = StorageManager.getInstance();
@@ -1,8 +1,7 @@
<script lang="ts"> <script lang="ts">
export let onClick: () => void; let { onClick, text, ...props } = $props<{ onClick: () => void, text: string, [key: string]: any }>();
export let text: string;
</script> </script>
<button on:click={onClick} class='px-4 py-1 text-[0.75rem] dark:bg-[#38373D] bg-[#DDDDDD] dark:text-white rounded-md'> <button onclick={onClick} class='px-4 py-1 text-[0.75rem] dark:bg-[#38373D] bg-[#DDDDDD] dark:text-white rounded-md' {...props}>
{text} {text}
</button> </button>
@@ -10,10 +10,6 @@
onChange(!state); onChange(!state);
}; };
$effect(() => {
console.log('state', state);
});
const springParams = { const springParams = {
stiffness: 700, stiffness: 700,
damping: 30, damping: 30,
@@ -6,24 +6,32 @@
import browser from "webextension-polyfill" import browser from "webextension-polyfill"
import type { SettingsList } from "../../types/SettingsProps" import type { SettingsList } from "@/svelte-interface/types/SettingsProps"
import { createSettingsState } from "../../state/SettingsStore.svelte.ts" import { settingsState } from "@/seqta/utils/listeners/SettingsState.ts"
</script>
const settingsStore = createSettingsState(); {#snippet Setting({ title, description, Component, props }: SettingsList) }
<div class="flex items-center justify-between px-4 py-3">
<div class="pr-4">
<h2 class="text-sm font-bold">{title}</h2>
<p class="text-xs">{description}</p>
</div>
<div>
<Component {...props} />
</div>
</div>
{/snippet}
let test = $state(false); <div class="flex flex-col -mt-4 overflow-y-scroll divide-y divide-zinc-100 dark:divide-zinc-700">
{#each [
const settings: SettingsList[] = [
{ {
title: "Transparency Effects", title: "Transparency Effects",
description: "Enables transparency effects on certain elements such as blur. (May impact battery life)", description: "Enables transparency effects on certain elements such as blur. (May impact battery life)",
id: 1, id: 1,
Component: Switch, Component: Switch,
props: { props: {
/* state: $settingsStore.transparencyEffects, state: $settingsState.transparencyEffects,
onChange: (isOn: boolean) => settingsStore.setKey('transparencyEffects', isOn) */ onChange: (isOn: boolean) => settingsState.transparencyEffects = isOn
state: test,
onChange: (isOn: boolean) => test = isOn
} }
}, },
{ {
@@ -32,8 +40,8 @@
id: 2, id: 2,
Component: Switch as any, Component: Switch as any,
props: { props: {
state: $settingsStore.animatedbk, state: $settingsState.animatedbk,
onChange: (isOn: boolean) => settingsStore.setKey('animatedbk', isOn) onChange: (isOn: boolean) => settingsState.animatedbk = isOn
} }
}, },
{ {
@@ -42,8 +50,8 @@
id: 3, id: 3,
Component: Slider, Component: Slider,
props: { props: {
state: $settingsStore.bksliderinput, state: $settingsState.bksliderinput,
onChange: (value: number) => settingsStore.setKey('bksliderinput', `${value}`) onChange: (value: number) => settingsState.bksliderinput = `${value}`
} }
}, },
/* { /* {
@@ -68,8 +76,8 @@
id: 7, id: 7,
Component: Switch, Component: Switch,
props: { props: {
state: $settingsStore.notificationcollector, state: $settingsState.notificationcollector,
onChange: (isOn: boolean) => settingsStore.setKey('notificationcollector', isOn) onChange: (isOn: boolean) => settingsState.notificationcollector = isOn
} }
}, },
{ {
@@ -78,8 +86,8 @@
id: 8, id: 8,
Component: Switch, Component: Switch,
props: { props: {
state: $settingsStore.lessonalert, state: $settingsState.lessonalert,
onChange: (isOn: boolean) => settingsStore.setKey('lessonalert', isOn) onChange: (isOn: boolean) => settingsState.lessonalert = isOn
} }
}, },
{ {
@@ -88,26 +96,11 @@
id: 9, id: 9,
Component: Switch, Component: Switch,
props: { props: {
state: $settingsStore.onoff, state: $settingsState.onoff,
onChange: (isOn: boolean) => settingsStore.setKey('onoff', isOn) onChange: (isOn: boolean) => settingsState.onoff = isOn
} }
} }
]; ] as setting}
</script> {@render Setting(setting)}
<div class="flex flex-col -mt-4 overflow-y-scroll divide-y divide-zinc-100 dark:divide-zinc-700">
<Switch state={$settingsStore.DarkMode} onChange={(isOn: boolean) => settingsStore.setKey('DarkMode', isOn)} />
{#if settings}
{#each settings as { title, description, Component, props, id } (id)}
<div class="flex items-center justify-between px-4 py-3">
<div class="pr-4">
<h2 class="text-sm font-bold">{title}</h2>
<p class="text-xs">{description}</p>
</div>
<div>
<Component {...props} />
</div>
</div>
{/each} {/each}
{/if}
</div> </div>
@@ -1,45 +0,0 @@
import { settingsState } from "@/seqta/utils/listeners/SettingsState";
import type { SettingsState } from '@/types/storage';
export function createSettingsState() {
let settings = $state<SettingsState>(settingsState);
const subscribers = new Set<(value: SettingsState) => void>();
// Register a global listener to notify subscribers on any change
settingsState.registerGlobal((newValue, oldValue, key) => {
console.log('Global listener triggered:', { newValue, oldValue, key });
if (newValue !== undefined) {
settings = { ...settings, [key]: newValue };
notifySubscribers(settings);
}
});
function notifySubscribers(newValue: SettingsState) {
console.log('Notifying subscribers with:', newValue);
subscribers.forEach(subscriber => subscriber(newValue));
}
return {
get settings() { return settings; },
set(newSettings: SettingsState) {
settings = newSettings;
notifySubscribers(settings);
},
setKey<K extends keyof SettingsState>(key: K, value: SettingsState[K]) {
settings[key] = value;
settingsState.setKey(key, value);
notifySubscribers(settings);
},
subscribe(callback: (value: SettingsState) => void) {
subscribers.add(callback);
// Immediately call the callback with the current value
callback(settings);
// Return an unsubscribe function
return () => {
subscribers.delete(callback);
};
}
};
}
+1 -2
View File
@@ -1,11 +1,10 @@
import type { SettingsState } from './AppProps'; import type { SettingsState } from './AppProps';
import type { Component } from 'svelte';
export interface SettingsList { export interface SettingsList {
title: string; title: string;
id: number; id: number;
description: string; description: string;
Component: Component; Component: any; /* TODO: Give this a type */
props?: any; props?: any;
} }
export interface SettingsProps { export interface SettingsProps {