init
This commit is contained in:
104
src/entities/app-settings/model/settingsStore.ts
Normal file
104
src/entities/app-settings/model/settingsStore.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { makeAutoObservable, reaction, runInAction } from 'mobx';
|
||||
import { getSetting, listSettings } from '@/shared/api';
|
||||
import { themeStore, type BrandColors } from '@/shared/config';
|
||||
import { appEvents, storage } from '@/shared/lib';
|
||||
import { loadRemoteSetting } from '../api/kioskSettingsApi';
|
||||
import type { AppSettings } from './types';
|
||||
|
||||
const STORAGE_KEY = 'app_settings';
|
||||
const SETTINGS_INTERVAL = 60_000;
|
||||
const HEADER_INTERVAL = 4_000;
|
||||
const CITY_INTERVAL = 120_000;
|
||||
|
||||
const defaultSettings: AppSettings = {
|
||||
scheduleDeviationSource: 'real',
|
||||
notifVolume: 70,
|
||||
brightness: 80,
|
||||
wifi: true,
|
||||
bluetooth: false,
|
||||
language: 'ru',
|
||||
};
|
||||
|
||||
function storedSettings(): AppSettings {
|
||||
const stored = storage.getJson<AppSettings>(STORAGE_KEY);
|
||||
return stored ? { ...defaultSettings, ...stored } : { ...defaultSettings };
|
||||
}
|
||||
|
||||
class SettingsStore {
|
||||
settings: AppSettings = storedSettings();
|
||||
|
||||
private timers: ReturnType<typeof setInterval>[] = [];
|
||||
private lastHeader = '';
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this, {}, { autoBind: true });
|
||||
reaction(
|
||||
() => this.settings.brandColorsTablet as BrandColors | undefined,
|
||||
(brand) => themeStore.setBrand(brand ?? null),
|
||||
{ fireImmediately: true },
|
||||
);
|
||||
}
|
||||
|
||||
start(): void {
|
||||
if (this.timers.length > 0) return;
|
||||
void this.pullSettings();
|
||||
void this.pullHeader();
|
||||
void this.pullCity();
|
||||
this.timers = [
|
||||
setInterval(() => void this.pullSettings(), SETTINGS_INTERVAL),
|
||||
setInterval(() => void this.pullHeader(), HEADER_INTERVAL),
|
||||
setInterval(() => void this.pullCity(), CITY_INTERVAL),
|
||||
];
|
||||
appEvents.on('app-settings:force-pull', this.forcePull);
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
for (const timer of this.timers) clearInterval(timer);
|
||||
this.timers = [];
|
||||
appEvents.off('app-settings:force-pull', this.forcePull);
|
||||
}
|
||||
|
||||
update(patch: Partial<AppSettings>): void {
|
||||
this.settings = { ...this.settings, ...patch };
|
||||
storage.setJson(STORAGE_KEY, this.settings);
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.settings = { ...defaultSettings };
|
||||
storage.remove(STORAGE_KEY);
|
||||
}
|
||||
|
||||
private forcePull(): void {
|
||||
this.lastHeader = '';
|
||||
void this.pullSettings();
|
||||
void this.pullHeader();
|
||||
}
|
||||
|
||||
private async pullSettings(): Promise<void> {
|
||||
const all = await listSettings();
|
||||
const patch: Record<string, unknown> = {};
|
||||
for (const [key, value] of Object.entries(all)) {
|
||||
if (key.startsWith('ui.') && value != null) patch[key.slice(3)] = value;
|
||||
}
|
||||
if (Object.keys(patch).length === 0) return;
|
||||
runInAction(() => this.update(patch as Partial<AppSettings>));
|
||||
}
|
||||
|
||||
private async pullHeader(): Promise<void> {
|
||||
const value = await getSetting<AppSettings['tabletHeader']>('ui.tabletHeader');
|
||||
if (value == null) return;
|
||||
const serialized = JSON.stringify(value);
|
||||
if (serialized === this.lastHeader) return;
|
||||
this.lastHeader = serialized;
|
||||
runInAction(() => this.update({ tabletHeader: value }));
|
||||
}
|
||||
|
||||
private async pullCity(): Promise<void> {
|
||||
const value = await loadRemoteSetting<{ city?: string; customCityName?: string }>('global_city', {});
|
||||
if (!value.city) return;
|
||||
if (this.settings.city === value.city && this.settings.customCityName === value.customCityName) return;
|
||||
runInAction(() => this.update({ city: value.city, customCityName: value.customCityName }));
|
||||
}
|
||||
}
|
||||
|
||||
export const settingsStore = new SettingsStore();
|
||||
Reference in New Issue
Block a user