From d1c295d5177083602547c2f5c327e818c88d4516 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Fri, 18 Oct 2024 14:12:22 +0800 Subject: [PATCH] feat(blocks): allow peek view to be closed by the caller --- .../specs/custom/spec-patchers.tsx | 20 ++++++++++---- .../modules/peek-view/entities/peek-view.ts | 27 +++++++++++++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx index 6bdce4f58843a..1d23ee38f6736 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx @@ -11,7 +11,6 @@ import type { EditorService } from '@affine/core/modules/editor'; import { EditorSettingService } from '@affine/core/modules/editor-settting'; import { resolveLinkToDoc } from '@affine/core/modules/navigation'; import type { PeekViewService } from '@affine/core/modules/peek-view'; -import type { ActivePeekView } from '@affine/core/modules/peek-view/entities/peek-view'; import { CreationQuickSearchSession, DocsQuickSearchSession, @@ -35,6 +34,8 @@ import type { AffineReference, DocMode, DocModeProvider, + PeekOptions, + PeekViewService as BSPeekViewService, QuickSearchResult, RootService, } from '@blocksuite/affine/blocks'; @@ -243,11 +244,20 @@ export function patchEmbedLinkedDocBlockConfig(framework: FrameworkProvider) { export function patchPeekViewService(service: PeekViewService) { return PeekViewExtension({ - peek: (target: ActivePeekView['target'], template?: TemplateResult) => { - logger.debug('center peek', target, template); - return service.peekView.open(target, template); + peek: ( + element: { + target: HTMLElement; + docId: string; + blockIds?: string[]; + template?: TemplateResult; + }, + options?: PeekOptions + ) => { + logger.debug('center peek', element); + const { template, ...target } = element; + return service.peekView.open(target, template, options?.abortSignal); }, - }); + } satisfies BSPeekViewService); } export function patchDocModeService( 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 6556b6c6a6766..af4a3801d40f8 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 @@ -208,7 +208,8 @@ export class PeekViewEntity extends Entity { // return true if the peek view will be handled open = async ( target: ActivePeekView['target'], - template?: TemplateResult + template?: TemplateResult, + abortSignal?: AbortSignal ) => { const resolvedInfo = resolvePeekInfoFromPeekTarget(target, template); if (!resolvedInfo) { @@ -220,7 +221,11 @@ export class PeekViewEntity extends Entity { // 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?.value) { // TODO(@pengx17): scroll to the viewing position? - this.workbenchService.workbench.openDoc(active.info.docId); + this.workbenchService.workbench.openDoc({ + docId: active.info.docId, + blockIds: active.info.blockIds, + elementIds: active.info.elementIds, + }); } this._active$.next({ target, info: resolvedInfo }); @@ -231,6 +236,24 @@ export class PeekViewEntity extends Entity { ? 'zoom' : 'fade', }); + + if (abortSignal) { + const abortListener = () => { + if (this.active$.value?.target === target) { + this.close(); + } + }; + + abortSignal.addEventListener('abort', abortListener); + + const showSubscription = this.show$.subscribe(v => { + if (!v && !abortSignal.aborted) { + abortSignal.removeEventListener('abort', abortListener); + showSubscription.unsubscribe(); + } + }); + } + return firstValueFrom(race(this._active$, this.show$).pipe(map(() => {}))); };