From 6c1d9528550103aac76f256ce4fddf060eb9c1bb Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Tue, 3 Nov 2020 17:15:39 +1100 Subject: [PATCH] Added basic persistance to notes --- src/components/map/Map.js | 4 ++ src/components/map/MapNote.js | 31 +++++++++++++ src/components/map/MapNotes.js | 66 +++++++++++++++++----------- src/database.js | 11 +++++ src/network/NetworkedMapAndTokens.js | 21 +++++++++ 5 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 src/components/map/MapNote.js diff --git a/src/components/map/Map.js b/src/components/map/Map.js index 7a35759..05f806d 100644 --- a/src/components/map/Map.js +++ b/src/components/map/Map.js @@ -33,6 +33,7 @@ function Map({ onFogDraw, onFogDrawUndo, onFogDrawRedo, + onMapNoteAdd, allowMapDrawing, allowFogDrawing, allowMapChange, @@ -356,6 +357,9 @@ function Map({ active={selectedToolId === "note"} gridSize={gridSizeNormalized} selectedToolSettings={settings[selectedToolId]} + onNoteAdd={onMapNoteAdd} + // TODO: Sort by last modified + notes={mapState ? Object.values(mapState.notes) : []} /> ); diff --git a/src/components/map/MapNote.js b/src/components/map/MapNote.js new file mode 100644 index 0000000..bd95179 --- /dev/null +++ b/src/components/map/MapNote.js @@ -0,0 +1,31 @@ +import React, { useContext } from "react"; +import { Group, Rect } from "react-konva"; + +import MapInteractionContext from "../../contexts/MapInteractionContext"; + +function MapNote({ note, map }) { + const { mapWidth, mapHeight } = useContext(MapInteractionContext); + + const noteWidth = map && (mapWidth / map.grid.size.x) * note.size; + const noteHeight = map && (mapHeight / map.grid.size.y) * note.size; + + return ( + + + + ); +} + +export default MapNote; diff --git a/src/components/map/MapNotes.js b/src/components/map/MapNotes.js index 8d3ba34..64a0463 100644 --- a/src/components/map/MapNotes.js +++ b/src/components/map/MapNotes.js @@ -1,21 +1,31 @@ import React, { useContext, useState, useEffect } from "react"; -import { Group, Rect } from "react-konva"; +import shortid from "shortid"; +import { Group } from "react-konva"; import MapInteractionContext from "../../contexts/MapInteractionContext"; import MapStageContext from "../../contexts/MapStageContext"; +import AuthContext from "../../contexts/AuthContext"; import { getBrushPositionForTool } from "../../helpers/drawing"; import { getRelativePointerPositionNormalized } from "../../helpers/konva"; +import MapNote from "./MapNote"; + const defaultNoteSize = 2; -function MapNotes({ map, selectedToolSettings, active, gridSize }) { - const { mapWidth, mapHeight, interactionEmitter } = useContext( - MapInteractionContext - ); +function MapNotes({ + map, + selectedToolSettings, + active, + gridSize, + onNoteAdd, + notes, +}) { + const { interactionEmitter } = useContext(MapInteractionContext); + const { userId } = useContext(AuthContext); const mapStageRef = useContext(MapStageContext); const [isBrushDown, setIsBrushDown] = useState(false); - const [brushPosition, setBrushPosition] = useState({ x: 0, y: 0 }); + const [noteData, setNoteData] = useState(null); useEffect(() => { if (!active) { @@ -36,17 +46,34 @@ function MapNotes({ map, selectedToolSettings, active, gridSize }) { } function handleBrushDown() { - setBrushPosition(getBrushPosition()); + const brushPosition = getBrushPosition(); + setNoteData({ + x: brushPosition.x, + y: brushPosition.y, + size: defaultNoteSize, + text: "", + id: shortid.generate(), + lastModified: Date.now(), + lastModifiedBy: userId, + visible: true, + locked: false, + }); setIsBrushDown(true); } function handleBrushMove() { - setBrushPosition(getBrushPosition()); + const brushPosition = getBrushPosition(); + setNoteData((prev) => ({ + ...prev, + x: brushPosition.x, + y: brushPosition.y, + })); setIsBrushDown(true); } function handleBrushUp() { - setBrushPosition({ x: 0, y: 0 }); + onNoteAdd(noteData); + setNoteData(null); setIsBrushDown(false); } @@ -61,25 +88,12 @@ function MapNotes({ map, selectedToolSettings, active, gridSize }) { }; }); - const noteWidth = map && (mapWidth / map.grid.size.x) * defaultNoteSize; - const noteHeight = map && (mapHeight / map.grid.size.y) * defaultNoteSize; - return ( - {isBrushDown && ( - - )} + {notes.map((note) => ( + + ))} + {isBrushDown && noteData && } ); } diff --git a/src/database.js b/src/database.js index 8c233fd..91cf035 100644 --- a/src/database.js +++ b/src/database.js @@ -268,6 +268,17 @@ function loadVersions(db) { token.height = tokenSizes[token.id].height; }); }); + // v1.7.0 - Added note tool + db.version(16) + .stores({}) + .upgrade((tx) => { + return tx + .table("states") + .toCollection() + .modify((state) => { + state.notes = {}; + }); + }); } // Get the dexie database used in DatabaseContext diff --git a/src/network/NetworkedMapAndTokens.js b/src/network/NetworkedMapAndTokens.js index 0640690..98c992a 100644 --- a/src/network/NetworkedMapAndTokens.js +++ b/src/network/NetworkedMapAndTokens.js @@ -167,6 +167,17 @@ function NetworkedMapAndTokens({ session }) { session.send("mapFogIndex", index); } + function handleNoteAdd(note) { + setCurrentMapState((prevMapState) => ({ + ...prevMapState, + notes: { + ...prevMapState.notes, + [note.id]: note, + }, + })); + session.send("mapNoteAdd", note); + } + /** * Token state */ @@ -395,6 +406,15 @@ function NetworkedMapAndTokens({ session }) { fogDrawActionIndex: data, })); } + if (id === "mapNoteAdd" && currentMapState) { + setCurrentMapState((prevMapState) => ({ + ...prevMapState, + notes: { + ...prevMapState.notes, + [data.id]: data, + }, + })); + } } function handlePeerDataProgress({ id, total, count }) { @@ -460,6 +480,7 @@ function NetworkedMapAndTokens({ session }) { onFogDraw={handleFogDraw} onFogDrawUndo={handleFogDrawUndo} onFogDrawRedo={handleFogDrawRedo} + onMapNoteAdd={handleNoteAdd} allowMapDrawing={canEditMapDrawing} allowFogDrawing={canEditFogDrawing} allowMapChange={canChangeMap}