mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-15 23:47:33 +08:00
sync application settings
This commit is contained in:
+285
-36
@@ -1,7 +1,24 @@
|
||||
import { ref } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import type { ApplicationSettings, LocaleDefaultSettings } from '@/core/setting.ts';
|
||||
import {
|
||||
type ApplicationSettingValue,
|
||||
type ApplicationSettingSubValue,
|
||||
type ApplicationSettings,
|
||||
type ApplicationCloudSetting,
|
||||
type LocaleDefaultSettings,
|
||||
UserApplicationCloudSettingType,
|
||||
ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES
|
||||
} from '@/core/setting.ts';
|
||||
|
||||
import {
|
||||
isObject,
|
||||
isString,
|
||||
isBoolean,
|
||||
getObjectOwnFieldCount,
|
||||
arrayItemToObjectField
|
||||
} from '@/lib/common.ts';
|
||||
|
||||
import {
|
||||
getApplicationSettings,
|
||||
getLocaleDefaultSettings,
|
||||
@@ -10,10 +27,100 @@ import {
|
||||
clearSettings
|
||||
} from '@/lib/settings.ts';
|
||||
|
||||
import logger from '@/lib/logger.ts';
|
||||
import services from '@/lib/services.ts';
|
||||
|
||||
export const useSettingsStore = defineStore('settings', () => {
|
||||
const appSettings = ref<ApplicationSettings>(getApplicationSettings());
|
||||
const syncedAppSettings = ref<Record<string, boolean>>({});
|
||||
const localeDefaultSettings = ref<LocaleDefaultSettings>(getLocaleDefaultSettings());
|
||||
|
||||
const enableApplicationCloudSync = computed<boolean>(() => getObjectOwnFieldCount(syncedAppSettings.value) > 0);
|
||||
|
||||
function updateApplicationSettingsValueAndAppSettingsFromCloudSetting(key: string, value: string | number | boolean | Record<string, boolean>): void {
|
||||
const keyItems = key.split('.');
|
||||
|
||||
if (keyItems.length === 1) {
|
||||
updateApplicationSettingsValue(keyItems[0], value);
|
||||
appSettings.value[keyItems[0]] = value;
|
||||
} else if (keyItems.length === 2) {
|
||||
updateApplicationSettingsSubValue(keyItems[0], keyItems[1], value);
|
||||
(appSettings.value[keyItems[0]] as Record<string, ApplicationSettingSubValue>)[keyItems[1]] = value;
|
||||
} else {
|
||||
logger.warn(`cannot load application cloud setting "${key}", because it has invalid key format`);
|
||||
}
|
||||
}
|
||||
|
||||
function createUserApplicationCloudSetting(key: string): ApplicationCloudSetting | null {
|
||||
const settingType = ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES[key];
|
||||
|
||||
if (!settingType) {
|
||||
logger.warn(`cannot get application cloud setting "${key}", because it is not supported to sync`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const keyItems = key.split('.');
|
||||
let value: ApplicationSettingValue | ApplicationSettingSubValue = appSettings.value[key];
|
||||
|
||||
if (keyItems.length === 2) {
|
||||
value = (appSettings.value[keyItems[0]] as Record<string, ApplicationSettingSubValue>)[keyItems[1]];
|
||||
} else if (keyItems.length > 2) {
|
||||
logger.warn(`cannot get application cloud setting "${key}", because it has invalid key format`);
|
||||
return null;
|
||||
}
|
||||
|
||||
let settingValue = '';
|
||||
|
||||
if (settingType === UserApplicationCloudSettingType.String) {
|
||||
if (!value) {
|
||||
settingValue = '';
|
||||
} else {
|
||||
settingValue = value.toString();
|
||||
}
|
||||
} else {
|
||||
settingValue = JSON.stringify(value);
|
||||
}
|
||||
|
||||
return {
|
||||
settingKey: key,
|
||||
settingValue: settingValue
|
||||
};
|
||||
}
|
||||
|
||||
function updateUserApplicationCloudSettingValue(key: string, value: string | number | boolean | Record<string, boolean>): void {
|
||||
if (!syncedAppSettings.value || !syncedAppSettings.value[key]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const settingType = ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES[key];
|
||||
|
||||
if (!settingType) {
|
||||
return;
|
||||
}
|
||||
|
||||
const settingValue = isString(value) ? value : JSON.stringify(value);
|
||||
|
||||
services.updateUserApplicationCloudSettings({
|
||||
settings: [{
|
||||
settingKey: key,
|
||||
settingValue: settingValue
|
||||
}],
|
||||
fullUpdate: false
|
||||
}).then(response => {
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
logger.debug(`failed to update user application cloud setting "${key}" with value "${settingValue}"`);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug(`update user application cloud setting "${key}" with value "${settingValue}" successfully`);
|
||||
}).catch(error => {
|
||||
logger.debug(`failed to update user application cloud setting "${key}" with value "${settingValue}"`, error);
|
||||
});
|
||||
}
|
||||
|
||||
// Basic Settings
|
||||
function setTheme(value: string): void {
|
||||
updateApplicationSettingsValue('theme', value);
|
||||
appSettings.value.theme = value;
|
||||
@@ -29,6 +136,23 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
appSettings.value.timeZone = value;
|
||||
}
|
||||
|
||||
function setAutoUpdateExchangeRatesData(value: boolean): void {
|
||||
updateApplicationSettingsValue('autoUpdateExchangeRatesData', value);
|
||||
appSettings.value.autoUpdateExchangeRatesData = value;
|
||||
}
|
||||
|
||||
function setShowAccountBalance(value: boolean): void {
|
||||
updateApplicationSettingsValue('showAccountBalance', value);
|
||||
appSettings.value.showAccountBalance = value;
|
||||
updateUserApplicationCloudSettingValue('showAccountBalance', value);
|
||||
}
|
||||
|
||||
function setEnableAnimate(value: boolean): void {
|
||||
updateApplicationSettingsValue('animate', value);
|
||||
appSettings.value.animate = value;
|
||||
}
|
||||
|
||||
// Application Lock
|
||||
function setEnableApplicationLock(value: boolean): void {
|
||||
updateApplicationSettingsValue('applicationLock', value);
|
||||
appSettings.value.applicationLock = value;
|
||||
@@ -39,114 +163,123 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
appSettings.value.applicationLockWebAuthn = value;
|
||||
}
|
||||
|
||||
function setAutoUpdateExchangeRatesData(value: boolean): void {
|
||||
updateApplicationSettingsValue('autoUpdateExchangeRatesData', value);
|
||||
appSettings.value.autoUpdateExchangeRatesData = value;
|
||||
}
|
||||
|
||||
function setAutoSaveTransactionDraft(value: string): void {
|
||||
updateApplicationSettingsValue('autoSaveTransactionDraft', value);
|
||||
appSettings.value.autoSaveTransactionDraft = value;
|
||||
}
|
||||
|
||||
function setAutoGetCurrentGeoLocation(value: boolean): void {
|
||||
updateApplicationSettingsValue('autoGetCurrentGeoLocation', value);
|
||||
appSettings.value.autoGetCurrentGeoLocation = value;
|
||||
}
|
||||
|
||||
function setAlwaysShowTransactionPicturesInMobileTransactionEditPage(value: boolean): void {
|
||||
updateApplicationSettingsValue('alwaysShowTransactionPicturesInMobileTransactionEditPage', value);
|
||||
appSettings.value.alwaysShowTransactionPicturesInMobileTransactionEditPage = value;
|
||||
}
|
||||
|
||||
// Navigation Bar
|
||||
function setShowAddTransactionButtonInDesktopNavbar(value: boolean): void {
|
||||
updateApplicationSettingsValue('showAddTransactionButtonInDesktopNavbar', value);
|
||||
appSettings.value.showAddTransactionButtonInDesktopNavbar = value;
|
||||
}
|
||||
|
||||
// Overview Page
|
||||
function setShowAmountInHomePage(value: boolean): void {
|
||||
updateApplicationSettingsValue('showAmountInHomePage', value);
|
||||
appSettings.value.showAmountInHomePage = value;
|
||||
updateUserApplicationCloudSettingValue('showAmountInHomePage', value);
|
||||
}
|
||||
|
||||
function setTimezoneUsedForStatisticsInHomePage(value: number): void {
|
||||
updateApplicationSettingsValue('timezoneUsedForStatisticsInHomePage', value);
|
||||
appSettings.value.timezoneUsedForStatisticsInHomePage = value;
|
||||
updateUserApplicationCloudSettingValue('timezoneUsedForStatisticsInHomePage', value);
|
||||
}
|
||||
|
||||
// Transaction List Page
|
||||
function setItemsCountInTransactionListPage(value: number): void {
|
||||
updateApplicationSettingsValue('itemsCountInTransactionListPage', value);
|
||||
appSettings.value.itemsCountInTransactionListPage = value;
|
||||
updateUserApplicationCloudSettingValue('itemsCountInTransactionListPage', value);
|
||||
}
|
||||
|
||||
function setShowTotalAmountInTransactionListPage(value: boolean): void {
|
||||
updateApplicationSettingsValue('showTotalAmountInTransactionListPage', value);
|
||||
appSettings.value.showTotalAmountInTransactionListPage = value;
|
||||
updateUserApplicationCloudSettingValue('showTotalAmountInTransactionListPage', value);
|
||||
}
|
||||
|
||||
function setShowTagInTransactionListPage(value: boolean): void {
|
||||
updateApplicationSettingsValue('showTagInTransactionListPage', value);
|
||||
appSettings.value.showTagInTransactionListPage = value;
|
||||
updateUserApplicationCloudSettingValue('showTagInTransactionListPage', value);
|
||||
}
|
||||
|
||||
function setShowAccountBalance(value: boolean): void {
|
||||
updateApplicationSettingsValue('showAccountBalance', value);
|
||||
appSettings.value.showAccountBalance = value;
|
||||
// Transaction Edit Page
|
||||
function setAutoSaveTransactionDraft(value: string): void {
|
||||
updateApplicationSettingsValue('autoSaveTransactionDraft', value);
|
||||
appSettings.value.autoSaveTransactionDraft = value;
|
||||
updateUserApplicationCloudSettingValue('autoSaveTransactionDraft', value);
|
||||
}
|
||||
|
||||
function setAutoGetCurrentGeoLocation(value: boolean): void {
|
||||
updateApplicationSettingsValue('autoGetCurrentGeoLocation', value);
|
||||
appSettings.value.autoGetCurrentGeoLocation = value;
|
||||
updateUserApplicationCloudSettingValue('autoGetCurrentGeoLocation', value);
|
||||
}
|
||||
|
||||
function setAlwaysShowTransactionPicturesInMobileTransactionEditPage(value: boolean): void {
|
||||
updateApplicationSettingsValue('alwaysShowTransactionPicturesInMobileTransactionEditPage', value);
|
||||
appSettings.value.alwaysShowTransactionPicturesInMobileTransactionEditPage = value;
|
||||
updateUserApplicationCloudSettingValue('alwaysShowTransactionPicturesInMobileTransactionEditPage', value);
|
||||
}
|
||||
|
||||
// Exchange Rates Data Page
|
||||
function setCurrencySortByInExchangeRatesPage(value: number): void {
|
||||
updateApplicationSettingsValue('currencySortByInExchangeRatesPage', value);
|
||||
appSettings.value.currencySortByInExchangeRatesPage = value;
|
||||
updateUserApplicationCloudSettingValue('currencySortByInExchangeRatesPage', value);
|
||||
}
|
||||
|
||||
// Statistics Settings
|
||||
function setStatisticsDefaultChartDataType(value: number): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultChartDataType', value);
|
||||
appSettings.value.statistics.defaultChartDataType = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultChartDataType', value);
|
||||
}
|
||||
|
||||
function setStatisticsDefaultTimezoneType(value: number): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultTimezoneType', value);
|
||||
appSettings.value.statistics.defaultTimezoneType = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultTimezoneType', value);
|
||||
}
|
||||
|
||||
function setStatisticsDefaultAccountFilter(value: Record<string, boolean>): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultAccountFilter', value);
|
||||
appSettings.value.statistics.defaultAccountFilter = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultAccountFilter', value);
|
||||
}
|
||||
|
||||
function setStatisticsDefaultTransactionCategoryFilter(value: Record<string, boolean>): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultTransactionCategoryFilter', value);
|
||||
appSettings.value.statistics.defaultTransactionCategoryFilter = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultTransactionCategoryFilter', value);
|
||||
}
|
||||
|
||||
function setStatisticsSortingType(value: number): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultSortingType', value);
|
||||
appSettings.value.statistics.defaultSortingType = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultSortingType', value);
|
||||
}
|
||||
|
||||
function setStatisticsDefaultCategoricalChartType(value: number): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultCategoricalChartType', value);
|
||||
appSettings.value.statistics.defaultCategoricalChartType = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultCategoricalChartType', value);
|
||||
}
|
||||
|
||||
function setStatisticsDefaultCategoricalChartDateRange(value: number): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultCategoricalChartDataRangeType', value);
|
||||
appSettings.value.statistics.defaultCategoricalChartDataRangeType = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultCategoricalChartDataRangeType', value);
|
||||
}
|
||||
|
||||
function setStatisticsDefaultTrendChartType(value: number): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultTrendChartType', value);
|
||||
appSettings.value.statistics.defaultTrendChartType = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultTrendChartType', value);
|
||||
}
|
||||
|
||||
function setStatisticsDefaultTrendChartDateRange(value: number): void {
|
||||
updateApplicationSettingsSubValue('statistics', 'defaultTrendChartDataRangeType', value);
|
||||
appSettings.value.statistics.defaultTrendChartDataRangeType = value;
|
||||
}
|
||||
|
||||
function setEnableAnimate(value: boolean): void {
|
||||
updateApplicationSettingsValue('animate', value);
|
||||
appSettings.value.animate = value;
|
||||
updateUserApplicationCloudSettingValue('statistics.defaultTrendChartDataRangeType', value);
|
||||
}
|
||||
|
||||
function clearAppSettings(): void {
|
||||
@@ -154,6 +287,108 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
appSettings.value = getApplicationSettings();
|
||||
}
|
||||
|
||||
function createApplicationCloudSettings(applicationSettingKeys: string[]): ApplicationCloudSetting[] {
|
||||
if (!applicationSettingKeys || applicationSettingKeys.length < 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const settings: ApplicationCloudSetting[] = [];
|
||||
|
||||
for (let i = 0; i < applicationSettingKeys.length; i++) {
|
||||
const settingKey = applicationSettingKeys[i];
|
||||
const cloudSetting = createUserApplicationCloudSetting(settingKey);
|
||||
|
||||
if (cloudSetting) {
|
||||
settings.push(cloudSetting);
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
function setApplicationSettingsFromCloudSettings(cloudSettings?: ApplicationCloudSetting[]): void {
|
||||
if (!cloudSettings || cloudSettings.length < 1) {
|
||||
syncedAppSettings.value = {};
|
||||
return;
|
||||
}
|
||||
|
||||
syncedAppSettings.value = arrayItemToObjectField(cloudSettings.map(item => item.settingKey), true);
|
||||
|
||||
for (let i = 0; i < cloudSettings.length; i++) {
|
||||
const setting = cloudSettings[i];
|
||||
|
||||
if (!setting || !setting.settingKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const settingType = ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES[setting.settingKey];
|
||||
|
||||
if (!settingType) {
|
||||
logger.warn(`cannot load application cloud setting "${setting.settingKey}", because it is not supported to sync`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (settingType === UserApplicationCloudSettingType.String) {
|
||||
updateApplicationSettingsValueAndAppSettingsFromCloudSetting(setting.settingKey, setting.settingValue);
|
||||
} else if (settingType === UserApplicationCloudSettingType.Number) {
|
||||
const value = parseFloat(setting.settingValue);
|
||||
|
||||
if (isNaN(value)) {
|
||||
logger.warn(`cannot load application cloud setting "${setting.settingKey}", because it has invalid number value`);
|
||||
continue;
|
||||
}
|
||||
|
||||
updateApplicationSettingsValueAndAppSettingsFromCloudSetting(setting.settingKey, value);
|
||||
} else if (settingType === UserApplicationCloudSettingType.Boolean) {
|
||||
if (setting.settingValue !== 'true' && setting.settingValue !== 'false') {
|
||||
logger.warn(`cannot load application cloud setting "${setting.settingKey}", because it has invalid boolean value`);
|
||||
continue;
|
||||
}
|
||||
|
||||
updateApplicationSettingsValueAndAppSettingsFromCloudSetting(setting.settingKey, setting.settingValue === 'true');
|
||||
} else if (settingType === UserApplicationCloudSettingType.StringBooleanMap) {
|
||||
try {
|
||||
const map = JSON.parse(setting.settingValue);
|
||||
let isValid = isObject(map);
|
||||
|
||||
if (isValid) {
|
||||
for (const key in map) {
|
||||
if (!Object.prototype.hasOwnProperty.call(map, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = map[key];
|
||||
|
||||
if (!isBoolean(value)) {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
logger.warn(`cannot load application cloud setting "${setting.settingKey}", because it has invalid map value`);
|
||||
continue;
|
||||
}
|
||||
|
||||
updateApplicationSettingsValueAndAppSettingsFromCloudSetting(setting.settingKey, map as Record<string, boolean>);
|
||||
} catch (error) {
|
||||
logger.warn(`cannot load application cloud setting "${setting.settingKey}", because cannot parse JSON (${error})`);
|
||||
}
|
||||
} else {
|
||||
logger.warn(`cannot load application cloud setting "${setting.settingKey}", because it has unknown type "${settingType}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateApplicationSyncSettingKeys(settingKeys?: string[]): void {
|
||||
if (!settingKeys || settingKeys.length < 1) {
|
||||
syncedAppSettings.value = {};
|
||||
} else {
|
||||
syncedAppSettings.value = arrayItemToObjectField(settingKeys, true);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLocalizedDefaultSettings(newLocaleDefaultSettings: LocaleDefaultSettings | null) {
|
||||
if (!newLocaleDefaultSettings) {
|
||||
return;
|
||||
@@ -166,25 +401,37 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
return {
|
||||
// states
|
||||
appSettings,
|
||||
syncedAppSettings,
|
||||
localeDefaultSettings,
|
||||
// computed states
|
||||
enableApplicationCloudSync,
|
||||
// functions
|
||||
// -- Basic Settings
|
||||
setTheme,
|
||||
setFontSize,
|
||||
setTimeZone,
|
||||
setAutoUpdateExchangeRatesData,
|
||||
setShowAccountBalance,
|
||||
setEnableAnimate,
|
||||
// -- Application Lock
|
||||
setEnableApplicationLock,
|
||||
setEnableApplicationLockWebAuthn,
|
||||
setAutoUpdateExchangeRatesData,
|
||||
setAutoSaveTransactionDraft,
|
||||
setAutoGetCurrentGeoLocation,
|
||||
setAlwaysShowTransactionPicturesInMobileTransactionEditPage,
|
||||
// -- Navigation Bar
|
||||
setShowAddTransactionButtonInDesktopNavbar,
|
||||
// -- Overview Page
|
||||
setShowAmountInHomePage,
|
||||
setTimezoneUsedForStatisticsInHomePage,
|
||||
// -- Transaction List Page
|
||||
setItemsCountInTransactionListPage,
|
||||
setShowTotalAmountInTransactionListPage,
|
||||
setShowTagInTransactionListPage,
|
||||
setShowAccountBalance,
|
||||
// -- Transaction Edit Page
|
||||
setAutoSaveTransactionDraft,
|
||||
setAutoGetCurrentGeoLocation,
|
||||
setAlwaysShowTransactionPicturesInMobileTransactionEditPage,
|
||||
// -- Exchange Rates Data Page
|
||||
setCurrencySortByInExchangeRatesPage,
|
||||
// -- Statistics Settings
|
||||
setStatisticsDefaultChartDataType,
|
||||
setStatisticsDefaultTimezoneType,
|
||||
setStatisticsDefaultAccountFilter,
|
||||
@@ -194,8 +441,10 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
setStatisticsDefaultCategoricalChartDateRange,
|
||||
setStatisticsDefaultTrendChartType,
|
||||
setStatisticsDefaultTrendChartDateRange,
|
||||
setEnableAnimate,
|
||||
clearAppSettings,
|
||||
createApplicationCloudSettings,
|
||||
setApplicationSettingsFromCloudSettings,
|
||||
updateApplicationSyncSettingKeys,
|
||||
updateLocalizedDefaultSettings
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user