diff --git a/packages/frontend/core/src/modules/peek-view/view/doc-peek-view.tsx b/packages/frontend/core/src/modules/peek-view/view/doc-peek-view.tsx index 0ccc777bf3..e3488a14ff 100644 --- a/packages/frontend/core/src/modules/peek-view/view/doc-peek-view.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/doc-peek-view.tsx @@ -23,8 +23,13 @@ import { PeekViewService } from '../services/peek-view'; import * as styles from './doc-peek-view.css'; import { useDoc } from './utils'; +export type DocPreviewRef = { + getEditor: () => AffineEditorContainer | null; + fitViewportToTarget: () => void; +}; + const DocPreview = forwardRef< - AffineEditorContainer, + DocPreviewRef, { docId: string; blockId?: string; mode?: DocMode } >(function DocPreview({ docId, blockId, mode }, ref) { const { doc, workspace, loading } = useDoc(docId); @@ -34,17 +39,33 @@ const DocPreview = forwardRef< const [editor, setEditor] = useState(null); const onRef = (editor: AffineEditorContainer) => { - if (typeof ref === 'function') { - ref(editor); - } else if (ref) { - ref.current = editor; - } setEditor(editor); }; const docs = useService(DocsService); const [resolvedMode, setResolvedMode] = useState(mode); + useImperativeHandle( + ref, + () => ({ + getEditor: () => editor, + fitViewportToTarget: () => { + if (editor && resolvedMode === 'edgeless') { + const rootService = + editor.host.std.spec.getService('affine:page'); + rootService.viewport.onResize(); + const data = rootService.getFitToScreenData(); + rootService.viewport.setViewport( + data.zoom, + [data.centerX, data.centerY], + false + ); + } + }, + }), + [editor, resolvedMode] + ); + useEffect(() => { if (!mode || !resolvedMode) { setResolvedMode(docs.list.doc$(docId).value?.mode$.value || 'page'); @@ -122,17 +143,16 @@ const DocPreview = forwardRef< }); DocPreview.displayName = 'DocPreview'; -export const DocPeekView = ({ - docId, - blockId, - mode, -}: { - docId: string; - blockId?: string; - mode?: DocMode; -}) => { - return ; -}; +export const DocPeekView = forwardRef< + DocPreviewRef, + { + docId: string; + blockId?: string; + mode?: DocMode; + } +>(function DocPeekView({ docId, blockId, mode }, ref) { + return ; +}); export type SurfaceRefPeekViewRef = { fitViewportToTarget: () => void; @@ -145,6 +165,9 @@ export const SurfaceRefPeekView = forwardRef< const [editorRef, setEditorRef] = useState( null ); + const onRef = (editor: AffineEditorContainer | null) => { + setEditorRef(editor); + }; const fitViewportToTarget = useCallback(() => { if (!editorRef) { return; @@ -189,6 +212,14 @@ export const SurfaceRefPeekView = forwardRef< }; }, [editorRef, fitViewportToTarget]); - return ; + return ( + { + onRef(ref?.getEditor() ?? null); + }} + docId={docId} + mode={'edgeless'} + /> + ); }); SurfaceRefPeekView.displayName = 'SurfaceRefPeekView'; diff --git a/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx b/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx index 0c2747c116..084adb7640 100644 --- a/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx @@ -5,13 +5,13 @@ import { useEffect, useMemo, useRef } from 'react'; import type { ActivePeekView } from '../entities/peek-view'; import { PeekViewService } from '../services/peek-view'; import { DocPeekViewControls } from './doc-peek-controls'; -import type { SurfaceRefPeekViewRef } from './doc-peek-view'; +import type { DocPreviewRef, SurfaceRefPeekViewRef } from './doc-peek-view'; import { DocPeekView, SurfaceRefPeekView } from './doc-peek-view'; import { PeekViewModalContainer } from './modal-container'; function renderPeekView( { info }: ActivePeekView, - refCallback: (editor: SurfaceRefPeekViewRef) => void + refCallback: (editor: SurfaceRefPeekViewRef | DocPreviewRef | null) => void ) { if (info.mode === 'edgeless' && info.xywh) { return ( @@ -24,7 +24,12 @@ function renderPeekView( } return ( - + ); } @@ -42,7 +47,9 @@ export const PeekViewManagerModal = () => { const peekViewEntity = useService(PeekViewService).peekView; const activePeekView = useLiveData(peekViewEntity.active$); const show = useLiveData(peekViewEntity.show$); - const peekViewRef = useRef(null); + const peekViewRef = useRef( + null + ); const preview = useMemo(() => { return activePeekView