From eca484dc28bd76899a29cec7ca31a3f137bc3711 Mon Sep 17 00:00:00 2001 From: EYHN Date: Fri, 28 Jun 2024 14:19:59 +0800 Subject: [PATCH] fix(core): add loading for insert ai template (#7369) --- packages/common/infra/src/livedata/ops.ts | 1 - .../core/src/layouts/workspace-layout.tsx | 78 ++++++++++++++++--- packages/frontend/i18n/src/resources/en.json | 3 +- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/packages/common/infra/src/livedata/ops.ts b/packages/common/infra/src/livedata/ops.ts index a066b6b459..34e08674c2 100644 --- a/packages/common/infra/src/livedata/ops.ts +++ b/packages/common/infra/src/livedata/ops.ts @@ -107,7 +107,6 @@ export function fromPromise( .catch(error => { subscriber.error(error); }); - return () => abortController.abort('Aborted'); }); } diff --git a/packages/frontend/core/src/layouts/workspace-layout.tsx b/packages/frontend/core/src/layouts/workspace-layout.tsx index dda88d5a2f..1ba1a292c7 100644 --- a/packages/frontend/core/src/layouts/workspace-layout.tsx +++ b/packages/frontend/core/src/layouts/workspace-layout.tsx @@ -1,3 +1,9 @@ +import { toast } from '@affine/component'; +import { + pushGlobalLoadingEventAtom, + resolveGlobalLoadingEventAtom, +} from '@affine/component/global-loading'; +import { useI18n } from '@affine/i18n'; import { ZipTransformer } from '@blocksuite/blocks'; import { assertExists } from '@blocksuite/global/utils'; import { @@ -9,8 +15,13 @@ import { useSensors, } from '@dnd-kit/core'; import { + type DocMode, DocsService, + effect, + fromPromise, GlobalContextService, + onStart, + throwIfAborted, useLiveData, useService, WorkspaceService, @@ -19,6 +30,14 @@ import { useAtomValue, useSetAtom } from 'jotai'; import type { PropsWithChildren, ReactNode } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { createPortal } from 'react-dom'; +import { + catchError, + EMPTY, + finalize, + mergeMap, + switchMap, + timeout, +} from 'rxjs'; import { Map as YMap } from 'yjs'; import { openSettingModalAtom } from '../atoms'; @@ -103,6 +122,9 @@ export const WorkspaceLayout = function WorkspaceLayout({ }; export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => { + const t = useI18n(); + const pushGlobalLoadingEvent = useSetAtom(pushGlobalLoadingEventAtom); + const resolveGlobalLoadingEvent = useSetAtom(resolveGlobalLoadingEventAtom); const currentWorkspace = useService(WorkspaceService).workspace; const docsList = useService(DocsService).list; const { openPage } = useNavigateHelper(); @@ -120,26 +142,60 @@ export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => { ); useEffect(() => { - const disposable = AIProvider.slots.requestInsertTemplate.on( - ({ template, mode }) => { - (async () => { - const templateZip = await fetch(template); + const insertTemplate = effect( + switchMap(({ template, mode }: { template: string; mode: string }) => { + return fromPromise(async abort => { + const templateZip = await fetch(template, { signal: abort }); const templateBlob = await templateZip.blob(); + throwIfAborted(abort); const [doc] = await ZipTransformer.importDocs( currentWorkspace.docCollection, templateBlob ); doc.resetHistory(); - docsList.setMode(doc.id, mode); - workbench.openPage(doc.id); - })().catch(err => { - console.error(err); - }); + return { doc, mode }; + }).pipe( + timeout(10000 /* 10s */), + mergeMap(({ mode, doc }) => { + docsList.setMode(doc.id, mode as DocMode); + workbench.openPage(doc.id); + return EMPTY; + }), + onStart(() => { + pushGlobalLoadingEvent({ + key: 'insert-template', + }); + }), + catchError(err => { + console.error(err); + toast(t['com.affine.ai.template-insert.failed']()); + return EMPTY; + }), + finalize(() => { + resolveGlobalLoadingEvent('insert-template'); + }) + ); + }) + ); + + const disposable = AIProvider.slots.requestInsertTemplate.on( + ({ template, mode }) => { + insertTemplate({ template, mode }); } ); - return () => disposable.dispose(); - }, [currentWorkspace.docCollection, docsList, workbench]); + return () => { + disposable.dispose(); + insertTemplate.unsubscribe(); + }; + }, [ + currentWorkspace.docCollection, + docsList, + pushGlobalLoadingEvent, + resolveGlobalLoadingEvent, + t, + workbench, + ]); useRegisterWorkspaceCommands(); useRegisterNavigationCommands(); diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 951a0ca74d..c823c93ca4 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -1342,5 +1342,6 @@ "will be moved to Trash": "{{title}} will be moved to Trash", "will delete member": "will delete member", "com.affine.user-info.usage.ai": "AI Usage", - "com.affine.user-info.usage.cloud": "Cloud Storage" + "com.affine.user-info.usage.cloud": "Cloud Storage", + "com.affine.ai.template-insert.failed": "Failed to insert template, please try again." }