fix: peek view on synced doc (#7265)
This commit is contained in:
@@ -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';
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user