mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 20:44:34 +00:00
integrate localStorage options into preference system
This commit is contained in:
parent
16858cf2f7
commit
4085c8a4f1
5 changed files with 118 additions and 100 deletions
|
@ -23,24 +23,8 @@ import { i18n } from '@/i18n.js';
|
||||||
import { definePage } from '@/page.js';
|
import { definePage } from '@/page.js';
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import { reloadAsk } from '@/utility/reload-ask';
|
|
||||||
|
|
||||||
const customCssModel = prefer.model('customCss');
|
const localCustomCss = prefer.model('customCss');
|
||||||
const localCustomCss = computed<string>({
|
|
||||||
get() {
|
|
||||||
return customCssModel.value ?? miLocalStorage.getItem('customCss') ?? '';
|
|
||||||
},
|
|
||||||
set(newCustomCss) {
|
|
||||||
customCssModel.value = newCustomCss;
|
|
||||||
if (newCustomCss) {
|
|
||||||
miLocalStorage.setItem('customCss', newCustomCss);
|
|
||||||
} else {
|
|
||||||
miLocalStorage.removeItem('customCss');
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadAsk(true);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const headerActions = computed(() => []);
|
const headerActions = computed(() => []);
|
||||||
|
|
||||||
|
|
|
@ -1059,68 +1059,13 @@ const clickToOpen = prefer.model('clickToOpen');
|
||||||
const useCustomSearchEngine = computed(() => !Object.keys(searchEngineMap).includes(searchEngine.value));
|
const useCustomSearchEngine = computed(() => !Object.keys(searchEngineMap).includes(searchEngine.value));
|
||||||
const defaultCW = ref($i.defaultCW);
|
const defaultCW = ref($i.defaultCW);
|
||||||
const defaultCWPriority = ref($i.defaultCWPriority);
|
const defaultCWPriority = ref($i.defaultCWPriority);
|
||||||
|
const lang = prefer.model('lang');
|
||||||
const langModel = prefer.model('lang');
|
const fontSize = prefer.model('fontSize');
|
||||||
const lang = computed<string>({
|
const useSystemFont = prefer.model('useSystemFont');
|
||||||
get() {
|
const cornerRadius = prefer.model('cornerRadius');
|
||||||
return langModel.value ?? miLocalStorage.getItem('lang') ?? 'en-US';
|
|
||||||
},
|
|
||||||
set(newLang) {
|
|
||||||
langModel.value = newLang;
|
|
||||||
miLocalStorage.setItem('lang', newLang);
|
|
||||||
miLocalStorage.removeItem('locale');
|
|
||||||
miLocalStorage.removeItem('localeVersion');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const fontSizeModel = prefer.model('fontSize');
|
|
||||||
const fontSize = computed<'0' | '1' | '2' | '3'>({
|
|
||||||
get() {
|
|
||||||
return fontSizeModel.value ?? miLocalStorage.getItem('fontSize') ?? '0';
|
|
||||||
},
|
|
||||||
set(newFontSize) {
|
|
||||||
fontSizeModel.value = newFontSize;
|
|
||||||
if (newFontSize !== '0') {
|
|
||||||
miLocalStorage.setItem('fontSize', newFontSize);
|
|
||||||
} else {
|
|
||||||
miLocalStorage.removeItem('fontSize');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const useSystemFontModel = prefer.model('useSystemFont');
|
|
||||||
const useSystemFont = computed<boolean>({
|
|
||||||
get() {
|
|
||||||
return useSystemFontModel.value ?? (miLocalStorage.getItem('useSystemFont') != null);
|
|
||||||
},
|
|
||||||
set(newUseSystemFont) {
|
|
||||||
useSystemFontModel.value = newUseSystemFont;
|
|
||||||
if (newUseSystemFont) {
|
|
||||||
miLocalStorage.setItem('useSystemFont', 't');
|
|
||||||
} else {
|
|
||||||
miLocalStorage.removeItem('useSystemFont');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const cornerRadiusModel = prefer.model('cornerRadius');
|
|
||||||
const cornerRadius = computed<'misskey' | 'sharkey'>({
|
|
||||||
get() {
|
|
||||||
return cornerRadiusModel.value ?? miLocalStorage.getItem('cornerRadius') ?? 'sharkey';
|
|
||||||
},
|
|
||||||
set(newCornerRadius) {
|
|
||||||
cornerRadiusModel.value = newCornerRadius;
|
|
||||||
if (newCornerRadius === 'sharkey') {
|
|
||||||
miLocalStorage.removeItem('cornerRadius');
|
|
||||||
} else {
|
|
||||||
miLocalStorage.setItem('cornerRadius', newCornerRadius);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
watch([
|
watch([
|
||||||
hemisphere,
|
hemisphere,
|
||||||
lang,
|
|
||||||
enableInfiniteScroll,
|
enableInfiniteScroll,
|
||||||
showNoteActionsOnlyHover,
|
showNoteActionsOnlyHover,
|
||||||
overridedDeviceKind,
|
overridedDeviceKind,
|
||||||
|
@ -1142,9 +1087,6 @@ watch([
|
||||||
useStickyIcons,
|
useStickyIcons,
|
||||||
keepScreenOn,
|
keepScreenOn,
|
||||||
contextMenu,
|
contextMenu,
|
||||||
fontSize,
|
|
||||||
useSystemFont,
|
|
||||||
cornerRadius,
|
|
||||||
makeEveryTextElementsSelectable,
|
makeEveryTextElementsSelectable,
|
||||||
noteDesign,
|
noteDesign,
|
||||||
], async () => {
|
], async () => {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { deckStore } from '@/ui/deck/deck-store.js';
|
||||||
import { unisonReload } from '@/utility/unison-reload.js';
|
import { unisonReload } from '@/utility/unison-reload.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
import { miLocalStorage } from '@/local-storage';
|
||||||
|
|
||||||
// TODO: そのうち消す
|
// TODO: そのうち消す
|
||||||
export function migrateOldSettings() {
|
export function migrateOldSettings() {
|
||||||
|
@ -167,5 +168,15 @@ export function migrateOldSettings() {
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
unisonReload();
|
unisonReload();
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
//#region Hybrid migrations
|
||||||
|
prefer.commit('fontSize', miLocalStorage.getItem('fontSize') ?? '0');
|
||||||
|
prefer.commit('useSystemFont', miLocalStorage.getItem('useSystemFont') != null);
|
||||||
|
prefer.commit('cornerRadius', miLocalStorage.getItem('cornerRadius') ?? 'sharkey');
|
||||||
|
prefer.commit('lang', miLocalStorage.getItem('lang') ?? 'en-US');
|
||||||
|
prefer.commit('customCss', miLocalStorage.getItem('customCss') ?? '');
|
||||||
|
prefer.commit('neverShowDonationInfo', miLocalStorage.getItem('neverShowDonationInfo') != null);
|
||||||
|
prefer.commit('neverShowLocalOnlyInfo', miLocalStorage.getItem('neverShowLocalOnlyInfo') != null);
|
||||||
|
//#endregion
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,12 @@ import type { SoundType } from '@/utility/sound.js';
|
||||||
import type { Plugin } from '@/plugin.js';
|
import type { Plugin } from '@/plugin.js';
|
||||||
import type { DeviceKind } from '@/utility/device-kind.js';
|
import type { DeviceKind } from '@/utility/device-kind.js';
|
||||||
import type { DeckProfile } from '@/deck.js';
|
import type { DeckProfile } from '@/deck.js';
|
||||||
import type { PreferencesDefinition } from './manager.js';
|
import type { Pref, PreferencesDefinition } from './manager.js';
|
||||||
import type { FollowingFeedState } from '@/types/following-feed.js';
|
import type { FollowingFeedState } from '@/types/following-feed.js';
|
||||||
import { DEFAULT_DEVICE_KIND } from '@/utility/device-kind.js';
|
import { DEFAULT_DEVICE_KIND } from '@/utility/device-kind.js';
|
||||||
import { searchEngineMap } from '@/utility/search-engine-map.js';
|
import { searchEngineMap } from '@/utility/search-engine-map.js';
|
||||||
import { defaultFollowingFeedState } from '@/types/following-feed.js';
|
import { defaultFollowingFeedState } from '@/types/following-feed.js';
|
||||||
|
import { miLocalStorage } from '@/local-storage';
|
||||||
|
|
||||||
/** サウンド設定 */
|
/** サウンド設定 */
|
||||||
export type SoundStore = {
|
export type SoundStore = {
|
||||||
|
@ -484,25 +485,77 @@ export const PREF_DEF = {
|
||||||
// Null means "fall back to existing value from localStorage"
|
// Null means "fall back to existing value from localStorage"
|
||||||
// For all of these preferences, "null" means fall back to existing value in localStorage.
|
// For all of these preferences, "null" means fall back to existing value in localStorage.
|
||||||
fontSize: {
|
fontSize: {
|
||||||
default: null as null | '0' | '1' | '2' | '3',
|
default: '0',
|
||||||
},
|
needsReload: true,
|
||||||
|
onSet: fontSize => {
|
||||||
|
if (fontSize !== '0') {
|
||||||
|
miLocalStorage.setItem('fontSize', fontSize);
|
||||||
|
} else {
|
||||||
|
miLocalStorage.removeItem('fontSize');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as Pref<'0' | '1' | '2' | '3'>,
|
||||||
useSystemFont: {
|
useSystemFont: {
|
||||||
default: null as null | boolean,
|
default: false,
|
||||||
},
|
needsReload: true,
|
||||||
|
onSet: useSystemFont => {
|
||||||
|
if (useSystemFont) {
|
||||||
|
miLocalStorage.setItem('useSystemFont', 't');
|
||||||
|
} else {
|
||||||
|
miLocalStorage.removeItem('useSystemFont');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as Pref<boolean>,
|
||||||
cornerRadius: {
|
cornerRadius: {
|
||||||
default: null as null | 'misskey' | 'sharkey',
|
default: 'sharkey',
|
||||||
},
|
needsReload: true,
|
||||||
|
onSet: cornerRadius => {
|
||||||
|
if (cornerRadius === 'sharkey') {
|
||||||
|
miLocalStorage.removeItem('cornerRadius');
|
||||||
|
} else {
|
||||||
|
miLocalStorage.setItem('cornerRadius', cornerRadius);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as Pref<'misskey' | 'sharkey'>,
|
||||||
lang: {
|
lang: {
|
||||||
default: null as null | string,
|
default: 'en-US',
|
||||||
},
|
needsReload: true,
|
||||||
|
onSet: lang => {
|
||||||
|
miLocalStorage.setItem('lang', lang);
|
||||||
|
miLocalStorage.removeItem('locale');
|
||||||
|
miLocalStorage.removeItem('localeVersion');
|
||||||
|
},
|
||||||
|
} as Pref<string>,
|
||||||
customCss: {
|
customCss: {
|
||||||
default: null as null | string,
|
default: '',
|
||||||
},
|
needsReload: true,
|
||||||
|
onSet: customCss => {
|
||||||
|
if (customCss) {
|
||||||
|
miLocalStorage.setItem('customCss', customCss);
|
||||||
|
} else {
|
||||||
|
miLocalStorage.removeItem('customCss');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as Pref<string>,
|
||||||
neverShowDonationInfo: {
|
neverShowDonationInfo: {
|
||||||
default: null as null | 'true',
|
default: false,
|
||||||
},
|
onSet: neverShowDonationInfo => {
|
||||||
|
if (neverShowDonationInfo) {
|
||||||
|
miLocalStorage.setItem('neverShowDonationInfo', 'true');
|
||||||
|
} else {
|
||||||
|
miLocalStorage.removeItem('neverShowDonationInfo');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as Pref<boolean>,
|
||||||
neverShowLocalOnlyInfo: {
|
neverShowLocalOnlyInfo: {
|
||||||
default: null as null | 'true',
|
default: false,
|
||||||
},
|
onSet: neverShowLocalOnlyInfo => {
|
||||||
|
if (neverShowLocalOnlyInfo) {
|
||||||
|
miLocalStorage.setItem('neverShowLocalOnlyInfo', 'true');
|
||||||
|
} else {
|
||||||
|
miLocalStorage.removeItem('neverShowLocalOnlyInfo');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as Pref<boolean>,
|
||||||
//#endregion
|
//#endregion
|
||||||
} satisfies PreferencesDefinition;
|
} satisfies PreferencesDefinition;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { computed, onUnmounted, ref, watch } from 'vue';
|
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { host, version } from '@@/js/config.js';
|
import { host, version } from '@@/js/config.js';
|
||||||
import { PREF_DEF } from './def.js';
|
import { PREF_DEF } from './def.js';
|
||||||
|
@ -14,6 +14,7 @@ import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { deepEqual } from '@/utility/deep-equal.js';
|
import { deepEqual } from '@/utility/deep-equal.js';
|
||||||
|
import { reloadAsk } from '@/utility/reload-ask';
|
||||||
|
|
||||||
// NOTE: 明示的な設定値のひとつとして null もあり得るため、設定が存在しないかどうかを判定する目的で null で比較したり ?? を使ってはいけない
|
// NOTE: 明示的な設定値のひとつとして null もあり得るため、設定が存在しないかどうかを判定する目的で null で比較したり ?? を使ってはいけない
|
||||||
|
|
||||||
|
@ -84,16 +85,29 @@ export type StorageProvider = {
|
||||||
cloudSet: <K extends keyof PREF>(ctx: { key: K; scope: Scope; value: ValueOf<K>; }) => Promise<void>;
|
cloudSet: <K extends keyof PREF>(ctx: { key: K; scope: Scope; value: ValueOf<K>; }) => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PreferencesDefinition = Record<string, {
|
export type Pref<T> = {
|
||||||
default: any;
|
default: T;
|
||||||
accountDependent?: boolean;
|
accountDependent?: boolean;
|
||||||
serverDependent?: boolean;
|
serverDependent?: boolean;
|
||||||
}>;
|
needsReload?: boolean;
|
||||||
|
onSet?: (value: T) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PreferencesDefinition = Record<string, Pref<any> | undefined>;
|
||||||
|
|
||||||
export class PreferencesManager {
|
export class PreferencesManager {
|
||||||
private storageProvider: StorageProvider;
|
private storageProvider: StorageProvider;
|
||||||
public profile: PreferencesProfile;
|
public profile: PreferencesProfile;
|
||||||
public cloudReady: Promise<void>;
|
public cloudReady: Promise<void>;
|
||||||
|
private enableReload = true;
|
||||||
|
|
||||||
|
public suppressReload() {
|
||||||
|
this.enableReload = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public allowReload() {
|
||||||
|
this.enableReload = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* static / state の略 (static が予約語のため)
|
* static / state の略 (static が予約語のため)
|
||||||
|
@ -126,11 +140,11 @@ export class PreferencesManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private isAccountDependentKey<K extends keyof PREF>(key: K): boolean {
|
private isAccountDependentKey<K extends keyof PREF>(key: K): boolean {
|
||||||
return (PREF_DEF as PreferencesDefinition)[key].accountDependent === true;
|
return (PREF_DEF as PreferencesDefinition)[key]?.accountDependent === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isServerDependentKey<K extends keyof PREF>(key: K): boolean {
|
private isServerDependentKey<K extends keyof PREF>(key: K): boolean {
|
||||||
return (PREF_DEF as PreferencesDefinition)[key].serverDependent === true;
|
return (PREF_DEF as PreferencesDefinition)[key]?.serverDependent === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private rewriteRawState<K extends keyof PREF>(key: K, value: ValueOf<K>) {
|
private rewriteRawState<K extends keyof PREF>(key: K, value: ValueOf<K>) {
|
||||||
|
@ -150,6 +164,20 @@ export class PreferencesManager {
|
||||||
|
|
||||||
this.rewriteRawState(key, v);
|
this.rewriteRawState(key, v);
|
||||||
|
|
||||||
|
const pref = (PREF_DEF as PreferencesDefinition)[key];
|
||||||
|
if (pref) {
|
||||||
|
// Call custom setter
|
||||||
|
if (pref.onSet) {
|
||||||
|
pref.onSet(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prompt to reload the frontend
|
||||||
|
if (pref.needsReload && this.enableReload) {
|
||||||
|
// noinspection JSIgnoredPromiseFromCall
|
||||||
|
nextTick(() => reloadAsk({ unison: true }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const record = this.getMatchedRecordOf(key);
|
const record = this.getMatchedRecordOf(key);
|
||||||
|
|
||||||
if (parseScope(record[0]).account == null && this.isAccountDependentKey(key)) {
|
if (parseScope(record[0]).account == null && this.isAccountDependentKey(key)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue