diff --git a/packages/frontend/core/src/components/cloud/share-header-right-item/import-template.tsx b/packages/frontend/core/src/components/cloud/share-header-right-item/import-template.tsx index 5bc38bc9d0..7609e80ed6 100644 --- a/packages/frontend/core/src/components/cloud/share-header-right-item/import-template.tsx +++ b/packages/frontend/core/src/components/cloud/share-header-right-item/import-template.tsx @@ -3,20 +3,18 @@ import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; import { useI18n } from '@affine/i18n'; export const ImportTemplateButton = ({ - workspaceId, - docId, name, + snapshotUrl, }: { - workspaceId: string; - docId: string; name: string; + snapshotUrl: string; }) => { const t = useI18n(); const { jumpToImportTemplate } = useNavigateHelper(); return ( diff --git a/packages/frontend/core/src/components/cloud/share-header-right-item/index.tsx b/packages/frontend/core/src/components/cloud/share-header-right-item/index.tsx index 88a86f0b48..42ea2f5ba5 100644 --- a/packages/frontend/core/src/components/cloud/share-header-right-item/index.tsx +++ b/packages/frontend/core/src/components/cloud/share-header-right-item/index.tsx @@ -9,19 +9,17 @@ import * as styles from './styles.css'; import { PublishPageUserAvatar } from './user-avatar'; export type ShareHeaderRightItemProps = { - workspaceId: string; - docId: string; publishMode: DocMode; isTemplate?: boolean; templateName?: string; + snapshotUrl?: string; }; const ShareHeaderRightItem = ({ publishMode, isTemplate, templateName, - workspaceId, - docId, + snapshotUrl, }: ShareHeaderRightItemProps) => { const loginStatus = useLiveData(useService(AuthService).session.status$); const authenticated = loginStatus === 'authenticated'; @@ -29,9 +27,8 @@ const ShareHeaderRightItem = ({
{isTemplate ? ( ) : ( <> diff --git a/packages/frontend/core/src/hooks/use-navigate-helper.ts b/packages/frontend/core/src/hooks/use-navigate-helper.ts index 5c7fd27ea9..565be85e48 100644 --- a/packages/frontend/core/src/hooks/use-navigate-helper.ts +++ b/packages/frontend/core/src/hooks/use-navigate-helper.ts @@ -183,9 +183,9 @@ export function useNavigateHelper() { ); const jumpToImportTemplate = useCallback( - (workspaceId: string, docId: string, name: string) => { + (name: string, snapshotUrl: string) => { return navigate( - `/template/import?workspaceId=${encodeURIComponent(workspaceId)}&docId=${encodeURIComponent(docId)}&name=${encodeURIComponent(name)}` + `/template/import?name=${encodeURIComponent(name)}&snapshotUrl=${encodeURIComponent(snapshotUrl)}` ); }, [navigate] diff --git a/packages/frontend/core/src/modules/import-template/entities/dialog.ts b/packages/frontend/core/src/modules/import-template/entities/dialog.ts index a1253c983b..f81a756553 100644 --- a/packages/frontend/core/src/modules/import-template/entities/dialog.ts +++ b/packages/frontend/core/src/modules/import-template/entities/dialog.ts @@ -1,15 +1,16 @@ import { Entity, LiveData } from '@toeverything/infra'; +interface TemplateOptions { + templateName: string; + snapshotUrl: string; +} + export class ImportTemplateDialog extends Entity { readonly isOpen$ = new LiveData(false); - readonly template$ = new LiveData<{ - workspaceId: string; - docId: string; - templateName: string; - } | null>(null); + readonly template$ = new LiveData(null); - open(workspaceId: string, docId: string, templateName: string) { - this.template$.next({ workspaceId, docId, templateName }); + open(options: TemplateOptions) { + this.template$.next(options); this.isOpen$.next(true); } diff --git a/packages/frontend/core/src/modules/import-template/entities/downloader.ts b/packages/frontend/core/src/modules/import-template/entities/downloader.ts index 7ddb334904..ef3250beee 100644 --- a/packages/frontend/core/src/modules/import-template/entities/downloader.ts +++ b/packages/frontend/core/src/modules/import-template/entities/downloader.ts @@ -23,29 +23,27 @@ export class TemplateDownloader extends Entity { readonly error$ = new LiveData(null); readonly download = effect( - switchMap( - ({ workspaceId, docId }: { workspaceId: string; docId: string }) => { - return fromPromise(() => this.store.download(workspaceId, docId)).pipe( - mergeMap(({ data }) => { - this.data$.next(data); - return EMPTY; - }), - backoffRetry({ - when: isNetworkError, - count: Infinity, - }), - backoffRetry({ - when: isBackendError, - }), - catchErrorInto(this.error$), - onStart(() => { - this.isDownloading$.next(true); - this.data$.next(null); - this.error$.next(null); - }), - onComplete(() => this.isDownloading$.next(false)) - ); - } - ) + switchMap(({ snapshotUrl }: { snapshotUrl: string }) => { + return fromPromise(() => this.store.download(snapshotUrl)).pipe( + mergeMap(({ data }) => { + this.data$.next(data); + return EMPTY; + }), + backoffRetry({ + when: isNetworkError, + count: Infinity, + }), + backoffRetry({ + when: isBackendError, + }), + catchErrorInto(this.error$), + onStart(() => { + this.isDownloading$.next(true); + this.data$.next(null); + this.error$.next(null); + }), + onComplete(() => this.isDownloading$.next(false)) + ); + }) ); } diff --git a/packages/frontend/core/src/modules/import-template/services/import.ts b/packages/frontend/core/src/modules/import-template/services/import.ts index b97a4e7cfd..8c65bc27e4 100644 --- a/packages/frontend/core/src/modules/import-template/services/import.ts +++ b/packages/frontend/core/src/modules/import-template/services/import.ts @@ -1,7 +1,7 @@ import type { WorkspaceFlavour } from '@affine/env/workspace'; import { ZipTransformer } from '@blocksuite/blocks'; import type { WorkspaceMetadata, WorkspacesService } from '@toeverything/infra'; -import { Service } from '@toeverything/infra'; +import { DocsService, Service } from '@toeverything/infra'; export class ImportTemplateService extends Service { constructor(private readonly workspacesService: WorkspacesService) { @@ -23,7 +23,10 @@ export class ImportTemplateService extends Service { type: 'application/zip', }) ); + const docsService = workspace.scope.get(DocsService); if (importedDoc) { + // only support page mode for now + docsService.list.setPrimaryMode(importedDoc.id, 'page'); disposeWorkspace(); return importedDoc.id; } else { diff --git a/packages/frontend/core/src/modules/import-template/store/downloader.ts b/packages/frontend/core/src/modules/import-template/store/downloader.ts index e01fbe1e3e..de3ed824e5 100644 --- a/packages/frontend/core/src/modules/import-template/store/downloader.ts +++ b/packages/frontend/core/src/modules/import-template/store/downloader.ts @@ -7,16 +7,10 @@ export class TemplateDownloaderStore extends Store { super(); } - async download( - /* not support workspaceid for now */ _workspaceId: string, - docId: string - ) { - const response = await this.fetchService.fetch( - `https://affine.pro/templates/snapshots/${docId}.zip `, - { - priority: 'high', - } as any - ); + async download(snapshotUrl: string) { + const response = await this.fetchService.fetch(snapshotUrl, { + priority: 'high', + } as any); const arrayBuffer = await response.arrayBuffer(); return { data: new Uint8Array(arrayBuffer) }; diff --git a/packages/frontend/core/src/modules/import-template/views/dialog.tsx b/packages/frontend/core/src/modules/import-template/views/dialog.tsx index 9ce6aaa897..a3b0060f00 100644 --- a/packages/frontend/core/src/modules/import-template/views/dialog.tsx +++ b/packages/frontend/core/src/modules/import-template/views/dialog.tsx @@ -23,14 +23,12 @@ import { ImportTemplateService } from '../services/import'; import * as styles from './dialog.css'; const Dialog = ({ - workspaceId, - docId, templateName, + snapshotUrl, onClose, }: { - workspaceId: string; - docId: string; templateName: string; + snapshotUrl: string; onClose?: () => void; }) => { const t = useI18n(); @@ -69,28 +67,26 @@ const Dialog = ({ useEffect(() => { if (!isSessionRevalidating && notLogin) { jumpToSignIn( - '/template/import?workspaceId=' + - workspaceId + - '&docId=' + - docId + + '/template/import?' + '&name=' + - templateName + templateName + + '&snapshotUrl=' + + snapshotUrl ); onClose?.(); } }, [ - docId, isSessionRevalidating, jumpToSignIn, notLogin, onClose, + snapshotUrl, templateName, - workspaceId, ]); useEffect(() => { - templateDownloader.download({ workspaceId, docId }); - }, [docId, templateDownloader, workspaceId]); + templateDownloader.download({ snapshotUrl }); + }, [snapshotUrl, templateDownloader]); const handleSelectedWorkspace = useCallback( (workspaceMetadata: WorkspaceMetadata) => { @@ -238,9 +234,8 @@ export const ImportTemplateDialogProvider = () => { > {template && ( importTemplateDialogService.dialog.close()} /> )} diff --git a/packages/frontend/core/src/pages/import-template.tsx b/packages/frontend/core/src/pages/import-template.tsx index 41e6e40101..8a67cc0d80 100644 --- a/packages/frontend/core/src/pages/import-template.tsx +++ b/packages/frontend/core/src/pages/import-template.tsx @@ -10,11 +10,10 @@ export const Component = () => { const [searchParams] = useSearchParams(); const { jumpToIndex } = useNavigateHelper(); useEffect(() => { - importTemplateDialogService.dialog.open( - searchParams.get('workspaceId') ?? '', - searchParams.get('docId') ?? '', - searchParams.get('name') ?? '' - ); + importTemplateDialogService.dialog.open({ + templateName: searchParams.get('name') ?? '', + snapshotUrl: searchParams.get('snapshotUrl') ?? '', + }); }, [importTemplateDialogService.dialog, jumpToIndex, searchParams]); // no ui for this route, just open the dialog return null; diff --git a/packages/frontend/core/src/pages/workspace/share/share-header.tsx b/packages/frontend/core/src/pages/workspace/share/share-header.tsx index f09d01a2a1..532169364f 100644 --- a/packages/frontend/core/src/pages/workspace/share/share-header.tsx +++ b/packages/frontend/core/src/pages/workspace/share/share-header.tsx @@ -3,22 +3,21 @@ import { BlocksuiteHeaderTitle } from '@affine/core/components/blocksuite/block- import { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch'; import ShareHeaderRightItem from '@affine/core/components/cloud/share-header-right-item'; import type { DocMode } from '@blocksuite/blocks'; -import type { DocCollection } from '@blocksuite/store'; import * as styles from './share-header.css'; export function ShareHeader({ pageId, publishMode, - docCollection, isTemplate, templateName, + snapshotUrl, }: { pageId: string; publishMode: DocMode; - docCollection: DocCollection; isTemplate?: boolean; templateName?: string; + snapshotUrl?: string; }) { return (
@@ -26,10 +25,9 @@ export function ShareHeader({
diff --git a/packages/frontend/core/src/pages/workspace/share/share-page.tsx b/packages/frontend/core/src/pages/workspace/share/share-page.tsx index 30f11d03ab..df8b3eb095 100644 --- a/packages/frontend/core/src/pages/workspace/share/share-page.tsx +++ b/packages/frontend/core/src/pages/workspace/share/share-page.tsx @@ -57,19 +57,21 @@ export const SharePage = ({ const location = useLocation(); - const { mode, isTemplate, templateName } = useMemo(() => { - const searchParams = new URLSearchParams(location.search); - const queryStringMode = searchParams.get('mode') as DocMode | null; + const { mode, isTemplate, templateName, templateSnapshotUrl } = + useMemo(() => { + const searchParams = new URLSearchParams(location.search); + const queryStringMode = searchParams.get('mode') as DocMode | null; - return { - mode: - queryStringMode && DocModes.includes(queryStringMode) - ? queryStringMode - : null, - isTemplate: searchParams.has('isTemplate'), - templateName: searchParams.get('templateName') || '', - }; - }, [location.search]); + return { + mode: + queryStringMode && DocModes.includes(queryStringMode) + ? queryStringMode + : null, + isTemplate: searchParams.has('isTemplate'), + templateName: searchParams.get('templateName') || '', + templateSnapshotUrl: searchParams.get('snapshotUrl') || '', + }; + }, [location.search]); useEffect(() => { shareReaderService.reader.loadShare({ workspaceId, docId }); @@ -94,6 +96,7 @@ export const SharePage = ({ publishMode={mode || data.publishMode} isTemplate={isTemplate} templateName={templateName} + templateSnapshotUrl={templateSnapshotUrl} /> ); } else { @@ -109,6 +112,7 @@ const SharePageInner = ({ publishMode = 'page' as DocMode, isTemplate, templateName, + templateSnapshotUrl, }: { workspaceId: string; docId: string; @@ -117,6 +121,7 @@ const SharePageInner = ({ publishMode?: DocMode; isTemplate?: boolean; templateName?: string; + templateSnapshotUrl?: string; }) => { const workspacesService = useService(WorkspacesService); @@ -227,9 +232,9 @@ const SharePageInner = ({