Files
AFFiNE-Mirror/blocksuite/affine/gfx/text/src/commands/insert-edgeless-text.ts
T
Saul-Mirone 388641bc89 refactor(editor): rename doc to store on block components (#12173)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Unified internal data access by replacing all references from `doc` to `store` across all components, blocks, widgets, and utilities. This affects how readonly state, block operations, and service retrieval are handled throughout the application.
- **Tests**
  - Updated all test utilities and test cases to use `store` instead of `doc` for document-related operations.
- **Chores**
  - Updated context providers and property names to reflect the change from `doc` to `store` for improved consistency and maintainability.

No user-facing features or behaviors have changed.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-08 01:01:05 +00:00

115 lines
3.2 KiB
TypeScript

import {
EdgelessCRUDIdentifier,
getSurfaceBlock,
} from '@blocksuite/affine-block-surface';
import {
EDGELESS_TEXT_BLOCK_MIN_HEIGHT,
EDGELESS_TEXT_BLOCK_MIN_WIDTH,
EdgelessTextBlockModel,
} from '@blocksuite/affine-model';
import { focusTextModel } from '@blocksuite/affine-rich-text';
import { matchModels } from '@blocksuite/affine-shared/utils';
import { Bound } from '@blocksuite/global/gfx';
import type { Command } from '@blocksuite/std';
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
export const insertEdgelessTextCommand: Command<
{
x: number;
y: number;
},
{
textId: string;
}
> = (ctx, next) => {
const { std, x, y } = ctx;
const host = std.host;
const doc = host.store;
const surface = getSurfaceBlock(doc);
if (!surface) {
next();
return;
}
const gfx = std.get(GfxControllerIdentifier);
const zoom = gfx.viewport.zoom;
const selection = gfx.selection;
const textId = std.get(EdgelessCRUDIdentifier).addBlock(
'affine:edgeless-text',
{
xywh: new Bound(
x - (EDGELESS_TEXT_BLOCK_MIN_WIDTH * zoom) / 2,
y - (EDGELESS_TEXT_BLOCK_MIN_HEIGHT * zoom) / 2,
EDGELESS_TEXT_BLOCK_MIN_WIDTH * zoom,
EDGELESS_TEXT_BLOCK_MIN_HEIGHT * zoom
).serialize(),
},
surface.id
);
const blockId = doc.addBlock('affine:paragraph', { type: 'text' }, textId);
host.updateComplete
.then(() => {
selection.set({
elements: [textId],
editing: true,
});
const disposable = selection.slots.updated.subscribe(() => {
const editing = selection.editing;
const id = selection.selectedIds[0];
if (!editing || id !== textId) {
const textBlock = host.view.getBlock(textId);
const model = textBlock?.model;
if (matchModels(model, [EdgelessTextBlockModel])) {
model.props.hasMaxWidth = true;
}
disposable.unsubscribe();
}
});
focusTextModel(std, blockId);
host.updateComplete
.then(() => {
const edgelessText = host.view.getBlock(textId);
const paragraph = host.view.getBlock(blockId);
if (!edgelessText || !paragraph) return;
const abortController = new AbortController();
edgelessText.addEventListener(
'focusout',
e => {
if (edgelessText.model.children.length > 1) return;
if (
!paragraph.model.text ||
(paragraph.model.text.length === 0 && e.relatedTarget !== null)
) {
doc.deleteBlock(edgelessText.model);
}
},
{
once: true,
signal: abortController.signal,
}
);
const subscription = paragraph.model.deleted.subscribe(() => {
subscription.unsubscribe();
abortController.abort();
});
edgelessText.addEventListener(
'beforeinput',
() => {
abortController.abort();
},
{
once: true,
}
);
})
.catch(console.error);
})
.catch(console.error);
next({ textId });
};