From 1d5cf77aeabee55dd4e3e9f8b0c19546a5320bd7 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Fri, 16 Apr 2021 13:36:14 +1000 Subject: [PATCH] Fixed bug with corrupted map state on token deletion --- src/components/map/Map.js | 1 - src/components/map/MapToken.js | 3 --- src/components/map/MapTokens.js | 1 - src/components/token/TokenDragOverlay.js | 2 -- src/components/token/TokenMenu.js | 14 +++++------- src/helpers/diff.js | 11 +++++++++- src/network/NetworkedMapAndTokens.js | 28 +++++++++++++++++------- 7 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/components/map/Map.js b/src/components/map/Map.js index 19ad2be..340749e 100644 --- a/src/components/map/Map.js +++ b/src/components/map/Map.js @@ -209,7 +209,6 @@ function Map({ tokenGroup={tokenDraggingOptions && tokenDraggingOptions.tokenGroup} dragging={!!(tokenDraggingOptions && tokenDraggingOptions.dragging)} token={tokensById[tokenDraggingOptions.tokenState.tokenId]} - mapState={mapState} /> ); diff --git a/src/components/map/MapToken.js b/src/components/map/MapToken.js index 9885721..1f7258f 100644 --- a/src/components/map/MapToken.js +++ b/src/components/map/MapToken.js @@ -31,7 +31,6 @@ function MapToken({ onTokenDragStart, onTokenDragEnd, draggable, - mapState, fadeOnHover, map, }) { @@ -111,7 +110,6 @@ function MapToken({ mountedToken.moveTo(parent); mountedToken.absolutePosition(position); mountChanges[mountedToken.id()] = { - ...mapState.tokens[mountedToken.id()], x: mountedToken.x() / mapWidth, y: mountedToken.y() / mapHeight, lastModifiedBy: userId, @@ -124,7 +122,6 @@ function MapToken({ onTokenStateChange({ ...mountChanges, [tokenState.id]: { - ...tokenState, x: tokenGroup.x() / mapWidth, y: tokenGroup.y() / mapHeight, lastModifiedBy: userId, diff --git a/src/components/map/MapTokens.js b/src/components/map/MapTokens.js index 3949c30..426dcfe 100644 --- a/src/components/map/MapTokens.js +++ b/src/components/map/MapTokens.js @@ -119,7 +119,6 @@ function MapTokens({ !(tokenState.id in disabledTokens) && !tokenState.locked } - mapState={mapState} fadeOnHover={selectedToolId === "drawing"} map={map} /> diff --git a/src/components/token/TokenDragOverlay.js b/src/components/token/TokenDragOverlay.js index 721d05d..d5d9348 100644 --- a/src/components/token/TokenDragOverlay.js +++ b/src/components/token/TokenDragOverlay.js @@ -15,7 +15,6 @@ function TokenDragOverlay({ tokenState, tokenGroup, dragging, - mapState, }) { const { userId } = useAuth(); @@ -34,7 +33,6 @@ function TokenDragOverlay({ mountedToken.absolutePosition(position); onTokenStateChange({ [mountedToken.id()]: { - ...mapState.tokens[mountedToken.id()], x: mountedToken.x() / mapWidth, y: mountedToken.y() / mapHeight, lastModifiedBy: userId, diff --git a/src/components/token/TokenMenu.js b/src/components/token/TokenMenu.js index d319082..9f4b024 100644 --- a/src/components/token/TokenMenu.js +++ b/src/components/token/TokenMenu.js @@ -51,8 +51,7 @@ function TokenMenu({ function handleLabelChange(event) { const label = event.target.value.substring(0, 144); - tokenState && - onTokenStateChange({ [tokenState.id]: { ...tokenState, label: label } }); + tokenState && onTokenStateChange({ [tokenState.id]: { label: label } }); } function handleStatusChange(status) { @@ -66,35 +65,34 @@ function TokenMenu({ statuses.add(status); } onTokenStateChange({ - [tokenState.id]: { ...tokenState, statuses: [...statuses] }, + [tokenState.id]: { statuses: [...statuses] }, }); } function handleSizeChange(event) { const newSize = parseFloat(event.target.value); - tokenState && - onTokenStateChange({ [tokenState.id]: { ...tokenState, size: newSize } }); + tokenState && onTokenStateChange({ [tokenState.id]: { size: newSize } }); } function handleRotationChange(event) { const newRotation = parseInt(event.target.value); tokenState && onTokenStateChange({ - [tokenState.id]: { ...tokenState, rotation: newRotation }, + [tokenState.id]: { rotation: newRotation }, }); } function handleVisibleChange() { tokenState && onTokenStateChange({ - [tokenState.id]: { ...tokenState, visible: !tokenState.visible }, + [tokenState.id]: { visible: !tokenState.visible }, }); } function handleLockChange() { tokenState && onTokenStateChange({ - [tokenState.id]: { ...tokenState, locked: !tokenState.locked }, + [tokenState.id]: { locked: !tokenState.locked }, }); } diff --git a/src/helpers/diff.js b/src/helpers/diff.js index bb36900..c1b503a 100644 --- a/src/helpers/diff.js +++ b/src/helpers/diff.js @@ -1,8 +1,17 @@ import { applyChange, revertChange, diff as deepDiff } from "deep-diff"; +import get from "lodash.get"; export function applyChanges(target, changes) { for (let change of changes) { - applyChange(target, true, change); + if (change.path && (change.kind === "E" || change.kind === "A")) { + // If editing an object or array ensure that the value exists + const valid = get(target, change.path) !== undefined; + if (valid) { + applyChange(target, true, change); + } + } else { + applyChange(target, true, change); + } } } diff --git a/src/network/NetworkedMapAndTokens.js b/src/network/NetworkedMapAndTokens.js index 68e1b59..d38413a 100644 --- a/src/network/NetworkedMapAndTokens.js +++ b/src/network/NetworkedMapAndTokens.js @@ -377,20 +377,32 @@ function NetworkedMapAndTokens({ session }) { const { id, lastModified, owner } = token; addAssetIfNeeded({ type: "token", id, lastModified, owner }); } - handleMapTokenStateChange({ [tokenState.id]: tokenState }); + setCurrentMapState((prevMapState) => ({ + ...prevMapState, + tokens: { + ...prevMapState.tokens, + [tokenState.id]: tokenState, + }, + })); } function handleMapTokenStateChange(change) { if (!currentMapState) { return; } - setCurrentMapState((prevMapState) => ({ - ...prevMapState, - tokens: { - ...prevMapState.tokens, - ...change, - }, - })); + setCurrentMapState((prevMapState) => { + let tokens = { ...prevMapState.tokens }; + for (let id in change) { + if (id in tokens) { + tokens[id] = { ...tokens[id], ...change[id] }; + } + } + + return { + ...prevMapState, + tokens, + }; + }); } function handleMapTokenStateRemove(tokenState) {