mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
fix: update props and types for General Settings page
This commit is contained in:
@@ -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,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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user