diff --git a/apps/web/src/atoms/settings.ts b/apps/web/src/atoms/settings.ts index ca07ad5086..de76f23f74 100644 --- a/apps/web/src/atoms/settings.ts +++ b/apps/web/src/atoms/settings.ts @@ -1,6 +1,5 @@ -import { useAtom } from 'jotai'; +import { atom, useAtom } from 'jotai'; import { atomWithStorage } from 'jotai/utils'; -import { useCallback } from 'react'; export type DateFormats = | 'MM/dd/YYYY' @@ -15,7 +14,7 @@ export type AppSetting = { clientBorder: boolean; fullWidthLayout: boolean; windowFrameStyle: 'frameless' | 'NativeTitleBar'; - fontStyle: 'Sans' | 'Serif' | 'Mono'; + fontStyle: FontFamily; dateFormat: DateFormats; startWeekOnMonday: boolean; enableBlurBackground: boolean; @@ -38,16 +37,18 @@ export const dateFormatOptions: DateFormats[] = [ 'dd MMMM YYYY', ]; -export const fontStyleOptions: { - key: AppSetting['fontStyle']; - value: string; -}[] = [ +export type FontFamily = 'Sans' | 'Serif' | 'Mono'; + +export const fontStyleOptions = [ { key: 'Sans', value: 'var(--affine-font-sans-family)' }, { key: 'Serif', value: 'var(--affine-font-serif-family)' }, { key: 'Mono', value: 'var(--affine-font-mono-family)' }, -]; +] satisfies { + key: FontFamily; + value: string; +}[]; -export const AppSettingAtom = atomWithStorage('AFFiNE settings', { +const appSettingBaseAtom = atomWithStorage('affine-settings', { clientBorder: false, fullWidthLayout: false, windowFrameStyle: 'frameless', @@ -60,19 +61,21 @@ export const AppSettingAtom = atomWithStorage('AFFiNE settings', { autoDownloadUpdate: true, }); -export const useAppSetting = () => { - const [settings, setSettings] = useAtom(AppSettingAtom); +type SetStateAction = Value | ((prev: Value) => Value); - return [ - settings, - useCallback( - (patch: Partial) => { - setSettings((prev: AppSetting) => ({ - ...prev, - ...patch, - })); - }, - [setSettings] - ), - ] as const; +const appSettingAtom = atom< + AppSetting, + [SetStateAction>], + void +>( + get => get(appSettingBaseAtom), + (get, set, apply) => { + const prev = get(appSettingBaseAtom); + const next = typeof apply === 'function' ? apply(prev) : apply; + set(appSettingBaseAtom, { ...prev, ...next }); + } +); + +export const useAppSetting = () => { + return useAtom(appSettingAtom); }; diff --git a/apps/web/src/components/affine/setting-modal/general-setting/appearance/index.tsx b/apps/web/src/components/affine/setting-modal/general-setting/appearance/index.tsx index acf00e88b6..69e89218d1 100644 --- a/apps/web/src/components/affine/setting-modal/general-setting/appearance/index.tsx +++ b/apps/web/src/components/affine/setting-modal/general-setting/appearance/index.tsx @@ -58,14 +58,7 @@ const FontFamilySettings = () => { defaultValue={appSettings.fontStyle} onValueChange={useCallback( (key: AppSetting['fontStyle']) => { - const value = fontStyleOptions.find(option => option.key === key) - ?.value; - setAppSettings({ fontStyle: key }); - - document - .querySelector('html') - ?.style.setProperty('--affine-font-family', value || null); }, [setAppSettings] )} diff --git a/apps/web/src/components/page-detail-editor.tsx b/apps/web/src/components/page-detail-editor.tsx index a99bacc763..773b39fc96 100644 --- a/apps/web/src/components/page-detail-editor.tsx +++ b/apps/web/src/components/page-detail-editor.tsx @@ -21,13 +21,13 @@ import type { PluginBlockSuiteAdapter } from '@toeverything/plugin-infra/type'; import clsx from 'clsx'; import { useAtomValue, useSetAtom } from 'jotai'; import Head from 'next/head'; -import type { FC, ReactElement } from 'react'; -import React, { memo, Suspense, useCallback, useMemo } from 'react'; +import type { CSSProperties, FC, ReactElement } from 'react'; +import { memo, Suspense, useCallback, useMemo } from 'react'; import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels'; import { pageSettingFamily } from '../atoms'; import { contentLayoutAtom } from '../atoms/layout'; -import { useAppSetting } from '../atoms/settings'; +import { fontStyleOptions, useAppSetting } from '../atoms/settings'; import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor'; import { editor } from './page-detail-editor.css'; import { pluginContainer } from './page-detail-editor.css'; @@ -69,12 +69,24 @@ const EditorWrapper = memo(function EditorWrapper({ const [appSettings] = useAppSetting(); assertExists(meta); + const value = useMemo(() => { + const fontStyle = fontStyleOptions.find( + option => option.key === appSettings.fontStyle + ); + assertExists(fontStyle); + return fontStyle.value; + }, [appSettings.fontStyle]); return ( { return ( - + ); };