aboutsummaryrefslogtreecommitdiff
path: root/extension/src/features/settings.ts
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-11-19 14:50:46 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2023-11-19 14:50:46 -0500
commitbc7b86a242673d7831f6105d000995d9f4d63e09 (patch)
tree8da5c92047e92174b80ff6f460f8c3148e1e00ca /extension/src/features/settings.ts
parent0b609c17199e937518c42365b360288acfa872be (diff)
hasty not working update to get my workspace clean
Diffstat (limited to 'extension/src/features/settings.ts')
-rw-r--r--extension/src/features/settings.ts165
1 files changed, 165 insertions, 0 deletions
diff --git a/extension/src/features/settings.ts b/extension/src/features/settings.ts
new file mode 100644
index 0000000..a67957c
--- /dev/null
+++ b/extension/src/features/settings.ts
@@ -0,0 +1,165 @@
+// Copyright (C) 2023 Vaughn Nugent
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+import { storage } from "webextension-polyfill"
+import { isEmpty, merge } from 'lodash'
+import { configureApi, debugLog } from '@vnuge/vnlib.browser'
+import { readonly, ref, Ref } from "vue";
+import { JsonObject } from "type-fest";
+import { Watchable, useSingleSlotStorage } from "./types";
+import { BgRuntime, FeatureApi, optionsOnly, IFeatureExport, exportForegroundApi } from './framework'
+import { get, watchOnce } from "@vueuse/core";
+
+export interface PluginConfig extends JsonObject {
+ readonly apiUrl: string;
+ readonly accountBasePath: string;
+ readonly nostrEndpoint: string;
+ readonly heartbeat: boolean;
+ readonly maxHistory: number;
+ readonly tagFilter: boolean,
+}
+
+//Default storage config
+const defaultConfig : PluginConfig = {
+ apiUrl: import.meta.env.VITE_API_URL,
+ accountBasePath: import.meta.env.VITE_ACCOUNTS_BASE_PATH,
+ nostrEndpoint: import.meta.env.VITE_NOSTR_ENDPOINT,
+ heartbeat: import.meta.env.VITE_HEARTBEAT_ENABLED === 'true',
+ maxHistory: 50,
+ tagFilter: true,
+};
+
+export interface AppSettings{
+ getCurrentConfig: () => Promise<PluginConfig>;
+ restoreApiSettings: () => Promise<void>;
+ saveConfig: (config: PluginConfig) => Promise<void>;
+ readonly currentConfig: Readonly<Ref<PluginConfig>>;
+}
+
+export interface SettingsApi extends FeatureApi, Watchable {
+ getSiteConfig: () => Promise<PluginConfig>;
+ setSiteConfig: (config: PluginConfig) => Promise<PluginConfig>;
+ setDarkMode: (darkMode: boolean) => Promise<void>;
+ getDarkMode: () => Promise<boolean>;
+}
+
+export const useAppSettings = (): AppSettings => {
+ const currentConfig = ref<PluginConfig>({} as PluginConfig);
+ const store = useSingleSlotStorage<PluginConfig>(storage.local, 'siteConfig', defaultConfig);
+
+ const getCurrentConfig = async () => {
+
+ const siteConfig = await store.get()
+
+ //Store a default config if none exists
+ if (isEmpty(siteConfig)) {
+ await store.set(defaultConfig);
+ }
+
+ //Merge the default config with the site config
+ return merge(defaultConfig, siteConfig)
+ }
+
+ const restoreApiSettings = async () => {
+ //Set the current config
+ const current = await getCurrentConfig();
+ currentConfig.value = current;
+
+ //Configure the vnlib api
+ configureApi({
+ session: {
+ cookiesEnabled: false,
+ browserIdSize: 32,
+ },
+ user: {
+ accountBasePath: current.accountBasePath,
+ },
+ axios: {
+ baseURL: current.apiUrl,
+ tokenHeader: import.meta.env.VITE_WEB_TOKEN_HEADER,
+ },
+ storage: localStorage
+ })
+ }
+
+ const saveConfig = async (config: PluginConfig) => {
+ //Save the config and update the current config
+ await store.set(config);
+ currentConfig.value = config;
+ }
+
+ return {
+ getCurrentConfig,
+ restoreApiSettings,
+ saveConfig,
+ currentConfig:readonly(currentConfig)
+ }
+}
+
+export const useSettingsApi = () : IFeatureExport<AppSettings, SettingsApi> =>{
+
+ return{
+ background: ({ state, onConnected, onInstalled }: BgRuntime<AppSettings>) => {
+
+ const _darkMode = ref(false);
+
+ onInstalled(async () => {
+ await state.restoreApiSettings();
+ debugLog('Server settings restored from storage');
+ })
+
+ onConnected(async () => {
+ //refresh the config on connect
+ await state.restoreApiSettings();
+ })
+
+ return {
+
+ getSiteConfig: () => state.getCurrentConfig(),
+
+ setSiteConfig: optionsOnly(async (config: PluginConfig): Promise<PluginConfig> => {
+
+ //Save the config
+ await state.saveConfig(config);
+
+ //Restore the api settings
+ await state.restoreApiSettings();
+
+ debugLog('Config settings saved!');
+
+ //Return the config
+ return state.currentConfig.value
+ }),
+
+ setDarkMode: optionsOnly(async (darkMode: boolean) => {
+ console.log('Setting dark mode to', darkMode, 'from', _darkMode.value)
+ _darkMode.value = darkMode
+ }),
+ getDarkMode: async () => get(_darkMode),
+
+ waitForChange: () => {
+ return new Promise((resolve) => watchOnce([state.currentConfig, _darkMode] as any, () => resolve()))
+ },
+ }
+ },
+ foreground: exportForegroundApi([
+ 'getSiteConfig',
+ 'setSiteConfig',
+ 'setDarkMode',
+ 'getDarkMode',
+ 'waitForChange'
+ ])
+ }
+} \ No newline at end of file