fix: peek view on synced doc (#7265)

This commit is contained in:
doouding
2024-06-19 06:41:08 +00:00
parent bbf796faaf
commit 314fa064ab
2 changed files with 60 additions and 22 deletions

View File

@@ -23,8 +23,13 @@ import { PeekViewService } from '../services/peek-view';
import * as styles from './doc-peek-view.css'; import * as styles from './doc-peek-view.css';
import { useDoc } from './utils'; import { useDoc } from './utils';
export type DocPreviewRef = {
getEditor: () => AffineEditorContainer | null;
fitViewportToTarget: () => void;
};
const DocPreview = forwardRef< const DocPreview = forwardRef<
AffineEditorContainer, DocPreviewRef,
{ docId: string; blockId?: string; mode?: DocMode } { docId: string; blockId?: string; mode?: DocMode }
>(function DocPreview({ docId, blockId, mode }, ref) { >(function DocPreview({ docId, blockId, mode }, ref) {
const { doc, workspace, loading } = useDoc(docId); const { doc, workspace, loading } = useDoc(docId);
@@ -34,17 +39,33 @@ const DocPreview = forwardRef<
const [editor, setEditor] = useState<AffineEditorContainer | null>(null); const [editor, setEditor] = useState<AffineEditorContainer | null>(null);
const onRef = (editor: AffineEditorContainer) => { const onRef = (editor: AffineEditorContainer) => {
if (typeof ref === 'function') {
ref(editor);
} else if (ref) {
ref.current = editor;
}
setEditor(editor); setEditor(editor);
}; };
const docs = useService(DocsService); const docs = useService(DocsService);
const [resolvedMode, setResolvedMode] = useState<DocMode | undefined>(mode); const [resolvedMode, setResolvedMode] = useState<DocMode | undefined>(mode);
useImperativeHandle(
ref,
() => ({
getEditor: () => editor,
fitViewportToTarget: () => {
if (editor && resolvedMode === 'edgeless') {
const rootService =
editor.host.std.spec.getService<EdgelessRootService>('affine:page');
rootService.viewport.onResize();
const data = rootService.getFitToScreenData();
rootService.viewport.setViewport(
data.zoom,
[data.centerX, data.centerY],
false
);
}
},
}),
[editor, resolvedMode]
);
useEffect(() => { useEffect(() => {
if (!mode || !resolvedMode) { if (!mode || !resolvedMode) {
setResolvedMode(docs.list.doc$(docId).value?.mode$.value || 'page'); setResolvedMode(docs.list.doc$(docId).value?.mode$.value || 'page');
@@ -122,17 +143,16 @@ const DocPreview = forwardRef<
}); });
DocPreview.displayName = 'DocPreview'; DocPreview.displayName = 'DocPreview';
export const DocPeekView = ({ export const DocPeekView = forwardRef<
docId, DocPreviewRef,
blockId, {
mode, docId: string;
}: { blockId?: string;
docId: string; mode?: DocMode;
blockId?: string; }
mode?: DocMode; >(function DocPeekView({ docId, blockId, mode }, ref) {
}) => { return <DocPreview ref={ref} mode={mode} docId={docId} blockId={blockId} />;
return <DocPreview mode={mode} docId={docId} blockId={blockId} />; });
};
export type SurfaceRefPeekViewRef = { export type SurfaceRefPeekViewRef = {
fitViewportToTarget: () => void; fitViewportToTarget: () => void;
@@ -145,6 +165,9 @@ export const SurfaceRefPeekView = forwardRef<
const [editorRef, setEditorRef] = useState<AffineEditorContainer | null>( const [editorRef, setEditorRef] = useState<AffineEditorContainer | null>(
null null
); );
const onRef = (editor: AffineEditorContainer | null) => {
setEditorRef(editor);
};
const fitViewportToTarget = useCallback(() => { const fitViewportToTarget = useCallback(() => {
if (!editorRef) { if (!editorRef) {
return; return;
@@ -189,6 +212,14 @@ export const SurfaceRefPeekView = forwardRef<
}; };
}, [editorRef, fitViewportToTarget]); }, [editorRef, fitViewportToTarget]);
return <DocPreview ref={setEditorRef} docId={docId} mode={'edgeless'} />; return (
<DocPreview
ref={ref => {
onRef(ref?.getEditor() ?? null);
}}
docId={docId}
mode={'edgeless'}
/>
);
}); });
SurfaceRefPeekView.displayName = 'SurfaceRefPeekView'; SurfaceRefPeekView.displayName = 'SurfaceRefPeekView';

View File

@@ -5,13 +5,13 @@ import { useEffect, useMemo, useRef } from 'react';
import type { ActivePeekView } from '../entities/peek-view'; import type { ActivePeekView } from '../entities/peek-view';
import { PeekViewService } from '../services/peek-view'; import { PeekViewService } from '../services/peek-view';
import { DocPeekViewControls } from './doc-peek-controls'; 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 { DocPeekView, SurfaceRefPeekView } from './doc-peek-view';
import { PeekViewModalContainer } from './modal-container'; import { PeekViewModalContainer } from './modal-container';
function renderPeekView( function renderPeekView(
{ info }: ActivePeekView, { info }: ActivePeekView,
refCallback: (editor: SurfaceRefPeekViewRef) => void refCallback: (editor: SurfaceRefPeekViewRef | DocPreviewRef | null) => void
) { ) {
if (info.mode === 'edgeless' && info.xywh) { if (info.mode === 'edgeless' && info.xywh) {
return ( return (
@@ -24,7 +24,12 @@ function renderPeekView(
} }
return ( return (
<DocPeekView mode={info.mode} docId={info.docId} blockId={info.blockId} /> <DocPeekView
ref={refCallback}
mode={info.mode}
docId={info.docId}
blockId={info.blockId}
/>
); );
} }
@@ -42,7 +47,9 @@ export const PeekViewManagerModal = () => {
const peekViewEntity = useService(PeekViewService).peekView; const peekViewEntity = useService(PeekViewService).peekView;
const activePeekView = useLiveData(peekViewEntity.active$); const activePeekView = useLiveData(peekViewEntity.active$);
const show = useLiveData(peekViewEntity.show$); const show = useLiveData(peekViewEntity.show$);
const peekViewRef = useRef<SurfaceRefPeekViewRef | null>(null); const peekViewRef = useRef<SurfaceRefPeekViewRef | DocPreviewRef | null>(
null
);
const preview = useMemo(() => { const preview = useMemo(() => {
return activePeekView return activePeekView