Skip to content

Commit 0a0bc47

Browse files
committed
feat: Commit moves before running keyboard shortcuts.
1 parent 2fd7671 commit 0a0bc47

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/actions/mover.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
registry,
1919
utils,
2020
WorkspaceSvg,
21+
ShortcutRegistry,
2122
} from 'blockly';
2223
import * as Constants from '../constants';
2324
import {Direction, getXYFromDirection} from '../drag_direction';
@@ -36,6 +37,11 @@ const UNCONSTRAINED_MOVE_DISTANCE = 20;
3637
*/
3738
const CONSTRAINED_ADDITIONAL_PADDING = 70;
3839

40+
/**
41+
* Identifier for a keyboard shortcut that commits the in-progress move.
42+
*/
43+
const COMMIT_MOVE_SHORTCUT = 'commitMove';
44+
3945
/**
4046
* Low-level code for moving blocks with keyboard shortcuts.
4147
*/
@@ -140,6 +146,47 @@ export class Mover {
140146
// (otherwise dragging will break).
141147
getFocusManager().focusNode(block);
142148
block.getFocusableElement().addEventListener('blur', blurListener);
149+
150+
// Register a keyboard shortcut under the key combos of all existing
151+
// keyboard shortcuts that commits the move before allowing the real
152+
// shortcut to proceed. This avoids all kinds of fun brokenness when
153+
// deleting/copying/otherwise acting on a block in move mode.
154+
const shortcutKeys = Object.values(ShortcutRegistry.registry.getRegistry())
155+
.flatMap((shortcut) => shortcut.keyCodes)
156+
.filter((keyCode) => {
157+
return (
158+
keyCode &&
159+
![
160+
utils.KeyCodes.RIGHT,
161+
utils.KeyCodes.LEFT,
162+
utils.KeyCodes.UP,
163+
utils.KeyCodes.DOWN,
164+
utils.KeyCodes.ENTER,
165+
].includes(
166+
typeof keyCode === 'number'
167+
? keyCode
168+
: parseInt(`${keyCode.split('+').pop()}`),
169+
)
170+
);
171+
})
172+
// Convince TS there aren't undefined values.
173+
.filter((keyCode): keyCode is string | number => !!keyCode);
174+
175+
const commitMoveShortcut = {
176+
name: COMMIT_MOVE_SHORTCUT,
177+
preconditionFn: (workspace: WorkspaceSvg) => {
178+
return !!this.moves.get(workspace);
179+
},
180+
callback: (workspace: WorkspaceSvg) => {
181+
this.finishMove(workspace);
182+
return false;
183+
},
184+
keyCodes: shortcutKeys,
185+
allowCollision: true,
186+
};
187+
188+
ShortcutRegistry.registry.register(commitMoveShortcut);
189+
143190
return true;
144191
}
145192

@@ -152,6 +199,8 @@ export class Mover {
152199
* @returns True iff move successfully finished.
153200
*/
154201
finishMove(workspace: WorkspaceSvg) {
202+
ShortcutRegistry.registry.unregister(COMMIT_MOVE_SHORTCUT);
203+
155204
clearMoveHints(workspace);
156205

157206
const info = this.moves.get(workspace);

0 commit comments

Comments
 (0)