refactor(editor): extract note block (#9310)
This commit is contained in:
50 files changed
+467
-394
No files matched your search
@@ -5,14 +5,18 @@ import {
|
|||||||
NoteDisplayMode,
|
NoteDisplayMode,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { EMBED_CARD_HEIGHT } from '@blocksuite/affine-shared/consts';
|
import { EMBED_CARD_HEIGHT } from '@blocksuite/affine-shared/consts';
|
||||||
|
import { NotificationProvider } from '@blocksuite/affine-shared/services';
|
||||||
import { matchFlavours, SpecProvider } from '@blocksuite/affine-shared/utils';
|
import { matchFlavours, SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||||
import { BlockStdScope } from '@blocksuite/block-std';
|
import { BlockStdScope } from '@blocksuite/block-std';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
type BlockModel,
|
type BlockModel,
|
||||||
|
type BlockSnapshot,
|
||||||
BlockViewType,
|
BlockViewType,
|
||||||
type Doc,
|
type Doc,
|
||||||
|
type DraftModel,
|
||||||
type Query,
|
type Query,
|
||||||
|
Slice,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import { render, type TemplateResult } from 'lit';
|
import { render, type TemplateResult } from 'lit';
|
||||||
|
|
||||||
@@ -295,3 +299,122 @@ export function getDocContentWithMaxLength(doc: Doc, maxlength = 500) {
|
|||||||
|
|
||||||
return texts.join('\n');
|
return texts.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTitleFromSelectedModels(selectedModels: DraftModel[]) {
|
||||||
|
const firstBlock = selectedModels[0];
|
||||||
|
if (
|
||||||
|
matchFlavours(firstBlock, ['affine:paragraph']) &&
|
||||||
|
firstBlock.type.startsWith('h')
|
||||||
|
) {
|
||||||
|
return firstBlock.text.toString();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function promptDocTitle(std: BlockStdScope, autofill?: string) {
|
||||||
|
const notification = std.getOptional(NotificationProvider);
|
||||||
|
if (!notification) return Promise.resolve(undefined);
|
||||||
|
|
||||||
|
return notification.prompt({
|
||||||
|
title: 'Create linked doc',
|
||||||
|
message: 'Enter a title for the new doc.',
|
||||||
|
placeholder: 'Untitled',
|
||||||
|
autofill,
|
||||||
|
confirmText: 'Confirm',
|
||||||
|
cancelText: 'Cancel',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function notifyDocCreated(std: BlockStdScope, doc: Doc) {
|
||||||
|
const notification = std.getOptional(NotificationProvider);
|
||||||
|
if (!notification) return;
|
||||||
|
|
||||||
|
const abortController = new AbortController();
|
||||||
|
const clear = () => {
|
||||||
|
doc.history.off('stack-item-added', addHandler);
|
||||||
|
doc.history.off('stack-item-popped', popHandler);
|
||||||
|
disposable.dispose();
|
||||||
|
};
|
||||||
|
const closeNotify = () => {
|
||||||
|
abortController.abort();
|
||||||
|
clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
// edit or undo or switch doc, close notify toast
|
||||||
|
const addHandler = doc.history.on('stack-item-added', closeNotify);
|
||||||
|
const popHandler = doc.history.on('stack-item-popped', closeNotify);
|
||||||
|
const disposable = std.host.slots.unmounted.on(closeNotify);
|
||||||
|
|
||||||
|
notification.notify({
|
||||||
|
title: 'Linked doc created',
|
||||||
|
message: 'You can click undo to recovery block content',
|
||||||
|
accent: 'info',
|
||||||
|
duration: 10 * 1000,
|
||||||
|
action: {
|
||||||
|
label: 'Undo',
|
||||||
|
onClick: () => {
|
||||||
|
doc.undo();
|
||||||
|
clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
abort: abortController.signal,
|
||||||
|
onClose: clear,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function convertSelectedBlocksToLinkedDoc(
|
||||||
|
std: BlockStdScope,
|
||||||
|
doc: Doc,
|
||||||
|
selectedModels: DraftModel[] | Promise<DraftModel[]>,
|
||||||
|
docTitle?: string
|
||||||
|
) {
|
||||||
|
const models = await selectedModels;
|
||||||
|
const slice = std.clipboard.sliceToSnapshot(Slice.fromModels(doc, models));
|
||||||
|
if (!slice) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const firstBlock = models[0];
|
||||||
|
if (!firstBlock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// if title undefined, use the first heading block content as doc title
|
||||||
|
const title = docTitle || getTitleFromSelectedModels(models);
|
||||||
|
const linkedDoc = createLinkedDocFromSlice(std, doc, slice.content, title);
|
||||||
|
// insert linked doc card
|
||||||
|
doc.addSiblingBlocks(
|
||||||
|
doc.getBlock(firstBlock.id)!.model,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
flavour: 'affine:embed-linked-doc',
|
||||||
|
pageId: linkedDoc.id,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'before'
|
||||||
|
);
|
||||||
|
// delete selected elements
|
||||||
|
models.forEach(model => doc.deleteBlock(model));
|
||||||
|
return linkedDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createLinkedDocFromSlice(
|
||||||
|
std: BlockStdScope,
|
||||||
|
doc: Doc,
|
||||||
|
snapshots: BlockSnapshot[],
|
||||||
|
docTitle?: string
|
||||||
|
) {
|
||||||
|
// const modelsWithChildren = (list:BlockModel[]):BlockModel[]=>list.flatMap(model=>[model,...modelsWithChildren(model.children)])
|
||||||
|
const linkedDoc = doc.collection.createDoc({});
|
||||||
|
linkedDoc.load(() => {
|
||||||
|
const rootId = linkedDoc.addBlock('affine:page', {
|
||||||
|
title: new doc.Text(docTitle),
|
||||||
|
});
|
||||||
|
linkedDoc.addBlock('affine:surface', {}, rootId);
|
||||||
|
const noteId = linkedDoc.addBlock('affine:note', {}, rootId);
|
||||||
|
snapshots.forEach(snapshot => {
|
||||||
|
std.clipboard
|
||||||
|
.pasteBlockSnapshot(snapshot, linkedDoc, noteId)
|
||||||
|
.catch(console.error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return linkedDoc;
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ export {
|
|||||||
LinkPreviewer,
|
LinkPreviewer,
|
||||||
type LinkPreviewResponseData,
|
type LinkPreviewResponseData,
|
||||||
} from './common/link-previewer.js';
|
} from './common/link-previewer.js';
|
||||||
export { getDocContentWithMaxLength } from './common/render-linked-doc';
|
export * from './common/render-linked-doc';
|
||||||
export { toEdgelessEmbedBlock } from './common/to-edgeless-embed-block';
|
export { toEdgelessEmbedBlock } from './common/to-edgeless-embed-block';
|
||||||
export * from './common/utils';
|
export * from './common/utils';
|
||||||
export * from './embed-figma-block';
|
export * from './embed-figma-block';
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "@blocksuite/affine-block-note",
|
||||||
|
"description": "Note block for BlockSuite.",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"test:unit": "nx vite:test --run --passWithNoTests",
|
||||||
|
"test:unit:coverage": "nx vite:test --run --coverage",
|
||||||
|
"test:e2e": "playwright test"
|
||||||
|
},
|
||||||
|
"sideEffects": false,
|
||||||
|
"keywords": [],
|
||||||
|
"author": "toeverything",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@blocksuite/affine-block-embed": "workspace:*",
|
||||||
|
"@blocksuite/affine-components": "workspace:*",
|
||||||
|
"@blocksuite/affine-model": "workspace:*",
|
||||||
|
"@blocksuite/affine-shared": "workspace:*",
|
||||||
|
"@blocksuite/block-std": "workspace:*",
|
||||||
|
"@blocksuite/global": "workspace:*",
|
||||||
|
"@blocksuite/icons": "^2.1.75",
|
||||||
|
"@blocksuite/inline": "workspace:*",
|
||||||
|
"@blocksuite/store": "workspace:*",
|
||||||
|
"@floating-ui/dom": "^1.6.10",
|
||||||
|
"@lit/context": "^1.1.2",
|
||||||
|
"@preact/signals-core": "^1.8.0",
|
||||||
|
"@toeverything/theme": "^1.1.1",
|
||||||
|
"lit": "^3.2.0",
|
||||||
|
"minimatch": "^10.0.1",
|
||||||
|
"zod": "^3.23.8"
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.ts",
|
||||||
|
"./effects": "./src/effects.ts"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src",
|
||||||
|
"dist",
|
||||||
|
"!src/__tests__",
|
||||||
|
"!dist/__tests__"
|
||||||
|
]
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,52 @@
|
|||||||
|
import type { BlockComponent } from '@blocksuite/block-std';
|
||||||
|
import type { BlockModel } from '@blocksuite/store';
|
||||||
|
|
||||||
|
import type { updateBlockType } from './commands/block-type';
|
||||||
|
import type { dedentBlock } from './commands/dedent-block';
|
||||||
|
import type { dedentBlockToRoot } from './commands/dedent-block-to-root';
|
||||||
|
import type { dedentBlocks } from './commands/dedent-blocks';
|
||||||
|
import type { dedentBlocksToRoot } from './commands/dedent-blocks-to-root';
|
||||||
|
import type { focusBlockEnd } from './commands/focus-block-end';
|
||||||
|
import type { focusBlockStart } from './commands/focus-block-start';
|
||||||
|
import type { indentBlock } from './commands/indent-block';
|
||||||
|
import type { indentBlocks } from './commands/indent-blocks';
|
||||||
|
import type { selectBlock } from './commands/select-block';
|
||||||
|
import type { selectBlocksBetween } from './commands/select-blocks-between';
|
||||||
|
import { NoteBlockComponent } from './note-block';
|
||||||
|
import {
|
||||||
|
EdgelessNoteBlockComponent,
|
||||||
|
EdgelessNoteMask,
|
||||||
|
} from './note-edgeless-block';
|
||||||
|
import type { NoteBlockService } from './note-service';
|
||||||
|
|
||||||
|
export function effects() {
|
||||||
|
customElements.define('affine-note', NoteBlockComponent);
|
||||||
|
customElements.define('edgeless-note-mask', EdgelessNoteMask);
|
||||||
|
customElements.define('affine-edgeless-note', EdgelessNoteBlockComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace BlockSuite {
|
||||||
|
interface Commands {
|
||||||
|
selectBlock: typeof selectBlock;
|
||||||
|
selectBlocksBetween: typeof selectBlocksBetween;
|
||||||
|
focusBlockStart: typeof focusBlockStart;
|
||||||
|
focusBlockEnd: typeof focusBlockEnd;
|
||||||
|
indentBlocks: typeof indentBlocks;
|
||||||
|
dedentBlock: typeof dedentBlock;
|
||||||
|
dedentBlocksToRoot: typeof dedentBlocksToRoot;
|
||||||
|
dedentBlocks: typeof dedentBlocks;
|
||||||
|
indentBlock: typeof indentBlock;
|
||||||
|
updateBlockType: typeof updateBlockType;
|
||||||
|
dedentBlockToRoot: typeof dedentBlockToRoot;
|
||||||
|
}
|
||||||
|
interface CommandContext {
|
||||||
|
focusBlock?: BlockComponent | null;
|
||||||
|
anchorBlock?: BlockComponent | null;
|
||||||
|
updatedBlocks?: BlockModel[];
|
||||||
|
}
|
||||||
|
interface BlockServices {
|
||||||
|
'affine:note': NoteBlockService;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export * from './adapters';
|
||||||
|
export * from './commands';
|
||||||
|
export * from './note-block';
|
||||||
|
export * from './note-edgeless-block';
|
||||||
|
export * from './note-service';
|
||||||
|
export * from './note-spec';
|
||||||
File renamed without changes.
File renamed without changes.
+11
-7
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
||||||
import { MoreIndicatorIcon } from '@blocksuite/affine-components/icons';
|
import { MoreIndicatorIcon } from '@blocksuite/affine-components/icons';
|
||||||
import type { NoteBlockModel } from '@blocksuite/affine-model';
|
import type { NoteBlockModel } from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
@@ -14,7 +13,11 @@ import {
|
|||||||
matchFlavours,
|
matchFlavours,
|
||||||
stopPropagation,
|
stopPropagation,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
import type { BlockComponent, EditorHost } from '@blocksuite/block-std';
|
import type {
|
||||||
|
BlockComponent,
|
||||||
|
BlockService,
|
||||||
|
EditorHost,
|
||||||
|
} from '@blocksuite/block-std';
|
||||||
import { ShadowlessElement, toGfxBlockComponent } from '@blocksuite/block-std';
|
import { ShadowlessElement, toGfxBlockComponent } from '@blocksuite/block-std';
|
||||||
import {
|
import {
|
||||||
almostEqual,
|
almostEqual,
|
||||||
@@ -23,13 +26,12 @@ import {
|
|||||||
Point,
|
Point,
|
||||||
WithDisposable,
|
WithDisposable,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import type { BlockModel } from '@blocksuite/store';
|
import type { BlockModel, Slot } from '@blocksuite/store';
|
||||||
import { css, html, nothing } from 'lit';
|
import { css, html, nothing } from 'lit';
|
||||||
import { property, query, state } from 'lit/decorators.js';
|
import { property, query, state } from 'lit/decorators.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
|
||||||
import type { EdgelessRootService } from '../root-block/index.js';
|
|
||||||
import { NoteBlockComponent } from './note-block.js';
|
import { NoteBlockComponent } from './note-block.js';
|
||||||
|
|
||||||
export class EdgelessNoteMask extends WithDisposable(ShadowlessElement) {
|
export class EdgelessNoteMask extends WithDisposable(ShadowlessElement) {
|
||||||
@@ -151,7 +153,9 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
get rootService() {
|
get rootService() {
|
||||||
return this.std.getService('affine:page') as EdgelessRootService;
|
return this.std.getService('affine:page') as BlockService & {
|
||||||
|
slots: Record<string, Slot>;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _collapsedContent() {
|
private _collapsedContent() {
|
||||||
@@ -312,7 +316,7 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
|
|||||||
override connectedCallback(): void {
|
override connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
const selection = this.rootService.selection;
|
const selection = this.gfx.selection;
|
||||||
|
|
||||||
this._editing = selection.has(this.model.id) && selection.editing;
|
this._editing = selection.has(this.model.id) && selection.editing;
|
||||||
this._disposables.add(
|
this._disposables.add(
|
||||||
@@ -328,7 +332,7 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
|
|||||||
|
|
||||||
override firstUpdated() {
|
override firstUpdated() {
|
||||||
const { _disposables } = this;
|
const { _disposables } = this;
|
||||||
const selection = this.rootService.selection;
|
const selection = this.gfx.selection;
|
||||||
|
|
||||||
_disposables.add(
|
_disposables.add(
|
||||||
this.rootService.slots.elementResizeStart.on(() => {
|
this.rootService.slots.elementResizeStart.on(() => {
|
||||||
+25
-9
@@ -1,3 +1,4 @@
|
|||||||
|
import { textConversionConfigs } from '@blocksuite/affine-components/rich-text';
|
||||||
import { NoteBlockSchema } from '@blocksuite/affine-model';
|
import { NoteBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||||
import {
|
import {
|
||||||
@@ -5,14 +6,14 @@ import {
|
|||||||
type BlockComponent,
|
type BlockComponent,
|
||||||
type BlockSelection,
|
type BlockSelection,
|
||||||
BlockService,
|
BlockService,
|
||||||
|
type BlockStdScope,
|
||||||
type UIEventHandler,
|
type UIEventHandler,
|
||||||
type UIEventStateContext,
|
type UIEventStateContext,
|
||||||
} from '@blocksuite/block-std';
|
} from '@blocksuite/block-std';
|
||||||
|
import type { BlockModel } from '@blocksuite/store';
|
||||||
|
|
||||||
import { moveBlockConfigs } from '../_common/configs/move-block.js';
|
import { moveBlockConfigs } from './move-block';
|
||||||
import { quickActionConfig } from '../_common/configs/quick-action/config.js';
|
import { quickActionConfig } from './quick-action';
|
||||||
import { textConversionConfigs } from '../_common/configs/text-conversion.js';
|
|
||||||
import { onModelElementUpdated } from '../root-block/utils/callback.js';
|
|
||||||
|
|
||||||
export class NoteBlockService extends BlockService {
|
export class NoteBlockService extends BlockService {
|
||||||
static override readonly flavour = NoteBlockSchema.model.flavour;
|
static override readonly flavour = NoteBlockSchema.model.flavour;
|
||||||
@@ -51,10 +52,10 @@ export class NoteBlockService extends BlockService {
|
|||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[config.hotkey!]: ctx => {
|
[config.hotkey!]: ctx => {
|
||||||
if (!config.showWhen(this.std.host)) return;
|
if (!config.showWhen(this.std)) return;
|
||||||
|
|
||||||
ctx.get('defaultState').event.preventDefault();
|
ctx.get('defaultState').event.preventDefault();
|
||||||
config.action(this.std.host);
|
config.action(this.std);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -83,8 +84,7 @@ export class NoteBlockService extends BlockService {
|
|||||||
})
|
})
|
||||||
.inline((ctx, next) => {
|
.inline((ctx, next) => {
|
||||||
const newModels = ctx.updatedBlocks;
|
const newModels = ctx.updatedBlocks;
|
||||||
const host = ctx.std.host;
|
if (!newModels) {
|
||||||
if (!host || !newModels) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ export class NoteBlockService extends BlockService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [codeModel] = newModels;
|
const [codeModel] = newModels;
|
||||||
onModelElementUpdated(host, codeModel, codeElement => {
|
onModelElementUpdated(ctx.std, codeModel, codeElement => {
|
||||||
this._std.selection.setGroup('note', [
|
this._std.selection.setGroup('note', [
|
||||||
this._std.selection.create('text', {
|
this._std.selection.create('text', {
|
||||||
from: {
|
from: {
|
||||||
@@ -584,3 +584,19 @@ export class NoteBlockService extends BlockService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onModelElementUpdated(
|
||||||
|
std: BlockStdScope,
|
||||||
|
model: BlockModel,
|
||||||
|
callback: (block: BlockComponent) => void
|
||||||
|
) {
|
||||||
|
const page = model.doc;
|
||||||
|
if (!page.root) return;
|
||||||
|
|
||||||
|
const rootComponent = std.view.getBlock(page.root.id);
|
||||||
|
if (!rootComponent) return;
|
||||||
|
await rootComponent.updateComplete;
|
||||||
|
|
||||||
|
const element = std.view.getBlock(model.id);
|
||||||
|
if (element) callback(element);
|
||||||
|
}
|
||||||
File renamed without changes.
@@ -0,0 +1,62 @@
|
|||||||
|
import {
|
||||||
|
convertSelectedBlocksToLinkedDoc,
|
||||||
|
getTitleFromSelectedModels,
|
||||||
|
notifyDocCreated,
|
||||||
|
promptDocTitle,
|
||||||
|
} from '@blocksuite/affine-block-embed';
|
||||||
|
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||||
|
|
||||||
|
export interface QuickActionConfig {
|
||||||
|
id: string;
|
||||||
|
hotkey?: string;
|
||||||
|
showWhen: (std: BlockStdScope) => boolean;
|
||||||
|
action: (std: BlockStdScope) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const quickActionConfig: QuickActionConfig[] = [
|
||||||
|
{
|
||||||
|
id: 'convert-to-linked-doc',
|
||||||
|
hotkey: `Mod-Shift-l`,
|
||||||
|
showWhen: std => {
|
||||||
|
const [_, ctx] = std.command
|
||||||
|
.chain()
|
||||||
|
.getSelectedModels({
|
||||||
|
types: ['block'],
|
||||||
|
})
|
||||||
|
.run();
|
||||||
|
const { selectedModels } = ctx;
|
||||||
|
return !!selectedModels && selectedModels.length > 0;
|
||||||
|
},
|
||||||
|
action: std => {
|
||||||
|
const [_, ctx] = std.command
|
||||||
|
.chain()
|
||||||
|
.getSelectedModels({
|
||||||
|
types: ['block'],
|
||||||
|
mode: 'highest',
|
||||||
|
})
|
||||||
|
.draftSelectedModels()
|
||||||
|
.run();
|
||||||
|
const { selectedModels, draftedModels } = ctx;
|
||||||
|
if (!selectedModels) return;
|
||||||
|
|
||||||
|
if (!selectedModels.length || !draftedModels) return;
|
||||||
|
|
||||||
|
std.selection.clear();
|
||||||
|
|
||||||
|
const doc = std.doc;
|
||||||
|
const autofill = getTitleFromSelectedModels(selectedModels);
|
||||||
|
promptDocTitle(std, autofill)
|
||||||
|
.then(title => {
|
||||||
|
if (title === null) return;
|
||||||
|
convertSelectedBlocksToLinkedDoc(
|
||||||
|
std,
|
||||||
|
doc,
|
||||||
|
draftedModels,
|
||||||
|
title
|
||||||
|
).catch(console.error);
|
||||||
|
notifyDocCreated(std, doc);
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./src/",
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"noEmit": false
|
||||||
|
},
|
||||||
|
"include": ["./src"],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../../framework/global"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../framework/store"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../framework/block-std"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../framework/inline"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../model"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../components"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../shared"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../block-embed"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+3
-2
@@ -1,3 +1,5 @@
|
|||||||
|
import type { TemplateResult } from 'lit';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BulletedListIcon,
|
BulletedListIcon,
|
||||||
CheckBoxIcon,
|
CheckBoxIcon,
|
||||||
@@ -12,8 +14,7 @@ import {
|
|||||||
NumberedListIcon,
|
NumberedListIcon,
|
||||||
QuoteIcon,
|
QuoteIcon,
|
||||||
TextIcon,
|
TextIcon,
|
||||||
} from '@blocksuite/affine-components/icons';
|
} from '../icons';
|
||||||
import type { TemplateResult } from 'lit';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Text primitive entries used in slash menu and format bar,
|
* Text primitive entries used in slash menu and format bar,
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './all-extensions.js';
|
export * from './all-extensions';
|
||||||
|
export { type TextConversionConfig, textConversionConfigs } from './conversion';
|
||||||
export {
|
export {
|
||||||
asyncGetRichText,
|
asyncGetRichText,
|
||||||
asyncSetInlineRange,
|
asyncSetInlineRange,
|
||||||
@@ -7,9 +8,9 @@ export {
|
|||||||
getRichTextByModel,
|
getRichTextByModel,
|
||||||
onModelTextUpdated,
|
onModelTextUpdated,
|
||||||
selectTextModel,
|
selectTextModel,
|
||||||
} from './dom.js';
|
} from './dom';
|
||||||
export * from './effects.js';
|
export * from './effects';
|
||||||
export * from './extension/index.js';
|
export * from './extension';
|
||||||
export {
|
export {
|
||||||
clearMarksOnDiscontinuousInput,
|
clearMarksOnDiscontinuousInput,
|
||||||
FORMAT_BLOCK_SUPPORT_FLAVOURS,
|
FORMAT_BLOCK_SUPPORT_FLAVOURS,
|
||||||
@@ -20,9 +21,9 @@ export {
|
|||||||
textCommands,
|
textCommands,
|
||||||
type TextFormatConfig,
|
type TextFormatConfig,
|
||||||
textFormatConfigs,
|
textFormatConfigs,
|
||||||
} from './format/index.js';
|
} from './format';
|
||||||
export * from './inline/index.js';
|
export * from './inline';
|
||||||
export { textKeymap } from './keymap/index.js';
|
export { textKeymap } from './keymap';
|
||||||
export { insertLinkedNode } from './linked-node.js';
|
export { insertLinkedNode } from './linked-node';
|
||||||
export { markdownInput } from './markdown/index.js';
|
export { markdownInput } from './markdown';
|
||||||
export { RichText } from './rich-text.js';
|
export { RichText } from './rich-text';
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
"@blocksuite/affine-block-embed": "workspace:*",
|
"@blocksuite/affine-block-embed": "workspace:*",
|
||||||
"@blocksuite/affine-block-image": "workspace:*",
|
"@blocksuite/affine-block-image": "workspace:*",
|
||||||
"@blocksuite/affine-block-list": "workspace:*",
|
"@blocksuite/affine-block-list": "workspace:*",
|
||||||
|
"@blocksuite/affine-block-note": "workspace:*",
|
||||||
"@blocksuite/affine-block-paragraph": "workspace:*",
|
"@blocksuite/affine-block-paragraph": "workspace:*",
|
||||||
"@blocksuite/affine-block-surface": "workspace:*",
|
"@blocksuite/affine-block-surface": "workspace:*",
|
||||||
"@blocksuite/affine-components": "workspace:*",
|
"@blocksuite/affine-components": "workspace:*",
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
import {
|
|
||||||
CopyIcon,
|
|
||||||
DatabaseTableViewIcon20,
|
|
||||||
LinkedDocIcon,
|
|
||||||
} from '@blocksuite/affine-components/icons';
|
|
||||||
import { toast } from '@blocksuite/affine-components/toast';
|
|
||||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
|
||||||
import type { EditorHost } from '@blocksuite/block-std';
|
|
||||||
import { tableViewMeta } from '@blocksuite/data-view/view-presets';
|
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
|
||||||
import type { TemplateResult } from 'lit';
|
|
||||||
|
|
||||||
import { convertToDatabase } from '../../../database-block/data-source.js';
|
|
||||||
import { DATABASE_CONVERT_WHITE_LIST } from '../../../database-block/utils/block-utils.js';
|
|
||||||
import {
|
|
||||||
convertSelectedBlocksToLinkedDoc,
|
|
||||||
getTitleFromSelectedModels,
|
|
||||||
notifyDocCreated,
|
|
||||||
promptDocTitle,
|
|
||||||
} from '../../utils/render-linked-doc.js';
|
|
||||||
|
|
||||||
export interface QuickActionConfig {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
disabledToolTip?: string;
|
|
||||||
icon: TemplateResult<1>;
|
|
||||||
hotkey?: string;
|
|
||||||
showWhen: (host: EditorHost) => boolean;
|
|
||||||
enabledWhen: (host: EditorHost) => boolean;
|
|
||||||
action: (host: EditorHost) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const quickActionConfig: QuickActionConfig[] = [
|
|
||||||
{
|
|
||||||
id: 'copy',
|
|
||||||
name: 'Copy',
|
|
||||||
disabledToolTip: undefined,
|
|
||||||
icon: CopyIcon,
|
|
||||||
hotkey: undefined,
|
|
||||||
showWhen: () => true,
|
|
||||||
enabledWhen: () => true,
|
|
||||||
action: host => {
|
|
||||||
host.std.command
|
|
||||||
.chain()
|
|
||||||
.getSelectedModels()
|
|
||||||
.with({
|
|
||||||
onCopy: () => {
|
|
||||||
toast(host, 'Copied to clipboard');
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.draftSelectedModels()
|
|
||||||
.copySelectedModels()
|
|
||||||
.run();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'convert-to-database',
|
|
||||||
name: 'Group as Table',
|
|
||||||
disabledToolTip:
|
|
||||||
'Contains Block types that cannot be converted to Database',
|
|
||||||
icon: DatabaseTableViewIcon20,
|
|
||||||
showWhen: host => {
|
|
||||||
const [_, ctx] = host.std.command
|
|
||||||
.chain()
|
|
||||||
.getSelectedModels({
|
|
||||||
types: ['block', 'text'],
|
|
||||||
})
|
|
||||||
.run();
|
|
||||||
const { selectedModels } = ctx;
|
|
||||||
if (!selectedModels || selectedModels.length === 0) return false;
|
|
||||||
|
|
||||||
const firstBlock = selectedModels[0];
|
|
||||||
assertExists(firstBlock);
|
|
||||||
if (matchFlavours(firstBlock, ['affine:database'])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
enabledWhen: host => {
|
|
||||||
const [_, ctx] = host.std.command
|
|
||||||
.chain()
|
|
||||||
.getSelectedModels({
|
|
||||||
types: ['block', 'text'],
|
|
||||||
})
|
|
||||||
.run();
|
|
||||||
const { selectedModels } = ctx;
|
|
||||||
if (!selectedModels || selectedModels.length === 0) return false;
|
|
||||||
|
|
||||||
return selectedModels.every(block =>
|
|
||||||
DATABASE_CONVERT_WHITE_LIST.includes(block.flavour)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
action: host => {
|
|
||||||
convertToDatabase(host, tableViewMeta.type);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'convert-to-linked-doc',
|
|
||||||
name: 'Create Linked Doc',
|
|
||||||
icon: LinkedDocIcon,
|
|
||||||
hotkey: `Mod-Shift-l`,
|
|
||||||
showWhen: host => {
|
|
||||||
const [_, ctx] = host.std.command
|
|
||||||
.chain()
|
|
||||||
.getSelectedModels({
|
|
||||||
types: ['block'],
|
|
||||||
})
|
|
||||||
.run();
|
|
||||||
const { selectedModels } = ctx;
|
|
||||||
return !!selectedModels && selectedModels.length > 0;
|
|
||||||
},
|
|
||||||
enabledWhen: host => {
|
|
||||||
const [_, ctx] = host.std.command
|
|
||||||
.chain()
|
|
||||||
.getSelectedModels({
|
|
||||||
types: ['block'],
|
|
||||||
})
|
|
||||||
.run();
|
|
||||||
const { selectedModels } = ctx;
|
|
||||||
return !!selectedModels && selectedModels.length > 0;
|
|
||||||
},
|
|
||||||
action: host => {
|
|
||||||
const [_, ctx] = host.std.command
|
|
||||||
.chain()
|
|
||||||
.getSelectedModels({
|
|
||||||
types: ['block'],
|
|
||||||
mode: 'highest',
|
|
||||||
})
|
|
||||||
.draftSelectedModels()
|
|
||||||
.run();
|
|
||||||
const { selectedModels, draftedModels } = ctx;
|
|
||||||
assertExists(selectedModels);
|
|
||||||
if (!selectedModels.length || !draftedModels) return;
|
|
||||||
|
|
||||||
host.selection.clear();
|
|
||||||
|
|
||||||
const doc = host.doc;
|
|
||||||
const autofill = getTitleFromSelectedModels(selectedModels);
|
|
||||||
promptDocTitle(host, autofill)
|
|
||||||
.then(title => {
|
|
||||||
if (title === null) return;
|
|
||||||
convertSelectedBlocksToLinkedDoc(
|
|
||||||
host.std,
|
|
||||||
doc,
|
|
||||||
draftedModels,
|
|
||||||
title
|
|
||||||
).catch(console.error);
|
|
||||||
notifyDocCreated(host, doc);
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,19 +1,9 @@
|
|||||||
import type { FrameBlockModel, NoteBlockModel } from '@blocksuite/affine-model';
|
import type { FrameBlockModel, NoteBlockModel } from '@blocksuite/affine-model';
|
||||||
import { NoteDisplayMode } from '@blocksuite/affine-model';
|
import { NoteDisplayMode } from '@blocksuite/affine-model';
|
||||||
import {
|
import { DocModeProvider } from '@blocksuite/affine-shared/services';
|
||||||
DocModeProvider,
|
import { getBlockProps } from '@blocksuite/affine-shared/utils';
|
||||||
NotificationProvider,
|
|
||||||
} from '@blocksuite/affine-shared/services';
|
|
||||||
import { getBlockProps, matchFlavours } from '@blocksuite/affine-shared/utils';
|
|
||||||
import type { EditorHost } from '@blocksuite/block-std';
|
import type { EditorHost } from '@blocksuite/block-std';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { type BlockModel, type Doc } from '@blocksuite/store';
|
||||||
import {
|
|
||||||
type BlockModel,
|
|
||||||
type BlockSnapshot,
|
|
||||||
type Doc,
|
|
||||||
type DraftModel,
|
|
||||||
Slice,
|
|
||||||
} from '@blocksuite/store';
|
|
||||||
|
|
||||||
import { GfxBlockModel } from '../../root-block/edgeless/block-model.js';
|
import { GfxBlockModel } from '../../root-block/edgeless/block-model.js';
|
||||||
import {
|
import {
|
||||||
@@ -27,68 +17,6 @@ import {
|
|||||||
} from '../../root-block/edgeless/utils/query.js';
|
} from '../../root-block/edgeless/utils/query.js';
|
||||||
import { getSurfaceBlock } from '../../surface-ref-block/utils.js';
|
import { getSurfaceBlock } from '../../surface-ref-block/utils.js';
|
||||||
|
|
||||||
export function promptDocTitle(host: EditorHost, autofill?: string) {
|
|
||||||
const notification = host.std.getOptional(NotificationProvider);
|
|
||||||
if (!notification) return Promise.resolve(undefined);
|
|
||||||
|
|
||||||
return notification.prompt({
|
|
||||||
title: 'Create linked doc',
|
|
||||||
message: 'Enter a title for the new doc.',
|
|
||||||
placeholder: 'Untitled',
|
|
||||||
autofill,
|
|
||||||
confirmText: 'Confirm',
|
|
||||||
cancelText: 'Cancel',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTitleFromSelectedModels(selectedModels: DraftModel[]) {
|
|
||||||
const firstBlock = selectedModels[0];
|
|
||||||
if (
|
|
||||||
matchFlavours(firstBlock, ['affine:paragraph']) &&
|
|
||||||
firstBlock.type.startsWith('h')
|
|
||||||
) {
|
|
||||||
return firstBlock.text.toString();
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function notifyDocCreated(host: EditorHost, doc: Doc) {
|
|
||||||
const notification = host.std.getOptional(NotificationProvider);
|
|
||||||
if (!notification) return;
|
|
||||||
|
|
||||||
const abortController = new AbortController();
|
|
||||||
const clear = () => {
|
|
||||||
doc.history.off('stack-item-added', addHandler);
|
|
||||||
doc.history.off('stack-item-popped', popHandler);
|
|
||||||
disposable.dispose();
|
|
||||||
};
|
|
||||||
const closeNotify = () => {
|
|
||||||
abortController.abort();
|
|
||||||
clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
// edit or undo or switch doc, close notify toast
|
|
||||||
const addHandler = doc.history.on('stack-item-added', closeNotify);
|
|
||||||
const popHandler = doc.history.on('stack-item-popped', closeNotify);
|
|
||||||
const disposable = host.slots.unmounted.on(closeNotify);
|
|
||||||
|
|
||||||
notification.notify({
|
|
||||||
title: 'Linked doc created',
|
|
||||||
message: 'You can click undo to recovery block content',
|
|
||||||
accent: 'info',
|
|
||||||
duration: 10 * 1000,
|
|
||||||
action: {
|
|
||||||
label: 'Undo',
|
|
||||||
onClick: () => {
|
|
||||||
doc.undo();
|
|
||||||
clear();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
abort: abortController.signal,
|
|
||||||
onClose: clear,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addBlocksToDoc(
|
export function addBlocksToDoc(
|
||||||
targetDoc: Doc,
|
targetDoc: Doc,
|
||||||
model: BlockModel,
|
model: BlockModel,
|
||||||
@@ -110,61 +38,6 @@ export function addBlocksToDoc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function convertSelectedBlocksToLinkedDoc(
|
|
||||||
std: BlockSuite.Std,
|
|
||||||
doc: Doc,
|
|
||||||
selectedModels: DraftModel[] | Promise<DraftModel[]>,
|
|
||||||
docTitle?: string
|
|
||||||
) {
|
|
||||||
const models = await selectedModels;
|
|
||||||
const slice = std.clipboard.sliceToSnapshot(Slice.fromModels(doc, models));
|
|
||||||
if (!slice) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const firstBlock = models[0];
|
|
||||||
assertExists(firstBlock);
|
|
||||||
// if title undefined, use the first heading block content as doc title
|
|
||||||
const title = docTitle || getTitleFromSelectedModels(models);
|
|
||||||
const linkedDoc = createLinkedDocFromSlice(std, doc, slice.content, title);
|
|
||||||
// insert linked doc card
|
|
||||||
doc.addSiblingBlocks(
|
|
||||||
doc.getBlock(firstBlock.id)!.model,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
flavour: 'affine:embed-linked-doc',
|
|
||||||
pageId: linkedDoc.id,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'before'
|
|
||||||
);
|
|
||||||
// delete selected elements
|
|
||||||
models.forEach(model => doc.deleteBlock(model));
|
|
||||||
return linkedDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createLinkedDocFromSlice(
|
|
||||||
std: BlockSuite.Std,
|
|
||||||
doc: Doc,
|
|
||||||
snapshots: BlockSnapshot[],
|
|
||||||
docTitle?: string
|
|
||||||
) {
|
|
||||||
// const modelsWithChildren = (list:BlockModel[]):BlockModel[]=>list.flatMap(model=>[model,...modelsWithChildren(model.children)])
|
|
||||||
const linkedDoc = doc.collection.createDoc({});
|
|
||||||
linkedDoc.load(() => {
|
|
||||||
const rootId = linkedDoc.addBlock('affine:page', {
|
|
||||||
title: new doc.Text(docTitle),
|
|
||||||
});
|
|
||||||
linkedDoc.addBlock('affine:surface', {}, rootId);
|
|
||||||
const noteId = linkedDoc.addBlock('affine:note', {}, rootId);
|
|
||||||
snapshots.forEach(snapshot => {
|
|
||||||
std.clipboard
|
|
||||||
.pasteBlockSnapshot(snapshot, linkedDoc, noteId)
|
|
||||||
.catch(console.error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return linkedDoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createLinkedDocFromNote(
|
export function createLinkedDocFromNote(
|
||||||
doc: Doc,
|
doc: Doc,
|
||||||
note: NoteBlockModel,
|
note: NoteBlockModel,
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import { BookmarkBlockSpec } from '@blocksuite/affine-block-bookmark';
|
|||||||
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
||||||
import { ImageBlockSpec } from '@blocksuite/affine-block-image';
|
import { ImageBlockSpec } from '@blocksuite/affine-block-image';
|
||||||
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
||||||
|
import {
|
||||||
|
EdgelessNoteBlockSpec,
|
||||||
|
NoteBlockSpec,
|
||||||
|
} from '@blocksuite/affine-block-note';
|
||||||
import { ParagraphBlockSpec } from '@blocksuite/affine-block-paragraph';
|
import { ParagraphBlockSpec } from '@blocksuite/affine-block-paragraph';
|
||||||
import { RichTextExtensions } from '@blocksuite/affine-components/rich-text';
|
import { RichTextExtensions } from '@blocksuite/affine-components/rich-text';
|
||||||
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
||||||
@@ -13,10 +17,6 @@ import { CodeBlockSpec } from '../code-block/code-block-spec.js';
|
|||||||
import { DataViewBlockSpec } from '../data-view-block/data-view-spec.js';
|
import { DataViewBlockSpec } from '../data-view-block/data-view-spec.js';
|
||||||
import { DatabaseBlockSpec } from '../database-block/database-spec.js';
|
import { DatabaseBlockSpec } from '../database-block/database-spec.js';
|
||||||
import { DividerBlockSpec } from '../divider-block/divider-spec.js';
|
import { DividerBlockSpec } from '../divider-block/divider-spec.js';
|
||||||
import {
|
|
||||||
EdgelessNoteBlockSpec,
|
|
||||||
NoteBlockSpec,
|
|
||||||
} from '../note-block/note-spec.js';
|
|
||||||
|
|
||||||
export const CommonFirstPartyBlockSpecs: ExtensionType[] = [
|
export const CommonFirstPartyBlockSpecs: ExtensionType[] = [
|
||||||
RichTextExtensions,
|
RichTextExtensions,
|
||||||
|
|||||||
@@ -11,16 +11,16 @@ import {
|
|||||||
} from '@blocksuite/affine-block-embed';
|
} from '@blocksuite/affine-block-embed';
|
||||||
import { ImageBlockSpec } from '@blocksuite/affine-block-image';
|
import { ImageBlockSpec } from '@blocksuite/affine-block-image';
|
||||||
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
||||||
|
import {
|
||||||
|
EdgelessNoteBlockSpec,
|
||||||
|
NoteBlockSpec,
|
||||||
|
} from '@blocksuite/affine-block-note';
|
||||||
import { ParagraphBlockSpec } from '@blocksuite/affine-block-paragraph';
|
import { ParagraphBlockSpec } from '@blocksuite/affine-block-paragraph';
|
||||||
|
|
||||||
import { CodeBlockSpec } from '../../code-block/code-block-spec.js';
|
import { CodeBlockSpec } from '../../code-block/code-block-spec.js';
|
||||||
import { DataViewBlockSpec } from '../../data-view-block/data-view-spec.js';
|
import { DataViewBlockSpec } from '../../data-view-block/data-view-spec.js';
|
||||||
import { DatabaseBlockSpec } from '../../database-block/database-spec.js';
|
import { DatabaseBlockSpec } from '../../database-block/database-spec.js';
|
||||||
import { DividerBlockSpec } from '../../divider-block/divider-spec.js';
|
import { DividerBlockSpec } from '../../divider-block/divider-spec.js';
|
||||||
import {
|
|
||||||
EdgelessNoteBlockSpec,
|
|
||||||
NoteBlockSpec,
|
|
||||||
} from '../../note-block/note-spec.js';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
AttachmentBlockSpec,
|
AttachmentBlockSpec,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { NoteBlockComponent } from '@blocksuite/affine-block-note';
|
||||||
import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
|
import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
|
||||||
import {
|
import {
|
||||||
menu,
|
menu,
|
||||||
@@ -40,7 +41,6 @@ import { html } from 'lit/static-html.js';
|
|||||||
|
|
||||||
import { BlockRenderer } from '../database-block/detail-panel/block-renderer.js';
|
import { BlockRenderer } from '../database-block/detail-panel/block-renderer.js';
|
||||||
import { NoteRenderer } from '../database-block/detail-panel/note-renderer.js';
|
import { NoteRenderer } from '../database-block/detail-panel/note-renderer.js';
|
||||||
import type { NoteBlockComponent } from '../note-block/index.js';
|
|
||||||
import {
|
import {
|
||||||
EdgelessRootBlockComponent,
|
EdgelessRootBlockComponent,
|
||||||
type RootService,
|
type RootService,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { NoteBlockComponent } from '@blocksuite/affine-block-note';
|
||||||
import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
|
import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
|
||||||
import {
|
import {
|
||||||
menu,
|
menu,
|
||||||
@@ -44,7 +45,6 @@ import { autoUpdate } from '@floating-ui/dom';
|
|||||||
import { computed, signal } from '@preact/signals-core';
|
import { computed, signal } from '@preact/signals-core';
|
||||||
import { css, html, nothing, unsafeCSS } from 'lit';
|
import { css, html, nothing, unsafeCSS } from 'lit';
|
||||||
|
|
||||||
import type { NoteBlockComponent } from '../note-block/index.js';
|
|
||||||
import { EdgelessRootBlockComponent } from '../root-block/index.js';
|
import { EdgelessRootBlockComponent } from '../root-block/index.js';
|
||||||
import { getDropResult } from '../root-block/widgets/drag-handle/utils.js';
|
import { getDropResult } from '../root-block/widgets/drag-handle/utils.js';
|
||||||
import { popSideDetail } from './components/layout.js';
|
import { popSideDetail } from './components/layout.js';
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { effects as blockBookmarkEffects } from '@blocksuite/affine-block-bookma
|
|||||||
import { effects as blockEmbedEffects } from '@blocksuite/affine-block-embed/effects';
|
import { effects as blockEmbedEffects } from '@blocksuite/affine-block-embed/effects';
|
||||||
import { effects as blockImageEffects } from '@blocksuite/affine-block-image/effects';
|
import { effects as blockImageEffects } from '@blocksuite/affine-block-image/effects';
|
||||||
import { effects as blockListEffects } from '@blocksuite/affine-block-list/effects';
|
import { effects as blockListEffects } from '@blocksuite/affine-block-list/effects';
|
||||||
|
import { effects as blockNoteEffects } from '@blocksuite/affine-block-note/effects';
|
||||||
import { effects as blockParagraphEffects } from '@blocksuite/affine-block-paragraph/effects';
|
import { effects as blockParagraphEffects } from '@blocksuite/affine-block-paragraph/effects';
|
||||||
import { effects as blockSurfaceEffects } from '@blocksuite/affine-block-surface/effects';
|
import { effects as blockSurfaceEffects } from '@blocksuite/affine-block-surface/effects';
|
||||||
import { effects as componentAiItemEffects } from '@blocksuite/affine-components/ai-item';
|
import { effects as componentAiItemEffects } from '@blocksuite/affine-components/ai-item';
|
||||||
@@ -66,23 +67,6 @@ import { EdgelessTextBlockComponent } from './edgeless-text-block/index.js';
|
|||||||
import { FrameBlockComponent } from './frame-block/index.js';
|
import { FrameBlockComponent } from './frame-block/index.js';
|
||||||
import { effects as blockLatexEffects } from './latex-block/effects.js';
|
import { effects as blockLatexEffects } from './latex-block/effects.js';
|
||||||
import { LatexBlockComponent } from './latex-block/index.js';
|
import { LatexBlockComponent } from './latex-block/index.js';
|
||||||
import type { updateBlockType } from './note-block/commands/block-type.js';
|
|
||||||
import type { dedentBlock } from './note-block/commands/dedent-block.js';
|
|
||||||
import type { dedentBlockToRoot } from './note-block/commands/dedent-block-to-root.js';
|
|
||||||
import type { dedentBlocks } from './note-block/commands/dedent-blocks.js';
|
|
||||||
import type { dedentBlocksToRoot } from './note-block/commands/dedent-blocks-to-root.js';
|
|
||||||
import type { focusBlockEnd } from './note-block/commands/focus-block-end.js';
|
|
||||||
import type { focusBlockStart } from './note-block/commands/focus-block-start.js';
|
|
||||||
import type { indentBlock } from './note-block/commands/indent-block.js';
|
|
||||||
import type { indentBlocks } from './note-block/commands/indent-blocks.js';
|
|
||||||
import type { selectBlock } from './note-block/commands/select-block.js';
|
|
||||||
import type { selectBlocksBetween } from './note-block/commands/select-blocks-between.js';
|
|
||||||
import {
|
|
||||||
EdgelessNoteBlockComponent,
|
|
||||||
EdgelessNoteMask,
|
|
||||||
NoteBlockComponent,
|
|
||||||
type NoteBlockService,
|
|
||||||
} from './note-block/index.js';
|
|
||||||
import { EdgelessAutoCompletePanel } from './root-block/edgeless/components/auto-complete/auto-complete-panel.js';
|
import { EdgelessAutoCompletePanel } from './root-block/edgeless/components/auto-complete/auto-complete-panel.js';
|
||||||
import { EdgelessAutoComplete } from './root-block/edgeless/components/auto-complete/edgeless-auto-complete.js';
|
import { EdgelessAutoComplete } from './root-block/edgeless/components/auto-complete/edgeless-auto-complete.js';
|
||||||
import { EdgelessToolIconButton } from './root-block/edgeless/components/buttons/tool-icon-button.js';
|
import { EdgelessToolIconButton } from './root-block/edgeless/components/buttons/tool-icon-button.js';
|
||||||
@@ -264,6 +248,7 @@ export function effects() {
|
|||||||
stdEffects();
|
stdEffects();
|
||||||
inlineEffects();
|
inlineEffects();
|
||||||
|
|
||||||
|
blockNoteEffects();
|
||||||
blockAttachmentEffects();
|
blockAttachmentEffects();
|
||||||
blockBookmarkEffects();
|
blockBookmarkEffects();
|
||||||
blockListEffects();
|
blockListEffects();
|
||||||
@@ -314,8 +299,6 @@ export function effects() {
|
|||||||
customElements.define('database-datasource-block-renderer', BlockRenderer);
|
customElements.define('database-datasource-block-renderer', BlockRenderer);
|
||||||
customElements.define('affine-latex', LatexBlockComponent);
|
customElements.define('affine-latex', LatexBlockComponent);
|
||||||
customElements.define('affine-page-root', PageRootBlockComponent);
|
customElements.define('affine-page-root', PageRootBlockComponent);
|
||||||
customElements.define('edgeless-note-mask', EdgelessNoteMask);
|
|
||||||
customElements.define('affine-edgeless-note', EdgelessNoteBlockComponent);
|
|
||||||
customElements.define('affine-preview-root', PreviewRootBlockComponent);
|
customElements.define('affine-preview-root', PreviewRootBlockComponent);
|
||||||
customElements.define('affine-code', CodeBlockComponent);
|
customElements.define('affine-code', CodeBlockComponent);
|
||||||
customElements.define('mini-mindmap-preview', MiniMindmapPreview);
|
customElements.define('mini-mindmap-preview', MiniMindmapPreview);
|
||||||
@@ -445,7 +428,6 @@ export function effects() {
|
|||||||
customElements.define('edgeless-present-button', EdgelessPresentButton);
|
customElements.define('edgeless-present-button', EdgelessPresentButton);
|
||||||
customElements.define('edgeless-color-picker', EdgelessColorPicker);
|
customElements.define('edgeless-color-picker', EdgelessColorPicker);
|
||||||
customElements.define('overlay-scrollbar', OverlayScrollbar);
|
customElements.define('overlay-scrollbar', OverlayScrollbar);
|
||||||
customElements.define('affine-note', NoteBlockComponent);
|
|
||||||
customElements.define('affine-template-loading', AffineTemplateLoading);
|
customElements.define('affine-template-loading', AffineTemplateLoading);
|
||||||
customElements.define(
|
customElements.define(
|
||||||
'edgeless-color-picker-button',
|
'edgeless-color-picker-button',
|
||||||
@@ -549,18 +531,7 @@ export function effects() {
|
|||||||
declare global {
|
declare global {
|
||||||
namespace BlockSuite {
|
namespace BlockSuite {
|
||||||
interface Commands {
|
interface Commands {
|
||||||
selectBlock: typeof selectBlock;
|
|
||||||
selectBlocksBetween: typeof selectBlocksBetween;
|
|
||||||
focusBlockStart: typeof focusBlockStart;
|
|
||||||
focusBlockEnd: typeof focusBlockEnd;
|
|
||||||
indentBlocks: typeof indentBlocks;
|
|
||||||
dedentBlock: typeof dedentBlock;
|
|
||||||
dedentBlocksToRoot: typeof dedentBlocksToRoot;
|
|
||||||
dedentBlocks: typeof dedentBlocks;
|
|
||||||
indentBlock: typeof indentBlock;
|
|
||||||
updateBlockType: typeof updateBlockType;
|
|
||||||
insertEdgelessText: typeof insertEdgelessTextCommand;
|
insertEdgelessText: typeof insertEdgelessTextCommand;
|
||||||
dedentBlockToRoot: typeof dedentBlockToRoot;
|
|
||||||
}
|
}
|
||||||
interface CommandContext {
|
interface CommandContext {
|
||||||
focusBlock?: BlockComponent | null;
|
focusBlock?: BlockComponent | null;
|
||||||
@@ -573,7 +544,6 @@ declare global {
|
|||||||
'affine:page': RootBlockConfig;
|
'affine:page': RootBlockConfig;
|
||||||
}
|
}
|
||||||
interface BlockServices {
|
interface BlockServices {
|
||||||
'affine:note': NoteBlockService;
|
|
||||||
'affine:page': RootService;
|
'affine:page': RootService;
|
||||||
'affine:database': DatabaseBlockService;
|
'affine:database': DatabaseBlockService;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ export * from './divider-block/index.js';
|
|||||||
export * from './edgeless-text-block/index.js';
|
export * from './edgeless-text-block/index.js';
|
||||||
export * from './frame-block/index.js';
|
export * from './frame-block/index.js';
|
||||||
export * from './latex-block/index.js';
|
export * from './latex-block/index.js';
|
||||||
export * from './note-block/index.js';
|
|
||||||
export { EdgelessTemplatePanel } from './root-block/edgeless/components/toolbar/template/template-panel.js';
|
export { EdgelessTemplatePanel } from './root-block/edgeless/components/toolbar/template/template-panel.js';
|
||||||
export type {
|
export type {
|
||||||
Template,
|
Template,
|
||||||
@@ -52,6 +51,7 @@ export * from '@blocksuite/affine-block-bookmark';
|
|||||||
export * from '@blocksuite/affine-block-embed';
|
export * from '@blocksuite/affine-block-embed';
|
||||||
export * from '@blocksuite/affine-block-image';
|
export * from '@blocksuite/affine-block-image';
|
||||||
export * from '@blocksuite/affine-block-list';
|
export * from '@blocksuite/affine-block-list';
|
||||||
|
export * from '@blocksuite/affine-block-note';
|
||||||
export * from '@blocksuite/affine-block-paragraph';
|
export * from '@blocksuite/affine-block-paragraph';
|
||||||
export * from '@blocksuite/affine-block-surface';
|
export * from '@blocksuite/affine-block-surface';
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
export * from './commands/index.js';
|
|
||||||
export * from './note-block.js';
|
|
||||||
export * from './note-edgeless-block.js';
|
|
||||||
export * from './note-service.js';
|
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
|
||||||
import type { BlockComponent, BlockSelection } from '@blocksuite/block-std';
|
|
||||||
import { IS_MAC, IS_WINDOWS } from '@blocksuite/global/env';
|
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
convertSelectedBlocksToLinkedDoc,
|
convertSelectedBlocksToLinkedDoc,
|
||||||
getTitleFromSelectedModels,
|
getTitleFromSelectedModels,
|
||||||
notifyDocCreated,
|
notifyDocCreated,
|
||||||
promptDocTitle,
|
promptDocTitle,
|
||||||
} from '../../_common/utils/render-linked-doc.js';
|
} from '@blocksuite/affine-block-embed';
|
||||||
|
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||||
|
import type { BlockComponent, BlockSelection } from '@blocksuite/block-std';
|
||||||
|
import { IS_MAC, IS_WINDOWS } from '@blocksuite/global/env';
|
||||||
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
|
|
||||||
export class PageKeyboardManager {
|
export class PageKeyboardManager {
|
||||||
private readonly _handleDelete = () => {
|
private readonly _handleDelete = () => {
|
||||||
@@ -117,7 +116,7 @@ export class PageKeyboardManager {
|
|||||||
|
|
||||||
const doc = rootComponent.host.doc;
|
const doc = rootComponent.host.doc;
|
||||||
const autofill = getTitleFromSelectedModels(selectedModels);
|
const autofill = getTitleFromSelectedModels(selectedModels);
|
||||||
promptDocTitle(rootComponent.host, autofill)
|
promptDocTitle(rootComponent.std, autofill)
|
||||||
.then(title => {
|
.then(title => {
|
||||||
if (title === null) return;
|
if (title === null) return;
|
||||||
convertSelectedBlocksToLinkedDoc(
|
convertSelectedBlocksToLinkedDoc(
|
||||||
@@ -126,7 +125,7 @@ export class PageKeyboardManager {
|
|||||||
draftedModels,
|
draftedModels,
|
||||||
title
|
title
|
||||||
).catch(console.error);
|
).catch(console.error);
|
||||||
notifyDocCreated(rootComponent.host, doc);
|
notifyDocCreated(rootComponent.std, doc);
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,4 @@
|
|||||||
|
import type { NoteBlockComponent } from '@blocksuite/affine-block-note';
|
||||||
import { captureEventTarget } from '@blocksuite/affine-shared/utils';
|
import { captureEventTarget } from '@blocksuite/affine-shared/utils';
|
||||||
import {
|
import {
|
||||||
BLOCK_ID_ATTR,
|
BLOCK_ID_ATTR,
|
||||||
@@ -8,7 +9,6 @@ import {
|
|||||||
import { Point, throttle } from '@blocksuite/global/utils';
|
import { Point, throttle } from '@blocksuite/global/utils';
|
||||||
import { computed } from '@preact/signals-core';
|
import { computed } from '@preact/signals-core';
|
||||||
|
|
||||||
import type { NoteBlockComponent } from '../../../../note-block/index.js';
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../../edgeless/index.js';
|
import type { EdgelessRootBlockComponent } from '../../../edgeless/index.js';
|
||||||
import {
|
import {
|
||||||
DRAG_HANDLE_CONTAINER_WIDTH,
|
DRAG_HANDLE_CONTAINER_WIDTH,
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import type { AttachmentBlockComponent } from '@blocksuite/affine-block-attachment';
|
import type { AttachmentBlockComponent } from '@blocksuite/affine-block-attachment';
|
||||||
import type { BookmarkBlockComponent } from '@blocksuite/affine-block-bookmark';
|
import type { BookmarkBlockComponent } from '@blocksuite/affine-block-bookmark';
|
||||||
import type {
|
import {
|
||||||
EmbedFigmaBlockComponent,
|
type EmbedFigmaBlockComponent,
|
||||||
EmbedGithubBlockComponent,
|
type EmbedGithubBlockComponent,
|
||||||
EmbedLoomBlockComponent,
|
type EmbedLoomBlockComponent,
|
||||||
EmbedYoutubeBlockComponent,
|
type EmbedYoutubeBlockComponent,
|
||||||
|
notifyDocCreated,
|
||||||
|
promptDocTitle,
|
||||||
} from '@blocksuite/affine-block-embed';
|
} from '@blocksuite/affine-block-embed';
|
||||||
import type { ImageBlockComponent } from '@blocksuite/affine-block-image';
|
import type { ImageBlockComponent } from '@blocksuite/affine-block-image';
|
||||||
import { isPeekable, peek } from '@blocksuite/affine-components/peek';
|
import { isPeekable, peek } from '@blocksuite/affine-components/peek';
|
||||||
@@ -30,8 +32,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
createLinkedDocFromEdgelessElements,
|
createLinkedDocFromEdgelessElements,
|
||||||
createLinkedDocFromNote,
|
createLinkedDocFromNote,
|
||||||
notifyDocCreated,
|
|
||||||
promptDocTitle,
|
|
||||||
} from '../../../../_common/utils/render-linked-doc.js';
|
} from '../../../../_common/utils/render-linked-doc.js';
|
||||||
import { duplicate } from '../../../edgeless/utils/clipboard-utils.js';
|
import { duplicate } from '../../../edgeless/utils/clipboard-utils.js';
|
||||||
import { getSortedCloneElements } from '../../../edgeless/utils/clone-utils.js';
|
import { getSortedCloneElements } from '../../../edgeless/utils/clone-utils.js';
|
||||||
@@ -245,11 +245,11 @@ export const conversionsGroup: MenuItemGroup<ElementToolbarMoreMenuContext> = {
|
|||||||
label: 'Turn into linked doc',
|
label: 'Turn into linked doc',
|
||||||
type: 'turn-into-linked-doc',
|
type: 'turn-into-linked-doc',
|
||||||
action: async ctx => {
|
action: async ctx => {
|
||||||
const { doc, service, surface, host, std } = ctx;
|
const { doc, service, surface, std } = ctx;
|
||||||
const element = ctx.getNoteBlock();
|
const element = ctx.getNoteBlock();
|
||||||
if (!element) return;
|
if (!element) return;
|
||||||
|
|
||||||
const title = await promptDocTitle(host);
|
const title = await promptDocTitle(std);
|
||||||
if (title === null) return;
|
if (title === null) return;
|
||||||
|
|
||||||
const linkedDoc = createLinkedDocFromNote(doc, element, title);
|
const linkedDoc = createLinkedDocFromNote(doc, element, title);
|
||||||
@@ -309,7 +309,7 @@ export const conversionsGroup: MenuItemGroup<ElementToolbarMoreMenuContext> = {
|
|||||||
host,
|
host,
|
||||||
std,
|
std,
|
||||||
}) => {
|
}) => {
|
||||||
const title = await promptDocTitle(host);
|
const title = await promptDocTitle(std);
|
||||||
if (title === null) return;
|
if (title === null) return;
|
||||||
|
|
||||||
const elements = getSortedCloneElements(selection.selectedElements);
|
const elements = getSortedCloneElements(selection.selectedElements);
|
||||||
@@ -360,7 +360,7 @@ export const conversionsGroup: MenuItemGroup<ElementToolbarMoreMenuContext> = {
|
|||||||
other: 'new doc',
|
other: 'new doc',
|
||||||
});
|
});
|
||||||
|
|
||||||
notifyDocCreated(host, doc);
|
notifyDocCreated(std, doc);
|
||||||
},
|
},
|
||||||
when: ctx => !(ctx.getLinkedDocBlock() || ctx.getNoteBlock()),
|
when: ctx => !(ctx.getLinkedDocBlock() || ctx.getNoteBlock()),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { whenHover } from '@blocksuite/affine-components/hover';
|
import { whenHover } from '@blocksuite/affine-components/hover';
|
||||||
import { ArrowDownIcon } from '@blocksuite/affine-components/icons';
|
import { ArrowDownIcon } from '@blocksuite/affine-components/icons';
|
||||||
|
import { textConversionConfigs } from '@blocksuite/affine-components/rich-text';
|
||||||
import type { ParagraphBlockModel } from '@blocksuite/affine-model';
|
import type { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||||
import type { EditorHost } from '@blocksuite/block-std';
|
import type { EditorHost } from '@blocksuite/block-std';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
@@ -8,7 +9,6 @@ import { html } from 'lit';
|
|||||||
import { ref, type RefOrCallback } from 'lit/directives/ref.js';
|
import { ref, type RefOrCallback } from 'lit/directives/ref.js';
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
|
|
||||||
import { textConversionConfigs } from '../../../../_common/configs/text-conversion.js';
|
|
||||||
import type { ParagraphActionConfigItem } from '../config.js';
|
import type { ParagraphActionConfigItem } from '../config.js';
|
||||||
import type { AffineFormatBarWidget } from '../format-bar.js';
|
import type { AffineFormatBarWidget } from '../format-bar.js';
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
import {
|
||||||
|
convertSelectedBlocksToLinkedDoc,
|
||||||
|
getTitleFromSelectedModels,
|
||||||
|
notifyDocCreated,
|
||||||
|
promptDocTitle,
|
||||||
|
} from '@blocksuite/affine-block-embed';
|
||||||
import {
|
import {
|
||||||
BoldIcon,
|
BoldIcon,
|
||||||
BulletedListIcon,
|
BulletedListIcon,
|
||||||
@@ -37,12 +43,6 @@ import { assertExists } from '@blocksuite/global/utils';
|
|||||||
import { Slice } from '@blocksuite/store';
|
import { Slice } from '@blocksuite/store';
|
||||||
import { html, type TemplateResult } from 'lit';
|
import { html, type TemplateResult } from 'lit';
|
||||||
|
|
||||||
import {
|
|
||||||
convertSelectedBlocksToLinkedDoc,
|
|
||||||
getTitleFromSelectedModels,
|
|
||||||
notifyDocCreated,
|
|
||||||
promptDocTitle,
|
|
||||||
} from '../../../_common/utils/render-linked-doc.js';
|
|
||||||
import { convertToDatabase } from '../../../database-block/data-source.js';
|
import { convertToDatabase } from '../../../database-block/data-source.js';
|
||||||
import { DATABASE_CONVERT_WHITE_LIST } from '../../../database-block/utils/block-utils.js';
|
import { DATABASE_CONVERT_WHITE_LIST } from '../../../database-block/utils/block-utils.js';
|
||||||
import { FormatBarContext } from './context.js';
|
import { FormatBarContext } from './context.js';
|
||||||
@@ -201,7 +201,7 @@ export function toolbarDefaultConfig(toolbar: AffineFormatBarWidget) {
|
|||||||
})
|
})
|
||||||
.draftSelectedModels()
|
.draftSelectedModels()
|
||||||
.run();
|
.run();
|
||||||
const { draftedModels, selectedModels } = ctx;
|
const { draftedModels, selectedModels, std } = ctx;
|
||||||
if (!selectedModels?.length || !draftedModels) return;
|
if (!selectedModels?.length || !draftedModels) return;
|
||||||
|
|
||||||
const host = formatBar.host;
|
const host = formatBar.host;
|
||||||
@@ -209,16 +209,16 @@ export function toolbarDefaultConfig(toolbar: AffineFormatBarWidget) {
|
|||||||
|
|
||||||
const doc = host.doc;
|
const doc = host.doc;
|
||||||
const autofill = getTitleFromSelectedModels(selectedModels);
|
const autofill = getTitleFromSelectedModels(selectedModels);
|
||||||
promptDocTitle(host, autofill)
|
promptDocTitle(std, autofill)
|
||||||
.then(async title => {
|
.then(async title => {
|
||||||
if (title === null) return;
|
if (title === null) return;
|
||||||
await convertSelectedBlocksToLinkedDoc(
|
await convertSelectedBlocksToLinkedDoc(
|
||||||
host.std,
|
std,
|
||||||
doc,
|
doc,
|
||||||
draftedModels,
|
draftedModels,
|
||||||
title
|
title
|
||||||
);
|
);
|
||||||
notifyDocCreated(host, doc);
|
notifyDocCreated(std, doc);
|
||||||
host.std.getOptional(TelemetryProvider)?.track('DocCreated', {
|
host.std.getOptional(TelemetryProvider)?.track('DocCreated', {
|
||||||
control: 'create linked doc',
|
control: 'create linked doc',
|
||||||
page: 'doc editor',
|
page: 'doc editor',
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import {
|
|||||||
getInlineEditorByModel,
|
getInlineEditorByModel,
|
||||||
insertContent,
|
insertContent,
|
||||||
REFERENCE_NODE,
|
REFERENCE_NODE,
|
||||||
|
textConversionConfigs,
|
||||||
textFormatConfigs,
|
textFormatConfigs,
|
||||||
} from '@blocksuite/affine-components/rich-text';
|
} from '@blocksuite/affine-components/rich-text';
|
||||||
import { toast } from '@blocksuite/affine-components/toast';
|
import { toast } from '@blocksuite/affine-components/toast';
|
||||||
@@ -49,7 +50,6 @@ import { Slice, Text } from '@blocksuite/store';
|
|||||||
import type { TemplateResult } from 'lit';
|
import type { TemplateResult } from 'lit';
|
||||||
|
|
||||||
import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js';
|
import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js';
|
||||||
import { textConversionConfigs } from '../../../_common/configs/text-conversion.js';
|
|
||||||
import type { DataViewBlockComponent } from '../../../data-view-block/index.js';
|
import type { DataViewBlockComponent } from '../../../data-view-block/index.js';
|
||||||
import { getSurfaceBlock } from '../../../surface-ref-block/utils.js';
|
import { getSurfaceBlock } from '../../../surface-ref-block/utils.js';
|
||||||
import type { RootBlockComponent } from '../../types.js';
|
import type { RootBlockComponent } from '../../types.js';
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import type { TextFormatConfig } from '@blocksuite/affine-components/rich-text';
|
import type {
|
||||||
|
TextConversionConfig,
|
||||||
|
TextFormatConfig,
|
||||||
|
} from '@blocksuite/affine-components/rich-text';
|
||||||
import { isInsideBlockByFlavour } from '@blocksuite/affine-shared/utils';
|
import { isInsideBlockByFlavour } from '@blocksuite/affine-shared/utils';
|
||||||
import { assertType } from '@blocksuite/global/utils';
|
import { assertType } from '@blocksuite/global/utils';
|
||||||
import type { BlockModel } from '@blocksuite/store';
|
import type { BlockModel } from '@blocksuite/store';
|
||||||
|
|
||||||
import type { TextConversionConfig } from '../../../_common/configs/text-conversion.js';
|
|
||||||
import type {
|
import type {
|
||||||
SlashMenuActionItem,
|
SlashMenuActionItem,
|
||||||
SlashMenuContext,
|
SlashMenuContext,
|
||||||
|
|||||||
@@ -37,6 +37,9 @@
|
|||||||
{
|
{
|
||||||
"path": "../affine/block-embed"
|
"path": "../affine/block-embed"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "../affine/block-note"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "../affine/block-bookmark"
|
"path": "../affine/block-bookmark"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -81,6 +81,20 @@ export const PackageList = [
|
|||||||
'blocksuite/framework/store',
|
'blocksuite/framework/store',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
location: 'blocksuite/affine/block-note',
|
||||||
|
name: '@blocksuite/affine-block-note',
|
||||||
|
workspaceDependencies: [
|
||||||
|
'blocksuite/affine/block-embed',
|
||||||
|
'blocksuite/affine/components',
|
||||||
|
'blocksuite/affine/model',
|
||||||
|
'blocksuite/affine/shared',
|
||||||
|
'blocksuite/framework/block-std',
|
||||||
|
'blocksuite/framework/global',
|
||||||
|
'blocksuite/framework/inline',
|
||||||
|
'blocksuite/framework/store',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
location: 'blocksuite/affine/block-paragraph',
|
location: 'blocksuite/affine/block-paragraph',
|
||||||
name: '@blocksuite/affine-block-paragraph',
|
name: '@blocksuite/affine-block-paragraph',
|
||||||
@@ -170,6 +184,7 @@ export const PackageList = [
|
|||||||
'blocksuite/affine/block-embed',
|
'blocksuite/affine/block-embed',
|
||||||
'blocksuite/affine/block-image',
|
'blocksuite/affine/block-image',
|
||||||
'blocksuite/affine/block-list',
|
'blocksuite/affine/block-list',
|
||||||
|
'blocksuite/affine/block-note',
|
||||||
'blocksuite/affine/block-paragraph',
|
'blocksuite/affine/block-paragraph',
|
||||||
'blocksuite/affine/block-surface',
|
'blocksuite/affine/block-surface',
|
||||||
'blocksuite/affine/components',
|
'blocksuite/affine/components',
|
||||||
@@ -506,6 +521,7 @@ export type PackageName =
|
|||||||
| '@blocksuite/affine-block-embed'
|
| '@blocksuite/affine-block-embed'
|
||||||
| '@blocksuite/affine-block-image'
|
| '@blocksuite/affine-block-image'
|
||||||
| '@blocksuite/affine-block-list'
|
| '@blocksuite/affine-block-list'
|
||||||
|
| '@blocksuite/affine-block-note'
|
||||||
| '@blocksuite/affine-block-paragraph'
|
| '@blocksuite/affine-block-paragraph'
|
||||||
| '@blocksuite/affine-block-surface'
|
| '@blocksuite/affine-block-surface'
|
||||||
| '@blocksuite/affine-components'
|
| '@blocksuite/affine-components'
|
||||||
|
|||||||
@@ -3340,6 +3340,29 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"@blocksuite/affine-block-note@workspace:*, @blocksuite/affine-block-note@workspace:blocksuite/affine/block-note":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@blocksuite/affine-block-note@workspace:blocksuite/affine/block-note"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/affine-block-embed": "workspace:*"
|
||||||
|
"@blocksuite/affine-components": "workspace:*"
|
||||||
|
"@blocksuite/affine-model": "workspace:*"
|
||||||
|
"@blocksuite/affine-shared": "workspace:*"
|
||||||
|
"@blocksuite/block-std": "workspace:*"
|
||||||
|
"@blocksuite/global": "workspace:*"
|
||||||
|
"@blocksuite/icons": "npm:^2.1.75"
|
||||||
|
"@blocksuite/inline": "workspace:*"
|
||||||
|
"@blocksuite/store": "workspace:*"
|
||||||
|
"@floating-ui/dom": "npm:^1.6.10"
|
||||||
|
"@lit/context": "npm:^1.1.2"
|
||||||
|
"@preact/signals-core": "npm:^1.8.0"
|
||||||
|
"@toeverything/theme": "npm:^1.1.1"
|
||||||
|
lit: "npm:^3.2.0"
|
||||||
|
minimatch: "npm:^10.0.1"
|
||||||
|
zod: "npm:^3.23.8"
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@blocksuite/affine-block-paragraph@workspace:*, @blocksuite/affine-block-paragraph@workspace:blocksuite/affine/block-paragraph":
|
"@blocksuite/affine-block-paragraph@workspace:*, @blocksuite/affine-block-paragraph@workspace:blocksuite/affine/block-paragraph":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@blocksuite/affine-block-paragraph@workspace:blocksuite/affine/block-paragraph"
|
resolution: "@blocksuite/affine-block-paragraph@workspace:blocksuite/affine/block-paragraph"
|
||||||
@@ -3511,6 +3534,7 @@ __metadata:
|
|||||||
"@blocksuite/affine-block-embed": "workspace:*"
|
"@blocksuite/affine-block-embed": "workspace:*"
|
||||||
"@blocksuite/affine-block-image": "workspace:*"
|
"@blocksuite/affine-block-image": "workspace:*"
|
||||||
"@blocksuite/affine-block-list": "workspace:*"
|
"@blocksuite/affine-block-list": "workspace:*"
|
||||||
|
"@blocksuite/affine-block-note": "workspace:*"
|
||||||
"@blocksuite/affine-block-paragraph": "workspace:*"
|
"@blocksuite/affine-block-paragraph": "workspace:*"
|
||||||
"@blocksuite/affine-block-surface": "workspace:*"
|
"@blocksuite/affine-block-surface": "workspace:*"
|
||||||
"@blocksuite/affine-components": "workspace:*"
|
"@blocksuite/affine-components": "workspace:*"
|
||||||
|
|||||||
Reference in new issue
Block a user