can paste

This commit is contained in:
Bowen Tan 2021-12-03 09:51:46 +08:00
parent ee058a7b0b
commit bbe97dc486
4 changed files with 115 additions and 2 deletions

View File

@ -1,5 +1,5 @@
import { css } from '@emotion/react';
import React from 'react';
import React, { useRef } from 'react';
import { eventBus } from '../eventBus';
import { genOperation } from '../operations';
@ -8,6 +8,7 @@ type Props = {
};
export const KeyboardEventWrapper: React.FC<Props> = props => {
const copyId = useRef('');
const style = css`
&:focus {
outline: none;
@ -41,6 +42,23 @@ export const KeyboardEventWrapper: React.FC<Props> = props => {
eventBus.send('redo');
}
break;
case 'c':
// FIXME: detect os version and set redo/undo logic
if (e.metaKey || e.ctrlKey) {
// eventBus.send('copy', { componentId: props.selectedComponentId });
copyId.current = props.selectedComponentId;
}
break;
case 'v':
eventBus.send(
'operation',
genOperation('pasteComponent', {
componentId: copyId.current,
parentId: props.selectedComponentId,
slot: 'content',
})
);
break;
}
};

View File

@ -6,13 +6,14 @@ export type EventNames = {
operation: IOperation;
redo: undefined;
undo: undefined;
copy: { componentId: string };
// when switch app or module, current components refresh
componentsRefresh: ApplicationComponent[];
// components change by operation
componentsChange: ApplicationComponent[];
// it is only used for some operations' side effect
selectComponent: string;
}
};
const emitter = mitt<EventNames>();

View File

@ -0,0 +1,84 @@
import { ApplicationComponent } from '@sunmao-ui/core';
import { CreateComponentBranchOperation } from '../branch';
import { BaseBranchOperation } from '../type';
export type PasteComponentBranchOperationContext = {
parentId: string;
slot: string;
componentId: string;
};
export class PasteComponentBranchOperation extends BaseBranchOperation<PasteComponentBranchOperationContext> {
do(prev: ApplicationComponent[]): ApplicationComponent[] {
console.log('paste', this.context)
// find component to remove
const targetComponent = prev.find(c => c.id === this.context.componentId);
if (!targetComponent) {
console.warn('paste component not found');
return prev;
}
// TODO: Change slot to target Parent
// this.operationStack.insert(
// new CreateComponentBranchOperation({ componentId: component.id })
// );
// TODO: O(n2) in worst case. Optimize in the future.
const children = prev.filter(c => {
const slotTrait = c.traits.find(t => t.type === 'core/v1/slot');
return (
slotTrait &&
(slotTrait.properties.container as { id: string }).id === this.context.componentId
);
});
children.forEach(component => {
this.operationStack.insert(
new CreateComponentBranchOperation({
componentId: `${component.id}_copy`,
componentType: component.type,
parentId: `${this.context.componentId}_copy`,
slot: this.context.slot,
})
);
});
// TODO: dont care about layout component
// if (parentId) {
// // modify layout property of parent grid layout component
// this.operationStack.insert(
// new ModifyComponentPropertiesLeafOperation({
// componentId: parentId,
// properties: {
// layout: (prev: Array<ReactGridLayout.Layout>) => {
// return produce(prev, draft => {
// const removeIndex = draft.findIndex(
// item => item.i === this.context.componentId
// );
// if (removeIndex === -1) {
// console.warn("parent element doesn' contain specific child");
// }
// draft.splice(removeIndex, 1);
// });
// },
// },
// })
// );
// }
// free component from schema
this.operationStack.insert(
new CreateComponentBranchOperation({
componentId: `${this.context.componentId}_copy`,
componentType: targetComponent.type,
parentId: this.context.parentId,
slot: this.context.slot,
})
);
// do the operation in order
return this.operationStack.reduce((prev, node) => {
prev = node.do(prev);
return prev;
}, prev);
}
}

View File

@ -6,6 +6,10 @@ import {
RemoveComponentBranchOperation,
RemoveComponentBranchOperationContext,
} from './branch';
import {
PasteComponentBranchOperation,
PasteComponentBranchOperationContext,
} from './branch/pasteComponentBranchOperation';
import {
AdjustComponentOrderLeafOperation,
AdjustComponentOrderLeafOperationContext,
@ -35,6 +39,7 @@ const OperationConstructors: Record<
removeTrait: RemoveTraitLeafOperation,
modifyTraitProperty: ModifyTraitPropertiesLeafOperation,
replaceApp: ReplaceAppLeafOperation,
pasteComponent: PasteComponentBranchOperation,
};
type OperationTypes = keyof OperationConfigMaps;
@ -78,6 +83,11 @@ type OperationConfigMaps = {
ModifyTraitPropertiesLeafOperationContext
>;
replaceApp: OperationConfigMap<ReplaceAppLeafOperation, ReplaceAppLeafOperationContext>;
pasteComponent: OperationConfigMap<
PasteComponentBranchOperation,
PasteComponentBranchOperationContext
>;
};
export const genOperation = <T extends OperationTypes>(