mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-14 06:57:35 +08:00
502 lines
21 KiB
TypeScript
502 lines
21 KiB
TypeScript
import { ref, computed } from 'vue';
|
|
import { defineStore } from 'pinia';
|
|
|
|
import {
|
|
values
|
|
} from '@/core/base.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,
|
|
updateApplicationSettingsValue,
|
|
updateApplicationSettingsSubValue,
|
|
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('.');
|
|
const keyFirstPart = keyItems[0] as string;
|
|
|
|
if (keyItems.length === 1) {
|
|
updateApplicationSettingsValue(keyFirstPart, value);
|
|
appSettings.value[keyFirstPart] = value;
|
|
} else if (keyItems.length === 2) {
|
|
const subKey = keyItems[1] as string;
|
|
updateApplicationSettingsSubValue(keyFirstPart, subKey, value);
|
|
(appSettings.value[keyFirstPart] as Record<string, ApplicationSettingSubValue>)[subKey] = 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] as (ApplicationSettingValue | ApplicationSettingSubValue);
|
|
|
|
if (keyItems.length === 2) {
|
|
const primaryKey = keyItems[0] as string;
|
|
const subKey = keyItems[1] as string;
|
|
value = (appSettings.value[primaryKey] as Record<string, ApplicationSettingSubValue>)[subKey] as ApplicationSettingSubValue;
|
|
} 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;
|
|
}
|
|
|
|
function setFontSize(value: number): void {
|
|
updateApplicationSettingsValue('fontSize', value);
|
|
appSettings.value.fontSize = value;
|
|
}
|
|
|
|
function setTimeZone(value: string): void {
|
|
updateApplicationSettingsValue('timeZone', value);
|
|
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 setEnableSwipeBack(value: boolean): void {
|
|
updateApplicationSettingsValue('swipeBack', value);
|
|
appSettings.value.swipeBack = 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;
|
|
}
|
|
|
|
function setEnableApplicationLockWebAuthn(value: boolean): void {
|
|
updateApplicationSettingsValue('applicationLockWebAuthn', value);
|
|
appSettings.value.applicationLockWebAuthn = 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);
|
|
}
|
|
|
|
function setOverviewAccountFilterInHomePage(value: Record<string, boolean>): void {
|
|
updateApplicationSettingsValue('overviewAccountFilterInHomePage', value);
|
|
appSettings.value.overviewAccountFilterInHomePage = value;
|
|
updateUserApplicationCloudSettingValue('overviewAccountFilterInHomePage', value);
|
|
}
|
|
|
|
function setOverviewTransactionCategoryFilterInHomePage(value: Record<string, boolean>): void {
|
|
updateApplicationSettingsValue('overviewTransactionCategoryFilterInHomePage', value);
|
|
appSettings.value.overviewTransactionCategoryFilterInHomePage = value;
|
|
updateUserApplicationCloudSettingValue('overviewTransactionCategoryFilterInHomePage', 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);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// Insights Explorer Page
|
|
function setInsightsExplorerDefaultDateRangeType(value: number): void {
|
|
updateApplicationSettingsValue('insightsExplorerDefaultDateRangeType', value);
|
|
appSettings.value.insightsExplorerDefaultDateRangeType = value;
|
|
updateUserApplicationCloudSettingValue('insightsExplorerDefaultDateRangeType', value);
|
|
}
|
|
|
|
// Account List Page
|
|
function setTotalAmountExcludeAccountIds(value: Record<string, boolean>): void {
|
|
updateApplicationSettingsValue('totalAmountExcludeAccountIds', value);
|
|
appSettings.value.totalAmountExcludeAccountIds = value;
|
|
updateUserApplicationCloudSettingValue('totalAmountExcludeAccountIds', 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;
|
|
updateUserApplicationCloudSettingValue('statistics.defaultTrendChartDataRangeType', value);
|
|
}
|
|
|
|
function setStatisticsDefaultAssetTrendsChartType(value: number): void {
|
|
updateApplicationSettingsSubValue('statistics', 'defaultAssetTrendsChartType', value);
|
|
appSettings.value.statistics.defaultAssetTrendsChartType = value;
|
|
updateUserApplicationCloudSettingValue('statistics.defaultAssetTrendsChartType', value);
|
|
}
|
|
|
|
function setStatisticsDefaultAssetTrendsChartDateRange(value: number): void {
|
|
updateApplicationSettingsSubValue('statistics', 'defaultAssetTrendsChartDataRangeType', value);
|
|
appSettings.value.statistics.defaultAssetTrendsChartDataRangeType = value;
|
|
updateUserApplicationCloudSettingValue('statistics.defaultAssetTrendsChartDataRangeType', value);
|
|
}
|
|
|
|
function clearAppSettings(): void {
|
|
clearSettings();
|
|
appSettings.value = getApplicationSettings();
|
|
}
|
|
|
|
function createApplicationCloudSettings(applicationSettingKeys: string[]): ApplicationCloudSetting[] {
|
|
if (!applicationSettingKeys || applicationSettingKeys.length < 1) {
|
|
return [];
|
|
}
|
|
|
|
const settings: ApplicationCloudSetting[] = [];
|
|
|
|
for (const settingKey of applicationSettingKeys) {
|
|
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 (const setting of cloudSettings) {
|
|
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 value of values(map)) {
|
|
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;
|
|
}
|
|
|
|
localeDefaultSettings.value.currency = newLocaleDefaultSettings.currency;
|
|
localeDefaultSettings.value.firstDayOfWeek = newLocaleDefaultSettings.firstDayOfWeek;
|
|
}
|
|
|
|
return {
|
|
// states
|
|
appSettings,
|
|
syncedAppSettings,
|
|
localeDefaultSettings,
|
|
// computed states
|
|
enableApplicationCloudSync,
|
|
// functions
|
|
// -- Basic Settings
|
|
setTheme,
|
|
setFontSize,
|
|
setTimeZone,
|
|
setAutoUpdateExchangeRatesData,
|
|
setShowAccountBalance,
|
|
setEnableSwipeBack,
|
|
setEnableAnimate,
|
|
// -- Application Lock
|
|
setEnableApplicationLock,
|
|
setEnableApplicationLockWebAuthn,
|
|
// -- Navigation Bar
|
|
setShowAddTransactionButtonInDesktopNavbar,
|
|
// -- Overview Page
|
|
setShowAmountInHomePage,
|
|
setTimezoneUsedForStatisticsInHomePage,
|
|
setOverviewAccountFilterInHomePage,
|
|
setOverviewTransactionCategoryFilterInHomePage,
|
|
// -- Transaction List Page
|
|
setItemsCountInTransactionListPage,
|
|
setShowTotalAmountInTransactionListPage,
|
|
setShowTagInTransactionListPage,
|
|
// -- Transaction Edit Page
|
|
setAutoSaveTransactionDraft,
|
|
setAutoGetCurrentGeoLocation,
|
|
setAlwaysShowTransactionPicturesInMobileTransactionEditPage,
|
|
// -- Insights Explorer Page
|
|
setInsightsExplorerDefaultDateRangeType,
|
|
// -- Account List Page
|
|
setTotalAmountExcludeAccountIds,
|
|
// -- Exchange Rates Data Page
|
|
setCurrencySortByInExchangeRatesPage,
|
|
// -- Statistics Settings
|
|
setStatisticsDefaultChartDataType,
|
|
setStatisticsDefaultTimezoneType,
|
|
setStatisticsDefaultAccountFilter,
|
|
setStatisticsDefaultTransactionCategoryFilter,
|
|
setStatisticsSortingType,
|
|
setStatisticsDefaultCategoricalChartType,
|
|
setStatisticsDefaultCategoricalChartDateRange,
|
|
setStatisticsDefaultTrendChartType,
|
|
setStatisticsDefaultTrendChartDateRange,
|
|
setStatisticsDefaultAssetTrendsChartType,
|
|
setStatisticsDefaultAssetTrendsChartDateRange,
|
|
clearAppSettings,
|
|
createApplicationCloudSettings,
|
|
setApplicationSettingsFromCloudSettings,
|
|
updateApplicationSyncSettingKeys,
|
|
updateLocalizedDefaultSettings
|
|
};
|
|
});
|