mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-18 02:21:51 +08:00
chore: merge blocksuite source code (#9213)
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
|
||||
export const clearAndSelectFirstModelCommand: Command<'selectedModels'> = (
|
||||
ctx,
|
||||
next
|
||||
) => {
|
||||
const models = ctx.selectedModels;
|
||||
|
||||
if (!models) {
|
||||
console.error(
|
||||
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (models.length > 0) {
|
||||
const firstModel = models[0];
|
||||
if (firstModel.text) {
|
||||
firstModel.text.clear();
|
||||
const selection = ctx.std.selection.create('text', {
|
||||
from: {
|
||||
blockId: firstModel.id,
|
||||
index: 0,
|
||||
length: 0,
|
||||
},
|
||||
to: null,
|
||||
});
|
||||
ctx.std.selection.setGroup('note', [selection]);
|
||||
}
|
||||
}
|
||||
|
||||
return next();
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface Commands {
|
||||
clearAndSelectFirstModel: typeof clearAndSelectFirstModelCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
import { Slice } from '@blocksuite/store';
|
||||
|
||||
export const copySelectedModelsCommand: Command<'draftedModels' | 'onCopy'> = (
|
||||
ctx,
|
||||
next
|
||||
) => {
|
||||
const models = ctx.draftedModels;
|
||||
if (!models) {
|
||||
console.error(
|
||||
'`draftedModels` is required, you need to use `draftSelectedModels` command before adding this command to the pipeline.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
models
|
||||
.then(models => {
|
||||
const slice = Slice.fromModels(ctx.std.doc, models);
|
||||
|
||||
return ctx.std.clipboard.copy(slice);
|
||||
})
|
||||
.then(() => ctx.onCopy?.())
|
||||
.catch(console.error);
|
||||
return next();
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface CommandContext {
|
||||
onCopy?: () => void;
|
||||
}
|
||||
interface Commands {
|
||||
copySelectedModels: typeof copySelectedModelsCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
|
||||
export const deleteSelectedModelsCommand: Command<'selectedModels'> = (
|
||||
ctx,
|
||||
next
|
||||
) => {
|
||||
const models = ctx.selectedModels;
|
||||
|
||||
if (!models) {
|
||||
console.error(
|
||||
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
models.forEach(model => {
|
||||
ctx.std.doc.deleteBlock(model);
|
||||
});
|
||||
|
||||
return next();
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface Commands {
|
||||
deleteSelectedModels: typeof deleteSelectedModelsCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
import {
|
||||
type BlockModel,
|
||||
type DraftModel,
|
||||
toDraftModel,
|
||||
} from '@blocksuite/store';
|
||||
|
||||
export const draftSelectedModelsCommand: Command<
|
||||
'selectedModels',
|
||||
'draftedModels'
|
||||
> = (ctx, next) => {
|
||||
const models = ctx.selectedModels;
|
||||
if (!models) {
|
||||
console.error(
|
||||
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const draftedModelsPromise = new Promise<DraftModel[]>(resolve => {
|
||||
const draftedModels = models.map(toDraftModel);
|
||||
|
||||
const modelMap = new Map(draftedModels.map(model => [model.id, model]));
|
||||
|
||||
const traverse = (model: DraftModel) => {
|
||||
const isDatabase = model.flavour === 'affine:database';
|
||||
const children = isDatabase
|
||||
? model.children
|
||||
: model.children.filter(child => modelMap.has(child.id));
|
||||
|
||||
children.forEach(child => {
|
||||
modelMap.delete(child.id);
|
||||
traverse(child);
|
||||
});
|
||||
model.children = children;
|
||||
};
|
||||
|
||||
draftedModels.forEach(traverse);
|
||||
|
||||
const remainingDraftedModels = Array.from(modelMap.values());
|
||||
|
||||
resolve(remainingDraftedModels);
|
||||
});
|
||||
|
||||
return next({ draftedModels: draftedModelsPromise });
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface CommandContext {
|
||||
draftedModels?: Promise<DraftModel<BlockModel<object>>[]>;
|
||||
}
|
||||
|
||||
interface Commands {
|
||||
draftSelectedModels: typeof draftSelectedModelsCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
import { Slice } from '@blocksuite/store';
|
||||
|
||||
export const duplicateSelectedModelsCommand: Command<
|
||||
'draftedModels' | 'selectedModels'
|
||||
> = (ctx, next) => {
|
||||
const { std, draftedModels, selectedModels } = ctx;
|
||||
if (!draftedModels || !selectedModels) return;
|
||||
|
||||
const model = selectedModels[selectedModels.length - 1];
|
||||
|
||||
const parentModel = std.doc.getParent(model.id);
|
||||
if (!parentModel) return;
|
||||
|
||||
const index = parentModel.children.findIndex(x => x.id === model.id);
|
||||
|
||||
draftedModels
|
||||
.then(models => {
|
||||
const slice = Slice.fromModels(std.doc, models);
|
||||
return std.clipboard.duplicateSlice(
|
||||
slice,
|
||||
std.doc,
|
||||
parentModel.id,
|
||||
index + 1
|
||||
);
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
return next();
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface Commands {
|
||||
duplicateSelectedModels: typeof duplicateSelectedModelsCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
/**
|
||||
* Retrieves the selected models based on the provided selection types and mode.
|
||||
*
|
||||
* @param ctx - The command context, which includes the types of selections to be retrieved and the mode of the selection.
|
||||
* @param ctx.types - The selection types to be retrieved. Can be an array of 'block', 'text', or 'image'.
|
||||
* @param ctx.mode - The mode of the selection. Can be 'all', 'flat', or 'highest'.
|
||||
* @example
|
||||
* // Assuming `commandContext` is an instance of the command context
|
||||
* getSelectedModelsCommand(commandContext, (result) => {
|
||||
* console.log(result.selectedModels);
|
||||
* });
|
||||
*
|
||||
* // Example selection:
|
||||
* // aaa
|
||||
* // b[bb
|
||||
* // ccc
|
||||
* // ddd
|
||||
* // ee]e
|
||||
*
|
||||
* // all mode: [aaa, bbb, ccc, ddd, eee]
|
||||
* // flat mode: [bbb, ccc, ddd, eee]
|
||||
* // highest mode: [bbb, ddd]
|
||||
*
|
||||
* // The match function will be evaluated before filtering using mode
|
||||
* @param next - The next function to be called.
|
||||
* @returns An object containing the selected models as an array of BlockModel instances.
|
||||
*/
|
||||
export const getSelectedModelsCommand: Command<
|
||||
never,
|
||||
'selectedModels',
|
||||
{
|
||||
types?: Extract<BlockSuite.SelectionType, 'block' | 'text' | 'image'>[];
|
||||
mode?: 'all' | 'flat' | 'highest';
|
||||
}
|
||||
> = (ctx, next) => {
|
||||
const types = ctx.types ?? ['block', 'text', 'image'];
|
||||
const mode = ctx.mode ?? 'flat';
|
||||
const selectedModels: BlockModel[] = [];
|
||||
ctx.std.command
|
||||
.chain()
|
||||
.tryAll(chain => [
|
||||
chain.getTextSelection(),
|
||||
chain.getBlockSelections(),
|
||||
chain.getImageSelections(),
|
||||
])
|
||||
.getSelectedBlocks({
|
||||
types,
|
||||
mode,
|
||||
})
|
||||
.inline(ctx => {
|
||||
const { selectedBlocks = [] } = ctx;
|
||||
selectedModels.push(...selectedBlocks.map(el => el.model));
|
||||
})
|
||||
.run();
|
||||
|
||||
next({ selectedModels });
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface CommandContext {
|
||||
selectedModels?: BlockModel[];
|
||||
}
|
||||
|
||||
interface Commands {
|
||||
getSelectedModels: typeof getSelectedModelsCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export { clearAndSelectFirstModelCommand } from './clear-and-select-first-model.js';
|
||||
export { copySelectedModelsCommand } from './copy-selected-models.js';
|
||||
export { deleteSelectedModelsCommand } from './delete-selected-models.js';
|
||||
export { draftSelectedModelsCommand } from './draft-selected-models.js';
|
||||
export { duplicateSelectedModelsCommand } from './duplicate-selected-model.js';
|
||||
export { getSelectedModelsCommand } from './get-selected-models.js';
|
||||
export { retainFirstModelCommand } from './retain-first-model.js';
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { Command } from '@blocksuite/block-std';
|
||||
|
||||
export const retainFirstModelCommand: Command<'selectedModels'> = (
|
||||
ctx,
|
||||
next
|
||||
) => {
|
||||
if (!ctx.selectedModels) {
|
||||
console.error(
|
||||
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx.selectedModels.length > 0) {
|
||||
ctx.selectedModels.shift();
|
||||
}
|
||||
|
||||
return next();
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface Commands {
|
||||
retainFirstModel: typeof retainFirstModelCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user