Added token edit modal, refactored map and token data providers
Refactored image drop code into reusable component as well
This commit is contained in:
146
src/contexts/MapDataContext.js
Normal file
146
src/contexts/MapDataContext.js
Normal file
@@ -0,0 +1,146 @@
|
||||
import React, { useEffect, useState, useContext } from "react";
|
||||
|
||||
import AuthContext from "./AuthContext";
|
||||
import DatabaseContext from "./DatabaseContext";
|
||||
|
||||
import { maps as defaultMaps } from "../maps";
|
||||
|
||||
const MapDataContext = React.createContext();
|
||||
|
||||
const defaultMapState = {
|
||||
tokens: {},
|
||||
// An index into the draw actions array to which only actions before the
|
||||
// index will be performed (used in undo and redo)
|
||||
mapDrawActionIndex: -1,
|
||||
mapDrawActions: [],
|
||||
fogDrawActionIndex: -1,
|
||||
fogDrawActions: [],
|
||||
// Flags to determine what other people can edit
|
||||
editFlags: ["drawing", "tokens"],
|
||||
};
|
||||
|
||||
export function MapDataProvider({ children }) {
|
||||
const { database } = useContext(DatabaseContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
|
||||
const [maps, setMaps] = useState([]);
|
||||
const [mapStates, setMapStates] = useState([]);
|
||||
// Load maps from the database and ensure state is properly setup
|
||||
useEffect(() => {
|
||||
if (!userId || !database) {
|
||||
return;
|
||||
}
|
||||
async function getDefaultMaps() {
|
||||
const defaultMapsWithIds = [];
|
||||
for (let i = 0; i < defaultMaps.length; i++) {
|
||||
const defaultMap = defaultMaps[i];
|
||||
const id = `__default-${defaultMap.name}`;
|
||||
defaultMapsWithIds.push({
|
||||
...defaultMap,
|
||||
id,
|
||||
owner: userId,
|
||||
// Emulate the time increasing to avoid sort errors
|
||||
created: Date.now() + i,
|
||||
lastModified: Date.now() + i,
|
||||
gridType: "grid",
|
||||
});
|
||||
// Add a state for the map if there isn't one already
|
||||
const state = await database.table("states").get(id);
|
||||
if (!state) {
|
||||
await database.table("states").add({ ...defaultMapState, mapId: id });
|
||||
}
|
||||
}
|
||||
return defaultMapsWithIds;
|
||||
}
|
||||
|
||||
async function loadMaps() {
|
||||
let storedMaps = await database
|
||||
.table("maps")
|
||||
.where({ owner: userId })
|
||||
.toArray();
|
||||
const sortedMaps = storedMaps.sort((a, b) => b.created - a.created);
|
||||
const defaultMapsWithIds = await getDefaultMaps();
|
||||
const allMaps = [...sortedMaps, ...defaultMapsWithIds];
|
||||
setMaps(allMaps);
|
||||
const storedStates = await database.table("states").toArray();
|
||||
setMapStates(storedStates);
|
||||
}
|
||||
|
||||
loadMaps();
|
||||
}, [userId, database]);
|
||||
|
||||
async function addMap(map) {
|
||||
await database.table("maps").add(map);
|
||||
const state = { ...defaultMapState, mapId: map.id };
|
||||
await database.table("states").add(state);
|
||||
setMaps((prevMaps) => [map, ...prevMaps]);
|
||||
setMapStates((prevStates) => [state, ...prevStates]);
|
||||
}
|
||||
|
||||
async function removeMap(id) {
|
||||
await database.table("maps").delete(id);
|
||||
await database.table("states").delete(id);
|
||||
setMaps((prevMaps) => {
|
||||
const filtered = prevMaps.filter((map) => map.id !== id);
|
||||
return filtered;
|
||||
});
|
||||
setMapStates((prevMapsStates) => {
|
||||
const filtered = prevMapsStates.filter((state) => state.mapId !== id);
|
||||
return filtered;
|
||||
});
|
||||
}
|
||||
|
||||
async function resetMap(id) {
|
||||
const state = { ...defaultMapState, mapId: id };
|
||||
await database.table("states").put(state);
|
||||
setMapStates((prevMapStates) => {
|
||||
const newStates = [...prevMapStates];
|
||||
const i = newStates.findIndex((state) => state.mapId === id);
|
||||
if (i > -1) {
|
||||
newStates[i] = state;
|
||||
}
|
||||
return newStates;
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
async function updateMap(id, update) {
|
||||
const change = { ...update, lastModified: Date.now() };
|
||||
await database.table("maps").update(id, change);
|
||||
setMaps((prevMaps) => {
|
||||
const newMaps = [...prevMaps];
|
||||
const i = newMaps.findIndex((map) => map.id === id);
|
||||
if (i > -1) {
|
||||
newMaps[i] = { ...newMaps[i], ...change };
|
||||
}
|
||||
return newMaps;
|
||||
});
|
||||
}
|
||||
|
||||
async function updateMapState(id, update) {
|
||||
await database.table("states").update(id, update);
|
||||
setMapStates((prevMapStates) => {
|
||||
const newStates = [...prevMapStates];
|
||||
const i = newStates.findIndex((state) => state.mapId === id);
|
||||
if (i > -1) {
|
||||
newStates[i] = { ...newStates[i], ...update };
|
||||
}
|
||||
return newStates;
|
||||
});
|
||||
}
|
||||
|
||||
const value = {
|
||||
maps,
|
||||
mapStates,
|
||||
addMap,
|
||||
removeMap,
|
||||
resetMap,
|
||||
updateMap,
|
||||
updateMapState,
|
||||
};
|
||||
return (
|
||||
<MapDataContext.Provider value={value}>{children}</MapDataContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default MapDataContext;
|
||||
Reference in New Issue
Block a user