mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-15 17:16:16 +08:00
feat: Intra-line double link interaction
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
/* eslint-disable max-lines */
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import {
|
||||
ReturnEditorBlock,
|
||||
UpdateEditorBlock,
|
||||
DefaultColumnsValue,
|
||||
Protocol,
|
||||
ReturnEditorBlock,
|
||||
UpdateEditorBlock,
|
||||
} from '@toeverything/datasource/db-service';
|
||||
import {
|
||||
isDev,
|
||||
createNoopWithMessage,
|
||||
lowerFirst,
|
||||
isDev,
|
||||
last,
|
||||
lowerFirst,
|
||||
} from '@toeverything/utils';
|
||||
import { BlockProvider } from './block-provider';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import { BaseView, BaseView as BlockView } from './../views/base-view';
|
||||
import { BlockProvider } from './block-provider';
|
||||
|
||||
type EventType = 'update';
|
||||
export interface EventData {
|
||||
@@ -154,6 +154,7 @@ export class AsyncBlock {
|
||||
}
|
||||
this.initialized = true;
|
||||
this.raw_data = await this.filterPageInvalidChildren(this.raw_data);
|
||||
this.raw_data = await this.updateDoubleLinkBlock(this.raw_data);
|
||||
const { workspace, id } = this.raw_data;
|
||||
this.unobserve = await this.services.observe(
|
||||
{ workspace, id },
|
||||
@@ -161,6 +162,7 @@ export class AsyncBlock {
|
||||
const oldData = this.raw_data;
|
||||
this.raw_data = blockData;
|
||||
this.raw_data = await this.filterPageInvalidChildren(blockData);
|
||||
this.raw_data = await this.updateDoubleLinkBlock(this.raw_data);
|
||||
this.emit('update', { block: this, oldData });
|
||||
}
|
||||
);
|
||||
@@ -495,4 +497,35 @@ export class AsyncBlock {
|
||||
getBoundingClientRect() {
|
||||
return this.dom?.getBoundingClientRect();
|
||||
}
|
||||
|
||||
async updateDoubleLinkBlock(rawData: ReturnEditorBlock) {
|
||||
const values = rawData.properties?.text?.value || [];
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const item = values[i] as any;
|
||||
if (item.linkType === 'doubleLink') {
|
||||
const linkBlock = await this.services.load({
|
||||
workspace: item.workspaceId,
|
||||
id: item.blockId,
|
||||
});
|
||||
|
||||
if (linkBlock) {
|
||||
let children = linkBlock.getProperties().text?.value || [];
|
||||
if (children.length === 1 && !children[0].text) {
|
||||
children = [{ text: 'Untitled' }];
|
||||
}
|
||||
if (
|
||||
children.map(v => v.text).join('') !==
|
||||
(item.children || []).map((v: any) => v.text).join('')
|
||||
) {
|
||||
const newItem = {
|
||||
...item,
|
||||
children: children,
|
||||
};
|
||||
values.splice(i, 1, newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rawData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@ type TextUtilsFunctions =
|
||||
| 'setSearchSlash'
|
||||
| 'removeSearchSlash'
|
||||
| 'getSearchSlashText'
|
||||
| 'setDoubleLinkSearchSlash'
|
||||
| 'getDoubleLinkSearchSlashText'
|
||||
| 'setSelectDoubleLinkSearchSlash'
|
||||
| 'removeDoubleLinkSearchSlash'
|
||||
| 'insertDoubleLink'
|
||||
| 'selectionToSlateRange'
|
||||
| 'transformPoint'
|
||||
| 'toggleTextFormatBySelection'
|
||||
@@ -32,7 +37,6 @@ type TextUtilsFunctions =
|
||||
| 'getCommentsIdsBySelection'
|
||||
| 'getCurrentSelection'
|
||||
| 'removeSelection'
|
||||
| 'insertReference'
|
||||
| 'isCollapsed'
|
||||
| 'blur'
|
||||
| 'setSelection'
|
||||
@@ -149,27 +153,60 @@ export class BlockHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public insertReference(
|
||||
reference: string,
|
||||
public setDoubleLinkSearchSlash(blockId: string, point: Point) {
|
||||
const textUtils = this._blockTextUtilsMap[blockId];
|
||||
if (textUtils) {
|
||||
textUtils.setDoubleLinkSearchSlash(point);
|
||||
} else {
|
||||
console.warn('Could find the block text utils');
|
||||
}
|
||||
}
|
||||
|
||||
public getDoubleLinkSearchSlashText(blockId: string) {
|
||||
const textUtils = this._blockTextUtilsMap[blockId];
|
||||
if (textUtils) {
|
||||
return textUtils.getDoubleLinkSearchSlashText();
|
||||
}
|
||||
console.warn('Could find the block text utils');
|
||||
return '';
|
||||
}
|
||||
public setSelectDoubleLinkSearchSlash(blockId: string) {
|
||||
const textUtils = this._blockTextUtilsMap[blockId];
|
||||
if (textUtils) {
|
||||
return textUtils.setSelectDoubleLinkSearchSlash();
|
||||
}
|
||||
console.warn('Could find the block text utils');
|
||||
return '';
|
||||
}
|
||||
|
||||
public removeDoubleLinkSearchSlash(
|
||||
blockId: string,
|
||||
selection: Selection,
|
||||
offset: number
|
||||
isRemoveSlash?: boolean
|
||||
) {
|
||||
const text_utils = this._blockTextUtilsMap[blockId];
|
||||
if (text_utils) {
|
||||
const offsetSelection = window.getSelection();
|
||||
offsetSelection.setBaseAndExtent(
|
||||
selection.anchorNode,
|
||||
selection.anchorOffset,
|
||||
selection.focusNode,
|
||||
selection.focusOffset + offset
|
||||
);
|
||||
const textUtils = this._blockTextUtilsMap[blockId];
|
||||
if (textUtils) {
|
||||
textUtils.removeDoubleLinkSearchSlash(isRemoveSlash);
|
||||
} else {
|
||||
console.warn('Could find the block text utils');
|
||||
}
|
||||
}
|
||||
|
||||
text_utils.removeSelection(offsetSelection);
|
||||
text_utils.insertReference(reference);
|
||||
|
||||
// range.
|
||||
// text_utils.toggleTextFormatBySelection(format, range);
|
||||
public async insertDoubleLink(
|
||||
workspaceId: string,
|
||||
linkBlockId: string,
|
||||
blockId: string
|
||||
) {
|
||||
const textUtils = this._blockTextUtilsMap[blockId];
|
||||
if (textUtils) {
|
||||
const linkBlock = await this._editor.getBlock({
|
||||
workspace: workspaceId,
|
||||
id: linkBlockId,
|
||||
});
|
||||
let children = linkBlock.getProperties().text?.value || [];
|
||||
if (children.length === 1 && !children[0].text) {
|
||||
children = [{ text: 'Untitled' }];
|
||||
}
|
||||
textUtils.insertDoubleLink(workspaceId, linkBlockId, children);
|
||||
}
|
||||
console.warn('Could find the block text utils');
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
/* eslint-disable max-lines */
|
||||
import HotKeys from 'hotkeys-js';
|
||||
|
||||
import type { PatchNode } from '@toeverything/components/ui';
|
||||
import { Commands } from '@toeverything/datasource/commands';
|
||||
import type {
|
||||
BlockFlavors,
|
||||
ReturnEditorBlock,
|
||||
UpdateEditorBlock,
|
||||
} from '@toeverything/datasource/db-service';
|
||||
import { services } from '@toeverything/datasource/db-service';
|
||||
|
||||
import { Commands } from '@toeverything/datasource/commands';
|
||||
import { domToRect, last, Point, sleep } from '@toeverything/utils';
|
||||
import assert from 'assert';
|
||||
import HotKeys from 'hotkeys-js';
|
||||
import type { WorkspaceAndBlockId } from './block';
|
||||
import { AsyncBlock } from './block';
|
||||
import { BlockHelper } from './block/block-helper';
|
||||
@@ -282,7 +280,7 @@ export class Editor implements Virgo {
|
||||
return await blockView.onCreate(block);
|
||||
}
|
||||
|
||||
private async getBlock({
|
||||
public async getBlock({
|
||||
workspace,
|
||||
id,
|
||||
}: WorkspaceAndBlockId): Promise<AsyncBlock | null> {
|
||||
|
||||
Reference in New Issue
Block a user