fix(core): center peek doc view circular deps (#10253)
This commit is contained in:
@@ -33,10 +33,7 @@ import {
|
|||||||
import { encodeStateAsUpdate } from 'yjs';
|
import { encodeStateAsUpdate } from 'yjs';
|
||||||
|
|
||||||
import { pageHistoryModalAtom } from '../../atoms/page-history';
|
import { pageHistoryModalAtom } from '../../atoms/page-history';
|
||||||
import {
|
import { BlockSuiteEditor } from '../../blocksuite/block-suite-editor';
|
||||||
BlockSuiteEditor,
|
|
||||||
CustomEditorWrapper,
|
|
||||||
} from '../../blocksuite/block-suite-editor';
|
|
||||||
import { PureEditorModeSwitch } from '../../blocksuite/block-suite-mode-switch';
|
import { PureEditorModeSwitch } from '../../blocksuite/block-suite-mode-switch';
|
||||||
import { AffineErrorBoundary } from '../affine-error-boundary';
|
import { AffineErrorBoundary } from '../affine-error-boundary';
|
||||||
import {
|
import {
|
||||||
@@ -134,14 +131,12 @@ const HistoryEditorPreview = ({
|
|||||||
<AffineErrorBoundary>
|
<AffineErrorBoundary>
|
||||||
<Scrollable.Root>
|
<Scrollable.Root>
|
||||||
<Scrollable.Viewport className="affine-page-viewport">
|
<Scrollable.Viewport className="affine-page-viewport">
|
||||||
<CustomEditorWrapper>
|
<BlockSuiteEditor
|
||||||
<BlockSuiteEditor
|
className={styles.editor}
|
||||||
className={styles.editor}
|
mode={mode}
|
||||||
mode={mode}
|
page={snapshotPage}
|
||||||
page={snapshotPage}
|
readonly={true}
|
||||||
readonly={true}
|
/>
|
||||||
/>
|
|
||||||
</CustomEditorWrapper>
|
|
||||||
</Scrollable.Viewport>
|
</Scrollable.Viewport>
|
||||||
<Scrollable.Scrollbar />
|
<Scrollable.Scrollbar />
|
||||||
</Scrollable.Root>
|
</Scrollable.Root>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { useRefEffect } from '@affine/component';
|
import { useRefEffect } from '@affine/component';
|
||||||
import { EditorLoading } from '@affine/component/page-detail-skeleton';
|
import { EditorLoading } from '@affine/component/page-detail-skeleton';
|
||||||
import { ServerService } from '@affine/core/modules/cloud';
|
import { ServerService } from '@affine/core/modules/cloud';
|
||||||
|
import {
|
||||||
|
EditorSettingService,
|
||||||
|
fontStyleOptions,
|
||||||
|
} from '@affine/core/modules/editor-setting';
|
||||||
import {
|
import {
|
||||||
customImageProxyMiddleware,
|
customImageProxyMiddleware,
|
||||||
type DocMode,
|
type DocMode,
|
||||||
@@ -10,9 +14,11 @@ import {
|
|||||||
import { DisposableGroup } from '@blocksuite/affine/global/utils';
|
import { DisposableGroup } from '@blocksuite/affine/global/utils';
|
||||||
import type { AffineEditorContainer } from '@blocksuite/affine/presets';
|
import type { AffineEditorContainer } from '@blocksuite/affine/presets';
|
||||||
import type { Store } from '@blocksuite/affine/store';
|
import type { Store } from '@blocksuite/affine/store';
|
||||||
import { useService } from '@toeverything/infra';
|
import { Slot } from '@radix-ui/react-slot';
|
||||||
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
|
import { cssVar } from '@toeverything/theme';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import type { DefaultOpenProperty } from '../../doc-properties';
|
import type { DefaultOpenProperty } from '../../doc-properties';
|
||||||
import { BlocksuiteEditorContainer } from './blocksuite-editor-container';
|
import { BlocksuiteEditorContainer } from './blocksuite-editor-container';
|
||||||
@@ -126,6 +132,28 @@ export const BlockSuiteEditor = (props: EditorProps) => {
|
|||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [error, setError] = useState<Error | null>(null);
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
const editorSetting = useService(EditorSettingService).editorSetting;
|
||||||
|
const settings = useLiveData(
|
||||||
|
editorSetting.settings$.selector(s => ({
|
||||||
|
fontFamily: s.fontFamily,
|
||||||
|
customFontFamily: s.customFontFamily,
|
||||||
|
fullWidthLayout: s.fullWidthLayout,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
const fontFamily = useMemo(() => {
|
||||||
|
const fontStyle = fontStyleOptions.find(
|
||||||
|
option => option.key === settings.fontFamily
|
||||||
|
);
|
||||||
|
if (!fontStyle) {
|
||||||
|
return cssVar('fontSansFamily');
|
||||||
|
}
|
||||||
|
const customFontFamily = settings.customFontFamily;
|
||||||
|
|
||||||
|
return customFontFamily && fontStyle.key === 'Custom'
|
||||||
|
? `${customFontFamily}, ${fontStyle.value}`
|
||||||
|
: fontStyle.value;
|
||||||
|
}, [settings.customFontFamily, settings.fontFamily]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.page.root) {
|
if (props.page.root) {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -149,9 +177,13 @@ export const BlockSuiteEditor = (props: EditorProps) => {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isLoading ? (
|
return (
|
||||||
<EditorLoading />
|
<Slot style={{ '--affine-font-family': fontFamily } as CSSProperties}>
|
||||||
) : (
|
{isLoading ? (
|
||||||
<BlockSuiteEditorImpl key={props.page.id} {...props} />
|
<EditorLoading />
|
||||||
|
) : (
|
||||||
|
<BlockSuiteEditorImpl key={props.page.id} {...props} />
|
||||||
|
)}
|
||||||
|
</Slot>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
import {
|
|
||||||
EditorSettingService,
|
|
||||||
fontStyleOptions,
|
|
||||||
} from '@affine/core/modules/editor-setting';
|
|
||||||
import { Slot } from '@radix-ui/react-slot';
|
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
|
||||||
import { cssVar } from '@toeverything/theme';
|
|
||||||
import { type CSSProperties, type ReactNode, useMemo } from 'react';
|
|
||||||
export const CustomEditorWrapper = ({ children }: { children: ReactNode }) => {
|
|
||||||
const editorSetting = useService(EditorSettingService).editorSetting;
|
|
||||||
const settings = useLiveData(
|
|
||||||
editorSetting.settings$.selector(s => ({
|
|
||||||
fontFamily: s.fontFamily,
|
|
||||||
customFontFamily: s.customFontFamily,
|
|
||||||
fullWidthLayout: s.fullWidthLayout,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
const value = useMemo(() => {
|
|
||||||
const fontStyle = fontStyleOptions.find(
|
|
||||||
option => option.key === settings.fontFamily
|
|
||||||
);
|
|
||||||
if (!fontStyle) {
|
|
||||||
return cssVar('fontSansFamily');
|
|
||||||
}
|
|
||||||
const customFontFamily = settings.customFontFamily;
|
|
||||||
|
|
||||||
return customFontFamily && fontStyle.key === 'Custom'
|
|
||||||
? `${customFontFamily}, ${fontStyle.value}`
|
|
||||||
: fontStyle.value;
|
|
||||||
}, [settings.customFontFamily, settings.fontFamily]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Slot
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
'--affine-font-family': value,
|
|
||||||
} as CSSProperties
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Slot>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -10,4 +10,3 @@ edgelessEffects();
|
|||||||
registerBlocksuitePresetsCustomComponents();
|
registerBlocksuitePresetsCustomComponents();
|
||||||
|
|
||||||
export * from './blocksuite-editor';
|
export * from './blocksuite-editor';
|
||||||
export * from './custom-editor-wrapper';
|
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ import { useEffect } from 'react';
|
|||||||
import { DocService } from '../modules/doc';
|
import { DocService } from '../modules/doc';
|
||||||
import { EditorService } from '../modules/editor';
|
import { EditorService } from '../modules/editor';
|
||||||
import { EditorSettingService } from '../modules/editor-setting';
|
import { EditorSettingService } from '../modules/editor-setting';
|
||||||
import {
|
import { BlockSuiteEditor } from './blocksuite/block-suite-editor';
|
||||||
BlockSuiteEditor as Editor,
|
|
||||||
CustomEditorWrapper,
|
|
||||||
} from './blocksuite/block-suite-editor';
|
|
||||||
import * as styles from './page-detail-editor.css';
|
import * as styles from './page-detail-editor.css';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@@ -57,19 +54,17 @@ export const PageDetailEditor = ({
|
|||||||
}, [editor, readonly]);
|
}, [editor, readonly]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CustomEditorWrapper>
|
<BlockSuiteEditor
|
||||||
<Editor
|
className={clsx(styles.editor, {
|
||||||
className={clsx(styles.editor, {
|
'full-screen': !isSharedMode && fullWidthLayout,
|
||||||
'full-screen': !isSharedMode && fullWidthLayout,
|
'is-public': isSharedMode,
|
||||||
'is-public': isSharedMode,
|
})}
|
||||||
})}
|
mode={mode}
|
||||||
mode={mode}
|
defaultOpenProperty={defaultOpenProperty}
|
||||||
defaultOpenProperty={defaultOpenProperty}
|
page={editor.doc.blockSuiteDoc}
|
||||||
page={editor.doc.blockSuiteDoc}
|
shared={isSharedMode}
|
||||||
shared={isSharedMode}
|
readonly={readonly}
|
||||||
readonly={readonly}
|
onEditorReady={onLoad}
|
||||||
onEditorReady={onLoad}
|
/>
|
||||||
/>
|
|
||||||
</CustomEditorWrapper>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ import { Scrollable } from '@affine/component';
|
|||||||
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
||||||
import { AIProvider } from '@affine/core/blocksuite/presets/ai';
|
import { AIProvider } from '@affine/core/blocksuite/presets/ai';
|
||||||
import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary';
|
import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary';
|
||||||
import {
|
|
||||||
BlockSuiteEditor,
|
|
||||||
CustomEditorWrapper,
|
|
||||||
} from '@affine/core/components/blocksuite/block-suite-editor';
|
|
||||||
import { EditorOutlineViewer } from '@affine/core/components/blocksuite/outline-viewer';
|
import { EditorOutlineViewer } from '@affine/core/components/blocksuite/outline-viewer';
|
||||||
import { PageNotFound } from '@affine/core/desktop/pages/404';
|
import { PageNotFound } from '@affine/core/desktop/pages/404';
|
||||||
import { EditorService } from '@affine/core/modules/editor';
|
import { EditorService } from '@affine/core/modules/editor';
|
||||||
@@ -26,7 +22,7 @@ import {
|
|||||||
useServices,
|
useServices,
|
||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { lazy, Suspense, useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
import { WorkbenchService } from '../../../workbench';
|
import { WorkbenchService } from '../../../workbench';
|
||||||
import type { DocReferenceInfo } from '../../entities/peek-view';
|
import type { DocReferenceInfo } from '../../entities/peek-view';
|
||||||
@@ -36,6 +32,15 @@ import * as styles from './doc-peek-view.css';
|
|||||||
|
|
||||||
const logger = new DebugLogger('doc-peek-view');
|
const logger = new DebugLogger('doc-peek-view');
|
||||||
|
|
||||||
|
// Lazy load BlockSuiteEditor to break circular dependency
|
||||||
|
const BlockSuiteEditor = lazy(() =>
|
||||||
|
import('@affine/core/components/blocksuite/block-suite-editor').then(
|
||||||
|
module => ({
|
||||||
|
default: module.BlockSuiteEditor,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
function fitViewport(
|
function fitViewport(
|
||||||
editor: AffineEditorContainer,
|
editor: AffineEditorContainer,
|
||||||
xywh?: `[${number},${number},${number},${number}]`
|
xywh?: `[${number},${number},${number},${number}]`
|
||||||
@@ -159,7 +164,7 @@ function DocPeekPreviewEditor({
|
|||||||
<Scrollable.Viewport
|
<Scrollable.Viewport
|
||||||
className={clsx('affine-page-viewport', styles.affineDocViewport)}
|
className={clsx('affine-page-viewport', styles.affineDocViewport)}
|
||||||
>
|
>
|
||||||
<CustomEditorWrapper>
|
<Suspense fallback={<PageDetailSkeleton />}>
|
||||||
<BlockSuiteEditor
|
<BlockSuiteEditor
|
||||||
className={styles.editor}
|
className={styles.editor}
|
||||||
mode={mode}
|
mode={mode}
|
||||||
@@ -168,7 +173,7 @@ function DocPeekPreviewEditor({
|
|||||||
onEditorReady={handleOnEditorReady}
|
onEditorReady={handleOnEditorReady}
|
||||||
defaultOpenProperty={defaultOpenProperty}
|
defaultOpenProperty={defaultOpenProperty}
|
||||||
/>
|
/>
|
||||||
</CustomEditorWrapper>
|
</Suspense>
|
||||||
</Scrollable.Viewport>
|
</Scrollable.Viewport>
|
||||||
<Scrollable.Scrollbar />
|
<Scrollable.Scrollbar />
|
||||||
</Scrollable.Root>
|
</Scrollable.Root>
|
||||||
|
|||||||
@@ -407,6 +407,8 @@ export const PeekViewModalContainer = forwardRef<
|
|||||||
<div className={styles.modalContentClip}>
|
<div className={styles.modalContentClip}>
|
||||||
<Dialog.Content
|
<Dialog.Content
|
||||||
{...contentOptions}
|
{...contentOptions}
|
||||||
|
// mute the radix-ui warning
|
||||||
|
aria-describedby={undefined}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[styles.modalContent]: true,
|
[styles.modalContent]: true,
|
||||||
[styles.dialog]: dialogFrame,
|
[styles.dialog]: dialogFrame,
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// the following import is used to ensure the block suite editor effects are run
|
||||||
|
import '../components/blocksuite/block-suite-editor';
|
||||||
|
|
||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { DEFAULT_WORKSPACE_NAME } from '@affine/env/constant';
|
import { DEFAULT_WORKSPACE_NAME } from '@affine/env/constant';
|
||||||
import onboardingUrl from '@affine/templates/onboarding.zip';
|
import onboardingUrl from '@affine/templates/onboarding.zip';
|
||||||
|
|||||||
Reference in New Issue
Block a user