mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 13:25:12 +00:00
feat(electron): onboarding at first launch logic for client and web (#5183)
- Added a simple abstraction of persistent storage class.
- Different persistence solutions are provided for web and client.
- web: stored in localStorage
- client: stored in the application directory as `.json` file
- Define persistent app-config schema
- Add a new hook that can interactive with persistent-app-config reactively
This commit is contained in:
83
packages/frontend/core/src/hooks/use-app-config-storage.ts
Normal file
83
packages/frontend/core/src/hooks/use-app-config-storage.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import {
|
||||
type AppConfigSchema,
|
||||
AppConfigStorage,
|
||||
defaultAppConfig,
|
||||
} from '@toeverything/infra/app-config-storage';
|
||||
import { type Dispatch, useEffect, useState } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
/**
|
||||
* Helper class to get/set app config from main process
|
||||
*/
|
||||
class AppConfigProxy {
|
||||
value: AppConfigSchema = defaultAppConfig;
|
||||
|
||||
async getSync(): Promise<AppConfigSchema> {
|
||||
return (this.value = await window.apis.configStorage.get());
|
||||
}
|
||||
|
||||
async setSync(): Promise<void> {
|
||||
await window.apis.configStorage.set(this.value);
|
||||
}
|
||||
|
||||
get(): AppConfigSchema {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
set(data: AppConfigSchema) {
|
||||
this.value = data;
|
||||
this.setSync().catch(console.error);
|
||||
}
|
||||
}
|
||||
export const appConfigProxy = new AppConfigProxy();
|
||||
|
||||
const storage = environment.isDesktop
|
||||
? new AppConfigStorage({
|
||||
config: defaultAppConfig,
|
||||
get: () => appConfigProxy.get(),
|
||||
set: v => appConfigProxy.set(v),
|
||||
})
|
||||
: new AppConfigStorage({
|
||||
config: defaultAppConfig,
|
||||
get: () => JSON.parse(localStorage.getItem('app_config') ?? 'null'),
|
||||
set: config => localStorage.setItem('app_config', JSON.stringify(config)),
|
||||
});
|
||||
|
||||
export const appConfigStorage = storage;
|
||||
|
||||
export function useAppConfigStorage(): [
|
||||
AppConfigSchema,
|
||||
Dispatch<AppConfigSchema>,
|
||||
];
|
||||
export function useAppConfigStorage(
|
||||
key: keyof AppConfigSchema
|
||||
): [AppConfigSchema[typeof key], Dispatch<AppConfigSchema[typeof key]>];
|
||||
|
||||
/**
|
||||
* Get reactive app config
|
||||
* @param key
|
||||
* @returns
|
||||
*/
|
||||
export function useAppConfigStorage(key?: keyof AppConfigSchema) {
|
||||
const [_config, _setConfig] = useState(storage.get());
|
||||
|
||||
useEffect(() => {
|
||||
storage.set(_config);
|
||||
}, [_config]);
|
||||
|
||||
const value = useMemo(() => (key ? _config[key] : _config), [_config, key]);
|
||||
|
||||
const setValue = useMemo(() => {
|
||||
if (key) {
|
||||
return (value: AppConfigSchema[typeof key]) => {
|
||||
_setConfig(cfg => ({ ...cfg, [key]: value }));
|
||||
};
|
||||
} else {
|
||||
return (config: AppConfigSchema) => {
|
||||
_setConfig(config);
|
||||
};
|
||||
}
|
||||
}, [_setConfig, key]);
|
||||
|
||||
return [value, setValue];
|
||||
}
|
||||
Reference in New Issue
Block a user