mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-13 16:16:46 +08:00
refactor(editor): remove global types in model (#10082)
Closes: [BS-2249](https://linear.app/affine-design/issue/BS-2249/remove-global-types-in-model) ```ts // before matchFlavours(model, ['affine:page']); // after matchFlavours(model, [PageBlockModel]); ```
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { SurfaceBlockModel } from '@blocksuite/affine-block-surface';
|
||||
import { FileDropConfigExtension } from '@blocksuite/affine-components/drop-indicator';
|
||||
import { AttachmentBlockSchema } from '@blocksuite/affine-model';
|
||||
import {
|
||||
@@ -23,7 +24,7 @@ export const AttachmentDropOption = FileDropConfigExtension({
|
||||
|
||||
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||
|
||||
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
|
||||
if (targetModel && !matchFlavours(targetModel, [SurfaceBlockModel])) {
|
||||
addSiblingAttachmentBlocks(
|
||||
std.host,
|
||||
attachmentFiles,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import type {
|
||||
DatabaseBlockModel,
|
||||
RootBlockModel,
|
||||
import {
|
||||
CodeBlockModel,
|
||||
type DatabaseBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
type RootBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
@@ -73,9 +76,9 @@ export class NoteRenderer
|
||||
.find(child => child.flavour === 'affine:note')
|
||||
?.children.find(block =>
|
||||
matchFlavours(block, [
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:code',
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { TextUtils } from '@blocksuite/affine-block-surface';
|
||||
import { formatBlockCommand } from '@blocksuite/affine-components/rich-text';
|
||||
import type { EdgelessTextBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
type EdgelessTextBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockComponent } from '@blocksuite/block-std';
|
||||
@@ -158,7 +162,7 @@ export class EdgelessTextBlockComponent extends GfxBlockComponent<EdgelessTextBl
|
||||
const firstChild = this.model.firstChild();
|
||||
if (
|
||||
!firstChild ||
|
||||
!matchFlavours(firstChild, ['affine:list', 'affine:paragraph'])
|
||||
!matchFlavours(firstChild, [ListBlockModel, ParagraphBlockModel])
|
||||
) {
|
||||
newParagraphId = this.doc.addBlock(
|
||||
'affine:paragraph',
|
||||
@@ -171,7 +175,7 @@ export class EdgelessTextBlockComponent extends GfxBlockComponent<EdgelessTextBl
|
||||
const lastChild = this.model.lastChild();
|
||||
if (
|
||||
!lastChild ||
|
||||
!matchFlavours(lastChild, ['affine:list', 'affine:paragraph'])
|
||||
!matchFlavours(lastChild, [ListBlockModel, ParagraphBlockModel])
|
||||
) {
|
||||
newParagraphId = this.doc.addBlock(
|
||||
'affine:paragraph',
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { getSurfaceBlock } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
type DocMode,
|
||||
type ImageBlockModel,
|
||||
ImageBlockModel,
|
||||
ListBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { EMBED_CARD_HEIGHT } from '@blocksuite/affine-shared/consts';
|
||||
import { NotificationProvider } from '@blocksuite/affine-shared/services';
|
||||
@@ -68,7 +71,7 @@ async function renderPageAsBanner(card: EmbedSyncedDocCard) {
|
||||
}
|
||||
|
||||
const target = notes.flatMap(note =>
|
||||
note.children.filter(child => matchFlavours(child, ['affine:image']))
|
||||
note.children.filter(child => matchFlavours(child, [ImageBlockModel]))
|
||||
)[0];
|
||||
|
||||
if (target) {
|
||||
@@ -135,9 +138,7 @@ async function renderNoteContent(
|
||||
|
||||
const cardStyle = card.model.style;
|
||||
const isHorizontal = cardStyle === 'horizontal';
|
||||
const allowFlavours: (keyof BlockSuite.BlockModels)[] = isHorizontal
|
||||
? []
|
||||
: ['affine:image'];
|
||||
const allowFlavours = isHorizontal ? [] : [ImageBlockModel];
|
||||
|
||||
const noteChildren = notes.flatMap(note =>
|
||||
note.children.filter(model => {
|
||||
@@ -214,7 +215,7 @@ async function renderNoteContent(
|
||||
}
|
||||
|
||||
function filterTextModel(model: BlockModel) {
|
||||
if (matchFlavours(model, ['affine:paragraph', 'affine:list'])) {
|
||||
if (matchFlavours(model, [ParagraphBlockModel, ListBlockModel])) {
|
||||
return !!model.text?.toString().length;
|
||||
}
|
||||
return false;
|
||||
@@ -223,7 +224,7 @@ function filterTextModel(model: BlockModel) {
|
||||
export function getNotesFromDoc(doc: Store) {
|
||||
const notes = doc.root?.children.filter(
|
||||
child =>
|
||||
matchFlavours(child, ['affine:note']) &&
|
||||
matchFlavours(child, [NoteBlockModel]) &&
|
||||
child.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
);
|
||||
|
||||
@@ -304,7 +305,7 @@ export function getDocContentWithMaxLength(doc: Store, maxlength = 500) {
|
||||
export function getTitleFromSelectedModels(selectedModels: DraftModel[]) {
|
||||
const firstBlock = selectedModels[0];
|
||||
if (
|
||||
matchFlavours(firstBlock, ['affine:paragraph']) &&
|
||||
matchFlavours(firstBlock, [ParagraphBlockModel]) &&
|
||||
firstBlock.type.startsWith('h')
|
||||
) {
|
||||
return firstBlock.text.toString();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SurfaceBlockModel } from '@blocksuite/affine-block-surface';
|
||||
import { isPeekable, Peekable } from '@blocksuite/affine-components/peek';
|
||||
import { RefNodeSlotsProvider } from '@blocksuite/affine-components/rich-text';
|
||||
import type {
|
||||
@@ -373,7 +374,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
|
||||
const isLoading = this._loading;
|
||||
const isError = this.isError;
|
||||
const isEmpty = this._isDocEmpty() && this.isBannerEmpty;
|
||||
const inCanvas = matchFlavours(this.model.parent, ['affine:surface']);
|
||||
const inCanvas = matchFlavours(this.model.parent, [SurfaceBlockModel]);
|
||||
|
||||
const cardClassMap = classMap({
|
||||
loading: isLoading,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SurfaceBlockModel } from '@blocksuite/affine-block-surface';
|
||||
import { FileDropConfigExtension } from '@blocksuite/affine-components/drop-indicator';
|
||||
import { ImageBlockSchema, MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
||||
import {
|
||||
@@ -25,7 +26,7 @@ export const ImageDropOption = FileDropConfigExtension({
|
||||
|
||||
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||
|
||||
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
|
||||
if (targetModel && !matchFlavours(targetModel, [SurfaceBlockModel])) {
|
||||
addSiblingImageBlock(
|
||||
std.host,
|
||||
imageFiles,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import type { IndentContext } from '@blocksuite/affine-shared/types';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import { type Command, TextSelection } from '@blocksuite/block-std';
|
||||
@@ -53,7 +54,7 @@ export const canDedentListCommand: Command<
|
||||
* ccc
|
||||
*/
|
||||
const model = store.getBlock(blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:list'])) {
|
||||
if (!model || !matchFlavours(model, [ListBlockModel])) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ListBlockModel, ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import type { IndentContext } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
getNearestHeadingBefore,
|
||||
@@ -54,7 +55,7 @@ export const canIndentListCommand: Command<
|
||||
* ccc
|
||||
*/
|
||||
const model = store.getBlock(blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:list'])) {
|
||||
if (!model || !matchFlavours(model, [ListBlockModel])) {
|
||||
return;
|
||||
}
|
||||
const schema = std.store.schema;
|
||||
@@ -125,7 +126,7 @@ export const indentListCommand: Command<{
|
||||
const nearestHeading = getNearestHeadingBefore(model);
|
||||
if (
|
||||
nearestHeading &&
|
||||
matchFlavours(nearestHeading, ['affine:paragraph']) &&
|
||||
matchFlavours(nearestHeading, [ParagraphBlockModel]) &&
|
||||
nearestHeading.collapsed
|
||||
) {
|
||||
store.updateBlock(nearestHeading, {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
||||
import { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
|
||||
@@ -16,7 +17,7 @@ export const listToParagraphCommand: Command<
|
||||
const doc = std.store;
|
||||
const model = doc.getBlock(id)?.model;
|
||||
|
||||
if (!model || !matchFlavours(model, ['affine:list'])) return false;
|
||||
if (!model || !matchFlavours(model, [ListBlockModel])) return false;
|
||||
|
||||
const parent = doc.getParent(model);
|
||||
if (!parent) return false;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
||||
import { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
getNextContinuousNumberedLists,
|
||||
matchFlavours,
|
||||
@@ -17,7 +18,7 @@ export const splitListCommand: Command<{
|
||||
const doc = host.doc;
|
||||
|
||||
const model = doc.getBlock(blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:list'])) {
|
||||
if (!model || !matchFlavours(model, [ListBlockModel])) {
|
||||
console.error(`block ${blockId} is not a list block`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
getNextContinuousNumberedLists,
|
||||
matchFlavours,
|
||||
@@ -22,7 +22,7 @@ export function correctNumberedListsOrderToPrev(
|
||||
if (!model) return;
|
||||
|
||||
if (
|
||||
!matchFlavours(model, ['affine:list']) ||
|
||||
!matchFlavours(model, [ListBlockModel]) ||
|
||||
model.type$.value !== 'numbered'
|
||||
) {
|
||||
return;
|
||||
@@ -33,7 +33,7 @@ export function correctNumberedListsOrderToPrev(
|
||||
const previousSibling = doc.getPrev(model);
|
||||
if (
|
||||
previousSibling &&
|
||||
matchFlavours(previousSibling, ['affine:list']) &&
|
||||
matchFlavours(previousSibling, [ListBlockModel]) &&
|
||||
previousSibling.type === 'numbered'
|
||||
) {
|
||||
if (!previousSibling.order) previousSibling.order = 1;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
getNextContentBlock,
|
||||
matchFlavours,
|
||||
@@ -25,7 +26,7 @@ export function forwardDelete(std: BlockStdScope): true | undefined {
|
||||
const isCollapsed = text.isCollapsed();
|
||||
const doc = std.store;
|
||||
const model = doc.getBlock(text.from.blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:list'])) return;
|
||||
if (!model || !matchFlavours(model, [ListBlockModel])) return;
|
||||
const isEnd = isCollapsed && text.from.index === model.text.length;
|
||||
if (!isEnd) return;
|
||||
// Has children in list
|
||||
|
||||
@@ -3,6 +3,11 @@ import {
|
||||
focusTextModel,
|
||||
onModelTextUpdated,
|
||||
} from '@blocksuite/affine-components/rich-text';
|
||||
import {
|
||||
CodeBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
getBlockSelectionsCommand,
|
||||
getSelectedBlocksCommand,
|
||||
@@ -196,9 +201,9 @@ export const updateBlockType: Command<
|
||||
blockModels.forEach(model => {
|
||||
if (
|
||||
!matchFlavours(model, [
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:code',
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
) {
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import { NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
|
||||
@@ -10,7 +10,7 @@ export const changeNoteDisplayMode: Command<{
|
||||
const { std, noteId, mode, stopCapture } = ctx;
|
||||
|
||||
const noteBlockModel = std.store.getBlock(noteId)?.model;
|
||||
if (!noteBlockModel || !matchFlavours(noteBlockModel, ['affine:note']))
|
||||
if (!noteBlockModel || !matchFlavours(noteBlockModel, [NoteBlockModel]))
|
||||
return;
|
||||
|
||||
const currentMode = noteBlockModel.displayMode;
|
||||
@@ -27,7 +27,7 @@ export const changeNoteDisplayMode: Command<{
|
||||
const parent = std.store.getParent(noteBlockModel);
|
||||
if (parent) {
|
||||
const notes = parent.children.filter(child =>
|
||||
matchFlavours(child, ['affine:note'])
|
||||
matchFlavours(child, [NoteBlockModel])
|
||||
);
|
||||
const firstEdgelessOnlyNote = notes.find(
|
||||
note => note.displayMode === NoteDisplayMode.EdgelessOnly
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { NoteBlockModel } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
|
||||
@@ -20,7 +21,7 @@ export const dedentBlockToRoot: Command<{
|
||||
|
||||
let parent = store.getParent(model);
|
||||
let changed = false;
|
||||
while (parent && !matchFlavours(parent, ['affine:note'])) {
|
||||
while (parent && !matchFlavours(parent, [NoteBlockModel])) {
|
||||
if (!changed) {
|
||||
if (stopCapture) store.captureSync();
|
||||
changed = true;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
calculateCollapsedSiblings,
|
||||
matchFlavours,
|
||||
@@ -45,7 +46,7 @@ export const dedentBlock: Command<{
|
||||
if (stopCapture) store.captureSync();
|
||||
|
||||
if (
|
||||
matchFlavours(model, ['affine:paragraph']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel]) &&
|
||||
model.type.startsWith('h') &&
|
||||
model.collapsed
|
||||
) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { NoteBlockModel } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import { type Command, TextSelection } from '@blocksuite/block-std';
|
||||
|
||||
@@ -30,7 +31,7 @@ export const dedentBlocksToRoot: Command<{
|
||||
for (let i = blockIds.length - 1; i >= 0; i--) {
|
||||
const model = blockIds[i];
|
||||
const parent = store.getParent(model);
|
||||
if (parent && !matchFlavours(parent, ['affine:note'])) {
|
||||
if (parent && !matchFlavours(parent, [NoteBlockModel])) {
|
||||
std.command.exec(dedentBlockToRoot, {
|
||||
blockId: model,
|
||||
stopCapture: false,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
calculateCollapsedSiblings,
|
||||
matchFlavours,
|
||||
@@ -57,7 +58,7 @@ export const dedentBlocks: Command<{
|
||||
const model = store.getBlock(id)?.model;
|
||||
if (!model) return;
|
||||
if (
|
||||
matchFlavours(model, ['affine:paragraph']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel]) &&
|
||||
model.type.startsWith('h') &&
|
||||
model.collapsed
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import { ListBlockModel, ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
calculateCollapsedSiblings,
|
||||
matchFlavours,
|
||||
@@ -50,7 +50,7 @@ export const indentBlock: Command<{
|
||||
if (stopCapture) store.captureSync();
|
||||
|
||||
if (
|
||||
matchFlavours(model, ['affine:paragraph']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel]) &&
|
||||
model.type.startsWith('h') &&
|
||||
model.collapsed
|
||||
) {
|
||||
@@ -62,12 +62,12 @@ export const indentBlock: Command<{
|
||||
|
||||
// update collapsed state of affine list
|
||||
if (
|
||||
matchFlavours(previousSibling, ['affine:list']) &&
|
||||
matchFlavours(previousSibling, [ListBlockModel]) &&
|
||||
previousSibling.collapsed
|
||||
) {
|
||||
store.updateBlock(previousSibling, {
|
||||
collapsed: false,
|
||||
} as Partial<ListBlockModel>);
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
calculateCollapsedSiblings,
|
||||
getNearestHeadingBefore,
|
||||
@@ -58,7 +59,7 @@ export const indentBlocks: Command<{
|
||||
const model = store.getBlock(id)?.model;
|
||||
if (!model) return;
|
||||
if (
|
||||
matchFlavours(model, ['affine:paragraph']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel]) &&
|
||||
model.type.startsWith('h') &&
|
||||
model.collapsed
|
||||
) {
|
||||
@@ -83,12 +84,10 @@ export const indentBlocks: Command<{
|
||||
const nearestHeading = getNearestHeadingBefore(firstModel);
|
||||
if (
|
||||
nearestHeading &&
|
||||
matchFlavours(nearestHeading, ['affine:paragraph']) &&
|
||||
matchFlavours(nearestHeading, [ParagraphBlockModel]) &&
|
||||
nearestHeading.collapsed
|
||||
) {
|
||||
store.updateBlock(nearestHeading, {
|
||||
collapsed: false,
|
||||
});
|
||||
store.updateBlock(nearestHeading, { collapsed: false });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,12 +105,10 @@ export const indentBlocks: Command<{
|
||||
const nearestHeading = getNearestHeadingBefore(firstModel);
|
||||
if (
|
||||
nearestHeading &&
|
||||
matchFlavours(nearestHeading, ['affine:paragraph']) &&
|
||||
matchFlavours(nearestHeading, [ParagraphBlockModel]) &&
|
||||
nearestHeading.collapsed
|
||||
) {
|
||||
store.updateBlock(nearestHeading, {
|
||||
collapsed: false,
|
||||
});
|
||||
store.updateBlock(nearestHeading, { collapsed: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
DefaultTheme,
|
||||
ListBlockModel,
|
||||
NoteBlockModel,
|
||||
ParagraphBlockModel,
|
||||
StrokeStyle,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
@@ -98,10 +100,10 @@ export class EdgelessNoteBackground extends SignalWatcher(
|
||||
|
||||
if (
|
||||
(!nearestModel.text ||
|
||||
!matchFlavours(nearestModel, ['affine:paragraph', 'affine:list'])) &&
|
||||
!matchFlavours(nearestModel, [ParagraphBlockModel, ListBlockModel])) &&
|
||||
(!siblingModel ||
|
||||
!siblingModel.text ||
|
||||
!matchFlavours(siblingModel, ['affine:paragraph', 'affine:list']))
|
||||
!matchFlavours(siblingModel, [ParagraphBlockModel, ListBlockModel]))
|
||||
) {
|
||||
const [pId] = this.doc.addSiblingBlocks(
|
||||
nearestModel,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { textConversionConfigs } from '@blocksuite/affine-components/rich-text';
|
||||
import { NoteBlockSchema } from '@blocksuite/affine-model';
|
||||
import {
|
||||
CodeBlockModel,
|
||||
ListBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteBlockSchema,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
getBlockSelectionsCommand,
|
||||
getNextBlockCommand,
|
||||
@@ -149,7 +155,7 @@ export class NoteBlockService extends BlockService {
|
||||
const doc = this._std.store;
|
||||
let parent = doc.getBlock(blockId)?.model ?? null;
|
||||
while (parent) {
|
||||
if (matchFlavours(parent, [NoteBlockSchema.model.flavour])) {
|
||||
if (matchFlavours(parent, [NoteBlockModel])) {
|
||||
return parent;
|
||||
}
|
||||
parent = doc.getParent(parent);
|
||||
@@ -189,9 +195,9 @@ export class NoteBlockService extends BlockService {
|
||||
|
||||
if (
|
||||
!matchFlavours(nextBlock.model, [
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:code',
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
) {
|
||||
this._std.command.exec(selectBlock, {
|
||||
@@ -225,9 +231,9 @@ export class NoteBlockService extends BlockService {
|
||||
event.preventDefault();
|
||||
if (
|
||||
matchFlavours(nextBlock.model, [
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:code',
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
) {
|
||||
this._std.command.exec(focusBlockStart, {
|
||||
@@ -279,9 +285,9 @@ export class NoteBlockService extends BlockService {
|
||||
|
||||
if (
|
||||
!matchFlavours(prevBlock.model, [
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:code',
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
) {
|
||||
this._std.command.exec(selectBlock, {
|
||||
@@ -313,9 +319,9 @@ export class NoteBlockService extends BlockService {
|
||||
|
||||
if (
|
||||
matchFlavours(prevBlock.model, [
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:code',
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import { NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
@@ -11,7 +11,7 @@ export function isPageBlock(std: BlockStdScope, note: NoteBlockModel) {
|
||||
std.get(FeatureFlagService).getFlag('enable_page_block') &&
|
||||
note.parent?.children.find(
|
||||
child =>
|
||||
matchFlavours(child, ['affine:note']) &&
|
||||
matchFlavours(child, [NoteBlockModel]) &&
|
||||
child.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
) === note
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import type { IndentContext } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
calculateCollapsedSiblings,
|
||||
@@ -34,7 +35,7 @@ export const canDedentParagraphCommand: Command<
|
||||
}
|
||||
|
||||
const model = store.getBlock(blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) {
|
||||
if (!model || !matchFlavours(model, [ParagraphBlockModel])) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ export const dedentParagraphCommand: Command<{
|
||||
store.captureSync();
|
||||
|
||||
if (
|
||||
matchFlavours(model, ['affine:paragraph']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel]) &&
|
||||
model.type.startsWith('h') &&
|
||||
model.collapsed
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import { ListBlockModel, ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import type { IndentContext } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
calculateCollapsedSiblings,
|
||||
@@ -37,7 +37,7 @@ export const canIndentParagraphCommand: Command<
|
||||
}
|
||||
|
||||
const model = std.store.getBlock(blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) {
|
||||
if (!model || !matchFlavours(model, [ParagraphBlockModel])) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ export const indentParagraphCommand: Command<{
|
||||
const nearestHeading = getNearestHeadingBefore(model);
|
||||
if (
|
||||
nearestHeading &&
|
||||
matchFlavours(nearestHeading, ['affine:paragraph']) &&
|
||||
matchFlavours(nearestHeading, [ParagraphBlockModel]) &&
|
||||
nearestHeading.collapsed
|
||||
) {
|
||||
store.updateBlock(nearestHeading, {
|
||||
@@ -105,7 +105,7 @@ export const indentParagraphCommand: Command<{
|
||||
}
|
||||
|
||||
if (
|
||||
matchFlavours(model, ['affine:paragraph']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel]) &&
|
||||
model.type.startsWith('h') &&
|
||||
model.collapsed
|
||||
) {
|
||||
@@ -124,7 +124,7 @@ export const indentParagraphCommand: Command<{
|
||||
const nearestHeading = getNearestHeadingBefore(model);
|
||||
if (
|
||||
nearestHeading &&
|
||||
matchFlavours(nearestHeading, ['affine:paragraph']) &&
|
||||
matchFlavours(nearestHeading, [ParagraphBlockModel]) &&
|
||||
nearestHeading.collapsed
|
||||
) {
|
||||
store.updateBlock(nearestHeading, {
|
||||
@@ -135,12 +135,12 @@ export const indentParagraphCommand: Command<{
|
||||
|
||||
// update collapsed state of affine list
|
||||
if (
|
||||
matchFlavours(previousSibling, ['affine:list']) &&
|
||||
matchFlavours(previousSibling, [ListBlockModel]) &&
|
||||
previousSibling.collapsed
|
||||
) {
|
||||
store.updateBlock(previousSibling, {
|
||||
collapsed: false,
|
||||
} as Partial<ListBlockModel>);
|
||||
});
|
||||
}
|
||||
|
||||
const textSelection = selection.find(TextSelection);
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
focusTextModel,
|
||||
getInlineEditorByModel,
|
||||
} from '@blocksuite/affine-components/rich-text';
|
||||
import { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import { type Command, TextSelection } from '@blocksuite/block-std';
|
||||
|
||||
@@ -23,7 +24,7 @@ export const splitParagraphCommand: Command<
|
||||
if (!blockId) return;
|
||||
|
||||
const model = store.getBlock(blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) return;
|
||||
if (!model || !matchFlavours(model, [ParagraphBlockModel])) return;
|
||||
|
||||
const inlineEditor = getInlineEditorByModel(host, model);
|
||||
const range = inlineEditor?.getInlineRange();
|
||||
|
||||
@@ -4,7 +4,10 @@ import {
|
||||
markdownInput,
|
||||
textKeymap,
|
||||
} from '@blocksuite/affine-components/rich-text';
|
||||
import { ParagraphBlockSchema } from '@blocksuite/affine-model';
|
||||
import {
|
||||
ParagraphBlockModel,
|
||||
ParagraphBlockSchema,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
calculateCollapsedSiblings,
|
||||
matchFlavours,
|
||||
@@ -37,7 +40,7 @@ export const ParagraphKeymapExtension = KeymapExtension(
|
||||
|
||||
const { store } = std;
|
||||
const model = store.getBlock(text.from.blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) return;
|
||||
if (!model || !matchFlavours(model, [ParagraphBlockModel])) return;
|
||||
|
||||
const event = ctx.get('keyboardState').raw;
|
||||
event.preventDefault();
|
||||
@@ -68,7 +71,7 @@ export const ParagraphKeymapExtension = KeymapExtension(
|
||||
const text = std.selection.find(TextSelection);
|
||||
if (!text) return;
|
||||
const model = store.getBlock(text.from.blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) return;
|
||||
if (!model || !matchFlavours(model, [ParagraphBlockModel])) return;
|
||||
const inlineEditor = getInlineEditorByModel(
|
||||
std.host,
|
||||
text.from.blockId
|
||||
@@ -95,7 +98,7 @@ export const ParagraphKeymapExtension = KeymapExtension(
|
||||
const text = std.selection.find(TextSelection);
|
||||
if (!text) return;
|
||||
const model = store.getBlock(text.from.blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) return;
|
||||
if (!model || !matchFlavours(model, [ParagraphBlockModel])) return;
|
||||
const inlineEditor = getInlineEditorByModel(
|
||||
std.host,
|
||||
text.from.blockId
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import { EMBED_BLOCK_FLAVOUR_LIST } from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
CodeBlockModel,
|
||||
DatabaseBlockModel,
|
||||
DividerBlockModel,
|
||||
ImageBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { EMBED_BLOCK_MODEL_LIST } from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
getNextContentBlock,
|
||||
matchFlavours,
|
||||
@@ -15,31 +25,32 @@ export function forwardDelete(std: BlockStdScope) {
|
||||
if (!text) return;
|
||||
const isCollapsed = text.isCollapsed();
|
||||
const model = store.getBlock(text.from.blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) return;
|
||||
if (!model || !matchFlavours(model, [ParagraphBlockModel])) return;
|
||||
const isEnd = isCollapsed && text.from.index === model.text.length;
|
||||
if (!isEnd) return;
|
||||
const parent = store.getParent(model);
|
||||
if (!parent) return;
|
||||
|
||||
const nextSibling = store.getNext(model);
|
||||
const ignoreForwardDeleteFlavourList: BlockSuite.Flavour[] = [
|
||||
'affine:attachment',
|
||||
'affine:bookmark',
|
||||
'affine:database',
|
||||
'affine:code',
|
||||
'affine:image',
|
||||
'affine:divider',
|
||||
...EMBED_BLOCK_FLAVOUR_LIST,
|
||||
];
|
||||
|
||||
if (matchFlavours(nextSibling, ignoreForwardDeleteFlavourList)) {
|
||||
if (
|
||||
matchFlavours(nextSibling, [
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
DatabaseBlockModel,
|
||||
CodeBlockModel,
|
||||
ImageBlockModel,
|
||||
DividerBlockModel,
|
||||
...EMBED_BLOCK_MODEL_LIST,
|
||||
] as const)
|
||||
) {
|
||||
std.selection.setGroup('note', [
|
||||
std.selection.create(BlockSelection, { blockId: nextSibling.id }),
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nextSibling?.text) {
|
||||
if (matchFlavours(nextSibling, [ParagraphBlockModel, ListBlockModel])) {
|
||||
model.text.join(nextSibling.text);
|
||||
if (nextSibling.children) {
|
||||
const parent = store.getParent(nextSibling);
|
||||
|
||||
@@ -2,8 +2,19 @@ import {
|
||||
asyncSetInlineRange,
|
||||
focusTextModel,
|
||||
} from '@blocksuite/affine-components/rich-text';
|
||||
import type { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { EMBED_BLOCK_FLAVOUR_LIST } from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
CodeBlockModel,
|
||||
DatabaseBlockModel,
|
||||
DividerBlockModel,
|
||||
EdgelessTextBlockModel,
|
||||
ImageBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
type RootBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { EMBED_BLOCK_MODEL_LIST } from '@blocksuite/affine-shared/consts';
|
||||
import type { ExtendedModel } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
focusTitle,
|
||||
@@ -33,7 +44,7 @@ export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) {
|
||||
const parent = doc.getParent(model);
|
||||
if (!parent) return false;
|
||||
|
||||
if (matchFlavours(parent, ['affine:edgeless-text'])) {
|
||||
if (matchFlavours(parent, [EdgelessTextBlockModel])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,7 +53,7 @@ export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) {
|
||||
return handleNoPreviousSibling(editorHost, model);
|
||||
}
|
||||
|
||||
if (matchFlavours(prevBlock, ['affine:paragraph', 'affine:list'])) {
|
||||
if (matchFlavours(prevBlock, [ParagraphBlockModel, ListBlockModel])) {
|
||||
const modelIndex = parent.children.indexOf(model);
|
||||
if (
|
||||
(modelIndex === -1 || modelIndex === parent.children.length - 1) &&
|
||||
@@ -64,12 +75,12 @@ export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) {
|
||||
|
||||
if (
|
||||
matchFlavours(prevBlock, [
|
||||
'affine:attachment',
|
||||
'affine:bookmark',
|
||||
'affine:code',
|
||||
'affine:image',
|
||||
'affine:divider',
|
||||
...EMBED_BLOCK_FLAVOUR_LIST,
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
CodeBlockModel,
|
||||
ImageBlockModel,
|
||||
DividerBlockModel,
|
||||
...EMBED_BLOCK_MODEL_LIST,
|
||||
])
|
||||
) {
|
||||
const selection = editorHost.selection.create(BlockSelection, {
|
||||
@@ -86,7 +97,7 @@ export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (matchFlavours(parent, ['affine:database'])) {
|
||||
if (matchFlavours(parent, [DatabaseBlockModel])) {
|
||||
doc.deleteBlock(model);
|
||||
focusTextModel(editorHost.std, prevBlock.id, prevBlock.text?.yText.length);
|
||||
return true;
|
||||
@@ -104,7 +115,7 @@ function handleNoPreviousSibling(editorHost: EditorHost, model: ExtendedModel) {
|
||||
// Probably no title, e.g. in edgeless mode
|
||||
if (!titleEditor) {
|
||||
if (
|
||||
matchFlavours(parent, ['affine:edgeless-text']) ||
|
||||
matchFlavours(parent, [EdgelessTextBlockModel]) ||
|
||||
model.children.length > 0
|
||||
) {
|
||||
doc.deleteBlock(model, {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { getSurfaceBlock } from '@blocksuite/affine-block-surface';
|
||||
import type { SurfaceRefProps } from '@blocksuite/affine-model';
|
||||
import {
|
||||
FrameBlockModel,
|
||||
type SurfaceRefProps,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
@@ -38,7 +41,7 @@ export const insertSurfaceRefBlockCommand: Command<
|
||||
|
||||
if (element?.type === 'group') {
|
||||
surfaceRefProps.refFlavour = 'group';
|
||||
} else if (matchFlavours(blockModel, ['affine:frame'])) {
|
||||
} else if (matchFlavours(blockModel, [FrameBlockModel])) {
|
||||
surfaceRefProps.refFlavour = 'frame';
|
||||
} else {
|
||||
console.error(`reference not found ${reference}`);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import {
|
||||
type NoteBlockModel,
|
||||
CodeBlockModel,
|
||||
ListBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
ParagraphBlockModel,
|
||||
type RootBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
@@ -69,7 +72,7 @@ export class DocTitle extends WithDisposable(ShadowlessElement) {
|
||||
private _getOrCreateFirstPageVisibleNote() {
|
||||
const note = this._rootModel.children.find(
|
||||
(child): child is NoteBlockModel =>
|
||||
matchFlavours(child, ['affine:note']) &&
|
||||
matchFlavours(child, [NoteBlockModel]) &&
|
||||
child.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
);
|
||||
if (note) return note;
|
||||
@@ -102,7 +105,11 @@ export class DocTitle extends WithDisposable(ShadowlessElement) {
|
||||
|
||||
const note = this._getOrCreateFirstPageVisibleNote();
|
||||
const firstText = note?.children.find(block =>
|
||||
matchFlavours(block, ['affine:paragraph', 'affine:list', 'affine:code'])
|
||||
matchFlavours(block, [
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
);
|
||||
if (firstText) {
|
||||
if (this._std) focusTextModel(this._std, firstText.id);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { NoteBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
calcDropTarget,
|
||||
type DropTarget,
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
type EditorHost,
|
||||
LifeCycleWatcher,
|
||||
} from '@blocksuite/block-std';
|
||||
import { SurfaceBlockModel } from '@blocksuite/block-std/gfx';
|
||||
import { createIdentifier } from '@blocksuite/global/di';
|
||||
import type { IVec } from '@blocksuite/global/utils';
|
||||
import { Point, throttle } from '@blocksuite/global/utils';
|
||||
@@ -57,7 +59,7 @@ export class FileDropExtension extends LifeCycleWatcher {
|
||||
const model = element.model;
|
||||
const parent = this.std.store.getParent(model);
|
||||
|
||||
if (!matchFlavours(parent, ['affine:surface' as BlockSuite.Flavour])) {
|
||||
if (!matchFlavours(parent, [SurfaceBlockModel])) {
|
||||
const point = this.point$.value;
|
||||
target = point && calcDropTarget(point, model, element);
|
||||
}
|
||||
@@ -73,7 +75,7 @@ export class FileDropExtension extends LifeCycleWatcher {
|
||||
if (!rootModel) return null;
|
||||
|
||||
let lastNote = rootModel.children[rootModel.children.length - 1];
|
||||
if (!lastNote || !matchFlavours(lastNote, ['affine:note'])) {
|
||||
if (!lastNote || !matchFlavours(lastNote, [NoteBlockModel])) {
|
||||
const newNoteId = this.doc.addBlock('affine:note', {}, rootModel.id);
|
||||
const newNote = this.doc.getBlock(newNoteId)?.model;
|
||||
if (!newNote) return null;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DatabaseBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
asyncGetBlockComponent,
|
||||
getCurrentNativeRange,
|
||||
@@ -41,7 +42,7 @@ export function getInlineEditorByModel(
|
||||
typeof model === 'string'
|
||||
? editorHost.std.store.getBlock(model)?.model
|
||||
: model;
|
||||
if (!blockModel || matchFlavours(blockModel, ['affine:database'])) {
|
||||
if (!blockModel || matchFlavours(blockModel, [DatabaseBlockModel])) {
|
||||
// Not support database model since it's may be have multiple inline editor instances.
|
||||
// Support to enter the editing state through the Enter key in the database.
|
||||
return null;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import { type Command, TextSelection } from '@blocksuite/block-std';
|
||||
import type { Text } from '@blocksuite/store';
|
||||
@@ -24,7 +25,7 @@ export const deleteTextCommand: Command<{
|
||||
if (!fromElement) return;
|
||||
|
||||
let fromText: Text | undefined;
|
||||
if (matchFlavours(fromElement.model, ['affine:page'])) {
|
||||
if (matchFlavours(fromElement.model, [RootBlockModel])) {
|
||||
fromText = fromElement.model.title;
|
||||
} else {
|
||||
fromText = fromElement.model.text;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CodeBlockModel } from '@blocksuite/affine-model';
|
||||
import { BRACKET_PAIRS } from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
createDefaultDoc,
|
||||
@@ -28,7 +29,7 @@ export const bracketKeymap = (
|
||||
if (!textSelection) return;
|
||||
const model = doc.getBlock(textSelection.from.blockId)?.model;
|
||||
if (!model) return;
|
||||
if (!matchFlavours(model, ['affine:code'])) return;
|
||||
if (!matchFlavours(model, [CodeBlockModel])) return;
|
||||
const inlineEditor = getInlineEditorByModel(
|
||||
std.host,
|
||||
textSelection.from.blockId
|
||||
@@ -55,7 +56,7 @@ export const bracketKeymap = (
|
||||
const model = doc.getBlock(textSelection.from.blockId)?.model;
|
||||
if (!model) return;
|
||||
|
||||
const isCodeBlock = matchFlavours(model, ['affine:code']);
|
||||
const isCodeBlock = matchFlavours(model, [CodeBlockModel]);
|
||||
// When selection is collapsed, only trigger auto complete in code block
|
||||
if (textSelection.isCollapsed() && !isCodeBlock) return;
|
||||
if (!textSelection.isInSameBlock()) return;
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
DividerBlockModel,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
@@ -12,8 +16,8 @@ export function toDivider(
|
||||
) {
|
||||
const { store: doc } = std;
|
||||
if (
|
||||
matchFlavours(model, ['affine:divider']) ||
|
||||
(matchFlavours(model, ['affine:paragraph']) && model.type === 'quote')
|
||||
matchFlavours(model, [DividerBlockModel]) ||
|
||||
(matchFlavours(model, [ParagraphBlockModel]) && model.type === 'quote')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { ListProps, ListType } from '@blocksuite/affine-model';
|
||||
import {
|
||||
type ListProps,
|
||||
type ListType,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { matchFlavours, toNumberedList } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
@@ -13,7 +17,7 @@ export function toList(
|
||||
prefix: string,
|
||||
otherProperties?: Partial<ListProps>
|
||||
) {
|
||||
if (!matchFlavours(model, ['affine:paragraph'])) {
|
||||
if (!matchFlavours(model, [ParagraphBlockModel])) {
|
||||
return;
|
||||
}
|
||||
const { store: doc } = std;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CodeBlockModel, ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
isMarkdownPrefix,
|
||||
matchFlavours,
|
||||
@@ -31,10 +32,10 @@ export function markdownInput(
|
||||
const prefixText = getPrefixText(inline);
|
||||
if (!isMarkdownPrefix(prefixText)) return;
|
||||
|
||||
const isParagraph = matchFlavours(model, ['affine:paragraph']);
|
||||
const isParagraph = matchFlavours(model, [ParagraphBlockModel]);
|
||||
const isHeading = isParagraph && model.type.startsWith('h');
|
||||
const isParagraphQuoteBlock = isParagraph && model.type === 'quote';
|
||||
const isCodeBlock = matchFlavours(model, ['affine:code']);
|
||||
const isCodeBlock = matchFlavours(model, [CodeBlockModel]);
|
||||
if (isHeading || isParagraphQuoteBlock || isCodeBlock) return;
|
||||
|
||||
const lineInfo = inline.getLine(range.index);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import type { ParagraphType } from '@blocksuite/affine-model';
|
||||
import {
|
||||
ParagraphBlockModel,
|
||||
type ParagraphType,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
@@ -13,7 +16,7 @@ export function toParagraph(
|
||||
prefix: string
|
||||
) {
|
||||
const { store: doc } = std;
|
||||
if (!matchFlavours(model, ['affine:paragraph'])) {
|
||||
if (!matchFlavours(model, [ParagraphBlockModel])) {
|
||||
const parent = doc.getParent(model);
|
||||
if (!parent) return;
|
||||
|
||||
@@ -33,7 +36,7 @@ export function toParagraph(
|
||||
return id;
|
||||
}
|
||||
|
||||
if (matchFlavours(model, ['affine:paragraph']) && model.type !== type) {
|
||||
if (matchFlavours(model, [ParagraphBlockModel]) && model.type !== type) {
|
||||
beforeConvert(std, model, prefix.length);
|
||||
|
||||
doc.updateBlock(model, { type });
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
@@ -10,7 +11,7 @@ export function toCode(
|
||||
prefixText: string,
|
||||
language: string | null
|
||||
) {
|
||||
if (matchFlavours(model, ['affine:paragraph']) && model.type === 'quote') {
|
||||
if (matchFlavours(model, [ParagraphBlockModel]) && model.type === 'quote') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
defineBlockSchema,
|
||||
type SchemaToModel,
|
||||
type Text,
|
||||
} from '@blocksuite/store';
|
||||
import { BlockModel, defineBlockSchema, type Text } from '@blocksuite/store';
|
||||
|
||||
interface CodeBlockProps {
|
||||
text: Text;
|
||||
@@ -31,9 +27,12 @@ export const CodeBlockSchema = defineBlockSchema({
|
||||
],
|
||||
children: [],
|
||||
},
|
||||
toModel: () => new CodeBlockModel(),
|
||||
});
|
||||
|
||||
export type CodeBlockModel = SchemaToModel<typeof CodeBlockSchema>;
|
||||
export class CodeBlockModel extends BlockModel<CodeBlockProps> {
|
||||
override text!: Text;
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineBlockSchema, type SchemaToModel } from '@blocksuite/store';
|
||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
||||
|
||||
export const DividerBlockSchema = defineBlockSchema({
|
||||
flavour: 'affine:divider',
|
||||
@@ -7,9 +7,14 @@ export const DividerBlockSchema = defineBlockSchema({
|
||||
role: 'content',
|
||||
children: [],
|
||||
},
|
||||
toModel: () => new DividerBlockModel(),
|
||||
});
|
||||
|
||||
export type DividerBlockModel = SchemaToModel<typeof DividerBlockSchema>;
|
||||
type Props = {
|
||||
text: string;
|
||||
};
|
||||
|
||||
export class DividerBlockModel extends BlockModel<Props> {}
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SchemaToModel, Text } from '@blocksuite/store';
|
||||
import { defineBlockSchema } from '@blocksuite/store';
|
||||
import type { Text } from '@blocksuite/store';
|
||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
||||
|
||||
// `toggle` type has been deprecated, do not use it
|
||||
export type ListType = 'bulleted' | 'numbered' | 'todo' | 'toggle';
|
||||
@@ -35,9 +35,12 @@ export const ListBlockSchema = defineBlockSchema({
|
||||
'affine:edgeless-text',
|
||||
],
|
||||
},
|
||||
toModel: () => new ListBlockModel(),
|
||||
});
|
||||
|
||||
export type ListBlockModel = SchemaToModel<typeof ListBlockSchema>;
|
||||
export class ListBlockModel extends BlockModel<ListProps> {
|
||||
override text!: Text;
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineBlockSchema, type SchemaToModel } from '@blocksuite/store';
|
||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
||||
|
||||
export type SurfaceRefProps = {
|
||||
reference: string;
|
||||
@@ -18,9 +18,10 @@ export const SurfaceRefBlockSchema = defineBlockSchema({
|
||||
role: 'content',
|
||||
parent: ['affine:note', 'affine:paragraph', 'affine:list'],
|
||||
},
|
||||
toModel: () => new SurfaceRefBlockModel(),
|
||||
});
|
||||
|
||||
export type SurfaceRefBlockModel = SchemaToModel<typeof SurfaceRefBlockSchema>;
|
||||
export class SurfaceRefBlockModel extends BlockModel<SurfaceRefProps> {}
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
type BlockStdScope,
|
||||
type EditorHost,
|
||||
@@ -19,7 +20,7 @@ const handlePoint = (
|
||||
model: DraftModel
|
||||
) => {
|
||||
const { index, length } = point;
|
||||
if (matchFlavours(model, ['affine:page'])) {
|
||||
if (matchFlavours(model, [RootBlockModel])) {
|
||||
if (length === 0) return;
|
||||
(snapshot.props.title as Record<string, unknown>).delta =
|
||||
model.title.sliceToDelta(index, length + index);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
CodeBlockModel,
|
||||
type DocMode,
|
||||
DocModes,
|
||||
ImageBlockModel,
|
||||
type ParagraphBlockModel,
|
||||
type ReferenceInfo,
|
||||
} from '@blocksuite/affine-model';
|
||||
@@ -291,7 +293,7 @@ class PasteTr {
|
||||
return;
|
||||
}
|
||||
if (!cursorModel.text) {
|
||||
if (matchFlavours(cursorModel, ['affine:image'])) {
|
||||
if (matchFlavours(cursorModel, [ImageBlockModel])) {
|
||||
const selection = this.std.selection.create(ImageSelection, {
|
||||
blockId: target.blockId,
|
||||
});
|
||||
@@ -356,7 +358,7 @@ class PasteTr {
|
||||
if (
|
||||
this.firstSnapshot !== this.lastSnapshot &&
|
||||
this.lastSnapshot.props.text &&
|
||||
!matchFlavours(this.pointState.model, ['affine:code'])
|
||||
!matchFlavours(this.pointState.model, [CodeBlockModel])
|
||||
) {
|
||||
const text = fromJSON(this.lastSnapshot.props.text) as Text;
|
||||
const doc = new Y.Doc();
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import type { EmbedCardStyle } from '@blocksuite/affine-model';
|
||||
import {
|
||||
type EmbedCardStyle,
|
||||
EmbedFigmaModel,
|
||||
EmbedGithubModel,
|
||||
EmbedHtmlModel,
|
||||
EmbedLinkedDocModel,
|
||||
EmbedLoomModel,
|
||||
EmbedSyncedDocModel,
|
||||
EmbedYoutubeModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
|
||||
export const BLOCK_CHILDREN_CONTAINER_PADDING_LEFT = 24;
|
||||
export const EDGELESS_BLOCK_CHILD_PADDING = 24;
|
||||
@@ -48,6 +57,16 @@ export const EMBED_BLOCK_FLAVOUR_LIST = [
|
||||
'affine:embed-loom',
|
||||
] as const;
|
||||
|
||||
export const EMBED_BLOCK_MODEL_LIST = [
|
||||
EmbedGithubModel,
|
||||
EmbedYoutubeModel,
|
||||
EmbedFigmaModel,
|
||||
EmbedLinkedDocModel,
|
||||
EmbedSyncedDocModel,
|
||||
EmbedHtmlModel,
|
||||
EmbedLoomModel,
|
||||
] as const;
|
||||
|
||||
export const DEFAULT_IMAGE_PROXY_ENDPOINT =
|
||||
'https://affine-worker.toeverything.workers.dev/api/worker/image-proxy';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
import { matchFlavours } from '../model/checker.js';
|
||||
@@ -15,7 +15,7 @@ export function calculateCollapsedSiblings(
|
||||
const collapsedEdgeIndex = children.findIndex((child, i) => {
|
||||
if (
|
||||
i > index &&
|
||||
matchFlavours(child, ['affine:paragraph']) &&
|
||||
matchFlavours(child, [ParagraphBlockModel]) &&
|
||||
child.type.startsWith('h')
|
||||
) {
|
||||
const modelLevel = parseInt(model.type.slice(1));
|
||||
@@ -46,7 +46,7 @@ export function getNearestHeadingBefore(
|
||||
for (let i = index - 1; i >= 0; i--) {
|
||||
const sibling = parent.children[i];
|
||||
if (
|
||||
matchFlavours(sibling, ['affine:paragraph']) &&
|
||||
matchFlavours(sibling, [ParagraphBlockModel]) &&
|
||||
sibling.type.startsWith('h')
|
||||
) {
|
||||
return sibling;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DatabaseBlockModel, ListBlockModel } from '@blocksuite/affine-model';
|
||||
import type { BlockComponent } from '@blocksuite/block-std';
|
||||
import { type Point, Rect } from '@blocksuite/global/utils';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
@@ -55,7 +56,7 @@ export function calcDropTarget(
|
||||
.every(m => children.includes(m.flavour));
|
||||
}
|
||||
|
||||
if (!shouldAppendToDatabase && !matchFlavours(model, ['affine:database'])) {
|
||||
if (!shouldAppendToDatabase && !matchFlavours(model, [DatabaseBlockModel])) {
|
||||
const databaseBlockComponent =
|
||||
element.closest<BlockComponent>('affine-database');
|
||||
if (databaseBlockComponent) {
|
||||
@@ -149,7 +150,7 @@ export function calcDropTarget(
|
||||
const hasChild = (element as BlockComponent).childBlocks.length;
|
||||
if (
|
||||
allowSublist &&
|
||||
matchFlavours(model, ['affine:list']) &&
|
||||
matchFlavours(model, [ListBlockModel]) &&
|
||||
!hasChild &&
|
||||
point.x > domRect.x + BLOCK_CHILDREN_CONTAINER_PADDING_LEFT
|
||||
) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DatabaseBlockModel } from '@blocksuite/affine-model';
|
||||
import { BLOCK_ID_ATTR } from '@blocksuite/block-std';
|
||||
import type { Point } from '@blocksuite/global/utils';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
@@ -24,7 +25,7 @@ export function getDropRectByPoint(
|
||||
flag: DropFlags.Normal,
|
||||
};
|
||||
|
||||
const isDatabase = matchFlavours(model, ['affine:database']);
|
||||
const isDatabase = matchFlavours(model, [DatabaseBlockModel]);
|
||||
|
||||
if (isDatabase) {
|
||||
const table = getDatabaseBlockTableElement(element);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { NoteBlockModel, RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { BLOCK_ID_ATTR, type BlockComponent } from '@blocksuite/block-std';
|
||||
import { SurfaceBlockModel } from '@blocksuite/block-std/gfx';
|
||||
import type { Point, Rect } from '@blocksuite/global/utils';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
@@ -35,10 +37,9 @@ function hasBlockId(element: Element): element is BlockComponent {
|
||||
*/
|
||||
function isRootOrNoteOrSurface(element: BlockComponent) {
|
||||
return matchFlavours(element.model, [
|
||||
'affine:page',
|
||||
'affine:note',
|
||||
// @ts-expect-error TODO: migrate surface model to @blocksuite/affine-model
|
||||
'affine:surface',
|
||||
RootBlockModel,
|
||||
NoteBlockModel,
|
||||
SurfaceBlockModel,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import type { BlockModel, DraftModel, Store } from '@blocksuite/store';
|
||||
import { minimatch } from 'minimatch';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
|
||||
export function matchFlavours<Key extends (keyof BlockSuite.BlockModels)[]>(
|
||||
model: DraftModel | null,
|
||||
expected: Key
|
||||
): model is BlockSuite.BlockModels[Key[number]] {
|
||||
type ConstructorType<U> = { new (): U };
|
||||
type ModelList<T> =
|
||||
T extends Array<infer U>
|
||||
? U extends ConstructorType<infer C>
|
||||
? Array<C>
|
||||
: never
|
||||
: never;
|
||||
|
||||
export function matchFlavours<
|
||||
const Model extends ConstructorType<BlockModel>[],
|
||||
U extends ModelList<Model>[number] = ModelList<Model>[number],
|
||||
>(model: unknown, expected: Model): model is U {
|
||||
return (
|
||||
!!model &&
|
||||
expected.some(key =>
|
||||
minimatch(model.flavour as keyof BlockSuite.BlockModels, key)
|
||||
)
|
||||
!!model && expected.some(expectedModel => model instanceof expectedModel)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ export function createDefaultDoc(
|
||||
title,
|
||||
});
|
||||
|
||||
// @ts-expect-error FIXME: will be fixed when surface model migrated to affine-model
|
||||
doc.addBlock('affine:surface', {}, rootId);
|
||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||
doc.addBlock('affine:paragraph', {}, noteId);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { FrameBlockModel } from '@blocksuite/affine-model';
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
@@ -73,7 +74,7 @@ export function getPrevContentBlock(
|
||||
|
||||
const prev = getPrev(model);
|
||||
if (prev) {
|
||||
if (prev.role === 'content' && !matchFlavours(prev, ['affine:frame'])) {
|
||||
if (prev.role === 'content' && !matchFlavours(prev, [FrameBlockModel])) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import { NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import type { BlockComponent, EditorHost } from '@blocksuite/block-std';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function asyncGetBlockComponent(
|
||||
|
||||
export function findNoteBlockModel(model: BlockModel) {
|
||||
return findAncestorModel(model, m =>
|
||||
matchFlavours(m, ['affine:note'])
|
||||
matchFlavours(m, [NoteBlockModel])
|
||||
) as NoteBlockModel | null;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ export function getLastNoteBlock(doc: Store) {
|
||||
for (let i = children.length - 1; i >= 0; i--) {
|
||||
const child = children[i];
|
||||
if (
|
||||
matchFlavours(child, ['affine:note']) &&
|
||||
matchFlavours(child, [NoteBlockModel]) &&
|
||||
child.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
) {
|
||||
note = child as NoteBlockModel;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
|
||||
@@ -23,7 +23,7 @@ export function getNextContinuousNumberedLists(
|
||||
const firstNotNumberedListIndex = parent.children.findIndex(
|
||||
(model, i) =>
|
||||
i > modelIndex &&
|
||||
(!matchFlavours(model, ['affine:list']) || model.type !== 'numbered')
|
||||
(!matchFlavours(model, [ListBlockModel]) || model.type !== 'numbered')
|
||||
);
|
||||
const newContinuousLists = parent.children.slice(
|
||||
modelIndex + 1,
|
||||
@@ -32,7 +32,7 @@ export function getNextContinuousNumberedLists(
|
||||
if (
|
||||
!newContinuousLists.every(
|
||||
model =>
|
||||
matchFlavours(model, ['affine:list']) && model.type === 'numbered'
|
||||
matchFlavours(model, [ListBlockModel]) && model.type === 'numbered'
|
||||
)
|
||||
)
|
||||
return [];
|
||||
@@ -56,7 +56,7 @@ export function toNumberedList(
|
||||
// if there is a numbered list before, the order continues from the previous list
|
||||
if (
|
||||
prevSibling &&
|
||||
matchFlavours(prevSibling, ['affine:list']) &&
|
||||
matchFlavours(prevSibling, [ListBlockModel]) &&
|
||||
prevSibling.type === 'numbered'
|
||||
) {
|
||||
doc.transact(() => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { correctNumberedListsOrderToPrev } from '@blocksuite/affine-block-list';
|
||||
import { ListBlockModel } from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import type { TransformerMiddleware } from '@blocksuite/store';
|
||||
@@ -10,7 +11,7 @@ export const reorderList =
|
||||
if (payload.type === 'block') {
|
||||
const model = payload.model;
|
||||
if (
|
||||
matchFlavours(model, ['affine:list']) &&
|
||||
matchFlavours(model, [ListBlockModel]) &&
|
||||
model.type === 'numbered'
|
||||
) {
|
||||
const next = std.store.getNext(model);
|
||||
|
||||
@@ -3,7 +3,11 @@ import {
|
||||
type EdgelessNoteBlockComponent,
|
||||
} from '@blocksuite/affine-block-note';
|
||||
import { ParagraphBlockComponent } from '@blocksuite/affine-block-paragraph';
|
||||
import type { ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
DatabaseBlockModel,
|
||||
ListBlockModel,
|
||||
type ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { DocModeProvider } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
calcDropTarget,
|
||||
@@ -216,7 +220,7 @@ export const getDropResult = (
|
||||
|
||||
const model = closestBlock.model;
|
||||
|
||||
const isDatabase = matchFlavours(model, ['affine:database']);
|
||||
const isDatabase = matchFlavours(model, [DatabaseBlockModel]);
|
||||
if (isDatabase) {
|
||||
return dropIndicator;
|
||||
}
|
||||
@@ -232,7 +236,7 @@ export const getDropResult = (
|
||||
export function getDragHandleLeftPadding(blocks: BlockComponent[]) {
|
||||
const hasToggleList = blocks.some(
|
||||
block =>
|
||||
(matchFlavours(block.model, ['affine:list']) &&
|
||||
(matchFlavours(block.model, [ListBlockModel]) &&
|
||||
block.model.children.length > 0) ||
|
||||
(block instanceof ParagraphBlockComponent &&
|
||||
block.model.type.startsWith('h') &&
|
||||
|
||||
@@ -2,9 +2,17 @@ import { ParagraphBlockComponent } from '@blocksuite/affine-block-paragraph';
|
||||
import {
|
||||
addNoteAtPoint,
|
||||
getSurfaceBlock,
|
||||
SurfaceBlockModel,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { DropIndicator } from '@blocksuite/affine-components/drop-indicator';
|
||||
import type { EmbedCardStyle, NoteBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
DatabaseBlockModel,
|
||||
type EmbedCardStyle,
|
||||
ListBlockModel,
|
||||
NoteBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
BLOCK_CHILDREN_CONTAINER_PADDING_LEFT,
|
||||
EMBED_CARD_HEIGHT,
|
||||
@@ -153,17 +161,17 @@ export class DragEventWatcher {
|
||||
!snapshot ||
|
||||
snapshot.content.length === 0 ||
|
||||
!dragPayload?.from ||
|
||||
matchFlavours(model, ['affine:database'])
|
||||
matchFlavours(model, [DatabaseBlockModel])
|
||||
)
|
||||
return null;
|
||||
|
||||
const isDropOnNoteBlock = matchFlavours(model, ['affine:note']);
|
||||
const isDropOnNoteBlock = matchFlavours(model, [NoteBlockModel]);
|
||||
|
||||
const edge = dropPayload.edge;
|
||||
const scale = this.widget.scale.peek();
|
||||
let result: DropResult;
|
||||
|
||||
if (edge === 'right' && matchFlavours(dropBlock.model, ['affine:list'])) {
|
||||
if (edge === 'right' && matchFlavours(dropBlock.model, [ListBlockModel])) {
|
||||
const domRect = getRectByBlockComponent(dropBlock);
|
||||
const placement = 'in';
|
||||
const rect = Rect.fromLWTH(
|
||||
@@ -365,7 +373,7 @@ export class DragEventWatcher {
|
||||
result.placement === 'in' ? model : this.std.store.getParent(model);
|
||||
|
||||
if (!parent) return;
|
||||
if (matchFlavours(parent, ['affine:surface'])) {
|
||||
if (matchFlavours(parent, [SurfaceBlockModel])) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -375,7 +383,7 @@ export class DragEventWatcher {
|
||||
: parent.children.indexOf(model) +
|
||||
(result.placement === 'before' ? 0 : 1);
|
||||
|
||||
if (matchFlavours(parent, ['affine:note'])) {
|
||||
if (matchFlavours(parent, [NoteBlockModel])) {
|
||||
const [first] = snapshot.content;
|
||||
if (first.flavour === 'affine:note') {
|
||||
if (parent.id !== first.id) {
|
||||
@@ -677,7 +685,7 @@ export class DragEventWatcher {
|
||||
})
|
||||
);
|
||||
|
||||
if (matchFlavours(view.model, ['affine:attachment', 'affine:bookmark'])) {
|
||||
if (matchFlavours(view.model, [AttachmentBlockModel, BookmarkBlockModel])) {
|
||||
cleanups.push(this._makeDraggable(view));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
type RootBlockModel,
|
||||
type SurfaceRefBlockModel,
|
||||
SurfaceRefBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
@@ -195,7 +195,7 @@ export class EdgelessAutoConnectWidget extends WidgetComponent<RootBlockModel> {
|
||||
|
||||
const pageVisibleBlocks = new Map<AutoConnectElement, number>();
|
||||
const notes = service.doc.root?.children.filter(child =>
|
||||
matchFlavours(child, ['affine:note'])
|
||||
matchFlavours(child, [NoteBlockModel])
|
||||
);
|
||||
const edgelessOnlyNotesSet = new Set<NoteBlockModel>();
|
||||
|
||||
@@ -209,7 +209,7 @@ export class EdgelessAutoConnectWidget extends WidgetComponent<RootBlockModel> {
|
||||
}
|
||||
|
||||
note.children.forEach(model => {
|
||||
if (matchFlavours(model, ['affine:surface-ref'])) {
|
||||
if (matchFlavours(model, [SurfaceRefBlockModel])) {
|
||||
const reference = this._crud.getElementById(model.reference);
|
||||
|
||||
if (!isAutoConnectElement(reference)) return;
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import {
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
CodeBlockModel,
|
||||
DatabaseBlockModel,
|
||||
ImageBlockModel,
|
||||
SurfaceRefBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { getSelectionRectsCommand } from '@blocksuite/affine-shared/commands';
|
||||
import { EMBED_BLOCK_MODEL_LIST } from '@blocksuite/affine-shared/consts';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
BlockSelection,
|
||||
@@ -67,16 +76,15 @@ export class AffineDocRemoteSelectionWidget extends WidgetComponent {
|
||||
private get _config(): DocRemoteSelectionConfig {
|
||||
return {
|
||||
blockSelectionBackgroundTransparent: block => {
|
||||
return (
|
||||
matchFlavours(block, [
|
||||
'affine:code',
|
||||
'affine:database',
|
||||
'affine:image',
|
||||
'affine:attachment',
|
||||
'affine:bookmark',
|
||||
'affine:surface-ref',
|
||||
]) || /affine:embed-*/.test(block.flavour)
|
||||
);
|
||||
return matchFlavours(block, [
|
||||
CodeBlockModel,
|
||||
DatabaseBlockModel,
|
||||
ImageBlockModel,
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
SurfaceRefBlockModel,
|
||||
...EMBED_BLOCK_MODEL_LIST,
|
||||
]);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ import {
|
||||
SurfaceElementModel,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
FrameBlockModel,
|
||||
GroupElementModel,
|
||||
ImageBlockModel,
|
||||
type RootBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { FetchUtils } from '@blocksuite/affine-shared/adapters';
|
||||
@@ -456,7 +458,7 @@ export class ExportManager {
|
||||
edgeless?.service.gfx.getElementsByBound(bound, { type: 'block' }) ??
|
||||
[];
|
||||
for (const block of blocks) {
|
||||
if (matchFlavours(block, ['affine:image'])) {
|
||||
if (matchFlavours(block, [ImageBlockModel])) {
|
||||
if (!block.sourceId) return;
|
||||
|
||||
const blob = await block.doc.blobSync.get(block.sourceId);
|
||||
@@ -493,7 +495,7 @@ export class ExportManager {
|
||||
);
|
||||
}
|
||||
|
||||
if (matchFlavours(block, ['affine:frame'])) {
|
||||
if (matchFlavours(block, [FrameBlockModel])) {
|
||||
// TODO(@L-Sun): use children of frame instead of bound
|
||||
const blocksInsideFrame = getBlocksInFrameBound(this.doc, block, false);
|
||||
const frameBound = Bound.deserialize(block.xywh);
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
BookmarkStyles,
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DEFAULT_NOTE_WIDTH,
|
||||
FrameBlockModel,
|
||||
MAX_IMAGE_WIDTH,
|
||||
ReferenceInfoSchema,
|
||||
} from '@blocksuite/affine-model';
|
||||
@@ -994,7 +995,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
||||
for (const nodeElement of nodeElements) {
|
||||
await _drawTopLevelBlock(nodeElement);
|
||||
|
||||
if (matchFlavours(nodeElement, ['affine:frame'])) {
|
||||
if (matchFlavours(nodeElement, [FrameBlockModel])) {
|
||||
const blocksInsideFrame: BlockSuite.EdgelessBlockModelType[] = [];
|
||||
this.edgeless.service.frame
|
||||
.getElementsInFrameBound(nodeElement, false)
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
GroupElementModel,
|
||||
LayoutType,
|
||||
MindmapElementModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
type ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
@@ -134,7 +135,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
selection.selectedElements.length === 1 &&
|
||||
selection.firstElement instanceof GfxBlockElementModel &&
|
||||
matchFlavours(selection.firstElement as GfxBlockElementModel, [
|
||||
'affine:note',
|
||||
NoteBlockModel,
|
||||
])
|
||||
) {
|
||||
rootComponent.slots.toggleNoteSlicer.emit();
|
||||
@@ -259,7 +260,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
block =>
|
||||
block.group === null &&
|
||||
!(
|
||||
matchFlavours(block, ['affine:note']) &&
|
||||
matchFlavours(block, [NoteBlockModel]) &&
|
||||
block.displayMode === NoteDisplayMode.DocOnly
|
||||
)
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
normalizeWheelDeltaY,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
type NoteBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
type RootBlockModel,
|
||||
type ShapeElementModel,
|
||||
@@ -350,7 +350,7 @@ export class EdgelessRootBlockComponent extends BlockComponent<
|
||||
const primaryMode = std.get(DocModeProvider).getPrimaryMode(this.doc.id);
|
||||
const note = this.model.children.find(
|
||||
(child): child is NoteBlockModel =>
|
||||
matchFlavours(child, ['affine:note']) &&
|
||||
matchFlavours(child, [NoteBlockModel]) &&
|
||||
child.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
promptDocTitle,
|
||||
} from '@blocksuite/affine-block-embed';
|
||||
import { ParagraphBlockComponent } from '@blocksuite/affine-block-paragraph';
|
||||
import { NoteBlockModel, ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
draftSelectedModelsCommand,
|
||||
getSelectedModelsCommand,
|
||||
@@ -37,7 +38,7 @@ export class PageKeyboardManager {
|
||||
const model = block.model;
|
||||
|
||||
if (
|
||||
matchFlavours(model, ['affine:paragraph']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel]) &&
|
||||
model.type.startsWith('h') &&
|
||||
model.collapsed
|
||||
) {
|
||||
@@ -133,7 +134,7 @@ export class PageKeyboardManager {
|
||||
const selectedModels = ctx.selectedModels?.filter(
|
||||
block =>
|
||||
!block.flavour.startsWith('affine:embed-') &&
|
||||
matchFlavours(doc.getParent(block), ['affine:note'])
|
||||
matchFlavours(doc.getParent(block), [NoteBlockModel])
|
||||
);
|
||||
|
||||
const draftedModels = ctx.draftedModels;
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
||||
import type { NoteBlockModel, RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import {
|
||||
CodeBlockModel,
|
||||
ListBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
ParagraphBlockModel,
|
||||
type RootBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { PageViewportService } from '@blocksuite/affine-shared/services';
|
||||
import type { Viewport } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
@@ -122,7 +128,11 @@ export class PageRootBlockComponent extends BlockComponent<
|
||||
focusFirstParagraph = (): { id: string; created: boolean } => {
|
||||
const defaultNote = this._getDefaultNoteBlock();
|
||||
const firstText = defaultNote?.children.find(block =>
|
||||
matchFlavours(block, ['affine:paragraph', 'affine:list', 'affine:code'])
|
||||
matchFlavours(block, [
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
])
|
||||
);
|
||||
if (firstText) {
|
||||
focusTextModel(this.std, firstText.id);
|
||||
@@ -238,9 +248,8 @@ export class PageRootBlockComponent extends BlockComponent<
|
||||
'Mod-a': () => {
|
||||
const blocks = this.model.children
|
||||
.filter(model => {
|
||||
if (matchFlavours(model, ['affine:note'])) {
|
||||
const note = model as NoteBlockModel;
|
||||
if (note.displayMode === NoteDisplayMode.EdgelessOnly)
|
||||
if (matchFlavours(model, [NoteBlockModel])) {
|
||||
if (model.displayMode === NoteDisplayMode.EdgelessOnly)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -385,12 +394,11 @@ export class PageRootBlockComponent extends BlockComponent<
|
||||
.slice()
|
||||
.reverse()
|
||||
.find(child => {
|
||||
const isNote = matchFlavours(child, ['affine:note']);
|
||||
const isNote = matchFlavours(child, [NoteBlockModel]);
|
||||
if (!isNote) return false;
|
||||
const note = child as NoteBlockModel;
|
||||
const displayOnDoc =
|
||||
!!note.displayMode &&
|
||||
note.displayMode !== NoteDisplayMode.EdgelessOnly;
|
||||
!!child.displayMode &&
|
||||
child.displayMode !== NoteDisplayMode.EdgelessOnly;
|
||||
return displayOnDoc;
|
||||
});
|
||||
if (!lastNote) {
|
||||
@@ -402,7 +410,9 @@ export class PageRootBlockComponent extends BlockComponent<
|
||||
const last = lastNote.children.at(-1);
|
||||
if (
|
||||
!last ||
|
||||
!(matchFlavours(last, ['affine:paragraph']) && last.text.length === 0)
|
||||
!(
|
||||
matchFlavours(last, [ParagraphBlockModel]) && last.text.length === 0
|
||||
)
|
||||
) {
|
||||
if (readonly) return;
|
||||
const paragraphId = this.doc.addBlock(
|
||||
@@ -442,7 +452,7 @@ export class PageRootBlockComponent extends BlockComponent<
|
||||
override firstUpdated() {
|
||||
this._initViewportResizeEffect();
|
||||
const noteModels = this.model.children.filter(model =>
|
||||
matchFlavours(model, ['affine:note'])
|
||||
matchFlavours(model, [NoteBlockModel])
|
||||
);
|
||||
noteModels.forEach(note => {
|
||||
this.disposables.add(
|
||||
@@ -463,7 +473,7 @@ export class PageRootBlockComponent extends BlockComponent<
|
||||
)}`;
|
||||
|
||||
const children = this.renderChildren(this.model, child => {
|
||||
const isNote = matchFlavours(child, ['affine:note']);
|
||||
const isNote = matchFlavours(child, [NoteBlockModel]);
|
||||
const note = child as NoteBlockModel;
|
||||
const displayOnEdgeless =
|
||||
!!note.displayMode && note.displayMode === NoteDisplayMode.EdgelessOnly;
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DefaultTheme,
|
||||
type FrameBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
resolveColor,
|
||||
} from '@blocksuite/affine-model';
|
||||
@@ -92,7 +93,7 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
|
||||
const rootModel = this.edgeless.doc.root;
|
||||
const notes = rootModel.children.filter(
|
||||
model =>
|
||||
matchFlavours(model, ['affine:note']) &&
|
||||
matchFlavours(model, [NoteBlockModel]) &&
|
||||
model.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
);
|
||||
const lastNote = notes[notes.length - 1];
|
||||
|
||||
@@ -6,7 +6,11 @@ import {
|
||||
import { toast } from '@blocksuite/affine-components/toast';
|
||||
import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import { DEFAULT_NOTE_HEIGHT, NoteDisplayMode } from '@blocksuite/affine-model';
|
||||
import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { matchFlavours } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
deserializeXYWH,
|
||||
@@ -27,7 +31,7 @@ export class EdgelessChangeGroupButton extends WithDisposable(LitElement) {
|
||||
const rootModel = this.edgeless.doc.root;
|
||||
const notes = rootModel.children.filter(
|
||||
model =>
|
||||
matchFlavours(model, ['affine:note']) &&
|
||||
matchFlavours(model, [NoteBlockModel]) &&
|
||||
model.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||
);
|
||||
const lastNote = notes[notes.length - 1];
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
import {
|
||||
type ColorScheme,
|
||||
DefaultTheme,
|
||||
type NoteBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
resolveColor,
|
||||
type StrokeStyle,
|
||||
@@ -158,7 +158,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
this._pageBlockEnabled &&
|
||||
this.notes.length === 1 &&
|
||||
this.notes[0].parent?.children.find(child =>
|
||||
matchFlavours(child, ['affine:note'])
|
||||
matchFlavours(child, [NoteBlockModel])
|
||||
) === this.notes[0]
|
||||
);
|
||||
}
|
||||
@@ -340,7 +340,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
|
||||
const isFirstNote =
|
||||
onlyOne &&
|
||||
note.parent?.children.find(child =>
|
||||
matchFlavours(child, ['affine:note'])
|
||||
matchFlavours(child, [NoteBlockModel])
|
||||
) === note;
|
||||
const theme = this.edgeless.std.get(ThemeProvider).theme;
|
||||
const buttons = [
|
||||
|
||||
@@ -10,6 +10,12 @@ import {
|
||||
getMoreMenuConfig,
|
||||
type MenuItemGroup,
|
||||
} from '@blocksuite/affine-components/toolbar';
|
||||
import {
|
||||
CodeBlockModel,
|
||||
ImageBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
getSelectedBlocksCommand,
|
||||
getTextSelectionCommand,
|
||||
@@ -355,10 +361,10 @@ export class AffineFormatBarWidget extends WidgetComponent {
|
||||
const selectedBlock = this._selectedBlocks[0];
|
||||
if (
|
||||
!matchFlavours(selectedBlock.model, [
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:code',
|
||||
'affine:image',
|
||||
ParagraphBlockModel,
|
||||
ListBlockModel,
|
||||
CodeBlockModel,
|
||||
ImageBlockModel,
|
||||
])
|
||||
) {
|
||||
return false;
|
||||
|
||||
@@ -35,7 +35,7 @@ export interface LinkedWidgetConfig {
|
||||
* [[ -> @
|
||||
*/
|
||||
convertTriggerKey: boolean;
|
||||
ignoreBlockTypes: (keyof BlockSuite.BlockModels)[];
|
||||
ignoreBlockTypes: string[];
|
||||
ignoreSelector: string;
|
||||
getMenus: (
|
||||
query: string,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { NoteBlockModel, RootBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
autoScroll,
|
||||
getScrollContainer,
|
||||
@@ -445,7 +445,7 @@ function isDragArea(e: PointerEventState) {
|
||||
const el = e.raw.target;
|
||||
assertInstanceOf(el, Element);
|
||||
const block = el.closest<BlockComponent>(`[${BLOCK_ID_ATTR}]`);
|
||||
return block && matchFlavours(block.model, ['affine:page', 'affine:note']);
|
||||
return block && matchFlavours(block.model, [RootBlockModel, NoteBlockModel]);
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -84,7 +84,7 @@ import {
|
||||
|
||||
export type SlashMenuConfig = {
|
||||
triggerKeys: string[];
|
||||
ignoreBlockTypes: BlockSuite.Flavour[];
|
||||
ignoreBlockTypes: string[];
|
||||
items: SlashMenuItem[];
|
||||
maxHeight: number;
|
||||
tooltipTimeout: number;
|
||||
|
||||
@@ -2,10 +2,7 @@ import {
|
||||
type AffineInlineEditor,
|
||||
getInlineEditorByModel,
|
||||
} from '@blocksuite/affine-components/rich-text';
|
||||
import {
|
||||
getCurrentNativeRange,
|
||||
matchFlavours,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import { getCurrentNativeRange } from '@blocksuite/affine-shared/utils';
|
||||
import type { UIEventStateContext } from '@blocksuite/block-std';
|
||||
import { TextSelection, WidgetComponent } from '@blocksuite/block-std';
|
||||
import {
|
||||
@@ -155,7 +152,7 @@ export class AffineSlashMenuWidget extends WidgetComponent {
|
||||
const model = this.host.doc.getBlock(textSelection.blockId)?.model;
|
||||
if (!model) return;
|
||||
|
||||
if (matchFlavours(model, this.config.ignoreBlockTypes)) return;
|
||||
if (this.config.ignoreBlockTypes.includes(model.flavour)) return;
|
||||
|
||||
const inlineRange = inlineEditor.getInlineRange();
|
||||
if (!inlineRange) return;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineBlockSchema, type SchemaToModel } from '@blocksuite/store';
|
||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
||||
|
||||
export const RootBlockSchema = defineBlockSchema({
|
||||
flavour: 'test:page',
|
||||
@@ -15,7 +15,9 @@ export const RootBlockSchema = defineBlockSchema({
|
||||
},
|
||||
});
|
||||
|
||||
export type RootBlockModel = SchemaToModel<typeof RootBlockSchema>;
|
||||
export class RootBlockModel extends BlockModel<
|
||||
ReturnType<(typeof RootBlockSchema)['model']['props']>
|
||||
> {}
|
||||
|
||||
export const NoteBlockSchema = defineBlockSchema({
|
||||
flavour: 'test:note',
|
||||
@@ -28,7 +30,9 @@ export const NoteBlockSchema = defineBlockSchema({
|
||||
},
|
||||
});
|
||||
|
||||
export type NoteBlockModel = SchemaToModel<typeof NoteBlockSchema>;
|
||||
export class NoteBlockModel extends BlockModel<
|
||||
ReturnType<(typeof NoteBlockSchema)['model']['props']>
|
||||
> {}
|
||||
|
||||
export const HeadingBlockSchema = defineBlockSchema({
|
||||
flavour: 'test:heading',
|
||||
@@ -43,7 +47,9 @@ export const HeadingBlockSchema = defineBlockSchema({
|
||||
},
|
||||
});
|
||||
|
||||
export type HeadingBlockModel = SchemaToModel<typeof HeadingBlockSchema>;
|
||||
export class HeadingBlockModel extends BlockModel<
|
||||
ReturnType<(typeof HeadingBlockSchema)['model']['props']>
|
||||
> {}
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
|
||||
@@ -4,9 +4,9 @@ import * as Y from 'yjs';
|
||||
|
||||
import {
|
||||
Block,
|
||||
BlockModel,
|
||||
defineBlockSchema,
|
||||
internalPrimitives,
|
||||
type SchemaToModel,
|
||||
} from '../model/block/index.js';
|
||||
import type { YBlock } from '../model/block/types.js';
|
||||
import { Schema } from '../schema/index.js';
|
||||
@@ -54,9 +54,15 @@ const flatTableSchema = defineBlockSchema({
|
||||
isFlatData: true,
|
||||
},
|
||||
});
|
||||
type RootModel = SchemaToModel<typeof pageSchema>;
|
||||
type TableModel = SchemaToModel<typeof tableSchema>;
|
||||
type FlatTableModel = SchemaToModel<typeof flatTableSchema>;
|
||||
class RootModel extends BlockModel<
|
||||
ReturnType<(typeof pageSchema)['model']['props']>
|
||||
> {}
|
||||
class TableModel extends BlockModel<
|
||||
ReturnType<(typeof tableSchema)['model']['props']>
|
||||
> {}
|
||||
class FlatTableModel extends BlockModel<
|
||||
ReturnType<(typeof flatTableSchema)['model']['props']>
|
||||
> {}
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineBlockSchema, type SchemaToModel } from '../model/index.js';
|
||||
import { BlockModel, defineBlockSchema } from '../model/index.js';
|
||||
|
||||
export const RootBlockSchema = defineBlockSchema({
|
||||
flavour: 'affine:page',
|
||||
@@ -14,7 +14,9 @@ export const RootBlockSchema = defineBlockSchema({
|
||||
},
|
||||
});
|
||||
|
||||
export type RootBlockModel = SchemaToModel<typeof RootBlockSchema>;
|
||||
export class RootBlockModel extends BlockModel<
|
||||
ReturnType<(typeof RootBlockSchema)['model']['props']>
|
||||
> {}
|
||||
|
||||
export const NoteBlockSchema = defineBlockSchema({
|
||||
flavour: 'affine:note',
|
||||
|
||||
@@ -2,8 +2,8 @@ import { expect, test } from 'vitest';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { MemoryBlobCRUD } from '../adapter/index.js';
|
||||
import type { BlockModel } from '../model/block/block-model.js';
|
||||
import { defineBlockSchema, type SchemaToModel } from '../model/block/zod.js';
|
||||
import { BlockModel } from '../model/block/block-model.js';
|
||||
import { defineBlockSchema } from '../model/block/zod.js';
|
||||
import { Text } from '../reactive/index.js';
|
||||
import { Schema } from '../schema/index.js';
|
||||
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
||||
@@ -39,7 +39,9 @@ const docSchema = defineBlockSchema({
|
||||
},
|
||||
});
|
||||
|
||||
type RootBlockModel = SchemaToModel<typeof docSchema>;
|
||||
class RootBlockModel extends BlockModel<
|
||||
ReturnType<(typeof docSchema)['model']['props']>
|
||||
> {}
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
|
||||
@@ -20,9 +20,7 @@ type SignaledProps<Props> = Props & {
|
||||
* myBlock.foo = 'bar';
|
||||
* ```
|
||||
*/
|
||||
function MagicProps(): {
|
||||
new <Props>(): Props;
|
||||
} {
|
||||
function MagicProps(): { new <Props>(): Props } {
|
||||
return class {} as never;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,18 +51,6 @@ export type PropsGetter<Props> = (
|
||||
internalPrimitives: InternalPrimitives
|
||||
) => Props;
|
||||
|
||||
export type SchemaToModel<
|
||||
Schema extends {
|
||||
model: {
|
||||
props: PropsGetter<object>;
|
||||
flavour: string;
|
||||
};
|
||||
},
|
||||
> = BlockModel<ReturnType<Schema['model']['props']>> &
|
||||
ReturnType<Schema['model']['props']> & {
|
||||
flavour: Schema['model']['flavour'];
|
||||
};
|
||||
|
||||
export function defineBlockSchema<
|
||||
Flavour extends string,
|
||||
Role extends RoleType,
|
||||
|
||||
@@ -451,20 +451,6 @@ export class Store {
|
||||
}
|
||||
}
|
||||
|
||||
addBlock<Key extends BlockSuite.Flavour>(
|
||||
flavour: Key,
|
||||
blockProps?: BlockSuite.ModelProps<BlockSuite.BlockModels[Key]>,
|
||||
parent?: BlockModel | string | null,
|
||||
parentIndex?: number
|
||||
): string;
|
||||
|
||||
addBlock(
|
||||
flavour: never,
|
||||
blockProps?: Partial<BlockProps & Omit<BlockProps, 'flavour'>>,
|
||||
parent?: BlockModel | string | null,
|
||||
parentIndex?: number
|
||||
): string;
|
||||
|
||||
addBlock(
|
||||
flavour: string,
|
||||
blockProps: Partial<BlockProps & Omit<BlockProps, 'flavour'>> = {},
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { effects } from '@blocksuite/affine-block-note/effects';
|
||||
import { ShadowlessElement, SurfaceSelection } from '@blocksuite/block-std';
|
||||
import type { NoteBlockModel } from '@blocksuite/blocks';
|
||||
import {
|
||||
changeNoteDisplayMode,
|
||||
matchFlavours,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/blocks';
|
||||
import {
|
||||
@@ -155,7 +155,7 @@ export class OutlinePanelBody extends SignalWatcher(
|
||||
|
||||
const noteIndex = new Map<NoteBlockModel, number>();
|
||||
children.forEach((block, index) => {
|
||||
if (matchFlavours(block, ['affine:note'])) {
|
||||
if (matchFlavours(block, [NoteBlockModel])) {
|
||||
noteIndex.set(block, index);
|
||||
}
|
||||
});
|
||||
@@ -171,7 +171,7 @@ export class OutlinePanelBody extends SignalWatcher(
|
||||
if (targetIndex === null) return;
|
||||
|
||||
const removeSelectedNoteFilter = (block: BlockModel) =>
|
||||
!matchFlavours(block, ['affine:note']) || !selected.includes(block);
|
||||
!matchFlavours(block, [NoteBlockModel]) || !selected.includes(block);
|
||||
|
||||
const leftPart = children
|
||||
.slice(0, targetIndex)
|
||||
@@ -200,7 +200,7 @@ export class OutlinePanelBody extends SignalWatcher(
|
||||
private _selectNote(e: SelectEvent) {
|
||||
const { selected, id, multiselect } = e.detail;
|
||||
const note = this.doc.getBlock(id)?.model;
|
||||
if (!note || !matchFlavours(note, ['affine:note'])) return;
|
||||
if (!note || !matchFlavours(note, [NoteBlockModel])) return;
|
||||
|
||||
let selectedNotes = this._selectedNotes$.peek();
|
||||
|
||||
@@ -231,7 +231,7 @@ export class OutlinePanelBody extends SignalWatcher(
|
||||
.filter(SurfaceSelection)
|
||||
.map(({ blockId }) => doc.getBlock(blockId)?.model)
|
||||
.filter(model => {
|
||||
return !!model && matchFlavours(model, ['affine:note']);
|
||||
return !!model && matchFlavours(model, [NoteBlockModel]);
|
||||
});
|
||||
|
||||
const preSelected = this._selectedNotes$.peek();
|
||||
|
||||
@@ -122,7 +122,7 @@ export class OutlineBlockPreview extends SignalWatcher(
|
||||
|
||||
const showPreviewIcon = this._context.showIcons$.value;
|
||||
|
||||
switch (block.flavour as keyof BlockSuite.BlockModels) {
|
||||
switch (block.flavour) {
|
||||
case 'affine:page':
|
||||
assertType<RootBlockModel>(block);
|
||||
return block.title.length > 0
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
|
||||
import { PropTypes, requiredProperties } from '@blocksuite/block-std';
|
||||
import { matchFlavours, NoteDisplayMode } from '@blocksuite/blocks';
|
||||
import {
|
||||
matchFlavours,
|
||||
NoteDisplayMode,
|
||||
ParagraphBlockModel,
|
||||
RootBlockModel,
|
||||
} from '@blocksuite/blocks';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
import { signal } from '@preact/signals-core';
|
||||
@@ -129,11 +134,11 @@ export class MobileOutlineMenu extends SignalWatcher(
|
||||
renderItem = (item: BlockModel) => {
|
||||
let className = '';
|
||||
let text = '';
|
||||
if (matchFlavours(item, ['affine:page'])) {
|
||||
if (matchFlavours(item, [RootBlockModel])) {
|
||||
className = 'title';
|
||||
text = item.title$.value.toString();
|
||||
} else if (
|
||||
matchFlavours(item, ['affine:paragraph']) &&
|
||||
matchFlavours(item, [ParagraphBlockModel]) &&
|
||||
['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(item.type$.value)
|
||||
) {
|
||||
className = item.type$.value;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {
|
||||
BlocksUtils,
|
||||
matchFlavours,
|
||||
type NoteBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
type ParagraphBlockModel,
|
||||
type RootBlockModel,
|
||||
ParagraphBlockModel,
|
||||
RootBlockModel,
|
||||
} from '@blocksuite/blocks';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
|
||||
@@ -24,7 +24,7 @@ export function getNotesFromDoc(
|
||||
const notes: NoteBlockModel[] = [];
|
||||
|
||||
rootModel.children.forEach(block => {
|
||||
if (!matchFlavours(block, ['affine:note'])) return;
|
||||
if (!matchFlavours(block, [NoteBlockModel])) return;
|
||||
|
||||
if (modes.includes(block.displayMode$.value)) {
|
||||
notes.push(block);
|
||||
@@ -35,14 +35,14 @@ export function getNotesFromDoc(
|
||||
}
|
||||
|
||||
export function isRootBlock(block: BlockModel): block is RootBlockModel {
|
||||
return BlocksUtils.matchFlavours(block, ['affine:page']);
|
||||
return BlocksUtils.matchFlavours(block, [RootBlockModel]);
|
||||
}
|
||||
|
||||
export function isHeadingBlock(
|
||||
block: BlockModel
|
||||
): block is ParagraphBlockModel {
|
||||
return (
|
||||
BlocksUtils.matchFlavours(block, ['affine:paragraph']) &&
|
||||
BlocksUtils.matchFlavours(block, [ParagraphBlockModel]) &&
|
||||
headingKeys.has(block.type$.value)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
getSelectedBlocksCommand,
|
||||
NoteDisplayMode,
|
||||
NotificationProvider,
|
||||
ParagraphBlockModel,
|
||||
RefNodeSlotsProvider,
|
||||
TelemetryProvider,
|
||||
} from '@blocksuite/affine/blocks';
|
||||
@@ -166,7 +167,7 @@ function addAIChatBlock(
|
||||
const y = viewportCenter.y - height / 2;
|
||||
const bound = new Bound(x, y, width, height);
|
||||
const aiChatBlockId = doc.addBlock(
|
||||
'affine:embed-ai-chat' as keyof BlockSuite.BlockModels,
|
||||
'affine:embed-ai-chat',
|
||||
{
|
||||
xywh: bound.serialize(),
|
||||
messages: JSON.stringify(messages),
|
||||
@@ -231,7 +232,7 @@ const REPLACE_SELECTION = {
|
||||
if (currentTextSelection) {
|
||||
const { doc } = host;
|
||||
const block = doc.getBlock(currentTextSelection.blockId);
|
||||
if (matchFlavours(block?.model ?? null, ['affine:paragraph'])) {
|
||||
if (matchFlavours(block?.model ?? null, [ParagraphBlockModel])) {
|
||||
block?.model.text?.replace(
|
||||
currentTextSelection.from.index,
|
||||
currentTextSelection.from.length,
|
||||
|
||||
@@ -2,8 +2,12 @@ import type { Chain, InitCommandCtx } from '@blocksuite/affine/block-std';
|
||||
import {
|
||||
type AIItemGroupConfig,
|
||||
type AISubItemConfig,
|
||||
CodeBlockModel,
|
||||
getSelectedModelsCommand,
|
||||
ImageBlockModel,
|
||||
ListBlockModel,
|
||||
matchFlavours,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine/blocks';
|
||||
|
||||
import { actionToHandler } from '../actions/doc-handler';
|
||||
@@ -103,7 +107,7 @@ const textBlockShowWhen = (chain: Chain<InitCommandCtx>) => {
|
||||
if (!selectedModels || selectedModels.length === 0) return false;
|
||||
|
||||
return selectedModels.some(model =>
|
||||
matchFlavours(model, ['affine:paragraph', 'affine:list'])
|
||||
matchFlavours(model, [ParagraphBlockModel, ListBlockModel])
|
||||
);
|
||||
};
|
||||
|
||||
@@ -117,7 +121,7 @@ const codeBlockShowWhen = (chain: Chain<InitCommandCtx>) => {
|
||||
if (!selectedModels || selectedModels.length > 1) return false;
|
||||
|
||||
const model = selectedModels[0];
|
||||
return matchFlavours(model, ['affine:code']);
|
||||
return matchFlavours(model, [CodeBlockModel]);
|
||||
};
|
||||
|
||||
const imageBlockShowWhen = (chain: Chain<InitCommandCtx>) => {
|
||||
@@ -130,7 +134,7 @@ const imageBlockShowWhen = (chain: Chain<InitCommandCtx>) => {
|
||||
if (!selectedModels || selectedModels.length > 1) return false;
|
||||
|
||||
const model = selectedModels[0];
|
||||
return matchFlavours(model, ['affine:image']);
|
||||
return matchFlavours(model, [ImageBlockModel]);
|
||||
};
|
||||
|
||||
const EditAIGroup: AIItemGroupConfig = {
|
||||
@@ -278,7 +282,7 @@ const GenerateWithAIGroup: AIItemGroupConfig = {
|
||||
|
||||
return selectedModels.every(
|
||||
model =>
|
||||
matchFlavours(model, ['affine:paragraph', 'affine:list']) &&
|
||||
matchFlavours(model, [ParagraphBlockModel, ListBlockModel]) &&
|
||||
!model.type.startsWith('h')
|
||||
);
|
||||
},
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
} from '@blocksuite/affine/blocks';
|
||||
import {
|
||||
BlocksUtils,
|
||||
CodeBlockModel,
|
||||
EdgelessTextBlockModel,
|
||||
EmbedSyncedDocModel,
|
||||
ImageBlockModel,
|
||||
@@ -485,7 +486,7 @@ export function noteWithCodeBlockShowWen(
|
||||
return (
|
||||
selected[0] instanceof NoteBlockModel &&
|
||||
selected[0].children.length === 1 &&
|
||||
BlocksUtils.matchFlavours(selected[0].children[0], ['affine:code'])
|
||||
BlocksUtils.matchFlavours(selected[0].children[0], [CodeBlockModel])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -527,7 +527,7 @@ async function responseToCreateSlides(host: EditorHost, ctx: AIContext) {
|
||||
await job.insertTemplate(content);
|
||||
}
|
||||
|
||||
getSurfaceElementFromEditor(host).refresh();
|
||||
getSurfaceElementFromEditor(host)?.refresh();
|
||||
} catch (error) {
|
||||
console.error('Error creating slides:', error);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ImageBlockModel,
|
||||
isInsideEdgelessEditor,
|
||||
matchFlavours,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/affine/blocks';
|
||||
import { assertExists, Bound } from '@blocksuite/affine/global/utils';
|
||||
@@ -115,7 +116,7 @@ function createNewNote(host: EditorHost): AIItemConfig {
|
||||
|
||||
// set the viewport to show the new note block and original note block
|
||||
const newNote = doc.getBlock(noteBlockId)?.model;
|
||||
if (!newNote || !matchFlavours(newNote, ['affine:note'])) return;
|
||||
if (!newNote || !matchFlavours(newNote, [NoteBlockModel])) return;
|
||||
const newNoteBound = Bound.deserialize(newNote.xywh);
|
||||
const bounds = [bound, newNoteBound];
|
||||
service.gfx.fitToScreen({
|
||||
|
||||
@@ -175,7 +175,7 @@ export class AIChatBlockPeekView extends LitElement {
|
||||
const edgelessService = this._rootService as EdgelessRootService;
|
||||
const bound = calcChildBound(this.parentModel, edgelessService);
|
||||
const aiChatBlockId = edgelessService.crud.addBlock(
|
||||
'affine:embed-ai-chat' as keyof BlockSuite.BlockModels,
|
||||
'affine:embed-ai-chat',
|
||||
{
|
||||
xywh: bound.serialize(),
|
||||
messages: JSON.stringify(messages),
|
||||
|
||||
@@ -51,7 +51,7 @@ export const PPTBuilder = (host: EditorHost) => {
|
||||
);
|
||||
}
|
||||
await job.insertTemplate(content);
|
||||
getSurfaceElementFromEditor(host).refresh();
|
||||
getSurfaceElementFromEditor(host)?.refresh();
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -5,7 +5,10 @@ import {
|
||||
type EdgelessRootService,
|
||||
matchFlavours,
|
||||
MindmapElementModel,
|
||||
NoteBlockModel,
|
||||
RootBlockModel,
|
||||
type ShapeElementModel,
|
||||
SurfaceBlockModel,
|
||||
} from '@blocksuite/affine/blocks';
|
||||
|
||||
export function mindMapToMarkdown(mindmap: MindmapElementModel) {
|
||||
@@ -62,10 +65,10 @@ export function getEdgelessCopilotWidget(
|
||||
export function findNoteBlockModel(blockElement: BlockComponent) {
|
||||
let curBlock = blockElement;
|
||||
while (curBlock) {
|
||||
if (matchFlavours(curBlock.model, ['affine:note'])) {
|
||||
if (matchFlavours(curBlock.model, [NoteBlockModel])) {
|
||||
return curBlock.model;
|
||||
}
|
||||
if (matchFlavours(curBlock.model, ['affine:page', 'affine:surface'])) {
|
||||
if (matchFlavours(curBlock.model, [RootBlockModel, SurfaceBlockModel])) {
|
||||
return null;
|
||||
}
|
||||
if (!curBlock.parentComponent) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import type { EditorHost } from '@blocksuite/affine/block-std';
|
||||
import {
|
||||
BlocksUtils,
|
||||
DatabaseBlockModel,
|
||||
DocModeProvider,
|
||||
embedSyncedDocMiddleware,
|
||||
getImageSelectionsCommand,
|
||||
getSelectedBlocksCommand,
|
||||
type ImageBlockModel,
|
||||
ImageBlockModel,
|
||||
isInsideEdgelessEditor,
|
||||
MarkdownAdapter,
|
||||
type NoteBlockModel,
|
||||
@@ -163,7 +164,7 @@ export async function extractMarkdownFromDoc(
|
||||
const blockModels = getNoteBlockModels(doc);
|
||||
const textModels = blockModels.filter(
|
||||
model =>
|
||||
!BlocksUtils.matchFlavours(model, ['affine:image', 'affine:database'])
|
||||
!BlocksUtils.matchFlavours(model, [ImageBlockModel, DatabaseBlockModel])
|
||||
);
|
||||
const drafts = textModels.map(toDraftModel);
|
||||
const slice = Slice.fromModels(doc, drafts);
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { GfxModel } from '@blocksuite/affine/block-std/gfx';
|
||||
import {
|
||||
BlocksUtils,
|
||||
type CopilotTool,
|
||||
DatabaseBlockModel,
|
||||
EdgelessRootService,
|
||||
type FrameBlockModel,
|
||||
getBlockSelectionsCommand,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
ImageBlockModel,
|
||||
type SurfaceBlockComponent,
|
||||
} from '@blocksuite/affine/blocks';
|
||||
import { assertExists } from '@blocksuite/affine/global/utils';
|
||||
import {
|
||||
type BlockModel,
|
||||
type DraftModel,
|
||||
@@ -134,7 +134,7 @@ export async function getTextContentFromBlockModels(
|
||||
// Currently only filter out images and databases
|
||||
const selectedTextModels = models.filter(
|
||||
model =>
|
||||
!BlocksUtils.matchFlavours(model, ['affine:image', 'affine:database'])
|
||||
!BlocksUtils.matchFlavours(model, [ImageBlockModel, DatabaseBlockModel])
|
||||
);
|
||||
const drafts = selectedTextModels.map(toDraftModel);
|
||||
drafts.forEach(draft => traverse(draft, drafts));
|
||||
@@ -147,13 +147,13 @@ export async function getSelectedTextContent(
|
||||
type: 'markdown' | 'plain-text' = 'markdown'
|
||||
) {
|
||||
const selectedModels = getSelectedModels(editorHost);
|
||||
assertExists(selectedModels);
|
||||
if (!selectedModels) return '';
|
||||
return getTextContentFromBlockModels(editorHost, selectedModels, type);
|
||||
}
|
||||
|
||||
export async function selectAboveBlocks(editorHost: EditorHost, num = 10) {
|
||||
let selectedModels = getSelectedModels(editorHost);
|
||||
assertExists(selectedModels);
|
||||
if (!selectedModels) return '';
|
||||
|
||||
const lastLeafModel = selectedModels[selectedModels.length - 1];
|
||||
|
||||
@@ -163,8 +163,7 @@ export async function selectAboveBlocks(editorHost: EditorHost, num = 10) {
|
||||
lastRootModel = noteModel;
|
||||
noteModel = editorHost.doc.getParent(noteModel);
|
||||
}
|
||||
assertExists(noteModel);
|
||||
assertExists(lastRootModel);
|
||||
if (!noteModel || !lastRootModel) return '';
|
||||
|
||||
const endIndex = noteModel.children.indexOf(lastRootModel) + 1;
|
||||
const startIndex = Math.max(0, endIndex - num);
|
||||
@@ -212,13 +211,13 @@ export const stopPropagation = (e: Event) => {
|
||||
export function getSurfaceElementFromEditor(editor: EditorHost) {
|
||||
const { doc } = editor;
|
||||
const surfaceModel = doc.getBlockByFlavour('affine:surface')[0];
|
||||
assertExists(surfaceModel);
|
||||
if (!surfaceModel) return null;
|
||||
|
||||
const surfaceId = surfaceModel.id;
|
||||
const surfaceElement = editor.querySelector(
|
||||
`affine-surface[data-block-id="${surfaceId}"]`
|
||||
) as SurfaceBlockComponent;
|
||||
assertExists(surfaceElement);
|
||||
if (!surfaceElement) return null;
|
||||
|
||||
return surfaceElement;
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import { track } from '@affine/track';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/affine/block-std/gfx';
|
||||
import {
|
||||
matchFlavours,
|
||||
type NoteBlockModel,
|
||||
NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/affine/blocks';
|
||||
import { Bound } from '@blocksuite/affine/global/utils';
|
||||
@@ -176,7 +176,7 @@ export const EdgelessNoteHeader = ({ note }: { note: NoteBlockModel }) => {
|
||||
const isFirstVisibleNote =
|
||||
note.parent?.children.find(
|
||||
child =>
|
||||
matchFlavours(child, ['affine:note']) &&
|
||||
matchFlavours(child, [NoteBlockModel]) &&
|
||||
child.displayMode === NoteDisplayMode.DocAndEdgeless
|
||||
) === note;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user