From b4e52ebb237e92d67698299f5e19455d96cecbaf Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Fri, 28 Aug 2020 17:06:13 +1000 Subject: [PATCH] Fixed 2 bugs with map loading and sending When a map was sent the receiver didn't save the resolutions tihs meant that if the original map owner left or wasn't the party leader the map would be blank when new users joined. Also if a map sender left when sending a map and rejoined their version of the map would be overriden by a corrupted version. --- src/components/map/MapInteraction.js | 14 ++++--- src/contexts/MapDataContext.js | 5 +++ src/network/NetworkedMapAndTokens.js | 61 +++++++++++++++++----------- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/components/map/MapInteraction.js b/src/components/map/MapInteraction.js index 60908ff..79e9447 100644 --- a/src/components/map/MapInteraction.js +++ b/src/components/map/MapInteraction.js @@ -31,13 +31,15 @@ function MapInteraction({ disabledControls, }) { let mapSourceMap = map; - if (map && map.type === "file") { - if ( - map.resolutions && - map.quality !== "original" && - map.resolutions[map.quality] - ) { + if (map && map.type === "file" && map.resolutions) { + // Set to the quality if available + if (map.quality !== "original" && map.resolutions[map.quality]) { mapSourceMap = map.resolutions[map.quality]; + } else if (!map.file) { + // If no file fallback to the highest resolution + for (let resolution in map.resolutions) { + mapSourceMap = map.resolutions[resolution]; + } } } diff --git a/src/contexts/MapDataContext.js b/src/contexts/MapDataContext.js index 57bdc71..860b9e5 100644 --- a/src/contexts/MapDataContext.js +++ b/src/contexts/MapDataContext.js @@ -147,6 +147,10 @@ export function MapDataProvider({ children }) { return maps.find((map) => map.id === mapId); } + async function getMapFromDB(mapId) { + return await database.table("maps").get(mapId); + } + const ownedMaps = maps.filter((map) => map.owner === userId); const value = { @@ -160,6 +164,7 @@ export function MapDataProvider({ children }) { updateMapState, putMap, getMap, + getMapFromDB, }; return ( {children} diff --git a/src/network/NetworkedMapAndTokens.js b/src/network/NetworkedMapAndTokens.js index 9355c1e..5405a35 100644 --- a/src/network/NetworkedMapAndTokens.js +++ b/src/network/NetworkedMapAndTokens.js @@ -33,7 +33,7 @@ function NetworkedMapAndTokens({ session }) { } = useContext(MapLoadingContext); const { putToken, getToken } = useContext(TokenDataContext); - const { putMap, getMap } = useContext(MapDataContext); + const { putMap, updateMap, getMapFromDB } = useContext(MapDataContext); const [currentMap, setCurrentMap] = useState(null); const [currentMapState, setCurrentMapState] = useState(null); @@ -243,11 +243,13 @@ function NetworkedMapAndTokens({ session }) { if (id === "map") { const newMap = data; if (newMap && newMap.type === "file") { - const cachedMap = getMap(newMap.id); - if (cachedMap && cachedMap.lastModified === newMap.lastModified) { + const cachedMap = await getMapFromDB(newMap.id); + if (cachedMap && cachedMap.lastModified >= newMap.lastModified) { setCurrentMap(cachedMap); } else { - await putMap(newMap); + // Save map data but remove last modified so if there is an error + // during the map request the cache is invalid + await putMap({ ...newMap, lastModified: 0 }); reply("mapRequest", newMap.id, "map"); } } else { @@ -255,17 +257,29 @@ function NetworkedMapAndTokens({ session }) { } } if (id === "mapRequest") { - const map = getMap(data); + const map = await getMapFromDB(data); - function replyWithFile(file, preview) { + function replyWithPreview(preview) { + if (map.resolutions[preview]) { + reply( + "mapResponse", + { + id: map.id, + resolutions: { [preview]: map.resolutions[preview] }, + }, + "map" + ); + } + } + + function replyWithFile(file) { reply( "mapResponse", { - ...map, + id: map.id, file, - resolutions: {}, - // If preview don't send the last modified so that it will not be cached - lastModified: preview ? 0 : map.lastModified, + // Add last modified back to file to set cache as valid + lastModified: map.lastModified, }, "map" ); @@ -273,35 +287,36 @@ function NetworkedMapAndTokens({ session }) { switch (map.quality) { case "low": - replyWithFile(map.resolutions.low.file, false); + replyWithFile(map.resolutions.low.file); break; case "medium": - replyWithFile(map.resolutions.low.file, true); - replyWithFile(map.resolutions.medium.file, false); + replyWithPreview("low"); + replyWithFile(map.resolutions.medium.file); break; case "high": - replyWithFile(map.resolutions.medium.file, true); - replyWithFile(map.resolutions.high.file, false); + replyWithPreview("medium"); + replyWithFile(map.resolutions.high.file); break; case "ultra": - replyWithFile(map.resolutions.medium.file, true); - replyWithFile(map.resolutions.ultra.file, false); + replyWithPreview("medium"); + replyWithFile(map.resolutions.ultra.file); break; case "original": if (map.resolutions.medium) { - replyWithFile(map.resolutions.medium.file, true); + replyWithPreview("medium"); } else if (map.resolutions.low) { - replyWithFile(map.resolutions.low.file, true); + replyWithPreview("low"); } - replyWithFile(map.file, false); + replyWithFile(map.file); break; default: - replyWithFile(map.file, false); + replyWithFile(map.file); } } if (id === "mapResponse") { - await putMap(data); - setCurrentMap(data); + await updateMap(data.id, data); + const newMap = await getMapFromDB(data.id); + setCurrentMap(newMap); } if (id === "mapState") { setCurrentMapState(data);