refactor(core): move fontFamily and fullWidthLayout to editor settings (#7988)

This commit is contained in:
JimmFly
2024-08-28 02:35:24 +00:00
parent 3e810eb043
commit 03b2cda845
13 changed files with 131 additions and 135 deletions

View File

@@ -19,10 +19,7 @@ export type DateFormats =
export type AppSetting = { export type AppSetting = {
clientBorder: boolean; clientBorder: boolean;
fullWidthLayout: boolean;
windowFrameStyle: 'frameless' | 'NativeTitleBar'; windowFrameStyle: 'frameless' | 'NativeTitleBar';
fontStyle: FontFamily;
customFontFamily: string;
dateFormat: DateFormats; dateFormat: DateFormats;
startWeekOnMonday: boolean; startWeekOnMonday: boolean;
enableBlurBackground: boolean; enableBlurBackground: boolean;
@@ -46,24 +43,9 @@ export const dateFormatOptions: DateFormats[] = [
'dd MMMM YYYY', 'dd MMMM YYYY',
]; ];
export type FontFamily = 'Sans' | 'Serif' | 'Mono' | 'Custom';
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)' },
{ key: 'Custom', value: 'var(--affine-font-sans-family)' },
] satisfies {
key: FontFamily;
value: string;
}[];
const appSettingBaseAtom = atomWithStorage<AppSetting>('affine-settings', { const appSettingBaseAtom = atomWithStorage<AppSetting>('affine-settings', {
clientBorder: environment.isDesktop && !environment.isWindows, clientBorder: environment.isDesktop && !environment.isWindows,
fullWidthLayout: false,
windowFrameStyle: 'frameless', windowFrameStyle: 'frameless',
fontStyle: 'Sans',
customFontFamily: '',
dateFormat: dateFormatOptions[0], dateFormat: dateFormatOptions[0],
startWeekOnMonday: false, startWeekOnMonday: false,
enableBlurBackground: true, enableBlurBackground: true,

View File

@@ -96,7 +96,7 @@ export const AFFINE_FLAGS = {
displayName: 'Editor Settings', displayName: 'Editor Settings',
description: 'Enables editor settings.', description: 'Enables editor settings.',
configurable: isCanaryBuild, configurable: isCanaryBuild,
defaultState: false, defaultState: isCanaryBuild,
}, },
} satisfies { [key in string]: FlagInfo }; } satisfies { [key in string]: FlagInfo };

View File

@@ -1,12 +1,12 @@
import type { useI18n } from '@affine/i18n'; import type { useI18n } from '@affine/i18n';
import { SettingsIcon } from '@blocksuite/icons/rc'; import { SettingsIcon } from '@blocksuite/icons/rc';
import type { AffineEditorContainer } from '@blocksuite/presets';
import { appSettingAtom } from '@toeverything/infra'; import { appSettingAtom } from '@toeverything/infra';
import type { createStore } from 'jotai'; import type { createStore } from 'jotai';
import type { useTheme } from 'next-themes'; import type { useTheme } from 'next-themes';
import type { useLanguageHelper } from '../hooks/affine/use-language-helper'; import type { useLanguageHelper } from '../hooks/affine/use-language-helper';
import { track } from '../mixpanel'; import { track } from '../mixpanel';
import type { EditorSettingService } from '../modules/editor-settting';
import { registerAffineCommand } from './registry'; import { registerAffineCommand } from './registry';
export function registerAffineSettingsCommands({ export function registerAffineSettingsCommands({
@@ -14,15 +14,20 @@ export function registerAffineSettingsCommands({
store, store,
theme, theme,
languageHelper, languageHelper,
editorSettingService,
}: { }: {
t: ReturnType<typeof useI18n>; t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>; store: ReturnType<typeof createStore>;
theme: ReturnType<typeof useTheme>; theme: ReturnType<typeof useTheme>;
languageHelper: ReturnType<typeof useLanguageHelper>; languageHelper: ReturnType<typeof useLanguageHelper>;
editor: AffineEditorContainer | null; editorSettingService: EditorSettingService;
}) { }) {
const unsubs: Array<() => void> = []; const unsubs: Array<() => void> = [];
const { onLanguageChange, languagesList, currentLanguage } = languageHelper; const { onLanguageChange, languagesList, currentLanguage } = languageHelper;
const updateSettings = editorSettingService.editorSetting.set.bind(
editorSettingService.editorSetting
);
const settings$ = editorSettingService.editorSetting.settings$;
// color modes // color modes
unsubs.push( unsubs.push(
@@ -91,18 +96,14 @@ export function registerAffineSettingsCommands({
]()}`, ]()}`,
category: 'affine:settings', category: 'affine:settings',
icon: <SettingsIcon />, icon: <SettingsIcon />,
preconditionStrategy: () => preconditionStrategy: () => settings$.value.fontFamily !== 'Sans',
store.get(appSettingAtom).fontStyle !== 'Sans',
run() { run() {
track.$.cmdk.settings.changeAppSetting({ track.$.cmdk.settings.changeAppSetting({
key: 'fontStyle', key: 'fontStyle',
value: 'Sans', value: 'Sans',
}); });
store.set(appSettingAtom, prev => ({ updateSettings('fontFamily', 'Sans');
...prev,
fontStyle: 'Sans',
}));
}, },
}) })
); );
@@ -115,18 +116,14 @@ export function registerAffineSettingsCommands({
]()}`, ]()}`,
category: 'affine:settings', category: 'affine:settings',
icon: <SettingsIcon />, icon: <SettingsIcon />,
preconditionStrategy: () => preconditionStrategy: () => settings$.value.fontFamily !== 'Serif',
store.get(appSettingAtom).fontStyle !== 'Serif',
run() { run() {
track.$.cmdk.settings.changeAppSetting({ track.$.cmdk.settings.changeAppSetting({
key: 'fontStyle', key: 'fontStyle',
value: 'Serif', value: 'Serif',
}); });
store.set(appSettingAtom, prev => ({ updateSettings('fontFamily', 'Serif');
...prev,
fontStyle: 'Serif',
}));
}, },
}) })
); );
@@ -139,18 +136,14 @@ export function registerAffineSettingsCommands({
]()}`, ]()}`,
category: 'affine:settings', category: 'affine:settings',
icon: <SettingsIcon />, icon: <SettingsIcon />,
preconditionStrategy: () => preconditionStrategy: () => settings$.value.fontFamily !== 'Mono',
store.get(appSettingAtom).fontStyle !== 'Mono',
run() { run() {
track.$.cmdk.settings.changeAppSetting({ track.$.cmdk.settings.changeAppSetting({
key: 'fontStyle', key: 'fontStyle',
value: 'Mono', value: 'Mono',
}); });
store.set(appSettingAtom, prev => ({ updateSettings('fontFamily', 'Mono');
...prev,
fontStyle: 'Mono',
}));
}, },
}) })
); );
@@ -209,7 +202,7 @@ export function registerAffineSettingsCommands({
id: `affine:change-full-width-layout`, id: `affine:change-full-width-layout`,
label: () => label: () =>
`${t['com.affine.cmdk.affine.full-width-layout.to']()} ${t[ `${t['com.affine.cmdk.affine.full-width-layout.to']()} ${t[
store.get(appSettingAtom).fullWidthLayout settings$.value.fullWidthLayout
? 'com.affine.cmdk.affine.switch-state.off' ? 'com.affine.cmdk.affine.switch-state.off'
: 'com.affine.cmdk.affine.switch-state.on' : 'com.affine.cmdk.affine.switch-state.on'
]()}`, ]()}`,
@@ -218,13 +211,9 @@ export function registerAffineSettingsCommands({
run() { run() {
track.$.cmdk.settings.changeAppSetting({ track.$.cmdk.settings.changeAppSetting({
key: 'fullWidthLayout', key: 'fullWidthLayout',
value: store.get(appSettingAtom).fullWidthLayout ? 'off' : 'on', value: settings$.value.fullWidthLayout ? 'off' : 'on',
}); });
updateSettings('fullWidthLayout', !settings$.value.fullWidthLayout);
store.set(appSettingAtom, prev => ({
...prev,
fullWidthLayout: !prev.fullWidthLayout,
}));
}, },
}) })
); );

View File

@@ -97,17 +97,6 @@ export const AppearanceSettings = () => {
/> />
</SettingRow> </SettingRow>
) : null} ) : null}
<SettingRow
name={t['com.affine.appearanceSettings.fullWidth.title']()}
desc={t['com.affine.appearanceSettings.fullWidth.description']()}
>
<Switch
data-testid="full-width-layout-trigger"
checked={appSettings.fullWidthLayout}
onChange={checked => updateSettings('fullWidthLayout', checked)}
/>
</SettingRow>
{runtimeConfig.enableNewSettingUnstableApi && environment.isDesktop ? ( {runtimeConfig.enableNewSettingUnstableApi && environment.isDesktop ? (
<SettingRow <SettingRow
name={t['com.affine.appearanceSettings.windowFrame.title']()} name={t['com.affine.appearanceSettings.windowFrame.title']()}

View File

@@ -13,19 +13,21 @@ import {
SettingRow, SettingRow,
SettingWrapper, SettingWrapper,
} from '@affine/component/setting-components'; } from '@affine/component/setting-components';
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper'; import {
EditorSettingService,
type FontFamily,
fontStyleOptions,
} from '@affine/core/modules/editor-settting';
import { import {
type FontData, type FontData,
SystemFontFamilyService, SystemFontFamilyService,
} from '@affine/core/modules/system-font-family'; } from '@affine/core/modules/system-font-family';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import { import {
type AppSetting,
type DocMode, type DocMode,
type FontFamily,
fontStyleOptions,
useLiveData, useLiveData,
useService, useService,
useServices,
} from '@toeverything/infra'; } from '@toeverything/infra';
import { import {
type ChangeEvent, type ChangeEvent,
@@ -43,7 +45,9 @@ import { menu, menuTrigger, searchInput, settingWrapper } from './style.css';
const FontFamilySettings = () => { const FontFamilySettings = () => {
const t = useI18n(); const t = useI18n();
const { appSettings, updateSettings } = useAppSettingHelper(); const { editorSettingService } = useServices({ EditorSettingService });
const settings = useLiveData(editorSettingService.editorSetting.settings$);
const getLabel = useCallback( const getLabel = useCallback(
(fontKey: FontFamily) => { (fontKey: FontFamily) => {
switch (fontKey) { switch (fontKey) {
@@ -70,8 +74,8 @@ const FontFamilySettings = () => {
} }
const label = getLabel(key); const label = getLabel(key);
let fontFamily = value; let fontFamily = value;
if (key === 'Custom' && appSettings.customFontFamily) { if (key === 'Custom' && settings.customFontFamily) {
fontFamily = `${appSettings.customFontFamily}, ${value}`; fontFamily = `${settings.customFontFamily}, ${value}`;
} }
return { return {
value: key, value: key,
@@ -83,20 +87,22 @@ const FontFamilySettings = () => {
} satisfies RadioItem; } satisfies RadioItem;
}) })
.filter(item => item !== null); .filter(item => item !== null);
}, [appSettings.customFontFamily, getLabel]); }, [getLabel, settings.customFontFamily]);
const handleFontFamilyChange = useCallback(
(value: FontFamily) => {
editorSettingService.editorSetting.set('fontFamily', value);
},
[editorSettingService.editorSetting]
);
return ( return (
<RadioGroup <RadioGroup
items={radioItems} items={radioItems}
value={appSettings.fontStyle} value={settings.fontFamily}
width={250} width={250}
className={settingWrapper} className={settingWrapper}
onChange={useCallback( onChange={handleFontFamilyChange}
(value: AppSetting['fontStyle']) => {
updateSettings('fontStyle', value);
},
[updateSettings]
)}
/> />
); );
}; };
@@ -211,15 +217,17 @@ const FontMenuItem = ({
const CustomFontFamilySettings = () => { const CustomFontFamilySettings = () => {
const t = useI18n(); const t = useI18n();
const { appSettings, updateSettings } = useAppSettingHelper(); const { editorSettingService } = useServices({ EditorSettingService });
const fontFamily = getFontFamily(appSettings.customFontFamily); const settings = useLiveData(editorSettingService.editorSetting.settings$);
const fontFamily = getFontFamily(settings.customFontFamily);
const onCustomFontFamilyChange = useCallback( const onCustomFontFamilyChange = useCallback(
(fontFamily: string) => { (fontFamily: string) => {
updateSettings('customFontFamily', fontFamily); editorSettingService.editorSetting.set('customFontFamily', fontFamily);
}, },
[updateSettings] [editorSettingService.editorSetting]
); );
if (appSettings.fontStyle !== 'Custom' || !environment.isDesktop) { if (settings.fontFamily !== 'Custom' || !environment.isDesktop) {
return null; return null;
} }
return ( return (
@@ -239,7 +247,7 @@ const CustomFontFamilySettings = () => {
}} }}
> >
<MenuTrigger className={menuTrigger} style={{ fontFamily }}> <MenuTrigger className={menuTrigger} style={{ fontFamily }}>
{appSettings.customFontFamily || 'Select a font'} {settings.customFontFamily || 'Select a font'}
</MenuTrigger> </MenuTrigger>
</Menu> </Menu>
</SettingRow> </SettingRow>
@@ -291,37 +299,6 @@ export const General = () => {
<FontFamilySettings /> <FontFamilySettings />
</SettingRow> </SettingRow>
<CustomFontFamilySettings /> <CustomFontFamilySettings />
<SettingRow
name={t[
'com.affine.settings.editorSettings.general.font-family.title'
]()}
desc={t[
'com.affine.settings.editorSettings.general.font-family.description'
]()}
>
<Menu items={<MenuItem>inter</MenuItem>}>
<MenuTrigger className={menuTrigger} disabled>
inter
</MenuTrigger>
</Menu>
</SettingRow>
<SettingRow
name={t['com.affine.settings.editorSettings.general.font-size.title']()}
desc={t[
'com.affine.settings.editorSettings.general.font-size.description'
]()}
>
<Menu
contentOptions={{
className: menu,
}}
items={<MenuItem>15</MenuItem>}
>
<MenuTrigger className={menuTrigger} disabled>
15
</MenuTrigger>
</Menu>
</SettingRow>
<SettingRow <SettingRow
name={t[ name={t[
'com.affine.settings.editorSettings.general.default-new-doc.title' 'com.affine.settings.editorSettings.general.default-new-doc.title'

View File

@@ -3,12 +3,35 @@ import {
SettingRow, SettingRow,
SettingWrapper, SettingWrapper,
} from '@affine/component/setting-components'; } from '@affine/component/setting-components';
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper'; import { EditorSettingService } from '@affine/core/modules/editor-settting';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { useCallback } from 'react';
export const Page = () => { export const Page = () => {
const t = useI18n(); const t = useI18n();
const { appSettings, updateSettings } = useAppSettingHelper(); const editorSetting = useService(EditorSettingService).editorSetting;
const settings = useLiveData(editorSetting.settings$);
const handleFullWidthLayoutChange = useCallback(
(checked: boolean) => {
editorSetting.set('fullWidthLayout', checked);
},
[editorSetting]
);
const handleDisplayDocInfoChange = useCallback(
(checked: boolean) => {
editorSetting.set('displayDocInfo', checked);
},
[editorSetting]
);
const handleDisplayBiDirectionalLinkChange = useCallback(
(checked: boolean) => {
editorSetting.set('displayBiDirectionalLink', checked);
},
[editorSetting]
);
return ( return (
<SettingWrapper title={t['com.affine.settings.editorSettings.page']()}> <SettingWrapper title={t['com.affine.settings.editorSettings.page']()}>
<SettingRow <SettingRow
@@ -19,8 +42,8 @@ export const Page = () => {
> >
<Switch <Switch
data-testid="full-width-layout-trigger" data-testid="full-width-layout-trigger"
checked={appSettings.fullWidthLayout} checked={settings.fullWidthLayout}
onChange={checked => updateSettings('fullWidthLayout', checked)} onChange={handleFullWidthLayoutChange}
/> />
</SettingRow> </SettingRow>
<SettingRow <SettingRow
@@ -31,7 +54,11 @@ export const Page = () => {
'com.affine.settings.editorSettings.page.display-doc-info.description' 'com.affine.settings.editorSettings.page.display-doc-info.description'
]()} ]()}
> >
<Switch /> <Switch
data-testid="display-doc-info-trigger"
checked={settings.displayDocInfo}
onChange={handleDisplayDocInfoChange}
/>
</SettingRow> </SettingRow>
<SettingRow <SettingRow
name={t[ name={t[
@@ -41,7 +68,11 @@ export const Page = () => {
'com.affine.settings.editorSettings.page.display-bi-link.description' 'com.affine.settings.editorSettings.page.display-bi-link.description'
]()} ]()}
> >
<Switch /> <Switch
data-testid="display-bi-link-trigger"
checked={settings.displayBiDirectionalLink}
onChange={handleDisplayBiDirectionalLinkChange}
/>
</SettingRow> </SettingRow>
</SettingWrapper> </SettingWrapper>
); );

View File

@@ -4,20 +4,18 @@ import { useDocCollectionPage } from '@affine/core/hooks/use-block-suite-workspa
import { DisposableGroup } from '@blocksuite/global/utils'; import { DisposableGroup } from '@blocksuite/global/utils';
import type { AffineEditorContainer } from '@blocksuite/presets'; import type { AffineEditorContainer } from '@blocksuite/presets';
import type { Doc as BlockSuiteDoc, DocCollection } from '@blocksuite/store'; import type { Doc as BlockSuiteDoc, DocCollection } from '@blocksuite/store';
import { import { type DocMode, useLiveData, useService } from '@toeverything/infra';
type DocMode,
fontStyleOptions,
useLiveData,
useService,
} from '@toeverything/infra';
import { cssVar } from '@toeverything/theme'; import { cssVar } from '@toeverything/theme';
import clsx from 'clsx'; import clsx from 'clsx';
import type { CSSProperties } from 'react'; import type { CSSProperties } from 'react';
import { memo, Suspense, useCallback, useMemo } from 'react'; import { memo, Suspense, useCallback, useMemo } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { useAppSettingHelper } from '../hooks/affine/use-app-setting-helper';
import { EditorService } from '../modules/editor'; import { EditorService } from '../modules/editor';
import {
EditorSettingService,
fontStyleOptions,
} from '../modules/editor-settting';
import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor'; import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor';
import * as styles from './page-detail-editor.css'; import * as styles from './page-detail-editor.css';
@@ -51,21 +49,22 @@ const PageDetailEditorMain = memo(function PageDetailEditorMain({
const mode = useLiveData(editor.mode$); const mode = useLiveData(editor.mode$);
const isSharedMode = editor.isSharedMode; const isSharedMode = editor.isSharedMode;
const { appSettings } = useAppSettingHelper(); const editorSetting = useService(EditorSettingService).editorSetting;
const settings = useLiveData(editorSetting.settings$);
const value = useMemo(() => { const value = useMemo(() => {
const fontStyle = fontStyleOptions.find( const fontStyle = fontStyleOptions.find(
option => option.key === appSettings.fontStyle option => option.key === settings.fontFamily
); );
if (!fontStyle) { if (!fontStyle) {
return cssVar('fontSansFamily'); return cssVar('fontSansFamily');
} }
const customFontFamily = appSettings.customFontFamily; const customFontFamily = settings.customFontFamily;
return customFontFamily && fontStyle.key === 'Custom' return customFontFamily && fontStyle.key === 'Custom'
? `${customFontFamily}, ${fontStyle.value}` ? `${customFontFamily}, ${fontStyle.value}`
: fontStyle.value; : fontStyle.value;
}, [appSettings.customFontFamily, appSettings.fontStyle]); }, [settings.customFontFamily, settings.fontFamily]);
const blockId = useRouterHash(); const blockId = useRouterHash();
@@ -96,7 +95,7 @@ const PageDetailEditorMain = memo(function PageDetailEditorMain({
return ( return (
<Editor <Editor
className={clsx(styles.editor, { className={clsx(styles.editor, {
'full-screen': !isSharedMode && appSettings.fullWidthLayout, 'full-screen': !isSharedMode && settings.fullWidthLayout,
'is-public': isSharedMode, 'is-public': isSharedMode,
})} })}
style={ style={

View File

@@ -16,6 +16,7 @@ import {
registerAffineUpdatesCommands, registerAffineUpdatesCommands,
} from '../commands'; } from '../commands';
import { usePageHelper } from '../components/blocksuite/block-suite-page-list/utils'; import { usePageHelper } from '../components/blocksuite/block-suite-page-list/utils';
import { EditorSettingService } from '../modules/editor-settting';
import { CMDKQuickSearchService } from '../modules/quicksearch/services/cmdk'; import { CMDKQuickSearchService } from '../modules/quicksearch/services/cmdk';
import { useLanguageHelper } from './affine/use-language-helper'; import { useLanguageHelper } from './affine/use-language-helper';
import { useActiveBlocksuiteEditor } from './use-block-suite-editor'; import { useActiveBlocksuiteEditor } from './use-block-suite-editor';
@@ -67,6 +68,7 @@ export function useRegisterWorkspaceCommands() {
const navigationHelper = useNavigateHelper(); const navigationHelper = useNavigateHelper();
const [editor] = useActiveBlocksuiteEditor(); const [editor] = useActiveBlocksuiteEditor();
const cmdkQuickSearchService = useService(CMDKQuickSearchService); const cmdkQuickSearchService = useService(CMDKQuickSearchService);
const editorSettingService = useService(EditorSettingService);
useEffect(() => { useEffect(() => {
const unsub = registerCMDKCommand(cmdkQuickSearchService, editor); const unsub = registerCMDKCommand(cmdkQuickSearchService, editor);
@@ -109,13 +111,13 @@ export function useRegisterWorkspaceCommands() {
t, t,
theme, theme,
languageHelper, languageHelper,
editor, editorSettingService,
}); });
return () => { return () => {
unsub(); unsub();
}; };
}, [store, t, theme, languageHelper, editor]); }, [editorSettingService, languageHelper, store, t, theme]);
// register AffineLayoutCommands // register AffineLayoutCommands
useEffect(() => { useEffect(() => {

View File

@@ -4,6 +4,9 @@ import { EditorSetting } from './entities/editor-setting';
import { GlobalStateEditorSettingProvider } from './impls/global-state'; import { GlobalStateEditorSettingProvider } from './impls/global-state';
import { EditorSettingProvider } from './provider/editor-setting-provider'; import { EditorSettingProvider } from './provider/editor-setting-provider';
import { EditorSettingService } from './services/editor-setting'; import { EditorSettingService } from './services/editor-setting';
export type { FontFamily } from './schema';
export { EditorSettingSchema, fontStyleOptions } from './schema';
export { EditorSettingService } from './services/editor-setting';
export function configureEditorSettingModule(framework: Framework) { export function configureEditorSettingModule(framework: Framework) {
framework framework

View File

@@ -1,5 +1,17 @@
import { z } from 'zod'; import { z } from 'zod';
export type FontFamily = 'Sans' | 'Serif' | 'Mono' | 'Custom';
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)' },
{ key: 'Custom', value: 'var(--affine-font-sans-family)' },
] satisfies {
key: FontFamily;
value: string;
}[];
const BSEditorSettingSchema = z.object({ const BSEditorSettingSchema = z.object({
// TODO: import from bs // TODO: import from bs
connector: z.object({ connector: z.object({
@@ -14,9 +26,14 @@ const BSEditorSettingSchema = z.object({
.default('#000000'), .default('#000000'),
}), }),
}); });
const AffineEditorSettingSchema = z.object({ const AffineEditorSettingSchema = z.object({
fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'), fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'),
customFontFamily: z.string().default(''),
newDocDefaultMode: z.enum(['edgeless', 'page']).default('page'),
spellCheck: z.boolean().default(false),
fullWidthLayout: z.boolean().default(false),
displayDocInfo: z.boolean().default(true),
displayBiDirectionalLink: z.boolean().default(true),
}); });
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends ( type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (

View File

@@ -1,5 +1,5 @@
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
import * as Dialog from '@radix-ui/react-dialog'; import * as Dialog from '@radix-ui/react-dialog';
import { useLiveData, useService } from '@toeverything/infra';
import anime, { type AnimeInstance, type AnimeParams } from 'animejs'; import anime, { type AnimeInstance, type AnimeParams } from 'animejs';
import clsx from 'clsx'; import clsx from 'clsx';
import { import {
@@ -13,6 +13,7 @@ import {
useState, useState,
} from 'react'; } from 'react';
import { EditorSettingService } from '../../editor-settting';
import type { PeekViewAnimation } from '../entities/peek-view'; import type { PeekViewAnimation } from '../entities/peek-view';
import * as styles from './modal-container.css'; import * as styles from './modal-container.css';
@@ -90,7 +91,8 @@ export const PeekViewModalContainer = forwardRef<
const overlayRef = useRef<HTMLDivElement>(null); const overlayRef = useRef<HTMLDivElement>(null);
const controlsRef = useRef<HTMLDivElement>(null); const controlsRef = useRef<HTMLDivElement>(null);
const prevAnimeMap = useRef<Record<string, AnimeInstance | undefined>>({}); const prevAnimeMap = useRef<Record<string, AnimeInstance | undefined>>({});
const { appSettings } = useAppSettingHelper(); const editorSettings = useService(EditorSettingService).editorSetting;
const settings = useLiveData(editorSettings.settings$);
const animateControls = useCallback((animateIn = false) => { const animateControls = useCallback((animateIn = false) => {
const controls = controlsRef.current; const controls = controlsRef.current;
@@ -320,7 +322,7 @@ export const PeekViewModalContainer = forwardRef<
> >
<div <div
data-anime-state={animeState} data-anime-state={animeState}
data-full-width-layout={appSettings.fullWidthLayout} data-full-width-layout={settings.fullWidthLayout}
ref={contentClipRef} ref={contentClipRef}
className={styles.modalContentContainer} className={styles.modalContentContainer}
> >

View File

@@ -5,6 +5,7 @@ import {
confirmExperimentalPrompt, confirmExperimentalPrompt,
openAboutPanel, openAboutPanel,
openAppearancePanel, openAppearancePanel,
openEditorSetting,
openExperimentalFeaturesPanel, openExperimentalFeaturesPanel,
openSettingModal, openSettingModal,
openShortcutsPanel, openShortcutsPanel,
@@ -61,8 +62,7 @@ test('Change theme', async ({ page }) => {
test('Change layout width', async ({ page }) => { test('Change layout width', async ({ page }) => {
await openHomePage(page); await openHomePage(page);
await waitForEditorLoad(page); await waitForEditorLoad(page);
await openSettingModal(page); await openEditorSetting(page);
await openAppearancePanel(page);
await page.getByTestId('full-width-layout-trigger').click(); await page.getByTestId('full-width-layout-trigger').click();

View File

@@ -16,6 +16,11 @@ export async function openAppearancePanel(page: Page) {
await page.getByTestId('appearance-panel-trigger').click(); await page.getByTestId('appearance-panel-trigger').click();
} }
export async function openEditorSetting(page: Page) {
await page.getByTestId('settings-modal-trigger').click();
await page.getByTestId('editor-panel-trigger').click();
}
export async function openShortcutsPanel(page: Page) { export async function openShortcutsPanel(page: Page) {
await page.getByTestId('shortcuts-panel-trigger').click(); await page.getByTestId('shortcuts-panel-trigger').click();
} }