mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
feat(core): add clipper import interface (#10619)
This commit is contained in:
10
packages/frontend/core/src/modules/import-clipper/index.ts
Normal file
10
packages/frontend/core/src/modules/import-clipper/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { type Framework } from '@toeverything/infra';
|
||||
|
||||
import { WorkspacesService } from '../workspace';
|
||||
import { ImportClipperService } from './services/import';
|
||||
|
||||
export { type ClipperInput, ImportClipperService } from './services/import';
|
||||
|
||||
export function configureImportClipperModule(framework: Framework) {
|
||||
framework.service(ImportClipperService, [WorkspacesService]);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { MarkdownTransformer } from '@blocksuite/affine/blocks';
|
||||
import { Service } from '@toeverything/infra';
|
||||
|
||||
import { DocsService } from '../../doc';
|
||||
import {
|
||||
getAFFiNEWorkspaceSchema,
|
||||
type WorkspaceMetadata,
|
||||
type WorkspacesService,
|
||||
} from '../../workspace';
|
||||
|
||||
export interface ClipperInput {
|
||||
title: string;
|
||||
contentMarkdown: string;
|
||||
contentHtml: string;
|
||||
attachments: Record<string, Blob>;
|
||||
}
|
||||
|
||||
export class ImportClipperService extends Service {
|
||||
constructor(private readonly workspacesService: WorkspacesService) {
|
||||
super();
|
||||
}
|
||||
|
||||
async importToWorkspace(
|
||||
workspaceMetadata: WorkspaceMetadata,
|
||||
clipperInput: ClipperInput
|
||||
) {
|
||||
const { workspace, dispose: disposeWorkspace } =
|
||||
this.workspacesService.open({
|
||||
metadata: workspaceMetadata,
|
||||
});
|
||||
await workspace.engine.doc.waitForDocReady(workspace.id); // wait for root doc ready
|
||||
const docId = await MarkdownTransformer.importMarkdownToDoc({
|
||||
collection: workspace.docCollection,
|
||||
schema: getAFFiNEWorkspaceSchema(),
|
||||
markdown: clipperInput.contentMarkdown,
|
||||
});
|
||||
const docsService = workspace.scope.get(DocsService);
|
||||
if (docId) {
|
||||
// only support page mode for now
|
||||
docsService.list.setPrimaryMode(docId, 'page');
|
||||
workspace.engine.doc.addPriority(workspace.id, 100);
|
||||
workspace.engine.doc.addPriority(docId, 100);
|
||||
await workspace.engine.doc.waitForDocSynced(workspace.id);
|
||||
await workspace.engine.doc.waitForDocSynced(docId);
|
||||
disposeWorkspace();
|
||||
return docId;
|
||||
} else {
|
||||
throw new Error('Failed to import doc');
|
||||
}
|
||||
}
|
||||
|
||||
async importToNewWorkspace(
|
||||
flavour: string,
|
||||
workspaceName: string,
|
||||
clipperInput: ClipperInput
|
||||
) {
|
||||
// oxlint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
let docId: string | undefined;
|
||||
const { id: workspaceId } = await this.workspacesService.create(
|
||||
flavour,
|
||||
async docCollection => {
|
||||
docCollection.meta.initialize();
|
||||
docCollection.meta.setName(workspaceName);
|
||||
docId = await MarkdownTransformer.importMarkdownToDoc({
|
||||
collection: docCollection,
|
||||
schema: getAFFiNEWorkspaceSchema(),
|
||||
markdown: clipperInput.contentMarkdown,
|
||||
});
|
||||
}
|
||||
);
|
||||
if (!docId) {
|
||||
throw new Error('Failed to import doc');
|
||||
}
|
||||
return { workspaceId, docId };
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { DocMode } from '@blocksuite/affine/blocks';
|
||||
import { Entity, LiveData } from '@toeverything/infra';
|
||||
|
||||
interface TemplateOptions {
|
||||
templateName: string;
|
||||
snapshotUrl: string;
|
||||
templateMode: DocMode;
|
||||
}
|
||||
|
||||
export class ImportTemplateDialog extends Entity {
|
||||
readonly isOpen$ = new LiveData(false);
|
||||
readonly template$ = new LiveData<TemplateOptions | null>(null);
|
||||
|
||||
open(options: TemplateOptions) {
|
||||
this.template$.next(options);
|
||||
this.isOpen$.next(true);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.isOpen$.next(false);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import { type Framework } from '@toeverything/infra';
|
||||
|
||||
import { WorkspacesService } from '../workspace';
|
||||
import { ImportTemplateDialog } from './entities/dialog';
|
||||
import { TemplateDownloader } from './entities/downloader';
|
||||
import { TemplateDownloaderService } from './services/downloader';
|
||||
import { ImportTemplateService } from './services/import';
|
||||
@@ -12,7 +11,6 @@ export { ImportTemplateService } from './services/import';
|
||||
|
||||
export function configureImportTemplateModule(framework: Framework) {
|
||||
framework
|
||||
.entity(ImportTemplateDialog)
|
||||
.service(TemplateDownloaderService)
|
||||
.entity(TemplateDownloader, [TemplateDownloaderStore])
|
||||
.store(TemplateDownloaderStore)
|
||||
|
||||
@@ -26,6 +26,7 @@ import { configureFavoriteModule } from './favorite';
|
||||
import { configureFeatureFlagModule } from './feature-flag';
|
||||
import { configureGlobalContextModule } from './global-context';
|
||||
import { configureI18nModule } from './i18n';
|
||||
import { configureImportClipperModule } from './import-clipper';
|
||||
import { configureImportTemplateModule } from './import-template';
|
||||
import { configureJournalModule } from './journal';
|
||||
import { configureLifecycleModule } from './lifecycle';
|
||||
@@ -100,4 +101,5 @@ export function configureCommonModules(framework: Framework) {
|
||||
configureAIButtonModule(framework);
|
||||
configureTemplateDocModule(framework);
|
||||
configureBlobManagementModule(framework);
|
||||
configureImportClipperModule(framework);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user