👀 format (packages/frontend/src/store.ts)
This commit is contained in:
parent
0b9035c9fc
commit
312232e990
1 changed files with 579 additions and 551 deletions
|
@ -3,31 +3,31 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { markRaw, ref } from 'vue';
|
import { markRaw, ref } from "vue";
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from "misskey-js";
|
||||||
import { hemisphere } from '@@/js/intl-const.js';
|
import { hemisphere } from "@@/js/intl-const.js";
|
||||||
import lightTheme from '@@/themes/l-cherry.json5';
|
import lightTheme from "@@/themes/l-cherry.json5";
|
||||||
import darkTheme from '@@/themes/d-ice.json5';
|
import darkTheme from "@@/themes/d-ice.json5";
|
||||||
import { searchEngineMap } from './scripts/search-engine-map.js';
|
import { searchEngineMap } from "./scripts/search-engine-map.js";
|
||||||
import type { SoundType } from '@/scripts/sound.js';
|
import type { SoundType } from "@/scripts/sound.js";
|
||||||
import { DEFAULT_DEVICE_KIND, type DeviceKind } from '@/scripts/device-kind.js';
|
import { DEFAULT_DEVICE_KIND, type DeviceKind } from "@/scripts/device-kind.js";
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from "@/local-storage.js";
|
||||||
import { defaultFollowingFeedState } from '@/scripts/following-feed-utils.js';
|
import { defaultFollowingFeedState } from "@/scripts/following-feed-utils.js";
|
||||||
import { Storage } from '@/pizzax.js';
|
import { Storage } from "@/pizzax.js";
|
||||||
import type { Ast } from '@syuilo/aiscript';
|
import type { Ast } from "@syuilo/aiscript";
|
||||||
|
|
||||||
interface PostFormAction {
|
interface PostFormAction {
|
||||||
title: string,
|
title: string;
|
||||||
handler: <T>(form: T, update: (key: unknown, value: unknown) => void) => void;
|
handler: <T>(form: T, update: (key: unknown, value: unknown) => void) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserAction {
|
interface UserAction {
|
||||||
title: string,
|
title: string;
|
||||||
handler: (user: Misskey.entities.UserDetailed) => void;
|
handler: (user: Misskey.entities.UserDetailed) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NoteAction {
|
interface NoteAction {
|
||||||
title: string,
|
title: string;
|
||||||
handler: (note: Misskey.entities.Note) => void;
|
handler: (note: Misskey.entities.Note) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,11 +44,13 @@ interface PageViewInterruptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** サウンド設定 */
|
/** サウンド設定 */
|
||||||
export type SoundStore = {
|
export type SoundStore =
|
||||||
type: Exclude<SoundType, '_driveFile_'>;
|
| {
|
||||||
|
type: Exclude<SoundType, "_driveFile_">;
|
||||||
volume: number;
|
volume: number;
|
||||||
} | {
|
}
|
||||||
type: '_driveFile_';
|
| {
|
||||||
|
type: "_driveFile_";
|
||||||
|
|
||||||
/** ドライブのファイルID */
|
/** ドライブのファイルID */
|
||||||
fileId: string;
|
fileId: string;
|
||||||
|
@ -57,7 +59,7 @@ export type SoundStore = {
|
||||||
fileUrl: string;
|
fileUrl: string;
|
||||||
|
|
||||||
volume: number;
|
volume: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const postFormActions: PostFormAction[] = [];
|
export const postFormActions: PostFormAction[] = [];
|
||||||
export const userActions: UserAction[] = [];
|
export const userActions: UserAction[] = [];
|
||||||
|
@ -68,13 +70,14 @@ export const pageViewInterruptors: PageViewInterruptor[] = [];
|
||||||
|
|
||||||
// TODO: それぞれいちいちwhereとかdefaultというキーを付けなきゃいけないの冗長なのでなんとかする(ただ型定義が面倒になりそう)
|
// TODO: それぞれいちいちwhereとかdefaultというキーを付けなきゃいけないの冗長なのでなんとかする(ただ型定義が面倒になりそう)
|
||||||
// あと、現行の定義の仕方なら「whereが何であるかに関わらずキー名の重複不可」という制約を付けられるメリットもあるからそのメリットを引き継ぐ方法も考えないといけない
|
// あと、現行の定義の仕方なら「whereが何であるかに関わらずキー名の重複不可」という制約を付けられるメリットもあるからそのメリットを引き継ぐ方法も考えないといけない
|
||||||
export const defaultStore = markRaw(new Storage('base', {
|
export const defaultStore = markRaw(
|
||||||
|
new Storage("base", {
|
||||||
accountSetupWizard: {
|
accountSetupWizard: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
timelineTutorials: {
|
timelineTutorials: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: {
|
default: {
|
||||||
home: false,
|
home: false,
|
||||||
local: false,
|
local: false,
|
||||||
|
@ -83,146 +86,151 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
abusesTutorial: {
|
abusesTutorial: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
keepCw: {
|
keepCw: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
showFullAcct: {
|
showFullAcct: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
collapseRenotes: {
|
collapseRenotes: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
collapseNotesRepliedTo: {
|
collapseNotesRepliedTo: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
collapseFiles: {
|
collapseFiles: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
uncollapseCW: {
|
uncollapseCW: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
expandLongNote: {
|
expandLongNote: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
rememberNoteVisibility: {
|
rememberNoteVisibility: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
defaultNoteVisibility: {
|
defaultNoteVisibility: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: 'public' as (typeof Misskey.noteVisibilities)[number],
|
default: "public" as (typeof Misskey.noteVisibilities)[number],
|
||||||
},
|
},
|
||||||
defaultNoteLocalOnly: {
|
defaultNoteLocalOnly: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
uploadFolder: {
|
uploadFolder: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: null as string | null,
|
default: null as string | null,
|
||||||
},
|
},
|
||||||
pastedFileName: {
|
pastedFileName: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: 'yyyy-MM-dd HH-mm-ss [{{number}}]',
|
default: "yyyy-MM-dd HH-mm-ss [{{number}}]",
|
||||||
},
|
},
|
||||||
keepOriginalUploading: {
|
keepOriginalUploading: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
memo: {
|
memo: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
reactions: {
|
reactions: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: ['👍', '❤️', '😆', '🤔', '😮', '🎉', '💢', '😥', '😇', '🍮'],
|
default: ["👍", "❤", "😆", "🤔", "😮", "🎉", "💢", "😥", "😇", "🍮"],
|
||||||
},
|
},
|
||||||
pinnedEmojis: {
|
pinnedEmojis: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
reactionAcceptance: {
|
reactionAcceptance: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: 'nonSensitiveOnly' as 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote' | null,
|
default: "nonSensitiveOnly" as
|
||||||
|
| "likeOnly"
|
||||||
|
| "likeOnlyForRemote"
|
||||||
|
| "nonSensitiveOnly"
|
||||||
|
| "nonSensitiveOnlyForLocalLikeOnlyForRemote"
|
||||||
|
| null,
|
||||||
},
|
},
|
||||||
like: {
|
like: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: null as string | null,
|
default: null as string | null,
|
||||||
},
|
},
|
||||||
mutedAds: {
|
mutedAds: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: [] as string[],
|
default: [] as string[],
|
||||||
},
|
},
|
||||||
autoloadConversation: {
|
autoloadConversation: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
showVisibilitySelectorOnBoost: {
|
showVisibilitySelectorOnBoost: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
visibilityOnBoost: {
|
visibilityOnBoost: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: 'public' as 'public' | 'home' | 'followers',
|
default: "public" as "public" | "home" | "followers",
|
||||||
},
|
},
|
||||||
trustedDomains: {
|
trustedDomains: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: [] as string[],
|
default: [] as string[],
|
||||||
},
|
},
|
||||||
warnExternalUrl: {
|
warnExternalUrl: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
menu: {
|
menu: {
|
||||||
where: 'deviceAccount',
|
where: "deviceAccount",
|
||||||
default: [
|
default: [
|
||||||
'notifications',
|
"notifications",
|
||||||
'explore',
|
"explore",
|
||||||
'followRequests',
|
"followRequests",
|
||||||
'-',
|
"-",
|
||||||
'announcements',
|
"announcements",
|
||||||
'search',
|
"search",
|
||||||
'-',
|
"-",
|
||||||
'favorites',
|
"favorites",
|
||||||
'drive',
|
"drive",
|
||||||
'achievements',
|
"achievements",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
visibility: {
|
visibility: {
|
||||||
where: 'deviceAccount',
|
where: "deviceAccount",
|
||||||
default: 'public' as (typeof Misskey.noteVisibilities)[number],
|
default: "public" as (typeof Misskey.noteVisibilities)[number],
|
||||||
},
|
},
|
||||||
localOnly: {
|
localOnly: {
|
||||||
where: 'deviceAccount',
|
where: "deviceAccount",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
showPreview: {
|
showPreview: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
statusbars: {
|
statusbars: {
|
||||||
where: 'deviceAccount',
|
where: "deviceAccount",
|
||||||
default: [] as {
|
default: [] as {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
type: string;
|
type: string;
|
||||||
size: 'verySmall' | 'small' | 'medium' | 'large' | 'veryLarge';
|
size: "verySmall" | "small" | "medium" | "large" | "veryLarge";
|
||||||
black: boolean;
|
black: boolean;
|
||||||
props: Record<string, any>;
|
props: Record<string, any>;
|
||||||
}[],
|
}[],
|
||||||
},
|
},
|
||||||
widgets: {
|
widgets: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: [] as {
|
default: [] as {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -231,9 +239,15 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||||
}[],
|
}[],
|
||||||
},
|
},
|
||||||
tl: {
|
tl: {
|
||||||
where: 'deviceAccount',
|
where: "deviceAccount",
|
||||||
default: {
|
default: {
|
||||||
src: 'home' as 'home' | 'local' | 'social' | 'global' | 'bubble' | `list:${string}`,
|
src: "home" as
|
||||||
|
| "home"
|
||||||
|
| "local"
|
||||||
|
| "social"
|
||||||
|
| "global"
|
||||||
|
| "bubble"
|
||||||
|
| `list:${string}`,
|
||||||
userList: null as Misskey.entities.UserList | null,
|
userList: null as Misskey.entities.UserList | null,
|
||||||
filter: {
|
filter: {
|
||||||
withReplies: true,
|
withReplies: true,
|
||||||
|
@ -245,272 +259,276 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pinnedUserLists: {
|
pinnedUserLists: {
|
||||||
where: 'deviceAccount',
|
where: "deviceAccount",
|
||||||
default: [] as Misskey.entities.UserList[],
|
default: [] as Misskey.entities.UserList[],
|
||||||
},
|
},
|
||||||
followingFeed: {
|
followingFeed: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: defaultFollowingFeedState,
|
default: defaultFollowingFeedState,
|
||||||
},
|
},
|
||||||
|
|
||||||
overridedDeviceKind: {
|
overridedDeviceKind: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: null as DeviceKind | null,
|
default: null as DeviceKind | null,
|
||||||
},
|
},
|
||||||
serverDisconnectedBehavior: {
|
serverDisconnectedBehavior: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'disabled' as 'quiet' | 'dialog' | 'disabled',
|
default: "disabled" as "quiet" | "dialog" | "disabled",
|
||||||
},
|
},
|
||||||
nsfw: {
|
nsfw: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'respect' as 'respect' | 'force' | 'ignore',
|
default: "respect" as "respect" | "force" | "ignore",
|
||||||
},
|
},
|
||||||
highlightSensitiveMedia: {
|
highlightSensitiveMedia: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: !window.matchMedia('(prefers-reduced-motion)').matches,
|
default: !window.matchMedia("(prefers-reduced-motion)").matches,
|
||||||
},
|
},
|
||||||
animatedMfm: {
|
animatedMfm: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: !window.matchMedia('(prefers-reduced-motion)').matches,
|
default: !window.matchMedia("(prefers-reduced-motion)").matches,
|
||||||
},
|
},
|
||||||
advancedMfm: {
|
advancedMfm: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
showReactionsCount: {
|
showReactionsCount: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
enableQuickAddMfmFunction: {
|
enableQuickAddMfmFunction: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
loadRawImages: {
|
loadRawImages: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
warnMissingAltText: {
|
warnMissingAltText: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
enableFaviconNotificationDot: {
|
enableFaviconNotificationDot: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
imageNewTab: {
|
imageNewTab: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
disableShowingAnimatedImages: {
|
disableShowingAnimatedImages: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: window.matchMedia('(prefers-reduced-motion)').matches,
|
default: window.matchMedia("(prefers-reduced-motion)").matches,
|
||||||
},
|
},
|
||||||
disableCatSpeak: {
|
disableCatSpeak: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
emojiStyle: {
|
emojiStyle: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'twemoji', // twemoji / fluentEmoji / native
|
default: "twemoji", // twemoji / fluentEmoji / native
|
||||||
},
|
},
|
||||||
menuStyle: {
|
menuStyle: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'auto' as 'auto' | 'popup' | 'drawer',
|
default: "auto" as "auto" | "popup" | "drawer",
|
||||||
},
|
},
|
||||||
useBlurEffectForModal: {
|
useBlurEffectForModal: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: DEFAULT_DEVICE_KIND === 'desktop',
|
default: DEFAULT_DEVICE_KIND === "desktop",
|
||||||
},
|
},
|
||||||
useBlurEffect: {
|
useBlurEffect: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: DEFAULT_DEVICE_KIND === 'desktop',
|
default: DEFAULT_DEVICE_KIND === "desktop",
|
||||||
},
|
},
|
||||||
showFixedPostForm: {
|
showFixedPostForm: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
showFixedPostFormInChannel: {
|
showFixedPostFormInChannel: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
showTickerOnReplies: {
|
showTickerOnReplies: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
searchEngine: {
|
searchEngine: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: Object.keys(searchEngineMap)[0],
|
default: Object.keys(searchEngineMap)[0],
|
||||||
},
|
},
|
||||||
noteDesign: {
|
noteDesign: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'sharkey' as 'sharkey' | 'misskey',
|
default: "sharkey" as "sharkey" | "misskey",
|
||||||
},
|
},
|
||||||
enableInfiniteScroll: {
|
enableInfiniteScroll: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
useReactionPickerForContextMenu: {
|
useReactionPickerForContextMenu: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
showGapBetweenNotesInTimeline: {
|
showGapBetweenNotesInTimeline: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
darkMode: {
|
darkMode: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
instanceTicker: {
|
instanceTicker: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'remote' as 'none' | 'remote' | 'always',
|
default: "remote" as "none" | "remote" | "always",
|
||||||
},
|
},
|
||||||
emojiPickerScale: {
|
emojiPickerScale: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 1,
|
default: 1,
|
||||||
},
|
},
|
||||||
emojiPickerWidth: {
|
emojiPickerWidth: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 1,
|
default: 1,
|
||||||
},
|
},
|
||||||
emojiPickerHeight: {
|
emojiPickerHeight: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 2,
|
default: 2,
|
||||||
},
|
},
|
||||||
emojiPickerStyle: {
|
emojiPickerStyle: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'auto' as 'auto' | 'popup' | 'drawer',
|
default: "auto" as "auto" | "popup" | "drawer",
|
||||||
},
|
},
|
||||||
recentlyUsedEmojis: {
|
recentlyUsedEmojis: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: [] as string[],
|
default: [] as string[],
|
||||||
},
|
},
|
||||||
recentlyUsedUsers: {
|
recentlyUsedUsers: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: [] as string[],
|
default: [] as string[],
|
||||||
},
|
},
|
||||||
defaultSideView: {
|
defaultSideView: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
menuDisplay: {
|
menuDisplay: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'sideFull' as 'sideFull' | 'sideIcon' | 'top',
|
default: "sideFull" as "sideFull" | "sideIcon" | "top",
|
||||||
},
|
},
|
||||||
reportError: {
|
reportError: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
squareAvatars: {
|
squareAvatars: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
showAvatarDecorations: {
|
showAvatarDecorations: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
postFormWithHashtags: {
|
postFormWithHashtags: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
postFormHashtags: {
|
postFormHashtags: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: '',
|
default: "",
|
||||||
},
|
},
|
||||||
themeInitial: {
|
themeInitial: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
numberOfPageCache: {
|
numberOfPageCache: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 3,
|
default: 3,
|
||||||
},
|
},
|
||||||
numberOfReplies: {
|
numberOfReplies: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 5,
|
default: 5,
|
||||||
},
|
},
|
||||||
showNoteActionsOnlyHover: {
|
showNoteActionsOnlyHover: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
showClipButtonInNoteFooter: {
|
showClipButtonInNoteFooter: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
reactionsDisplaySize: {
|
reactionsDisplaySize: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'medium' as 'small' | 'medium' | 'large',
|
default: "medium" as "small" | "medium" | "large",
|
||||||
},
|
},
|
||||||
limitWidthOfReaction: {
|
limitWidthOfReaction: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
forceShowAds: {
|
forceShowAds: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
oneko: {
|
oneko: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
clickToOpen: {
|
clickToOpen: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
aiChanMode: {
|
aiChanMode: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
devMode: {
|
devMode: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
mediaListWithOneImageAppearance: {
|
mediaListWithOneImageAppearance: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'expand' as 'expand' | '16_9' | '1_1' | '2_3',
|
default: "expand" as "expand" | "16_9" | "1_1" | "2_3",
|
||||||
},
|
},
|
||||||
notificationPosition: {
|
notificationPosition: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'rightBottom' as 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom',
|
default: "rightBottom" as
|
||||||
|
| "leftTop"
|
||||||
|
| "leftBottom"
|
||||||
|
| "rightTop"
|
||||||
|
| "rightBottom",
|
||||||
},
|
},
|
||||||
notificationStackAxis: {
|
notificationStackAxis: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'horizontal' as 'vertical' | 'horizontal',
|
default: "horizontal" as "vertical" | "horizontal",
|
||||||
},
|
},
|
||||||
notificationClickable: {
|
notificationClickable: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
enableCondensedLine: {
|
enableCondensedLine: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
additionalUnicodeEmojiIndexes: {
|
additionalUnicodeEmojiIndexes: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: {} as Record<string, Record<string, string[]>>,
|
default: {} as Record<string, Record<string, string[]>>,
|
||||||
},
|
},
|
||||||
keepScreenOn: {
|
keepScreenOn: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
defaultWithReplies: {
|
defaultWithReplies: {
|
||||||
where: 'account',
|
where: "account",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
disableStreamingTimeline: {
|
disableStreamingTimeline: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
useGroupedNotifications: {
|
useGroupedNotifications: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
dataSaver: {
|
dataSaver: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: {
|
default: {
|
||||||
media: false,
|
media: false,
|
||||||
avatar: false,
|
avatar: false,
|
||||||
|
@ -519,82 +537,83 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||||
} as Record<string, boolean>,
|
} as Record<string, boolean>,
|
||||||
},
|
},
|
||||||
enableSeasonalScreenEffect: {
|
enableSeasonalScreenEffect: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
dropAndFusion: {
|
dropAndFusion: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: {
|
default: {
|
||||||
bgmVolume: 0.25,
|
bgmVolume: 0.25,
|
||||||
sfxVolume: 1,
|
sfxVolume: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hemisphere: {
|
hemisphere: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: hemisphere as 'N' | 'S',
|
default: hemisphere as "N" | "S",
|
||||||
},
|
},
|
||||||
enableHorizontalSwipe: {
|
enableHorizontalSwipe: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
useNativeUIForVideoAudioPlayer: {
|
useNativeUIForVideoAudioPlayer: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
keepOriginalFilename: {
|
keepOriginalFilename: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
alwaysConfirmFollow: {
|
alwaysConfirmFollow: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
confirmWhenRevealingSensitiveMedia: {
|
confirmWhenRevealingSensitiveMedia: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
contextMenu: {
|
contextMenu: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 'app' as 'app' | 'appWithShift' | 'native',
|
default: "app" as "app" | "appWithShift" | "native",
|
||||||
},
|
},
|
||||||
skipNoteRender: {
|
skipNoteRender: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
sound_masterVolume: {
|
sound_masterVolume: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: 0.3,
|
default: 0.3,
|
||||||
},
|
},
|
||||||
sound_notUseSound: {
|
sound_notUseSound: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
sound_useSoundOnlyWhenActive: {
|
sound_useSoundOnlyWhenActive: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
sound_note: {
|
sound_note: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: { type: 'syuilo/n-aec', volume: 0 } as SoundStore,
|
default: { type: "syuilo/n-aec", volume: 0 } as SoundStore,
|
||||||
},
|
},
|
||||||
sound_noteMy: {
|
sound_noteMy: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: { type: 'syuilo/n-cea-4va', volume: 1 } as SoundStore,
|
default: { type: "syuilo/n-cea-4va", volume: 1 } as SoundStore,
|
||||||
},
|
},
|
||||||
sound_notification: {
|
sound_notification: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: { type: 'syuilo/n-ea', volume: 1 } as SoundStore,
|
default: { type: "syuilo/n-ea", volume: 1 } as SoundStore,
|
||||||
},
|
},
|
||||||
sound_reaction: {
|
sound_reaction: {
|
||||||
where: 'device',
|
where: "device",
|
||||||
default: { type: 'syuilo/bubble2', volume: 1 } as SoundStore,
|
default: { type: "syuilo/bubble2", volume: 1 } as SoundStore,
|
||||||
},
|
},
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: 他のタブと永続化されたstateを同期
|
// TODO: 他のタブと永続化されたstateを同期
|
||||||
|
|
||||||
const PREFIX = 'miux:' as const;
|
const PREFIX = "miux:" as const;
|
||||||
|
|
||||||
export type Plugin = {
|
export type Plugin = {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -630,7 +649,9 @@ export class ColdDeviceStorage {
|
||||||
|
|
||||||
public static watchers: Watcher[] = [];
|
public static watchers: Watcher[] = [];
|
||||||
|
|
||||||
public static get<T extends keyof typeof ColdDeviceStorage.default>(key: T): typeof ColdDeviceStorage.default[T] {
|
public static get<T extends keyof typeof ColdDeviceStorage.default>(
|
||||||
|
key: T,
|
||||||
|
): (typeof ColdDeviceStorage.default)[T] {
|
||||||
// TODO: indexedDBにする
|
// TODO: indexedDBにする
|
||||||
// ただしその際はnullチェックではなくキー存在チェックにしないとダメ
|
// ただしその際はnullチェックではなくキー存在チェックにしないとダメ
|
||||||
// (indexedDBはnullを保存できるため、ユーザーが意図してnullを格納した可能性がある)
|
// (indexedDBはnullを保存できるため、ユーザーが意図してnullを格納した可能性がある)
|
||||||
|
@ -643,7 +664,9 @@ export class ColdDeviceStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getAll(): Partial<typeof this.default> {
|
public static getAll(): Partial<typeof this.default> {
|
||||||
return (Object.keys(this.default) as (keyof typeof this.default)[]).reduce<Partial<typeof this.default>>((acc, key) => {
|
return (Object.keys(this.default) as (keyof typeof this.default)[]).reduce<
|
||||||
|
Partial<typeof this.default>
|
||||||
|
>((acc, key) => {
|
||||||
const value = localStorage.getItem(PREFIX + key);
|
const value = localStorage.getItem(PREFIX + key);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
acc[key] = JSON.parse(value);
|
acc[key] = JSON.parse(value);
|
||||||
|
@ -652,7 +675,10 @@ export class ColdDeviceStorage {
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static set<T extends keyof typeof ColdDeviceStorage.default>(key: T, value: typeof ColdDeviceStorage.default[T]): void {
|
public static set<T extends keyof typeof ColdDeviceStorage.default>(
|
||||||
|
key: T,
|
||||||
|
value: (typeof ColdDeviceStorage.default)[T],
|
||||||
|
): void {
|
||||||
// 呼び出し側のバグ等で undefined が来ることがある
|
// 呼び出し側のバグ等で undefined が来ることがある
|
||||||
// undefined を文字列として miLocalStorage に入れると参照する際の JSON.parse でコケて不具合の元になるため無視
|
// undefined を文字列として miLocalStorage に入れると参照する際の JSON.parse でコケて不具合の元になるため無視
|
||||||
|
|
||||||
|
@ -677,7 +703,7 @@ export class ColdDeviceStorage {
|
||||||
const v = ColdDeviceStorage.get(key);
|
const v = ColdDeviceStorage.get(key);
|
||||||
const r = ref(v);
|
const r = ref(v);
|
||||||
// TODO: このままではwatcherがリークするので開放する方法を考える
|
// TODO: このままではwatcherがリークするので開放する方法を考える
|
||||||
this.watch(key, v => {
|
this.watch(key, (v) => {
|
||||||
r.value = v;
|
r.value = v;
|
||||||
});
|
});
|
||||||
return r;
|
return r;
|
||||||
|
@ -687,14 +713,16 @@ export class ColdDeviceStorage {
|
||||||
* 特定のキーの、簡易的なgetter/setterを作ります
|
* 特定のキーの、簡易的なgetter/setterを作ります
|
||||||
* 主にvue場で設定コントロールのmodelとして使う用
|
* 主にvue場で設定コントロールのmodelとして使う用
|
||||||
*/
|
*/
|
||||||
public static makeGetterSetter<K extends keyof typeof ColdDeviceStorage.default>(key: K) {
|
public static makeGetterSetter<
|
||||||
|
K extends keyof typeof ColdDeviceStorage.default,
|
||||||
|
>(key: K) {
|
||||||
// TODO: VueのcustomRef使うと良い感じになるかも
|
// TODO: VueのcustomRef使うと良い感じになるかも
|
||||||
const valueRef = ColdDeviceStorage.ref(key);
|
const valueRef = ColdDeviceStorage.ref(key);
|
||||||
return {
|
return {
|
||||||
get: () => {
|
get: () => {
|
||||||
return valueRef.value;
|
return valueRef.value;
|
||||||
},
|
},
|
||||||
set: (value: typeof ColdDeviceStorage.default[K]) => {
|
set: (value: (typeof ColdDeviceStorage.default)[K]) => {
|
||||||
const val = value;
|
const val = value;
|
||||||
ColdDeviceStorage.set(key, val);
|
ColdDeviceStorage.set(key, val);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue