mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
@@ -174,10 +174,10 @@ export function registerAffineSettingsCommands({
|
||||
registerAffineCommand({
|
||||
id: `affine:change-full-width-layout`,
|
||||
label: () =>
|
||||
`${t['com.affine.cmdk.affine.full-width-layout.to']()} ${t[
|
||||
`${t[
|
||||
settings$.value.fullWidthLayout
|
||||
? 'com.affine.cmdk.affine.switch-state.off'
|
||||
: 'com.affine.cmdk.affine.switch-state.on'
|
||||
? 'com.affine.cmdk.affine.default-page-width-layout.standard'
|
||||
: 'com.affine.cmdk.affine.default-page-width-layout.full-width'
|
||||
]()}`,
|
||||
category: 'affine:settings',
|
||||
icon: <SettingsIcon />,
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
EdgelessIcon,
|
||||
FileIcon,
|
||||
HistoryIcon,
|
||||
LongerIcon,
|
||||
NumberIcon,
|
||||
TagIcon,
|
||||
TextIcon,
|
||||
@@ -19,6 +20,7 @@ import { DocPrimaryModeValue } from './doc-primary-mode';
|
||||
import { EdgelessThemeValue } from './edgeless-theme';
|
||||
import { JournalValue } from './journal';
|
||||
import { NumberValue } from './number';
|
||||
import { PageWidthValue } from './page-width';
|
||||
import { TagsValue } from './tags';
|
||||
import { TextValue } from './text';
|
||||
import type { PropertyValueProps } from './types';
|
||||
@@ -100,6 +102,12 @@ export const DocPropertyTypes = {
|
||||
name: 'com.affine.page-properties.property.edgelessTheme',
|
||||
description: 'com.affine.page-properties.property.edgelessTheme.tooltips',
|
||||
},
|
||||
pageWidth: {
|
||||
icon: LongerIcon,
|
||||
value: PageWidthValue,
|
||||
name: 'com.affine.page-properties.property.pageWidth',
|
||||
description: 'com.affine.page-properties.property.pageWidth.tooltips',
|
||||
},
|
||||
} as Record<
|
||||
string,
|
||||
{
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
export const container = style({
|
||||
paddingTop: '3px',
|
||||
paddingBottom: '3px',
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import { PropertyValue, RadioGroup, type RadioItem } from '@affine/component';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { DocService, useLiveData, useService } from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { container } from './page-width.css';
|
||||
import type { PageLayoutMode } from './types';
|
||||
|
||||
export const PageWidthValue = () => {
|
||||
const t = useI18n();
|
||||
const editorSetting = useService(EditorSettingService).editorSetting;
|
||||
const defaultPageWidth = useLiveData(editorSetting.settings$).fullWidthLayout;
|
||||
|
||||
const doc = useService(DocService).doc;
|
||||
const pageWidth = useLiveData(doc.properties$.selector(p => p.pageWidth));
|
||||
|
||||
const radioValue =
|
||||
pageWidth ??
|
||||
((defaultPageWidth ? 'fullWidth' : 'standard') as PageLayoutMode);
|
||||
|
||||
const radioItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: 'standard' as PageLayoutMode,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.page.default-page-width.standard'
|
||||
](),
|
||||
testId: 'standard-width-trigger',
|
||||
},
|
||||
{
|
||||
value: 'fullWidth' as PageLayoutMode,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.page.default-page-width.full-width'
|
||||
](),
|
||||
testId: 'full-width-trigger',
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(value: PageLayoutMode) => {
|
||||
doc.record.setProperty('pageWidth', value);
|
||||
},
|
||||
[doc]
|
||||
);
|
||||
return (
|
||||
<PropertyValue className={container} hoverable={false}>
|
||||
<RadioGroup
|
||||
width={194}
|
||||
itemHeight={24}
|
||||
value={radioValue}
|
||||
onChange={handleChange}
|
||||
items={radioItems}
|
||||
/>
|
||||
</PropertyValue>
|
||||
);
|
||||
};
|
||||
@@ -5,3 +5,5 @@ export interface PropertyValueProps {
|
||||
value: any;
|
||||
onChange: (value: any) => void;
|
||||
}
|
||||
|
||||
export type PageLayoutMode = 'standard' | 'fullWidth';
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
} from '@affine/core/commands';
|
||||
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
||||
import type { Editor } from '@affine/core/modules/editor';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
@@ -30,6 +31,11 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
|
||||
const t = useI18n();
|
||||
const workspace = useService(WorkspaceService).workspace;
|
||||
|
||||
const editorSetting = useService(EditorSettingService).editorSetting;
|
||||
const defaultPageWidth = useLiveData(editorSetting.settings$).fullWidthLayout;
|
||||
const pageWidth = useLiveData(doc.properties$.selector(p => p.pageWidth));
|
||||
const checked = pageWidth ? pageWidth === 'fullWidth' : defaultPageWidth;
|
||||
|
||||
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
|
||||
const favorite = useLiveData(favAdapter.isFavorite$(docId, 'doc'));
|
||||
const trash = useLiveData(doc.trash$);
|
||||
@@ -159,6 +165,24 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
|
||||
})
|
||||
);
|
||||
|
||||
unsubs.push(
|
||||
registerAffineCommand({
|
||||
id: `editor:page-set-width`,
|
||||
preconditionStrategy: () => mode === 'page',
|
||||
category: `editor:page`,
|
||||
icon: <PageIcon />,
|
||||
label: checked
|
||||
? t['com.affine.cmdk.affine.current-page-width-layout.standard']()
|
||||
: t['com.affine.cmdk.affine.current-page-width-layout.full-width'](),
|
||||
async run() {
|
||||
doc.record.setProperty(
|
||||
'pageWidth',
|
||||
checked ? 'standard' : 'fullWidth'
|
||||
);
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// TODO(@Peng): should not show duplicate for journal
|
||||
unsubs.push(
|
||||
registerAffineCommand({
|
||||
@@ -308,5 +332,8 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
|
||||
docId,
|
||||
doc,
|
||||
openInfoModal,
|
||||
pageWidth,
|
||||
defaultPageWidth,
|
||||
checked,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import './page-detail-editor.css';
|
||||
|
||||
import type { AffineEditorContainer } from '@blocksuite/affine/presets';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { DocService, useLiveData, useService } from '@toeverything/infra';
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import clsx from 'clsx';
|
||||
import type { CSSProperties } from 'react';
|
||||
@@ -33,6 +33,9 @@ export const PageDetailEditor = ({ onLoad }: PageDetailEditorProps) => {
|
||||
const mode = useLiveData(editor.mode$);
|
||||
const defaultOpenProperty = useLiveData(editor.defaultOpenProperty$);
|
||||
|
||||
const doc = useService(DocService).doc;
|
||||
const pageWidth = useLiveData(doc.properties$.selector(p => p.pageWidth));
|
||||
|
||||
const isSharedMode = editor.isSharedMode;
|
||||
const editorSetting = useService(EditorSettingService).editorSetting;
|
||||
const settings = useLiveData(
|
||||
@@ -42,6 +45,9 @@ export const PageDetailEditor = ({ onLoad }: PageDetailEditorProps) => {
|
||||
fullWidthLayout: s.fullWidthLayout,
|
||||
}))
|
||||
);
|
||||
const fullWidthLayout = pageWidth
|
||||
? pageWidth === 'fullWidth'
|
||||
: settings.fullWidthLayout;
|
||||
|
||||
const value = useMemo(() => {
|
||||
const fontStyle = fontStyleOptions.find(
|
||||
@@ -60,7 +66,7 @@ export const PageDetailEditor = ({ onLoad }: PageDetailEditorProps) => {
|
||||
return (
|
||||
<Editor
|
||||
className={clsx(styles.editor, {
|
||||
'full-screen': !isSharedMode && settings.fullWidthLayout,
|
||||
'full-screen': !isSharedMode && fullWidthLayout,
|
||||
'is-public': isSharedMode,
|
||||
})}
|
||||
style={
|
||||
|
||||
@@ -1,20 +1,46 @@
|
||||
import { Switch } from '@affine/component';
|
||||
import { RadioGroup, type RadioItem, Switch } from '@affine/component';
|
||||
import {
|
||||
SettingRow,
|
||||
SettingWrapper,
|
||||
} from '@affine/component/setting-components';
|
||||
import type { PageLayoutMode } from '@affine/core/components/doc-properties/types/types';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { settingWrapper } from './style.css';
|
||||
|
||||
export const Page = () => {
|
||||
const t = useI18n();
|
||||
const editorSetting = useService(EditorSettingService).editorSetting;
|
||||
const settings = useLiveData(editorSetting.settings$);
|
||||
|
||||
const radioItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: 'standard' as PageLayoutMode,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.page.default-page-width.standard'
|
||||
](),
|
||||
testId: 'standard-width-trigger',
|
||||
},
|
||||
{
|
||||
value: 'fullWidth' as PageLayoutMode,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.page.default-page-width.full-width'
|
||||
](),
|
||||
testId: 'full-width-trigger',
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
const handleFullWidthLayoutChange = useCallback(
|
||||
(checked: boolean) => {
|
||||
(value: PageLayoutMode) => {
|
||||
const checked = value === 'fullWidth';
|
||||
editorSetting.set('fullWidthLayout', checked);
|
||||
},
|
||||
[editorSetting]
|
||||
@@ -35,14 +61,18 @@ export const Page = () => {
|
||||
return (
|
||||
<SettingWrapper title={t['com.affine.settings.editorSettings.page']()}>
|
||||
<SettingRow
|
||||
name={t['com.affine.settings.editorSettings.page.full-width.title']()}
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.page.default-page-width.title'
|
||||
]()}
|
||||
desc={t[
|
||||
'com.affine.settings.editorSettings.page.full-width.description'
|
||||
'com.affine.settings.editorSettings.page.default-page-width.description'
|
||||
]()}
|
||||
>
|
||||
<Switch
|
||||
data-testid="full-width-layout-trigger"
|
||||
checked={settings.fullWidthLayout}
|
||||
<RadioGroup
|
||||
items={radioItems}
|
||||
value={settings.fullWidthLayout ? 'fullWidth' : 'standard'}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={handleFullWidthLayoutChange}
|
||||
/>
|
||||
</SettingRow>
|
||||
|
||||
Reference in New Issue
Block a user