このコミットが含まれているのは:
@@ -1,7 +1,9 @@
|
||||
import { CATEGORIES } from '@/consts'
|
||||
import { apiGet, apiPatch } from '@/lib/api'
|
||||
import { DEFAULT_KEY_BINDINGS, normaliseKeyBinding } from '@/lib/keyboardShortcuts'
|
||||
|
||||
import type { Category, FetchPostsOrder, FetchTagsOrder } from '@/types'
|
||||
import type { KeyBinding, ShortcutActionId } from '@/lib/keyboardShortcuts'
|
||||
|
||||
export type UserSettings = {
|
||||
theme: 'system' | 'light' | 'dark'
|
||||
@@ -61,6 +63,11 @@ type ClientListSettings = {
|
||||
limit?: ClientListLimit
|
||||
order?: string }
|
||||
|
||||
export type ClientKeyboardSettings = {
|
||||
enabled?: boolean
|
||||
bindings?: Partial<Record<ShortcutActionId, KeyBinding | null>>
|
||||
}
|
||||
|
||||
export type ClientAppearanceSettings = {
|
||||
activeThemeId?: ActiveThemeId
|
||||
customThemes?: Record<string, CustomClientTheme>
|
||||
@@ -80,6 +87,7 @@ export const DEFAULT_USER_SETTINGS: UserSettings = {
|
||||
// Browser-local settings only. These are device or screen specific.
|
||||
export type ClientSettings = {
|
||||
appearance?: ClientAppearanceSettings
|
||||
keyboard?: ClientKeyboardSettings
|
||||
panes?: Record<string, ClientPaneSettings>
|
||||
lists?: Partial<Record<ClientListKey, ClientListSettings>>
|
||||
theatre?: {
|
||||
@@ -295,6 +303,118 @@ const validListLimit = (value: unknown): ClientListLimit | null =>
|
||||
value === 20 || value === 50 || value === 100 ? value : null
|
||||
|
||||
|
||||
const normaliseKeyboardBindings = (
|
||||
bindings: unknown,
|
||||
): Partial<Record<ShortcutActionId, KeyBinding | null>> => {
|
||||
if (!(bindings) || typeof bindings !== 'object')
|
||||
return { }
|
||||
|
||||
return Object.keys (DEFAULT_KEY_BINDINGS).reduce<
|
||||
Partial<Record<ShortcutActionId, KeyBinding | null>>
|
||||
> (
|
||||
(normalised, actionId) => {
|
||||
const value = (bindings as Record<string, unknown>)[actionId]
|
||||
if (value === null)
|
||||
{
|
||||
normalised[actionId as ShortcutActionId] = null
|
||||
return normalised
|
||||
}
|
||||
|
||||
const binding = normaliseKeyBinding (value)
|
||||
if (binding != null)
|
||||
normalised[actionId as ShortcutActionId] = binding
|
||||
|
||||
return normalised
|
||||
},
|
||||
{ },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export const getClientKeyboardSettings = (): ClientKeyboardSettings => {
|
||||
const keyboard = loadClientSettings ().keyboard
|
||||
|
||||
return {
|
||||
enabled: keyboard?.enabled !== false,
|
||||
bindings: normaliseKeyboardBindings (keyboard?.bindings),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const setClientKeyboardSettings = (
|
||||
keyboard: ClientKeyboardSettings,
|
||||
): ClientKeyboardSettings => {
|
||||
const next: ClientKeyboardSettings = {
|
||||
enabled: keyboard.enabled !== false,
|
||||
bindings: normaliseKeyboardBindings (keyboard.bindings),
|
||||
}
|
||||
|
||||
updateClientSettings (settings => ({
|
||||
...settings,
|
||||
keyboard: next,
|
||||
}))
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
|
||||
export const getEffectiveKeyBindings = (
|
||||
bindings: Partial<Record<ShortcutActionId, KeyBinding | null>> =
|
||||
getClientKeyboardSettings ().bindings ?? { },
|
||||
): Record<ShortcutActionId, KeyBinding | null> =>
|
||||
Object.keys (DEFAULT_KEY_BINDINGS).reduce<Record<ShortcutActionId, KeyBinding | null>> (
|
||||
(effectiveBindings, actionId) => {
|
||||
const key = actionId as ShortcutActionId
|
||||
effectiveBindings[key] =
|
||||
Object.prototype.hasOwnProperty.call (bindings, key)
|
||||
? bindings[key] ?? null
|
||||
: DEFAULT_KEY_BINDINGS[key]
|
||||
return effectiveBindings
|
||||
},
|
||||
{ ...DEFAULT_KEY_BINDINGS },
|
||||
)
|
||||
|
||||
|
||||
export const setClientKeyBinding = (
|
||||
actionId: ShortcutActionId,
|
||||
binding: KeyBinding | null,
|
||||
): ClientKeyboardSettings => {
|
||||
const current = getClientKeyboardSettings ()
|
||||
|
||||
return setClientKeyboardSettings ({
|
||||
...current,
|
||||
bindings: {
|
||||
...(current.bindings ?? { }),
|
||||
[actionId]: binding,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const resetClientKeyBinding = (
|
||||
actionId: ShortcutActionId,
|
||||
): ClientKeyboardSettings => {
|
||||
const current = getClientKeyboardSettings ()
|
||||
const nextBindings = { ...(current.bindings ?? { }) }
|
||||
delete nextBindings[actionId]
|
||||
|
||||
return setClientKeyboardSettings ({
|
||||
...current,
|
||||
bindings: nextBindings,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const resetAllClientKeyBindings = (): ClientKeyboardSettings => {
|
||||
const current = getClientKeyboardSettings ()
|
||||
|
||||
return setClientKeyboardSettings ({
|
||||
...current,
|
||||
bindings: { },
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const normaliseHexColour = (value: string): string | null =>
|
||||
/^#[0-9a-fA-F]{6}$/.test (value) ? value.toLowerCase () : null
|
||||
|
||||
|
||||
新しい課題から参照
ユーザをブロックする