このコミットが含まれているのは:
+135
-1
@@ -51,6 +51,9 @@ export type CustomClientTheme =
|
||||
export type TheatreLayoutMode = 'threeColumns' | 'tagsBottom' | 'commentsBottom'
|
||||
export type TheatreTagFlow = 'vertical' | 'horizontal'
|
||||
export type GekanatorBackgroundMotionMode = 'on' | 'calm' | 'off'
|
||||
export type ClientAnimationMode = 'normal' | 'reduced' | 'off'
|
||||
export type ClientEmbedAutoLoadMode = 'auto' | 'manual' | 'off'
|
||||
export type ClientThumbnailMode = 'normal' | 'light' | 'off'
|
||||
export type ClientPaneBreakpoint = 'desktop' | 'tablet'
|
||||
export type ClientListKey = 'postList' | 'postSearch' | 'tagList'
|
||||
export type ClientListLimit = 20 | 50 | 100
|
||||
@@ -75,6 +78,12 @@ export type ClientAppearanceSettings = {
|
||||
theme?: UserSettings['theme']
|
||||
tagColours?: Partial<ThemeTagColours> }
|
||||
|
||||
export type ClientBehaviorSettings = {
|
||||
animation?: ClientAnimationMode
|
||||
embedAutoLoad?: ClientEmbedAutoLoadMode
|
||||
thumbnailMode?: ClientThumbnailMode
|
||||
}
|
||||
|
||||
// DB-backed settings. At present only `theme` is surfaced in `/users/settings`.
|
||||
// The remaining fields are retained for existing backend work and are not wired
|
||||
// to the common settings UI yet.
|
||||
@@ -87,6 +96,7 @@ export const DEFAULT_USER_SETTINGS: UserSettings = {
|
||||
// Browser-local settings only. These are device or screen specific.
|
||||
export type ClientSettings = {
|
||||
appearance?: ClientAppearanceSettings
|
||||
behavior?: ClientBehaviorSettings
|
||||
keyboard?: ClientKeyboardSettings
|
||||
panes?: Record<string, ClientPaneSettings>
|
||||
lists?: Partial<Record<ClientListKey, ClientListSettings>>
|
||||
@@ -303,6 +313,25 @@ const validListLimit = (value: unknown): ClientListLimit | null =>
|
||||
value === 20 || value === 50 || value === 100 ? value : null
|
||||
|
||||
|
||||
const normaliseAnimationMode = (value: unknown): ClientAnimationMode | null => {
|
||||
if (value === 'normal' || value === 'reduced' || value === 'off')
|
||||
return value
|
||||
if (value === 'true')
|
||||
return 'reduced'
|
||||
if (value === 'false')
|
||||
return 'normal'
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
const normaliseEmbedAutoLoadMode = (value: unknown): ClientEmbedAutoLoadMode | null =>
|
||||
value === 'auto' || value === 'manual' || value === 'off' ? value : null
|
||||
|
||||
|
||||
const normaliseThumbnailMode = (value: unknown): ClientThumbnailMode | null =>
|
||||
value === 'normal' || value === 'light' || value === 'off' ? value : null
|
||||
|
||||
|
||||
const normaliseKeyboardBindings = (
|
||||
bindings: unknown,
|
||||
): Partial<Record<ShortcutActionId, KeyBinding | null>> => {
|
||||
@@ -341,6 +370,110 @@ export const getClientKeyboardSettings = (): ClientKeyboardSettings => {
|
||||
}
|
||||
|
||||
|
||||
const legacyAnimationMode = (): ClientAnimationMode | null =>
|
||||
normaliseAnimationMode (loadClientSettings ().reducedMotion)
|
||||
|
||||
|
||||
const legacyEmbedAutoLoadMode = (): ClientEmbedAutoLoadMode | null =>
|
||||
normaliseEmbedAutoLoadMode (loadClientSettings ().embedAutoLoad)
|
||||
|
||||
|
||||
const legacyThumbnailMode = (): ClientThumbnailMode | null =>
|
||||
normaliseThumbnailMode (loadClientSettings ().thumbnailMode)
|
||||
|
||||
|
||||
export const getClientAnimationMode = (): ClientAnimationMode =>
|
||||
loadClientSettings ().behavior?.animation
|
||||
?? legacyAnimationMode ()
|
||||
?? 'normal'
|
||||
|
||||
|
||||
export const applyClientAnimationMode = (mode: ClientAnimationMode): void => {
|
||||
if (typeof document === 'undefined')
|
||||
return
|
||||
|
||||
if (mode === 'normal')
|
||||
{
|
||||
delete document.documentElement.dataset.animation
|
||||
return
|
||||
}
|
||||
|
||||
document.documentElement.dataset.animation = mode
|
||||
}
|
||||
|
||||
|
||||
export const setClientAnimationMode = (
|
||||
animation: ClientAnimationMode,
|
||||
): ClientBehaviorSettings =>
|
||||
setClientBehaviorSettings ({
|
||||
...getClientBehaviorSettings (),
|
||||
animation,
|
||||
})
|
||||
|
||||
export const getClientEmbedAutoLoadMode = (): ClientEmbedAutoLoadMode =>
|
||||
loadClientSettings ().behavior?.embedAutoLoad
|
||||
?? legacyEmbedAutoLoadMode ()
|
||||
?? 'auto'
|
||||
|
||||
|
||||
export const setClientEmbedAutoLoadMode = (
|
||||
embedAutoLoad: ClientEmbedAutoLoadMode,
|
||||
): ClientBehaviorSettings =>
|
||||
setClientBehaviorSettings ({
|
||||
...getClientBehaviorSettings (),
|
||||
embedAutoLoad,
|
||||
})
|
||||
|
||||
|
||||
export const getClientThumbnailMode = (): ClientThumbnailMode =>
|
||||
loadClientSettings ().behavior?.thumbnailMode
|
||||
?? legacyThumbnailMode ()
|
||||
?? 'normal'
|
||||
|
||||
|
||||
export const setClientThumbnailMode = (
|
||||
thumbnailMode: ClientThumbnailMode,
|
||||
): ClientBehaviorSettings =>
|
||||
setClientBehaviorSettings ({
|
||||
...getClientBehaviorSettings (),
|
||||
thumbnailMode,
|
||||
})
|
||||
|
||||
|
||||
export const getClientBehaviorSettings = (): ClientBehaviorSettings => ({
|
||||
animation: getClientAnimationMode (),
|
||||
embedAutoLoad: getClientEmbedAutoLoadMode (),
|
||||
thumbnailMode: getClientThumbnailMode (),
|
||||
})
|
||||
|
||||
|
||||
export const setClientBehaviorSettings = (
|
||||
behavior: ClientBehaviorSettings,
|
||||
): ClientBehaviorSettings => {
|
||||
const next: ClientBehaviorSettings = {
|
||||
animation: (
|
||||
normaliseAnimationMode (behavior.animation)
|
||||
?? getClientAnimationMode ()
|
||||
),
|
||||
embedAutoLoad: (
|
||||
normaliseEmbedAutoLoadMode (behavior.embedAutoLoad)
|
||||
?? getClientEmbedAutoLoadMode ()
|
||||
),
|
||||
thumbnailMode: (
|
||||
normaliseThumbnailMode (behavior.thumbnailMode)
|
||||
?? getClientThumbnailMode ()
|
||||
),
|
||||
}
|
||||
|
||||
updateClientSettings (settings => ({
|
||||
...settings,
|
||||
behavior: next,
|
||||
}))
|
||||
applyClientAnimationMode (next.animation ?? 'normal')
|
||||
return next
|
||||
}
|
||||
|
||||
|
||||
export const setClientKeyboardSettings = (
|
||||
keyboard: ClientKeyboardSettings,
|
||||
): ClientKeyboardSettings => {
|
||||
@@ -921,7 +1054,8 @@ export const setClientGekanatorBackgroundMotion = (
|
||||
): void => {
|
||||
updateClientSettings (settings => ({
|
||||
...settings,
|
||||
gekanator: { ...(settings.gekanator ?? { }), backgroundMotion } }))
|
||||
gekanator: { ...(settings.gekanator ?? { }), backgroundMotion },
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
|
||||
新しい課題から参照
ユーザをブロックする