このコミットが含まれているのは:
@@ -212,6 +212,15 @@ const LEGACY_GEKANATOR_BACKGROUND_MOTION_STORAGE_KEY =
|
||||
const LEGACY_MIGRATED_THEME_ID = 'custom:legacy-migrated'
|
||||
|
||||
|
||||
const createCustomThemeId = (): `custom:${ string }` => {
|
||||
const randomPart =
|
||||
globalThis.crypto?.randomUUID?.()
|
||||
?? `${ Date.now ().toString (36) }-${ Math.random ().toString (36).slice (2) }`
|
||||
|
||||
return `custom:${ randomPart }`
|
||||
}
|
||||
|
||||
|
||||
export const fetchUserSettings = async (): Promise<UserSettings> => {
|
||||
const raw = await apiGet<{
|
||||
theme: UserSettings['theme']
|
||||
@@ -567,7 +576,7 @@ export const createCustomThemeFromBase = (
|
||||
baseTheme: BuiltinThemeId,
|
||||
tokens?: ThemeTokens,
|
||||
): CustomClientTheme => {
|
||||
const id = `custom:${ crypto.randomUUID () }` as ThemeId
|
||||
const id = createCustomThemeId ()
|
||||
return {
|
||||
id,
|
||||
name: themeCopyName (baseTheme),
|
||||
|
||||
@@ -71,6 +71,7 @@ type SharedSectionProps = {
|
||||
selectedTheme: ClientTheme
|
||||
draftTagColours: ThemeTagColours
|
||||
onThemeChange: (themeId: ActiveThemeId) => void
|
||||
onEnsureEditableTheme: () => void
|
||||
onTagColourChange: (category: Category, colour: string) => void
|
||||
onResetAllTagColours: () => void
|
||||
onResetTagColour: (category: Category) => void
|
||||
@@ -252,6 +253,7 @@ const ThemeSection: FC<SharedSectionProps> = ({
|
||||
draftCustomThemes,
|
||||
selectedTheme,
|
||||
draftTagColours,
|
||||
onEnsureEditableTheme,
|
||||
onResetAllTagColours,
|
||||
onResetTagColour,
|
||||
onTagColourChange,
|
||||
@@ -331,6 +333,8 @@ const ThemeSection: FC<SharedSectionProps> = ({
|
||||
<input
|
||||
type="color"
|
||||
value={draftTagColours[category]}
|
||||
onPointerDown={onEnsureEditableTheme}
|
||||
onFocus={onEnsureEditableTheme}
|
||||
onChange={ev => onTagColourChange (category, ev.target.value)}
|
||||
className="h-10 w-16 cursor-pointer rounded border border-border
|
||||
bg-transparent p-1"/>
|
||||
@@ -514,6 +518,21 @@ const SettingPage: FC<Props> = ({ user, setUser }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleEnsureEditableTheme = (): {
|
||||
activeThemeId: ActiveThemeId
|
||||
customThemes: Record<string, CustomClientTheme>
|
||||
} => {
|
||||
const editable = ensureEditableCustomTheme ()
|
||||
|
||||
if (editable.activeThemeId !== draftActiveThemeId
|
||||
|| editable.customThemes !== draftCustomThemes)
|
||||
{
|
||||
applyDraftThemeSelection (editable.activeThemeId, editable.customThemes)
|
||||
}
|
||||
|
||||
return editable
|
||||
}
|
||||
|
||||
const handleTabKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {
|
||||
const currentIndex = tabs.findIndex (tab => tab.id === activeTab)
|
||||
|
||||
@@ -677,8 +696,11 @@ const SettingPage: FC<Props> = ({ user, setUser }) => {
|
||||
onThemeChange: themeId => {
|
||||
applyDraftThemeSelection (themeId, draftCustomThemes)
|
||||
},
|
||||
onEnsureEditableTheme: () => {
|
||||
handleEnsureEditableTheme ()
|
||||
},
|
||||
onTagColourChange: (category, colour) => {
|
||||
const editable = ensureEditableCustomTheme ()
|
||||
const editable = handleEnsureEditableTheme ()
|
||||
const editableTheme = editable.customThemes[editable.activeThemeId]
|
||||
const nextCustomThemes = {
|
||||
...editable.customThemes,
|
||||
|
||||
新しい課題から参照
ユーザをブロックする