Skip to content

Commit

Permalink
fix: indent behavior (#8941)
Browse files Browse the repository at this point in the history
  • Loading branch information
Flrande authored Dec 12, 2024
1 parent cdf5562 commit 541f254
Show file tree
Hide file tree
Showing 15 changed files with 224 additions and 247 deletions.
14 changes: 10 additions & 4 deletions packages/affine/block-list/src/commands/dedent-list.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { IndentContext } from '@blocksuite/affine-shared/types';
import type { Command } from '@blocksuite/block-std';

import { focusTextModel } from '@blocksuite/affine-components/rich-text';
import { matchFlavours } from '@blocksuite/affine-shared/utils';

import { correctNumberedListsOrderToPrev } from './utils.js';
Expand Down Expand Up @@ -95,7 +94,7 @@ export const canDedentListCommand: Command<

export const dedentListCommand: Command<'indentContext'> = (ctx, next) => {
const { indentContext: dedentContext, std } = ctx;
const { doc } = std;
const { doc, selection, range, host } = std;

if (
!dedentContext ||
Expand All @@ -108,7 +107,7 @@ export const dedentListCommand: Command<'indentContext'> = (ctx, next) => {
return;
}

const { blockId, inlineIndex } = dedentContext;
const { blockId } = dedentContext;

const model = doc.getBlock(blockId)?.model;
if (!model) return;
Expand Down Expand Up @@ -150,7 +149,14 @@ export const dedentListCommand: Command<'indentContext'> = (ctx, next) => {
doc.moveBlocks([model], grandParent, parent, false);
correctNumberedListsOrderToPrev(doc, model);

focusTextModel(std, model.id, inlineIndex);
const textSelection = selection.find('text');
if (textSelection) {
host.updateComplete
.then(() => {
range.syncTextSelectionToRange(textSelection);
})
.catch(console.error);
}

return next();
};
14 changes: 10 additions & 4 deletions packages/affine/block-list/src/commands/indent-list.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { IndentContext } from '@blocksuite/affine-shared/types';
import type { Command } from '@blocksuite/block-std';

import { focusTextModel } from '@blocksuite/affine-components/rich-text';
import { matchFlavours } from '@blocksuite/affine-shared/utils';

import { correctNumberedListsOrderToPrev } from './utils.js';
Expand Down Expand Up @@ -99,8 +98,8 @@ export const indentListCommand: Command<'indentContext', never> = (
return;
}

const { blockId, inlineIndex } = indentContext;
const { doc } = std;
const { blockId } = indentContext;
const { doc, selection, host, range } = std;

const model = doc.getBlock(blockId)?.model;
if (!model) return;
Expand All @@ -116,7 +115,14 @@ export const indentListCommand: Command<'indentContext', never> = (
correctNumberedListsOrderToPrev(doc, model);
if (nextSibling) correctNumberedListsOrderToPrev(doc, nextSibling);

focusTextModel(std, model.id, inlineIndex);
const textSelection = selection.find('text');
if (textSelection) {
host.updateComplete
.then(() => {
range.syncTextSelectionToRange(textSelection);
})
.catch(console.error);
}

return next();
};
14 changes: 10 additions & 4 deletions packages/affine/block-paragraph/src/commands/dedent-paragraph.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { IndentContext } from '@blocksuite/affine-shared/types';
import type { Command } from '@blocksuite/block-std';

import { focusTextModel } from '@blocksuite/affine-components/rich-text';
import { matchFlavours } from '@blocksuite/affine-shared/utils';

export const canDedentParagraphCommand: Command<
Expand Down Expand Up @@ -57,7 +56,7 @@ export const canDedentParagraphCommand: Command<

export const dedentParagraphCommand: Command<'indentContext'> = (ctx, next) => {
const { indentContext: dedentContext, std } = ctx;
const { doc } = std;
const { doc, selection, range, host } = std;

if (
!dedentContext ||
Expand All @@ -70,7 +69,7 @@ export const dedentParagraphCommand: Command<'indentContext'> = (ctx, next) => {
return;
}

const { blockId, inlineIndex } = dedentContext;
const { blockId } = dedentContext;

const model = doc.getBlock(blockId)?.model;
if (!model) return;
Expand All @@ -87,7 +86,14 @@ export const dedentParagraphCommand: Command<'indentContext'> = (ctx, next) => {
doc.moveBlocks(nextSiblings, model);
doc.moveBlocks([model], grandParent, parent, false);

focusTextModel(std, model.id, inlineIndex);
const textSelection = selection.find('text');
if (textSelection) {
host.updateComplete
.then(() => {
range.syncTextSelectionToRange(textSelection);
})
.catch(console.error);
}

return next();
};
14 changes: 10 additions & 4 deletions packages/affine/block-paragraph/src/commands/indent-paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { ListBlockModel } from '@blocksuite/affine-model';
import type { IndentContext } from '@blocksuite/affine-shared/types';
import type { Command } from '@blocksuite/block-std';

import { focusTextModel } from '@blocksuite/affine-components/rich-text';
import { matchFlavours } from '@blocksuite/affine-shared/utils';

export const canIndentParagraphCommand: Command<
Expand Down Expand Up @@ -60,7 +59,7 @@ export const canIndentParagraphCommand: Command<

export const indentParagraphCommand: Command<'indentContext'> = (ctx, next) => {
const { indentContext, std } = ctx;
const { doc } = std;
const { doc, selection, host, range } = std;

if (
!indentContext ||
Expand All @@ -72,7 +71,7 @@ export const indentParagraphCommand: Command<'indentContext'> = (ctx, next) => {
);
return;
}
const { blockId, inlineIndex } = indentContext;
const { blockId } = indentContext;

const model = doc.getBlock(blockId)?.model;
if (!model) return;
Expand All @@ -93,7 +92,14 @@ export const indentParagraphCommand: Command<'indentContext'> = (ctx, next) => {
} as Partial<ListBlockModel>);
}

focusTextModel(std, model.id, inlineIndex);
const textSelection = selection.find('text');
if (textSelection) {
host.updateComplete
.then(() => {
range.syncTextSelectionToRange(textSelection);
})
.catch(console.error);
}

return next();
};
2 changes: 1 addition & 1 deletion packages/blocks/src/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import type { insertEdgelessTextCommand } from './edgeless-text-block/commands/i
import type { updateBlockType } from './note-block/commands/block-type.js';
import type { dedentBlock } from './note-block/commands/dedent-block.js';
import type { dedentBlockToRoot } from './note-block/commands/dedent-block-to-root.js';
import type { dedentBlocks } from './note-block/commands/dedent-blocks.js';
import type { dedentBlocksToRoot } from './note-block/commands/dedent-blocks-to-root.js';
import type { dedentBlocks } from './note-block/commands/dendent-blocks.js';
import type { focusBlockEnd } from './note-block/commands/focus-block-end.js';
import type { focusBlockStart } from './note-block/commands/focus-block-start.js';
import type { indentBlock } from './note-block/commands/indent-block.js';
Expand Down
67 changes: 67 additions & 0 deletions packages/blocks/src/note-block/commands/dedent-blocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import type { Command } from '@blocksuite/block-std';

export const dedentBlocks: Command<
never,
never,
{
blockIds?: string[];
stopCapture?: boolean;
}
> = (ctx, next) => {
let { blockIds } = ctx;
const { std, stopCapture = true } = ctx;
const { doc, selection, range, host } = std;
const { schema } = doc;

if (!blockIds || !blockIds.length) {
const nativeRange = range.value;
if (nativeRange) {
const topBlocks = range.getSelectedBlockComponentsByRange(nativeRange, {
match: el => el.model.role === 'content',
mode: 'highest',
});
if (topBlocks.length > 0) {
blockIds = topBlocks.map(block => block.blockId);
}
} else {
blockIds = std.selection.getGroup('note').map(sel => sel.blockId);
}
}

if (!blockIds || !blockIds.length || doc.readonly) return;

// Find the first model that can be unindented
let firstDedentIndex = -1;
for (let i = 0; i < blockIds.length; i++) {
const model = doc.getBlock(blockIds[i])?.model;
if (!model) continue;
const parent = doc.getParent(blockIds[i]);
if (!parent) continue;
const grandParent = doc.getParent(parent);
if (!grandParent) continue;

if (schema.isValid(model.flavour, grandParent.flavour)) {
firstDedentIndex = i;
break;
}
}

if (firstDedentIndex === -1) return;

if (stopCapture) doc.captureSync();
const dedentIds = blockIds.slice(firstDedentIndex);
dedentIds.forEach(id => {
std.command.exec('dedentBlock', { blockId: id, stopCapture: false });
});

const textSelection = selection.find('text');
if (textSelection) {
host.updateComplete
.then(() => {
range.syncTextSelectionToRange(textSelection);
})
.catch(console.error);
}

return next();
};
60 changes: 0 additions & 60 deletions packages/blocks/src/note-block/commands/dendent-blocks.ts

This file was deleted.

44 changes: 22 additions & 22 deletions packages/blocks/src/note-block/commands/indent-blocks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Command } from '@blocksuite/block-std';
import type { BlockModel } from '@blocksuite/store';

export const indentBlocks: Command<
never,
Expand All @@ -11,31 +10,30 @@ export const indentBlocks: Command<
> = (ctx, next) => {
let { blockIds } = ctx;
const { std, stopCapture = true } = ctx;
const { doc } = std;
const { doc, selection, range, host } = std;
const { schema } = doc;

if (!blockIds || !blockIds.length) {
const text = std.selection.find('text');
if (text) {
blockIds = [text.from.blockId, text.to?.blockId].filter(
(x): x is string => !!x
);
const nativeRange = range.value;
if (nativeRange) {
const topBlocks = range.getSelectedBlockComponentsByRange(nativeRange, {
match: el => el.model.role === 'content',
mode: 'highest',
});
if (topBlocks.length > 0) {
blockIds = topBlocks.map(block => block.blockId);
}
} else {
blockIds = std.selection.getGroup('note').map(sel => sel.blockId);
}
}

if (!blockIds || !blockIds.length || doc.readonly) return;

if (blockIds.length === 1) {
const block = doc.getBlock(blockIds[0]);
if (!block || block.model.text) return;
}

// Find the first model that can be indented
let firstIndentIndex = -1;
let previousSibling: BlockModel | null = null;
for (let i = 0; i < blockIds.length; i++) {
previousSibling = doc.getPrev(blockIds[i]);
const previousSibling = doc.getPrev(blockIds[i]);
const model = doc.getBlock(blockIds[i])?.model;
if (
model &&
Expand All @@ -54,15 +52,17 @@ export const indentBlocks: Command<
// Models waiting to be indented
const indentIds = blockIds.slice(firstIndentIndex);
indentIds.forEach(id => {
const parent = doc.getParent(id);
if (!parent) return;
// Only indent the model which parent is not in the `indentModels`
// When parent is in the `indentModels`, it means the parent has been indented
// And the model should be indented with its parent
if (!indentIds.includes(parent.id)) {
std.command.exec('indentBlock', { blockId: id, stopCapture: false });
}
std.command.exec('indentBlock', { blockId: id, stopCapture: false });
});

const textSelection = selection.find('text');
if (textSelection) {
host.updateComplete
.then(() => {
range.syncTextSelectionToRange(textSelection);
})
.catch(console.error);
}

return next();
};
2 changes: 1 addition & 1 deletion packages/blocks/src/note-block/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
import { updateBlockType } from './block-type.js';
import { dedentBlock } from './dedent-block.js';
import { dedentBlockToRoot } from './dedent-block-to-root.js';
import { dedentBlocks } from './dedent-blocks.js';
import { dedentBlocksToRoot } from './dedent-blocks-to-root.js';
import { dedentBlocks } from './dendent-blocks.js';
import { focusBlockEnd } from './focus-block-end.js';
import { focusBlockStart } from './focus-block-start.js';
import { indentBlock } from './indent-block.js';
Expand Down
Loading

0 comments on commit 541f254

Please sign in to comment.