mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 00:11:33 +03:00
Merge pull request #279 from toeverything/refactor/clean
Refactor/clean
This commit is contained in:
commit
91fa616942
@ -14,7 +14,7 @@ import { CreateView } from '@toeverything/framework/virgo';
|
||||
import { BlockContainer } from '../../components/BlockContainer';
|
||||
import { IndentWrapper } from '../../components/IndentWrapper';
|
||||
import { TextManage } from '../../components/text-manage';
|
||||
import { tabBlock } from '../../utils/indent';
|
||||
import { dedentBlock, tabBlock } from '../../utils/indent';
|
||||
interface CreateTextView extends CreateView {
|
||||
// TODO: need to optimize
|
||||
containerClassName?: string;
|
||||
@ -115,7 +115,19 @@ export const TextView = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
const preParent = await parentBlock.previousSibling();
|
||||
// The parent block is group block or is the root block.
|
||||
// Merge block to previous sibling.
|
||||
//
|
||||
// - group/root <- parent block
|
||||
// - text1 <- preNode
|
||||
// - text2 <- press backspace before target block
|
||||
// - children
|
||||
//
|
||||
// ---
|
||||
//
|
||||
// - group/root
|
||||
// - text1text2 <- merge block to previous sibling
|
||||
// - children <- children should switch parent block
|
||||
if (
|
||||
Protocol.Block.Type.group === parentBlock.type ||
|
||||
editor.getRootBlockId() === parentBlock.id
|
||||
@ -130,10 +142,7 @@ export const TextView = ({
|
||||
block.id,
|
||||
'end'
|
||||
);
|
||||
if (
|
||||
block.getProperty('text').value[0] &&
|
||||
block.getProperty('text').value[0]?.text !== ''
|
||||
) {
|
||||
if (!block.blockProvider?.isEmpty()) {
|
||||
const value = [
|
||||
...preNode.getProperty('text').value,
|
||||
...block.getProperty('text').value,
|
||||
@ -145,12 +154,13 @@ export const TextView = ({
|
||||
await preNode.append(...children);
|
||||
await block.remove();
|
||||
} else {
|
||||
// If not pre node, block should be merged to the parent block
|
||||
// TODO: point does not clear
|
||||
await editor.selectionManager.activePreviousNode(
|
||||
block.id,
|
||||
'start'
|
||||
);
|
||||
if (block.blockProvider.isEmpty()) {
|
||||
if (block.blockProvider?.isEmpty()) {
|
||||
await block.remove();
|
||||
const parentChild = await parentBlock.children();
|
||||
if (
|
||||
@ -158,6 +168,8 @@ export const TextView = ({
|
||||
Protocol.Block.Type.group &&
|
||||
!parentChild.length
|
||||
) {
|
||||
const preParent =
|
||||
await parentBlock.previousSibling();
|
||||
await editor.selectionManager.setSelectedNodesIds(
|
||||
[preParent?.id ?? editor.getRootBlockId()]
|
||||
);
|
||||
@ -198,17 +210,9 @@ export const TextView = ({
|
||||
await parentBlock.remove();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
const nextNodes = await block.nextSiblings();
|
||||
for (const nextNode of nextNodes) {
|
||||
await nextNode.remove();
|
||||
}
|
||||
block.append(...nextNodes);
|
||||
editor.commands.blockCommands.moveBlockAfter(
|
||||
block.id,
|
||||
parentBlock.id
|
||||
);
|
||||
}
|
||||
|
||||
dedentBlock(editor, block);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
type BlockEditor,
|
||||
supportChildren,
|
||||
type BlockEditor,
|
||||
} from '@toeverything/components/editor-core';
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
import { AsyncBlock } from '@toeverything/framework/virgo';
|
||||
@ -81,7 +81,7 @@ const indentBlock = async (block: TodoAsyncBlock) => {
|
||||
* └─ [ ]
|
||||
* ```
|
||||
*/
|
||||
const dedentBlock = async (editor: BlockEditor, block: AsyncBlock) => {
|
||||
export const dedentBlock = async (editor: BlockEditor, block: AsyncBlock) => {
|
||||
if (editor.getRootBlockId() === block.id) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* eslint-disable max-lines */
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
import { domToRect, Point } from '@toeverything/utils';
|
||||
import { AsyncBlock } from '../..';
|
||||
import { GridDropType } from '../commands/types';
|
||||
@ -6,7 +7,6 @@ import { Editor } from '../editor';
|
||||
import { BlockDropPlacement, GroupDirection } from '../types';
|
||||
// TODO: Evaluate implementing custom events with Rxjs
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
|
||||
enum DragType {
|
||||
dragBlock = 'dragBlock',
|
||||
@ -281,6 +281,10 @@ export class DragDropManager {
|
||||
this._editor.getRootBlockId()
|
||||
);
|
||||
let direction = BlockDropPlacement.none;
|
||||
if (!rootBlock || !rootBlock.dom) {
|
||||
console.warn('Can not find dom bind with block', rootBlock);
|
||||
return;
|
||||
}
|
||||
const rootBlockRect = domToRect(rootBlock.dom);
|
||||
let targetBlock: AsyncBlock | undefined;
|
||||
let typesInfo = {
|
||||
@ -303,6 +307,10 @@ export class DragDropManager {
|
||||
if (direction !== BlockDropPlacement.none) {
|
||||
const blockList = await this._editor.getBlockListByLevelOrder();
|
||||
targetBlock = blockList.find(block => {
|
||||
if (!block.dom) {
|
||||
console.warn('Can not find dom bind with block', block);
|
||||
return false;
|
||||
}
|
||||
const domRect = domToRect(block.dom);
|
||||
const pointChecker =
|
||||
direction === BlockDropPlacement.outerLeft
|
||||
|
@ -1,15 +1,16 @@
|
||||
/* eslint-disable max-lines */
|
||||
import {
|
||||
debounce,
|
||||
domToRect,
|
||||
getBlockIdByDom,
|
||||
last,
|
||||
Point,
|
||||
Rect,
|
||||
last,
|
||||
without,
|
||||
debounce,
|
||||
getBlockIdByDom,
|
||||
} from '@toeverything/utils';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
import { BlockEditor } from '../..';
|
||||
import { AsyncBlock } from '../block';
|
||||
import { VirgoSelection } from '../types';
|
||||
@ -18,19 +19,17 @@ import {
|
||||
changeEventName,
|
||||
CursorTypes,
|
||||
IdList,
|
||||
SelectBlock,
|
||||
selectEndEventName,
|
||||
SelectEventCallbackTypes,
|
||||
SelectEventTypes,
|
||||
SelectInfo,
|
||||
SelectionSettings,
|
||||
SelectionSettingsMap,
|
||||
SelectionTypes,
|
||||
SelectPosition,
|
||||
SelectBlock,
|
||||
SelectInfo,
|
||||
} from './types';
|
||||
import { isLikeBlockListIds } from './utils';
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
import { Editor } from 'slate';
|
||||
// IMP: maybe merge active and select into single function
|
||||
|
||||
export type SelectionInfo = InstanceType<
|
||||
@ -336,12 +335,12 @@ export class SelectionManager implements VirgoSelection {
|
||||
});
|
||||
for await (const childBlock of selectableChildren) {
|
||||
const { dom } = childBlock;
|
||||
if (dom && selectionRect.isIntersect(domToRect(dom))) {
|
||||
selectedNodes.push(childBlock);
|
||||
}
|
||||
if (!dom) {
|
||||
console.warn('can not find dom bind with block');
|
||||
}
|
||||
if (dom && selectionRect.isIntersect(domToRect(dom))) {
|
||||
selectedNodes.push(childBlock);
|
||||
}
|
||||
}
|
||||
// if just only has one selected maybe select the children
|
||||
if (selectedNodes.length === 1) {
|
||||
@ -1063,10 +1062,10 @@ export class SelectionManager implements VirgoSelection {
|
||||
index: number,
|
||||
blockId: string
|
||||
): Promise<void> {
|
||||
let preRang = document.createRange();
|
||||
const preRang = document.createRange();
|
||||
preRang.setStart(nowRange.startContainer, index);
|
||||
preRang.setEnd(nowRange.endContainer, index);
|
||||
let prePosition = preRang.getClientRects().item(0);
|
||||
const prePosition = preRang.getClientRects().item(0);
|
||||
this.activeNodeByNodeId(
|
||||
blockId,
|
||||
new Point(prePosition.left, prePosition.bottom)
|
||||
|
@ -9,10 +9,10 @@ import {
|
||||
BlockDecoration,
|
||||
MapOperation,
|
||||
} from '@toeverything/datasource/jwt';
|
||||
import { cloneDeep } from '@toeverything/utils';
|
||||
import type { EventData } from '../block';
|
||||
import { AsyncBlock } from '../block';
|
||||
import type { Editor } from '../editor';
|
||||
import { cloneDeep } from '@toeverything/utils';
|
||||
import { SelectBlock } from '../selection';
|
||||
|
||||
export interface CreateView {
|
||||
@ -114,7 +114,21 @@ export abstract class BaseView {
|
||||
// Whether the component is empty
|
||||
isEmpty(block: AsyncBlock): boolean {
|
||||
const text = block.getProperty('text');
|
||||
return !text?.value?.[0]?.text;
|
||||
const result = !text?.value?.[0]?.text;
|
||||
|
||||
// Assert that the text is really empty
|
||||
if (
|
||||
result &&
|
||||
block.getProperty('text')?.value.some(content => content.text)
|
||||
) {
|
||||
console.warn(
|
||||
'Assertion isEmpty error! The block has an empty start fragment, but it is not empty',
|
||||
block
|
||||
);
|
||||
}
|
||||
// Assert end
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
getSelProperties(block: AsyncBlock, selectInfo: any): DefaultColumnsValue {
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { HookType, BlockDropPlacement } from '@toeverything/framework/virgo';
|
||||
import { StrictMode } from 'react';
|
||||
import { BasePlugin } from '../../base-plugin';
|
||||
import { ignoreBlockTypes } from './menu-config';
|
||||
import {
|
||||
LineInfoSubject,
|
||||
LeftMenuDraggable,
|
||||
BlockDomInfo,
|
||||
} from './LeftMenuDraggable';
|
||||
import { PluginRenderRoot } from '../../utils';
|
||||
import { Subject, throttleTime } from 'rxjs';
|
||||
import { BlockDropPlacement, HookType } from '@toeverything/framework/virgo';
|
||||
import { domToRect, last, Point } from '@toeverything/utils';
|
||||
import { StrictMode } from 'react';
|
||||
import { Subject, throttleTime } from 'rxjs';
|
||||
import { BasePlugin } from '../../base-plugin';
|
||||
import { PluginRenderRoot } from '../../utils';
|
||||
import {
|
||||
BlockDomInfo,
|
||||
LeftMenuDraggable,
|
||||
LineInfoSubject,
|
||||
} from './LeftMenuDraggable';
|
||||
import { ignoreBlockTypes } from './menu-config';
|
||||
const DRAG_THROTTLE_DELAY = 60;
|
||||
export class LeftMenuPlugin extends BasePlugin {
|
||||
private _mousedown?: boolean;
|
||||
@ -111,6 +111,10 @@ export class LeftMenuPlugin extends BasePlugin {
|
||||
block.dom,
|
||||
block.id
|
||||
);
|
||||
if (!targetBlock.dom) {
|
||||
console.warn('Can not find dom bind with block', targetBlock);
|
||||
return;
|
||||
}
|
||||
this._lineInfo.next({
|
||||
direction,
|
||||
blockInfo: {
|
||||
|
@ -3,9 +3,7 @@ import type {
|
||||
MouseEventHandler,
|
||||
PropsWithChildren,
|
||||
} from 'react';
|
||||
import { cx } from '../clsx';
|
||||
import { styled } from '../styled';
|
||||
import { buttonStatus } from './constants';
|
||||
|
||||
/* Temporary solution, needs to be adjusted */
|
||||
const SIZE_SMALL = 'small' as const;
|
||||
@ -29,13 +27,18 @@ const SIZE_CONFIG = {
|
||||
|
||||
type SizeType = keyof typeof SIZE_CONFIG;
|
||||
|
||||
interface IconButtonProps {
|
||||
type IconButtonContainerProps = {
|
||||
size?: SizeType;
|
||||
hoverColor?: string; // CSSProperties['backgroundColor'];
|
||||
backgroundColor?: string; // CSSProperties['backgroundColor'];
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
interface IconButtonProps extends IconButtonContainerProps {
|
||||
onClick?: MouseEventHandler;
|
||||
disabled?: boolean;
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
size?: SizeType;
|
||||
hoverColor?: string;
|
||||
}
|
||||
|
||||
export const IconButton = ({
|
||||
@ -50,17 +53,14 @@ export const IconButton = ({
|
||||
{...props}
|
||||
onClick={disabled ? undefined : onClick}
|
||||
disabled={disabled}
|
||||
className={cx({ [buttonStatus.disabled]: disabled }, className)}
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
const Container = styled('button')<{
|
||||
size?: SizeType;
|
||||
hoverColor?: string;
|
||||
}>(({ theme, size = SIZE_MIDDLE, hoverColor }) => {
|
||||
const Container = styled('button')<IconButtonContainerProps>(
|
||||
({ theme, size = SIZE_MIDDLE, hoverColor, backgroundColor, disabled }) => {
|
||||
const { iconSize, areaSize } = SIZE_CONFIG[size];
|
||||
|
||||
return {
|
||||
@ -69,7 +69,7 @@ const Container = styled('button')<{
|
||||
alignItems: 'center',
|
||||
width: areaSize,
|
||||
height: areaSize,
|
||||
backgroundColor: 'transparent',
|
||||
backgroundColor: backgroundColor ?? 'transparent',
|
||||
color: theme.affine.palette.icons,
|
||||
padding: theme.affine.spacing.iconPadding,
|
||||
borderRadius: '3px',
|
||||
@ -86,19 +86,7 @@ const Container = styled('button')<{
|
||||
backgroundColor: hoverColor || theme.affine.palette.hover,
|
||||
},
|
||||
|
||||
[`&${buttonStatus.hover}`]: {
|
||||
backgroundColor: theme.affine.palette.hover,
|
||||
},
|
||||
|
||||
'&:focus': {
|
||||
color: theme.affine.palette.primary,
|
||||
},
|
||||
[`&.${buttonStatus.focus}`]: {
|
||||
color: theme.affine.palette.primary,
|
||||
},
|
||||
|
||||
[`&${buttonStatus.disabled}`]: {
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
...(disabled ? { cursor: 'not-allowed' } : {}),
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -1,6 +0,0 @@
|
||||
export const buttonStatus = {
|
||||
hover: '.hover',
|
||||
focus: '.focus',
|
||||
active: '.focus',
|
||||
disabled: '.disabled',
|
||||
};
|
Loading…
Reference in New Issue
Block a user