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:
Saul-Mirone
2025-02-11 08:18:57 +00:00
parent 64bb6c5a71
commit 652865c7cf
97 changed files with 492 additions and 323 deletions

View File

@@ -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)

View File

@@ -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
)
)

View File

@@ -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
);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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];

View File

@@ -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];

View File

@@ -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 = [

View File

@@ -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;

View File

@@ -35,7 +35,7 @@ export interface LinkedWidgetConfig {
* [[ -> @
*/
convertTriggerKey: boolean;
ignoreBlockTypes: (keyof BlockSuite.BlockModels)[];
ignoreBlockTypes: string[];
ignoreSelector: string;
getMenus: (
query: string,

View File

@@ -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 {

View File

@@ -84,7 +84,7 @@ import {
export type SlashMenuConfig = {
triggerKeys: string[];
ignoreBlockTypes: BlockSuite.Flavour[];
ignoreBlockTypes: string[];
items: SlashMenuItem[];
maxHeight: number;
tooltipTimeout: number;

View File

@@ -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;