From 7baa260e97ccedadccfbbf1ffe2f6fbd4feb2ccd Mon Sep 17 00:00:00 2001 From: pengx17 Date: Wed, 26 Jun 2024 07:49:25 +0000 Subject: [PATCH] refactor(core): image block use peek view workflow (#7329) depends on https://github.com/toeverything/blocksuite/pull/7424 --- packages/common/env/package.json | 4 +- packages/common/infra/package.json | 10 +- packages/frontend/component/package.json | 10 +- packages/frontend/core/package.json | 12 +- .../modules/peek-view/entities/peek-view.ts | 68 +++++- .../core/src/modules/peek-view/index.ts | 8 +- .../{ => doc-preview}/doc-peek-view.css.ts | 0 .../view/{ => doc-preview}/doc-peek-view.tsx | 14 +- .../peek-view/view/doc-preview/index.ts | 1 + .../view}/image-preview/hooks/use-zoom.tsx | 0 .../view}/image-preview/index.css.ts | 0 .../peek-view/view}/image-preview/index.tsx | 219 +++++++----------- .../peek-view/view/modal-container.css.ts | 5 + .../peek-view/view/modal-container.tsx | 47 ++-- .../peek-view/view/peek-view-manager.tsx | 86 ++++--- .../workspace/detail-page/detail-page.tsx | 9 - packages/frontend/electron/package.json | 8 +- tests/affine-local/e2e/image-preview.spec.ts | 6 +- tools/cli/package.json | 2 +- yarn.lock | 136 +++++------ 20 files changed, 340 insertions(+), 305 deletions(-) rename packages/frontend/core/src/modules/peek-view/view/{ => doc-preview}/doc-peek-view.css.ts (100%) rename packages/frontend/core/src/modules/peek-view/view/{ => doc-preview}/doc-peek-view.tsx (91%) create mode 100644 packages/frontend/core/src/modules/peek-view/view/doc-preview/index.ts rename packages/frontend/core/src/{components => modules/peek-view/view}/image-preview/hooks/use-zoom.tsx (100%) rename packages/frontend/core/src/{components => modules/peek-view/view}/image-preview/index.css.ts (100%) rename packages/frontend/core/src/{components => modules/peek-view/view}/image-preview/index.tsx (69%) diff --git a/packages/common/env/package.json b/packages/common/env/package.json index e070e91c63..393fd4b623 100644 --- a/packages/common/env/package.json +++ b/packages/common/env/package.json @@ -3,8 +3,8 @@ "private": true, "type": "module", "devDependencies": { - "@blocksuite/global": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/store": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/global": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/store": "0.15.0-canary-202406260417-3b9fb16", "react": "18.3.1", "react-dom": "18.3.1", "vitest": "1.6.0" diff --git a/packages/common/infra/package.json b/packages/common/infra/package.json index 20da117513..80c13a8ee7 100644 --- a/packages/common/infra/package.json +++ b/packages/common/infra/package.json @@ -13,9 +13,9 @@ "@affine/debug": "workspace:*", "@affine/env": "workspace:*", "@affine/templates": "workspace:*", - "@blocksuite/blocks": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/global": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/store": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/blocks": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/global": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/store": "0.15.0-canary-202406260417-3b9fb16", "@datastructures-js/binary-search-tree": "^5.3.2", "foxact": "^0.2.33", "jotai": "^2.8.0", @@ -29,8 +29,8 @@ "devDependencies": { "@affine-test/fixtures": "workspace:*", "@affine/templates": "workspace:*", - "@blocksuite/block-std": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/presets": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/block-std": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/presets": "0.15.0-canary-202406260417-3b9fb16", "@testing-library/react": "^16.0.0", "async-call-rpc": "^6.4.0", "react": "^18.2.0", diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json index 4a530f08fd..b15c73c4cb 100644 --- a/packages/frontend/component/package.json +++ b/packages/frontend/component/package.json @@ -75,12 +75,12 @@ "zod": "^3.22.4" }, "devDependencies": { - "@blocksuite/block-std": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/blocks": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/global": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/block-std": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/blocks": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/global": "0.15.0-canary-202406260417-3b9fb16", "@blocksuite/icons": "2.1.58", - "@blocksuite/presets": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/store": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/presets": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/store": "0.15.0-canary-202406260417-3b9fb16", "@storybook/addon-actions": "^7.6.17", "@storybook/addon-essentials": "^7.6.17", "@storybook/addon-interactions": "^7.6.17", diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json index b0ec9476e6..78aa517558 100644 --- a/packages/frontend/core/package.json +++ b/packages/frontend/core/package.json @@ -19,13 +19,13 @@ "@affine/graphql": "workspace:*", "@affine/i18n": "workspace:*", "@affine/templates": "workspace:*", - "@blocksuite/block-std": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/blocks": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/global": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/block-std": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/blocks": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/global": "0.15.0-canary-202406260417-3b9fb16", "@blocksuite/icons": "2.1.58", - "@blocksuite/inline": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/presets": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/store": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/inline": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/presets": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/store": "0.15.0-canary-202406260417-3b9fb16", "@dnd-kit/core": "^6.1.0", "@dnd-kit/modifiers": "^7.0.0", "@dnd-kit/sortable": "^8.0.0", diff --git a/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts b/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts index e190c41669..d2dbf695af 100644 --- a/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts +++ b/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts @@ -3,6 +3,7 @@ import { AffineReference, type EmbedLinkedDocModel, type EmbedSyncedDocModel, + type ImageBlockModel, type SurfaceRefBlockComponent, type SurfaceRefBlockModel, } from '@blocksuite/blocks'; @@ -12,6 +13,7 @@ import type { TemplateResult } from 'lit'; import { firstValueFrom, map, race } from 'rxjs'; import { resolveLinkToDoc } from '../../navigation'; +import type { WorkbenchService } from '../../workbench'; export type PeekViewTarget = | HTMLElement @@ -20,17 +22,28 @@ export type PeekViewTarget = | HTMLAnchorElement | { docId: string; blockId?: string }; -export type DocPeekViewInfo = { +export interface DocPeekViewInfo { + type: 'doc'; docId: string; blockId?: string; mode?: DocMode; xywh?: `[${number},${number},${number},${number}]`; +} + +export type ImagePeekViewInfo = { + type: 'image'; + docId: string; + blockId: string; +}; + +export type CustomTemplatePeekViewInfo = { + type: 'template'; + template: TemplateResult; }; export type ActivePeekView = { target: PeekViewTarget; - info?: DocPeekViewInfo; - template?: TemplateResult; + info: DocPeekViewInfo | ImagePeekViewInfo | CustomTemplatePeekViewInfo; }; const EMBED_DOC_FLAVOURS = [ @@ -44,6 +57,12 @@ const isEmbedDocModel = ( return EMBED_DOC_FLAVOURS.includes(blockModel.flavour); }; +const isImageBlockModel = ( + blockModel: BlockModel +): blockModel is ImageBlockModel => { + return blockModel.flavour === 'affine:image'; +}; + const isSurfaceRefModel = ( blockModel: BlockModel ): blockModel is SurfaceRefBlockModel => { @@ -51,12 +70,20 @@ const isSurfaceRefModel = ( }; function resolvePeekInfoFromPeekTarget( - peekTarget?: PeekViewTarget -): DocPeekViewInfo | undefined { - if (!peekTarget) return; + peekTarget: PeekViewTarget, + template?: TemplateResult +): ActivePeekView['info'] | undefined { + if (template) { + return { + type: 'template', + template, + }; + } + if (peekTarget instanceof AffineReference) { if (peekTarget.refMeta) { return { + type: 'doc', docId: peekTarget.refMeta.id, }; } @@ -64,6 +91,7 @@ function resolvePeekInfoFromPeekTarget( const blockModel = peekTarget.model; if (isEmbedDocModel(blockModel)) { return { + type: 'doc', docId: blockModel.pageId, }; } else if (isSurfaceRefModel(blockModel)) { @@ -73,22 +101,31 @@ function resolvePeekInfoFromPeekTarget( const docId = 'doc' in refModel ? refModel.doc.id : refModel.surface.doc.id; return { + type: 'doc', docId, mode: 'edgeless', xywh: refModel.xywh, }; } + } else if (isImageBlockModel(blockModel)) { + return { + type: 'image', + docId: blockModel.doc.id, + blockId: blockModel.id, + }; } } else if (peekTarget instanceof HTMLAnchorElement) { const maybeDoc = resolveLinkToDoc(peekTarget.href); if (maybeDoc) { return { + type: 'doc', docId: maybeDoc.docId, blockId: maybeDoc.blockId, }; } } else if ('docId' in peekTarget) { return { + type: 'doc', docId: peekTarget.docId, blockId: peekTarget.blockId, }; @@ -100,6 +137,10 @@ export class PeekViewEntity extends Entity { private readonly _active$ = new LiveData(null); private readonly _show$ = new LiveData(false); + constructor(private readonly workbenchService: WorkbenchService) { + super(); + } + active$ = this._active$.distinctUntilChanged(); show$ = this._show$ .map(show => show && this._active$.value !== null) @@ -110,11 +151,20 @@ export class PeekViewEntity extends Entity { target: ActivePeekView['target'], template?: TemplateResult ) => { - const resolvedInfo = resolvePeekInfoFromPeekTarget(target); - if (!resolvedInfo && !template) { + const resolvedInfo = resolvePeekInfoFromPeekTarget(target, template); + if (!resolvedInfo) { return; } - this._active$.next({ target, info: resolvedInfo, template }); + + const active = this._active$.value; + + // if there is an active peek view and it is a doc peek view, we will navigate it first + if (active?.info.type === 'doc' && this.show$.value) { + // TODO(@pengx17): scroll to the viewing position? + this.workbenchService.workbench.openPage(active.info.docId); + } + + this._active$.next({ target, info: resolvedInfo }); this._show$.next(true); return firstValueFrom(race(this._active$, this.show$).pipe(map(() => {}))); }; diff --git a/packages/frontend/core/src/modules/peek-view/index.ts b/packages/frontend/core/src/modules/peek-view/index.ts index a857b8039d..0956ad7596 100644 --- a/packages/frontend/core/src/modules/peek-view/index.ts +++ b/packages/frontend/core/src/modules/peek-view/index.ts @@ -1,10 +1,14 @@ -import type { Framework } from '@toeverything/infra'; +import { type Framework, WorkspaceScope } from '@toeverything/infra'; +import { WorkbenchService } from '../workbench'; import { PeekViewEntity } from './entities/peek-view'; import { PeekViewService } from './services/peek-view'; export function configurePeekViewModule(framework: Framework) { - framework.service(PeekViewService).entity(PeekViewEntity); + framework + .scope(WorkspaceScope) + .service(PeekViewService) + .entity(PeekViewEntity, [WorkbenchService]); } export { PeekViewEntity, PeekViewService }; diff --git a/packages/frontend/core/src/modules/peek-view/view/doc-peek-view.css.ts b/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.css.ts similarity index 100% rename from packages/frontend/core/src/modules/peek-view/view/doc-peek-view.css.ts rename to packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.css.ts 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-preview/doc-peek-view.tsx similarity index 91% rename from packages/frontend/core/src/modules/peek-view/view/doc-peek-view.tsx rename to packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.tsx index 48e1d6d17e..228e6f3004 100644 --- a/packages/frontend/core/src/modules/peek-view/view/doc-peek-view.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/doc-preview/doc-peek-view.tsx @@ -3,7 +3,6 @@ import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton'; import { AIProvider } from '@affine/core/blocksuite/presets/ai'; import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary'; import { BlockSuiteEditor } from '@affine/core/components/blocksuite/block-suite-editor'; -import { ImagePreviewModal } from '@affine/core/components/image-preview'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; import { PageNotFound } from '@affine/core/pages/404'; import { Bound, type EdgelessRootService } from '@blocksuite/blocks'; @@ -14,10 +13,10 @@ import { DocsService, FrameworkScope, useService } from '@toeverything/infra'; import clsx from 'clsx'; import { useEffect, useState } from 'react'; -import { WorkbenchService } from '../../workbench'; -import { PeekViewService } from '../services/peek-view'; +import { WorkbenchService } from '../../../workbench'; +import { PeekViewService } from '../../services/peek-view'; +import { useDoc } from '../utils'; import * as styles from './doc-peek-view.css'; -import { useDoc } from './utils'; function fitViewport( editor: AffineEditorContainer, @@ -160,13 +159,6 @@ export function DocPeekPreview({ defaultSelectedBlockId={blockId} page={doc.blockSuiteDoc} /> - {editor?.host ? ( - - ) : null} diff --git a/packages/frontend/core/src/modules/peek-view/view/doc-preview/index.ts b/packages/frontend/core/src/modules/peek-view/view/doc-preview/index.ts new file mode 100644 index 0000000000..211fb57cb0 --- /dev/null +++ b/packages/frontend/core/src/modules/peek-view/view/doc-preview/index.ts @@ -0,0 +1 @@ +export { DocPeekPreview } from './doc-peek-view'; diff --git a/packages/frontend/core/src/components/image-preview/hooks/use-zoom.tsx b/packages/frontend/core/src/modules/peek-view/view/image-preview/hooks/use-zoom.tsx similarity index 100% rename from packages/frontend/core/src/components/image-preview/hooks/use-zoom.tsx rename to packages/frontend/core/src/modules/peek-view/view/image-preview/hooks/use-zoom.tsx diff --git a/packages/frontend/core/src/components/image-preview/index.css.ts b/packages/frontend/core/src/modules/peek-view/view/image-preview/index.css.ts similarity index 100% rename from packages/frontend/core/src/components/image-preview/index.css.ts rename to packages/frontend/core/src/modules/peek-view/view/image-preview/index.css.ts diff --git a/packages/frontend/core/src/components/image-preview/index.tsx b/packages/frontend/core/src/modules/peek-view/view/image-preview/index.tsx similarity index 69% rename from packages/frontend/core/src/components/image-preview/index.tsx rename to packages/frontend/core/src/modules/peek-view/view/image-preview/index.tsx index e9ba3a733b..41e8ae47e9 100644 --- a/packages/frontend/core/src/components/image-preview/index.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/image-preview/index.tsx @@ -2,7 +2,6 @@ import { toast } from '@affine/component'; import { Button, IconButton } from '@affine/component/ui/button'; import { Tooltip } from '@affine/component/ui/tooltip'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; -import { PeekViewModalContainer } from '@affine/core/modules/peek-view/view/modal-container'; import type { ImageBlockModel } from '@blocksuite/blocks'; import { assertExists } from '@blocksuite/global/utils'; import { @@ -16,7 +15,8 @@ import { PlusIcon, ViewBarIcon, } from '@blocksuite/icons/rc'; -import type { BlockModel, DocCollection } from '@blocksuite/store'; +import type { BlockModel } from '@blocksuite/store'; +import { useService } from '@toeverything/infra'; import clsx from 'clsx'; import { useErrorBoundary } from 'foxact/use-error-boundary'; import type { PropsWithChildren, ReactElement } from 'react'; @@ -24,7 +24,6 @@ import { Suspense, useCallback, useEffect, - useLayoutEffect, useMemo, useRef, useState, @@ -33,6 +32,8 @@ import type { FallbackProps } from 'react-error-boundary'; import { ErrorBoundary } from 'react-error-boundary'; import useSWR from 'swr'; +import { PeekViewService } from '../../services/peek-view'; +import { useDoc } from '../utils'; import { useZoomControls } from './hooks/use-zoom'; import * as styles from './index.css'; @@ -120,9 +121,8 @@ async function saveBufferToFile(url: string, filename: string) { } export type ImagePreviewModalProps = { - docCollection: DocCollection; - pageId: string; - host: HTMLElement; + docId: string; + blockId: string; }; const ButtonWithTooltip = ({ @@ -149,24 +149,25 @@ const ButtonWithTooltip = ({ } }; -const ImagePreviewModalImpl = ( - props: ImagePreviewModalProps & { - blockId: string; - onBlockIdChange: (blockId: string | null) => void; - onClose: () => void; - animating: boolean; - } -): ReactElement | null => { - const page = useMemo(() => { - return props.docCollection.getDoc(props.pageId); - }, [props.docCollection, props.pageId]); +const ImagePreviewModalImpl = ({ + docId, + blockId, + onBlockIdChange, + onClose, +}: ImagePreviewModalProps & { + onBlockIdChange: (blockId: string) => void; + onClose: () => void; +}): ReactElement | null => { + const { doc, workspace } = useDoc(docId); + const blocksuiteDoc = doc?.blockSuiteDoc; + const docCollection = workspace.docCollection; const blockModel = useMemo(() => { - const block = page?.getBlock(props.blockId); + const block = blocksuiteDoc?.getBlock(blockId); if (!block) { return null; } return block.model as ImageBlockModel; - }, [page, props.blockId]); + }, [blockId, blocksuiteDoc]); const caption = useMemo(() => { return blockModel?.caption ?? ''; }, [blockModel?.caption]); @@ -188,8 +189,7 @@ const ImagePreviewModalImpl = ( const goto = useCallback( (index: number) => { - const workspace = props.docCollection; - const page = workspace.getDoc(props.pageId); + const page = docCollection.getDoc(docId); assertExists(page); const block = blocks[index]; @@ -197,18 +197,17 @@ const ImagePreviewModalImpl = ( if (!block) return; setCursor(index); - props.onBlockIdChange(block.id); + onBlockIdChange(block.id); resetZoom(); }, - [props, blocks, resetZoom] + [docCollection, docId, blocks, onBlockIdChange, resetZoom] ); const deleteHandler = useCallback( (index: number) => { - const { pageId, docCollection: workspace, onClose } = props; - - const page = workspace.getDoc(pageId); - assertExists(page); + if (!blocksuiteDoc) { + return; + } let block = blocks[index]; @@ -216,7 +215,7 @@ const ImagePreviewModalImpl = ( const newBlocks = blocks.toSpliced(index, 1); setBlocks(newBlocks); - page.deleteBlock(block); + blocksuiteDoc.deleteBlock(block); // next block = newBlocks[index]; @@ -234,11 +233,11 @@ const ImagePreviewModalImpl = ( setCursor(index); } - props.onBlockIdChange(block.id); + onBlockIdChange(block.id); resetZoom(); }, - [props, blocks, setBlocks, setCursor, resetZoom] + [blocksuiteDoc, blocks, onBlockIdChange, resetZoom, onClose] ); const downloadHandler = useAsyncCallback(async () => { @@ -256,66 +255,58 @@ const ImagePreviewModalImpl = ( }, []); useEffect(() => { - const page = props.docCollection.getDoc(props.pageId); - assertExists(page); - - const block = page.getBlock(props.blockId); - if (!block) { + if (!blockModel || !blocksuiteDoc) { return; } - const blockModel = block.model as ImageBlockModel; - const prevs = page.getPrevs(blockModel).filter(filterImageBlock); - const nexts = page.getNexts(blockModel).filter(filterImageBlock); + const prevs = blocksuiteDoc.getPrevs(blockModel).filter(filterImageBlock); + const nexts = blocksuiteDoc.getNexts(blockModel).filter(filterImageBlock); const blocks = [...prevs, blockModel, ...nexts]; setBlocks(blocks); setCursor(blocks.length ? prevs.length : 0); - }, [props.blockId, props.pageId, props.docCollection, setBlocks]); + }, [setBlocks, blockModel, blocksuiteDoc]); - const { data, error } = useSWR( - ['workspace', 'image', props.pageId, props.blockId], - { - fetcher: ([_, __, pageId, blockId]) => { - const page = props.docCollection.getDoc(pageId); - assertExists(page); + const { data, error } = useSWR(['workspace', 'image', docId, blockId], { + fetcher: ([_, __, pageId, blockId]) => { + const page = docCollection.getDoc(pageId); + assertExists(page); - const block = page.getBlock(blockId); - if (!block) { - return null; - } - const blockModel = block.model as ImageBlockModel; - return props.docCollection.blobSync.get(blockModel.sourceId as string); - }, - suspense: true, - } - ); + const block = page.getBlock(blockId); + if (!block) { + return null; + } + const blockModel = block.model as ImageBlockModel; + return docCollection.blobSync.get(blockModel.sourceId as string); + }, + suspense: true, + }); useEffect(() => { const handleKeyUp = (event: KeyboardEvent) => { - if (!page || !blockModel) { + if (!blocksuiteDoc || !blockModel) { return; } if (event.key === 'ArrowLeft') { - const prevBlock = page + const prevBlock = blocksuiteDoc .getPrevs(blockModel) .findLast( (block): block is ImageBlockModel => block.flavour === 'affine:image' ); if (prevBlock) { - props.onBlockIdChange(prevBlock.id); + onBlockIdChange(prevBlock.id); } } else if (event.key === 'ArrowRight') { - const nextBlock = page + const nextBlock = blocksuiteDoc .getNexts(blockModel) .find( (block): block is ImageBlockModel => block.flavour === 'affine:image' ); if (nextBlock) { - props.onBlockIdChange(nextBlock.id); + onBlockIdChange(nextBlock.id); } } else { return; @@ -328,7 +319,7 @@ const ImagePreviewModalImpl = ( return () => { document.removeEventListener('keyup', handleKeyUp); }; - }, [blockModel, page, props]); + }, [blockModel, blocksuiteDoc, onBlockIdChange]); useErrorBoundary(error); @@ -351,8 +342,11 @@ const ImagePreviewModalImpl = ( return null; } return ( -
-
+
+
{caption}} - disabled={props.animating || cursor < 1} + disabled={cursor < 1} onClick={() => goto(cursor - 1)} />
@@ -407,7 +401,7 @@ const ImagePreviewModalImpl = ( data-testid="next-image-button" tooltip="Next" icon={} - disabled={props.animating || cursor + 1 === blocks.length} + disabled={cursor + 1 === blocks.length} onClick={() => goto(cursor + 1)} />
@@ -415,21 +409,18 @@ const ImagePreviewModalImpl = ( data-testid="fit-to-screen-button" tooltip="Fit to screen" icon={} - disabled={props.animating} onClick={() => resetZoom()} /> } - disabled={props.animating} onClick={zoomOut} /> {`${(currentScale * 100).toFixed(0)}%`} @@ -438,7 +429,6 @@ const ImagePreviewModalImpl = ( data-testid="zoom-in-button" tooltip="Zoom in" icon={} - disabled={props.animating} onClick={zoomIn} />
@@ -446,14 +436,12 @@ const ImagePreviewModalImpl = ( data-testid="download-button" tooltip="Download" icon={} - disabled={props.animating} onClick={downloadHandler} /> } - disabled={props.animating} onClick={copyHandler} />
@@ -461,7 +449,7 @@ const ImagePreviewModalImpl = ( data-testid="delete-button" tooltip="Delete" icon={} - disabled={props.animating || blocks.length === 0} + disabled={blocks.length === 0} onClick={() => deleteHandler(cursor)} />
@@ -483,67 +471,38 @@ export const ImagePreviewErrorBoundary = ( ); }; -export const ImagePreviewModal = ( +export const ImagePreviewPeekView = ( props: ImagePreviewModalProps ): ReactElement | null => { - const [show, setShow] = useState(false); - const [blockId, setBlockId] = useState(null); - const isOpen = show && !!blockId; + const [blockId, setBlockId] = useState(props.blockId); + const peekView = useService(PeekViewService).peekView; + const onClose = peekView.close; + const buttonRef = useRef(null); - // todo: refactor this to use peek view service - useLayoutEffect(() => { - const handleDblClick = (event: MouseEvent) => { - const target = event.target as HTMLElement | null; - if (target?.tagName === 'IMG') { - const imageBlock = target.closest('affine-image'); - if (imageBlock) { - const blockId = imageBlock.dataset.blockId; - if (!blockId) return; - setBlockId(blockId); - setShow(true); - } - } - }; - props.host.addEventListener('dblclick', handleDblClick); - return () => { - props.host.removeEventListener('dblclick', handleDblClick); - }; - }, [props.host]); - - const [animating, setAnimating] = useState(false); + useEffect(() => { + setBlockId(props.blockId); + }, [props.blockId]); return ( - setAnimating(true)} - onAnimateEnd={() => setAnimating(false)} - testId="image-preview-modal" - > - - - {blockId ? ( - setShow(false)} - /> - ) : null} - - - - + + + {blockId ? ( + + ) : null} + + + ); }; diff --git a/packages/frontend/core/src/modules/peek-view/view/modal-container.css.ts b/packages/frontend/core/src/modules/peek-view/view/modal-container.css.ts index d97ca50ea2..56bf7e0075 100644 --- a/packages/frontend/core/src/modules/peek-view/view/modal-container.css.ts +++ b/packages/frontend/core/src/modules/peek-view/view/modal-container.css.ts @@ -150,6 +150,11 @@ export const modalContent = style({ // :focus-visible will set outline outline: 'none', position: 'relative', + selectors: { + '&[data-no-interaction=true]': { + pointerEvents: 'none', + }, + }, }); export const modalControls = style({ diff --git a/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx b/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx index 385db277b2..0dbce1c46f 100644 --- a/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx @@ -3,6 +3,7 @@ import { assignInlineVars } from '@vanilla-extract/dynamic'; import clsx from 'clsx'; import { createContext, + forwardRef, type PropsWithChildren, useContext, useEffect, @@ -57,30 +58,38 @@ function getElementScreenPositionCenter(target: HTMLElement) { }; } -export const PeekViewModalContainer = ({ - onOpenChange, - open, - target, - controls, - children, - hideOnEntering, - onAnimationStart, - onAnimateEnd, - animation = 'zoom', - padding = true, - testId, -}: PropsWithChildren<{ - open: boolean; - hideOnEntering?: boolean; - target?: HTMLElement; +export type PeekViewModalContainerProps = PropsWithChildren<{ onOpenChange: (open: boolean) => void; + open: boolean; + target?: HTMLElement; controls?: React.ReactNode; + hideOnEntering?: boolean; onAnimationStart?: () => void; onAnimateEnd?: () => void; padding?: boolean; animation?: 'fade' | 'zoom'; testId?: string; -}>) => { +}>; + +export const PeekViewModalContainer = forwardRef< + HTMLDivElement, + PeekViewModalContainerProps +>(function PeekViewModalContainer( + { + onOpenChange, + open, + target, + controls, + children, + hideOnEntering, + onAnimationStart, + onAnimateEnd, + animation = 'zoom', + padding = true, + testId, + }, + ref +) { const [{ status }, toggle] = useTransition({ timeout: animationTimeout, }); @@ -112,6 +121,7 @@ export const PeekViewModalContainer = ({ onAnimationEnd={onAnimateEnd} />
{hideOnEntering && status === 'entering' ? null : children} @@ -148,4 +159,4 @@ export const PeekViewModalContainer = ({ ); -}; +}); 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 059d2a6944..23ac2d35f3 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,34 +5,41 @@ import { useEffect, useMemo } from 'react'; import type { ActivePeekView } from '../entities/peek-view'; import { PeekViewService } from '../services/peek-view'; -import { DocPeekPreview } from './doc-peek-view'; -import { PeekViewModalContainer } from './modal-container'; +import { DocPeekPreview } from './doc-preview'; +import { ImagePreviewPeekView } from './image-preview'; +import { + PeekViewModalContainer, + type PeekViewModalContainerProps, +} from './modal-container'; import { DefaultPeekViewControls, DocPeekViewControls, } from './peek-view-controls'; -function renderPeekView({ info, template }: ActivePeekView) { - if (template) { - return toReactNode(template); +function renderPeekView({ info }: ActivePeekView) { + if (info.type === 'template') { + return toReactNode(info.template); + } + if (info.type === 'doc') { + return ( + + ); } - if (!info) { - return null; + if (info.type === 'image') { + return ; } - return ( - - ); + return null; // unreachable } const renderControls = ({ info }: ActivePeekView) => { - if (info && 'docId' in info) { + if (info.type === 'doc') { return ( { ); } + if (info.type === 'image') { + return null; // image controls are rendered in the image preview + } + return ; }; +const getRendererProps = ( + activePeekView?: ActivePeekView +): Partial | undefined => { + if (!activePeekView) { + return; + } + + const preview = renderPeekView(activePeekView); + const controls = renderControls(activePeekView); + return { + children: preview, + controls, + target: + activePeekView?.target instanceof HTMLElement + ? activePeekView.target + : undefined, + padding: activePeekView.info.type === 'doc', + animation: activePeekView.info.type === 'image' ? 'fade' : 'zoom', + }; +}; + export const PeekViewManagerModal = () => { const peekViewEntity = useService(PeekViewService).peekView; const activePeekView = useLiveData(peekViewEntity.active$); const show = useLiveData(peekViewEntity.show$); - const preview = useMemo(() => { - return activePeekView ? renderPeekView(activePeekView) : null; - }, [activePeekView]); - - const controls = useMemo(() => { - return activePeekView ? renderControls(activePeekView) : null; + const renderProps = useMemo(() => { + if (!activePeekView) { + return; + } + return getRendererProps(activePeekView); }, [activePeekView]); useEffect(() => { @@ -72,20 +103,15 @@ export const PeekViewManagerModal = () => { return ( { if (!open) { peekViewEntity.close(); } }} > - {preview} + {renderProps?.children} ); }; diff --git a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx index 6bd5c010ce..8af1894175 100644 --- a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx +++ b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx @@ -36,7 +36,6 @@ import type { Map as YMap } from 'yjs'; import { AffineErrorBoundary } from '../../../components/affine/affine-error-boundary'; import { GlobalPageHistoryModal } from '../../../components/affine/page-history-modal'; -import { ImagePreviewModal } from '../../../components/image-preview'; import { PageDetailEditor } from '../../../components/page-detail-editor'; import { TrashPageFooter } from '../../../components/pure/trash-page-footer'; import { TopTip } from '../../../components/top-tip'; @@ -311,14 +310,6 @@ const DetailPageImpl = memo(function DetailPageImpl() { } /> - - {editor?.host ? ( - - ) : null} diff --git a/packages/frontend/electron/package.json b/packages/frontend/electron/package.json index 83ac8d2c2a..fc1a6f646d 100644 --- a/packages/frontend/electron/package.json +++ b/packages/frontend/electron/package.json @@ -29,10 +29,10 @@ "@affine/env": "workspace:*", "@affine/i18n": "workspace:*", "@affine/native": "workspace:*", - "@blocksuite/block-std": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/blocks": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/presets": "0.15.0-canary-202406252341-172c4b8", - "@blocksuite/store": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/block-std": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/blocks": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/presets": "0.15.0-canary-202406260417-3b9fb16", + "@blocksuite/store": "0.15.0-canary-202406260417-3b9fb16", "@electron-forge/cli": "^7.3.0", "@electron-forge/core": "^7.3.0", "@electron-forge/core-utils": "^7.3.0", diff --git a/tests/affine-local/e2e/image-preview.spec.ts b/tests/affine-local/e2e/image-preview.spec.ts index ac479a9cec..8448cb6f7b 100644 --- a/tests/affine-local/e2e/image-preview.spec.ts +++ b/tests/affine-local/e2e/image-preview.spec.ts @@ -38,11 +38,7 @@ async function importImage(page: Page, url: string) { } async function closeImagePreviewModal(page: Page) { - await page - .getByTestId('image-preview-modal') - .getByTestId('image-preview-close-button') - .first() - .click(); + await page.getByTestId('image-preview-close-button').first().click(); await page.waitForTimeout(500); } diff --git a/tools/cli/package.json b/tools/cli/package.json index 0491b9187b..95fc66b4ee 100644 --- a/tools/cli/package.json +++ b/tools/cli/package.json @@ -6,7 +6,7 @@ "@affine/env": "workspace:*", "@affine/templates": "workspace:*", "@aws-sdk/client-s3": "3.592.0", - "@blocksuite/presets": "0.15.0-canary-202406252341-172c4b8", + "@blocksuite/presets": "0.15.0-canary-202406260417-3b9fb16", "@clack/core": "^0.3.4", "@clack/prompts": "^0.7.0", "@magic-works/i18n-codegen": "^0.6.0", diff --git a/yarn.lock b/yarn.lock index fd4b556402..435f1f7b2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -226,7 +226,7 @@ __metadata: "@affine/env": "workspace:*" "@affine/templates": "workspace:*" "@aws-sdk/client-s3": "npm:3.592.0" - "@blocksuite/presets": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/presets": "npm:0.15.0-canary-202406260417-3b9fb16" "@clack/core": "npm:^0.3.4" "@clack/prompts": "npm:^0.7.0" "@magic-works/i18n-codegen": "npm:^0.6.0" @@ -282,12 +282,12 @@ __metadata: "@affine/electron-api": "workspace:*" "@affine/graphql": "workspace:*" "@affine/i18n": "workspace:*" - "@blocksuite/block-std": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/blocks": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/block-std": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/blocks": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" "@blocksuite/icons": "npm:2.1.58" - "@blocksuite/presets": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/store": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/presets": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/store": "npm:0.15.0-canary-202406260417-3b9fb16" "@dnd-kit/core": "npm:^6.1.0" "@dnd-kit/modifiers": "npm:^7.0.0" "@dnd-kit/sortable": "npm:^8.0.0" @@ -383,13 +383,13 @@ __metadata: "@affine/graphql": "workspace:*" "@affine/i18n": "workspace:*" "@affine/templates": "workspace:*" - "@blocksuite/block-std": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/blocks": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/block-std": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/blocks": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" "@blocksuite/icons": "npm:2.1.58" - "@blocksuite/inline": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/presets": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/store": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/inline": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/presets": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/store": "npm:0.15.0-canary-202406260417-3b9fb16" "@dnd-kit/core": "npm:^6.1.0" "@dnd-kit/modifiers": "npm:^7.0.0" "@dnd-kit/sortable": "npm:^8.0.0" @@ -514,10 +514,10 @@ __metadata: "@affine/env": "workspace:*" "@affine/i18n": "workspace:*" "@affine/native": "workspace:*" - "@blocksuite/block-std": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/blocks": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/presets": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/store": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/block-std": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/blocks": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/presets": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/store": "npm:0.15.0-canary-202406260417-3b9fb16" "@electron-forge/cli": "npm:^7.3.0" "@electron-forge/core": "npm:^7.3.0" "@electron-forge/core-utils": "npm:^7.3.0" @@ -573,8 +573,8 @@ __metadata: version: 0.0.0-use.local resolution: "@affine/env@workspace:packages/common/env" dependencies: - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/store": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/store": "npm:0.15.0-canary-202406260417-3b9fb16" lit: "npm:^3.1.2" react: "npm:18.3.1" react-dom: "npm:18.3.1" @@ -4105,30 +4105,30 @@ __metadata: languageName: node linkType: hard -"@blocksuite/block-std@npm:0.15.0-canary-202406252341-172c4b8": - version: 0.15.0-canary-202406252341-172c4b8 - resolution: "@blocksuite/block-std@npm:0.15.0-canary-202406252341-172c4b8" +"@blocksuite/block-std@npm:0.15.0-canary-202406260417-3b9fb16": + version: 0.15.0-canary-202406260417-3b9fb16 + resolution: "@blocksuite/block-std@npm:0.15.0-canary-202406260417-3b9fb16" dependencies: - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" lit: "npm:^3.1.3" lz-string: "npm:^1.5.0" w3c-keyname: "npm:^2.2.8" zod: "npm:^3.23.8" peerDependencies: - "@blocksuite/inline": 0.15.0-canary-202406252341-172c4b8 - "@blocksuite/store": 0.15.0-canary-202406252341-172c4b8 - checksum: 10/b3019cd56ac99e3474929a2a6bd9959035dc1901d4e6ab2c3e9911fd8ead94ba0b6025b8fa88d9987f5731c7f331e539e4402a3a0188531d77ae57f0df928d5c + "@blocksuite/inline": 0.15.0-canary-202406260417-3b9fb16 + "@blocksuite/store": 0.15.0-canary-202406260417-3b9fb16 + checksum: 10/5f39220f61a25205740097265610ee87faf6285a8ad6b1a0959ddfebda5c13df6d23de87af2e5d497c5e805ca546b0030328918e8ec7c8052721cdc72d44a547 languageName: node linkType: hard -"@blocksuite/blocks@npm:0.15.0-canary-202406252341-172c4b8": - version: 0.15.0-canary-202406252341-172c4b8 - resolution: "@blocksuite/blocks@npm:0.15.0-canary-202406252341-172c4b8" +"@blocksuite/blocks@npm:0.15.0-canary-202406260417-3b9fb16": + version: 0.15.0-canary-202406260417-3b9fb16 + resolution: "@blocksuite/blocks@npm:0.15.0-canary-202406260417-3b9fb16" dependencies: - "@blocksuite/block-std": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/inline": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/store": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/block-std": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/inline": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/store": "npm:0.15.0-canary-202406260417-3b9fb16" "@dotlottie/player-component": "npm:^2.7.12" "@floating-ui/dom": "npm:^1.6.5" "@lit/context": "npm:^1.1.1" @@ -4165,17 +4165,17 @@ __metadata: sortablejs: "npm:^1.15.2" unified: "npm:^11.0.4" zod: "npm:^3.23.8" - checksum: 10/4a35f9ecf79be53cafd53c197b8f1335f2615e91f68b417473a8681e5c57bc0c62954eb1a5925c0e49899144dd6a95b10900ef0bdbae1709fc20118797f09b58 + checksum: 10/e96521e726df32722c044be42355a3161251afb1ef77e19396fe20d5593b05e3a6a54bb57791c80521b43078d5573374286a6b7f0874f75f9f7a2dd5c9741dee languageName: node linkType: hard -"@blocksuite/global@npm:0.15.0-canary-202406252341-172c4b8": - version: 0.15.0-canary-202406252341-172c4b8 - resolution: "@blocksuite/global@npm:0.15.0-canary-202406252341-172c4b8" +"@blocksuite/global@npm:0.15.0-canary-202406260417-3b9fb16": + version: 0.15.0-canary-202406260417-3b9fb16 + resolution: "@blocksuite/global@npm:0.15.0-canary-202406260417-3b9fb16" dependencies: lib0: "npm:^0.2.94" zod: "npm:^3.23.8" - checksum: 10/e4804b03a03fbd019616c54729563f2fd087d302034529829a1ad7dd8343ac405ee18776cd3f36409e447e4f07b7a8b7099d915af5fb834db21d7be4e0eb3f08 + checksum: 10/2d4717ef757045ae494df389b78548d873accd294d8ae9742e789a4e759cda3c180bad2063015b8d804d5120c1ee6910ad3409dcf68347a001742a5d0a452452 languageName: node linkType: hard @@ -4195,45 +4195,45 @@ __metadata: languageName: node linkType: hard -"@blocksuite/inline@npm:0.15.0-canary-202406252341-172c4b8": - version: 0.15.0-canary-202406252341-172c4b8 - resolution: "@blocksuite/inline@npm:0.15.0-canary-202406252341-172c4b8" +"@blocksuite/inline@npm:0.15.0-canary-202406260417-3b9fb16": + version: 0.15.0-canary-202406260417-3b9fb16 + resolution: "@blocksuite/inline@npm:0.15.0-canary-202406260417-3b9fb16" dependencies: - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" zod: "npm:^3.23.8" peerDependencies: lit: ^3.1.1 yjs: ^13.6.15 - checksum: 10/766524a5c923bc2be852763173042d59bd1dbe7736c37fb096a23bab580fa2baa85e768333f72ccdf3d362ba91ec19cff0cda4a8ef072489581cbf846859bc38 + checksum: 10/8c4387116ddc3f65408cc15b4ef1e63f089d8b18891ac79a78c8707c6e88c0d8d6017768c38877e38e73d977f7ca4618d8fe09da8b9cc5e429273dbcd066e176 languageName: node linkType: hard -"@blocksuite/presets@npm:0.15.0-canary-202406252341-172c4b8": - version: 0.15.0-canary-202406252341-172c4b8 - resolution: "@blocksuite/presets@npm:0.15.0-canary-202406252341-172c4b8" +"@blocksuite/presets@npm:0.15.0-canary-202406260417-3b9fb16": + version: 0.15.0-canary-202406260417-3b9fb16 + resolution: "@blocksuite/presets@npm:0.15.0-canary-202406260417-3b9fb16" dependencies: - "@blocksuite/block-std": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/blocks": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/inline": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/store": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/block-std": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/blocks": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/inline": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/store": "npm:0.15.0-canary-202406260417-3b9fb16" "@dotlottie/player-component": "npm:^2.7.12" "@fal-ai/serverless-client": "npm:^0.10.0" "@floating-ui/dom": "npm:^1.6.5" "@toeverything/theme": "npm:^0.7.32" lit: "npm:^3.1.3" openai: "npm:^4.47.2" - checksum: 10/f15f9cf8293c132df0cf48b83021a328a45a29e8426a2ab28878e18e80e23aebd1d3c8a8429af49df97c3c178bb71be47a15cf2559672ff6de901508a599324d + checksum: 10/7ca99e06c13edbb2585dbc2fc79a2f3f231e17698d361407f4921947cf460efaac8eb63c8c28817d085507139171ebb6179b2fb781dba648785337aba07728e3 languageName: node linkType: hard -"@blocksuite/store@npm:0.15.0-canary-202406252341-172c4b8": - version: 0.15.0-canary-202406252341-172c4b8 - resolution: "@blocksuite/store@npm:0.15.0-canary-202406252341-172c4b8" +"@blocksuite/store@npm:0.15.0-canary-202406260417-3b9fb16": + version: 0.15.0-canary-202406260417-3b9fb16 + resolution: "@blocksuite/store@npm:0.15.0-canary-202406260417-3b9fb16" dependencies: - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/inline": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/sync": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/inline": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/sync": "npm:0.15.0-canary-202406260417-3b9fb16" "@types/flexsearch": "npm:^0.7.6" flexsearch: "npm:0.7.43" lib0: "npm:^0.2.94" @@ -4244,21 +4244,21 @@ __metadata: zod: "npm:^3.23.8" peerDependencies: yjs: ^13.6.15 - checksum: 10/fc63b49298debf3afbbed25e0671418ea2b0e1963f955c2ca51d7f8f86994b7ff83fbbbb1e89a78eb2c9e5643ecbd27f1e1565a13ba3d9dd5710a1efb0132755 + checksum: 10/7e5aa60619d6cac4619d390391d190c2401e47d12cc7df5db315e492a2fda701aa93aa791bcef8bf73fdfc9180d54f0bb1d007b81755f0c12f29d0379827fa77 languageName: node linkType: hard -"@blocksuite/sync@npm:0.15.0-canary-202406252341-172c4b8": - version: 0.15.0-canary-202406252341-172c4b8 - resolution: "@blocksuite/sync@npm:0.15.0-canary-202406252341-172c4b8" +"@blocksuite/sync@npm:0.15.0-canary-202406260417-3b9fb16": + version: 0.15.0-canary-202406260417-3b9fb16 + resolution: "@blocksuite/sync@npm:0.15.0-canary-202406260417-3b9fb16" dependencies: - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" idb: "npm:^8.0.0" idb-keyval: "npm:^6.2.1" y-protocols: "npm:^1.0.6" peerDependencies: yjs: ^13.6.15 - checksum: 10/22a320983945d14f28fdd83baf219e8a2e3b37ead6556cff58557b1822b3f84ec841e6c1373cf62ae536923d45baea007c6e155839fbde5539105304aeb7da83 + checksum: 10/f1493bf7d54e1ea2990ba6898c4df0cc3fb2f193e81281bf3fbbe0093e6252e655d69b3af059a09a6f35180490d2291beb25b2f7e9d0208b1fd0e7b509504c2f languageName: node linkType: hard @@ -15649,11 +15649,11 @@ __metadata: "@affine/debug": "workspace:*" "@affine/env": "workspace:*" "@affine/templates": "workspace:*" - "@blocksuite/block-std": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/blocks": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/global": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/presets": "npm:0.15.0-canary-202406252341-172c4b8" - "@blocksuite/store": "npm:0.15.0-canary-202406252341-172c4b8" + "@blocksuite/block-std": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/blocks": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/global": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/presets": "npm:0.15.0-canary-202406260417-3b9fb16" + "@blocksuite/store": "npm:0.15.0-canary-202406260417-3b9fb16" "@datastructures-js/binary-search-tree": "npm:^5.3.2" "@testing-library/react": "npm:^16.0.0" async-call-rpc: "npm:^6.4.0"