Added owner to map and token keys, added map cache

This commit is contained in:
Mitchell McCaffrey 2020-04-30 11:25:33 +10:00
parent 88b4785307
commit 58bee3085d
4 changed files with 67 additions and 13 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useContext } from "react";
import { Box } from "theme-ui";
import shortid from "shortid";
import SimpleBar from "simplebar-react";
@ -9,10 +9,13 @@ import NumberInput from "../NumberInput";
import { fromEntries } from "../../helpers/shared";
import AuthContext from "../../contexts/AuthContext";
const listTokenClassName = "list-token";
function Tokens({ onCreateMapTokenState, tokens }) {
const [tokenSize, setTokenSize] = useState(1);
const { userId } = useContext(AuthContext);
function handleProxyDragEnd(isOnMap, token) {
if (isOnMap && onCreateMapTokenState) {
@ -20,6 +23,7 @@ function Tokens({ onCreateMapTokenState, tokens }) {
onCreateMapTokenState({
id: shortid.generate(),
tokenId: token.id,
owner: userId,
size: tokenSize,
label: "",
statuses: [],

View File

@ -2,9 +2,9 @@ import Dexie from "dexie";
const db = new Dexie("OwlbearRodeoDB");
db.version(1).stores({
maps: "id",
maps: "id, owner",
states: "mapId",
tokens: "id",
tokens: "id, owner",
user: "key",
});

View File

@ -67,7 +67,8 @@ function SelectMapModal({
id,
owner: userId,
// Emulate the time increasing to avoid sort errors
timestamp: Date.now() + i,
created: Date.now() + i,
lastModified: Date.now() + i,
...defaultMapProps,
});
// Add a state for the map if there isn't one already
@ -80,12 +81,16 @@ function SelectMapModal({
}
async function loadMaps() {
let storedMaps = await db.table("maps").toArray();
let storedMaps = await db
.table("maps")
.where({ owner: userId })
.toArray();
const defaultMapsWithIds = await getDefaultMaps();
const sortedMaps = [...defaultMapsWithIds, ...storedMaps].sort(
(a, b) => a.timestamp - b.timestamp
(a, b) => a.created - b.created
);
setMaps(sortedMaps);
// TODO: Does this work with default maps?
if (selectedMap) {
const map = await db.table("maps").get(selectedMap.id);
const state = await db.table("states").get(selectedMap.id);
@ -147,7 +152,8 @@ function SelectMapModal({
width: image.width,
height: image.height,
id: shortid.generate(),
timestamp: Date.now(),
created: Date.now(),
lastModified: Date.now(),
owner: userId,
...defaultMapProps,
});
@ -246,8 +252,9 @@ function SelectMapModal({
const [showMoreSettings, setShowMoreSettings] = useState(false);
async function handleMapSettingsChange(key, value) {
db.table("maps").update(selectedMap.id, { [key]: value });
const newMap = { ...selectedMap, [key]: value };
const change = { [key]: value, lastModified: Date.now() };
db.table("maps").update(selectedMap.id, change);
const newMap = { ...selectedMap, ...change };
setMaps((prevMaps) => {
const newMaps = [...prevMaps];
const i = newMaps.findIndex((map) => map.id === selectedMap.id);

View File

@ -79,7 +79,18 @@ function Game() {
// Clear the map so the new map state isn't shown on an old map
peer.connection.send({ id: "map", data: null });
peer.connection.send({ id: "mapState", data: newMapState });
peer.connection.send({ id: "map", data: newMap });
sendMapDataToPeer(peer, newMap);
}
}
function sendMapDataToPeer(peer, mapData) {
// Omit file from map change, receiver will request the file if
// they have an outdated version
if (mapData.type === "file") {
const { file, ...rest } = mapData;
peer.connection.send({ id: "map", data: rest });
} else {
peer.connection.send({ id: "map", data: mapData });
}
}
@ -237,14 +248,42 @@ function Game() {
peer.connection.send({ id: "mapState", data: mapState });
}
if (map) {
peer.connection.send({ id: "map", data: map });
sendMapDataToPeer(peer, map);
}
}
if (data.id === "map") {
const newMap = data.data;
// If is a file map check cache and request the full file if outdated
if (newMap && newMap.type === "file") {
db.table("maps")
.get(newMap.id)
.then((cachedMap) => {
if (cachedMap && cachedMap.lastModified === newMap.lastModified) {
setMap(cachedMap);
} else {
peer.connection.send({ id: "mapRequest" });
}
});
} else {
setMap(newMap);
}
}
// Send full map data including file
if (data.id === "mapRequest") {
peer.connection.send({ id: "mapResponse", data: map });
}
// A new map response with a file attached
if (data.id === "mapResponse") {
if (data.data && data.data.type === "file") {
// Convert file back to blob after peer transfer
const file = new Blob([data.data.file]);
setMap({ ...data.data, file });
const newMap = { ...data.data, file };
// Store in db
db.table("maps")
.put(newMap)
.then(() => {
setMap(newMap);
});
} else {
setMap(data.data);
}
@ -387,15 +426,19 @@ function Game() {
*/
const [tokens, setTokens] = useState([]);
useEffect(() => {
if (!userId) {
return;
}
const defaultTokensWithIds = [];
for (let defaultToken of defaultTokens) {
defaultTokensWithIds.push({
...defaultToken,
id: `__default-${defaultToken.name}`,
owner: userId,
});
}
setTokens(defaultTokensWithIds);
}, []);
}, [userId]);
return (
<>