From d6d8ee2f11acd1b01ddb29e4b0efc4c9845fc323 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Fri, 6 Aug 2021 12:04:22 +1000 Subject: [PATCH] Add alt drag duplicate shortcut for tokens, notes and selection --- src/components/map/Map.tsx | 4 +++ src/hooks/useMapNotes.tsx | 30 ++++++++++++++++++ src/hooks/useMapSelection.tsx | 44 +++++++++++++++++++++++++++ src/hooks/useMapTokens.tsx | 31 +++++++++++++++++++ src/network/NetworkedMapAndTokens.tsx | 1 + src/shortcuts.ts | 1 + 6 files changed, 111 insertions(+) diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index 9f31ab5..7c1565d 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -40,6 +40,7 @@ import { SelectionItemsChangeEventHandler, SelectionItemsRemoveEventHandler, SelectionItemsCreateEventHandler, + TokensStateCreateHandler, } from "../../types/Events"; import useMapTokens from "../../hooks/useMapTokens"; @@ -53,6 +54,7 @@ type MapProps = { mapActions: MapActions; onMapTokenStateChange: TokenStateChangeEventHandler; onMapTokenStateRemove: TokenStateRemoveHandler; + onMapTokensStateCreate: TokensStateCreateHandler; onSelectionItemsChange: SelectionItemsChangeEventHandler; onSelectionItemsRemove: SelectionItemsRemoveEventHandler; onSelectionItemsCreate: SelectionItemsCreateEventHandler; @@ -75,6 +77,7 @@ function Map({ mapActions, onMapTokenStateChange, onMapTokenStateRemove, + onMapTokensStateCreate, onSelectionItemsChange, onSelectionItemsRemove, onSelectionItemsCreate, @@ -142,6 +145,7 @@ function Map({ mapState, onMapTokenStateChange, onMapTokenStateRemove, + onMapTokensStateCreate, selectedToolId ); diff --git a/src/hooks/useMapNotes.tsx b/src/hooks/useMapNotes.tsx index 52bf2a0..ee17fb3 100644 --- a/src/hooks/useMapNotes.tsx +++ b/src/hooks/useMapNotes.tsx @@ -1,11 +1,15 @@ import Konva from "konva"; import { KonvaEventObject } from "konva/lib/Node"; import { useState } from "react"; +import { v4 as uuid } from "uuid"; + import Note from "../components/konva/Note"; import NoteDragOverlay from "../components/note/NoteDragOverlay"; import NoteMenu from "../components/note/NoteMenu"; import NoteTool from "../components/tools/NoteTool"; +import { useBlur, useKeyboard } from "../contexts/KeyboardContext"; import { useUserId } from "../contexts/UserIdContext"; +import shortcuts from "../shortcuts"; import { NoteChangeEventHandler, NoteCreateEventHander, @@ -47,6 +51,12 @@ function useMapNotes( } function handleNoteDragStart(_: KonvaEventObject, noteId: string) { + if (duplicateNote) { + const note = mapState?.notes[noteId]; + if (note) { + onNoteCreate([{ ...note, id: uuid() }]); + } + } setNoteDraggingOptions({ dragging: true, noteId }); } @@ -60,6 +70,26 @@ function useMapNotes( setNoteDraggingOptions(undefined); } + const [duplicateNote, setDuplicateNote] = useState(false); + function handleKeyDown(event: KeyboardEvent) { + if (shortcuts.duplicate(event)) { + setDuplicateNote(true); + } + } + + function handleKeyUp(event: KeyboardEvent) { + if (shortcuts.duplicate(event)) { + setDuplicateNote(false); + } + } + + function handleBlur() { + setDuplicateNote(false); + } + + useKeyboard(handleKeyDown, handleKeyUp); + useBlur(handleBlur); + const notes = ( , tokenStateId: string ) { + if (duplicateToken) { + const state = mapState?.tokens[tokenStateId]; + if (state) { + onTokensStateCreate([{ ...state, id: uuid() }]); + } + } setTokenDraggingOptions({ dragging: true, tokenStateId, @@ -76,6 +87,26 @@ function useMapTokens( setTokenDraggingOptions(undefined); } + const [duplicateToken, setDuplicateToken] = useState(false); + function handleKeyDown(event: KeyboardEvent) { + if (shortcuts.duplicate(event)) { + setDuplicateToken(true); + } + } + + function handleKeyUp(event: KeyboardEvent) { + if (shortcuts.duplicate(event)) { + setDuplicateToken(false); + } + } + + function handleBlur() { + setDuplicateToken(false); + } + + useKeyboard(handleKeyDown, handleKeyUp); + useBlur(handleBlur); + function tokenFromTokenState(tokenState: TokenState) { return ( map && ( diff --git a/src/network/NetworkedMapAndTokens.tsx b/src/network/NetworkedMapAndTokens.tsx index b52fa35..997c53e 100644 --- a/src/network/NetworkedMapAndTokens.tsx +++ b/src/network/NetworkedMapAndTokens.tsx @@ -417,6 +417,7 @@ function NetworkedMapAndTokens({ session }: { session: Session }) { mapActions={mapActions} onMapTokenStateChange={handleMapTokenStateChange} onMapTokenStateRemove={handleMapTokenStateRemove} + onMapTokensStateCreate={handleMapTokensStateCreate} onSelectionItemsChange={handleSelectionItemsChange} onSelectionItemsRemove={handleSelectionItemsRemove} onSelectionItemsCreate={handleSelectionItemsCreate} diff --git a/src/shortcuts.ts b/src/shortcuts.ts index 4f596e1..6433aa3 100644 --- a/src/shortcuts.ts +++ b/src/shortcuts.ts @@ -104,6 +104,7 @@ const shortcuts: Record = { paste, delete: ({ key }) => key === "Backspace" || key === "Delete", disableSnapping: ({ key }) => key === "Control" || key === "Meta", + duplicate: ({ key }) => key === "Alt", }; export default shortcuts;