diff --git a/package.json b/package.json
index e700bdd..927f659 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"comlink": "^4.3.0",
"deep-diff": "^1.0.2",
"dexie": "^3.0.3",
+ "dexie-observable": "^3.0.0-beta.10",
"err-code": "^2.0.3",
"fake-indexeddb": "^3.1.2",
"file-saver": "^2.0.5",
diff --git a/src/contexts/MapDataContext.js b/src/contexts/MapDataContext.js
index d804568..8c45a2f 100644
--- a/src/contexts/MapDataContext.js
+++ b/src/contexts/MapDataContext.js
@@ -112,6 +112,14 @@ export function MapDataProvider({ children }) {
[database]
);
+ const getMapStateFromDB = useCallback(
+ async (mapId) => {
+ let mapState = await database.table("states").get(mapId);
+ return mapState;
+ },
+ [database]
+ );
+
/**
* Keep up to cachedMapMax amount of maps that you don't own
* Sorted by when they we're last used
@@ -140,11 +148,10 @@ export function MapDataProvider({ children }) {
*/
const addMap = useCallback(
async (map) => {
- await database.table("maps").add(map);
+ // Just update map database as react state will be updated with an Observable
const state = { ...defaultMapState, mapId: map.id };
+ await database.table("maps").add(map);
await database.table("states").add(state);
- setMaps((prevMaps) => [map, ...prevMaps]);
- setMapStates((prevStates) => [state, ...prevStates]);
if (map.owner !== userId) {
await updateCache();
}
@@ -156,14 +163,6 @@ export function MapDataProvider({ children }) {
async (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;
- });
},
[database]
);
@@ -172,16 +171,6 @@ export function MapDataProvider({ children }) {
async (ids) => {
await database.table("maps").bulkDelete(ids);
await database.table("states").bulkDelete(ids);
- setMaps((prevMaps) => {
- const filtered = prevMaps.filter((map) => !ids.includes(map.id));
- return filtered;
- });
- setMapStates((prevMapsStates) => {
- const filtered = prevMapsStates.filter(
- (state) => !ids.includes(state.mapId)
- );
- return filtered;
- });
},
[database]
);
@@ -284,6 +273,46 @@ export function MapDataProvider({ children }) {
[database, updateCache, userId]
);
+ // Create DB observable to sync creating and deleting
+ useEffect(() => {
+ if (!database || databaseStatus === "loading") {
+ return;
+ }
+
+ function handleMapChanges(changes) {
+ for (let change of changes) {
+ if (change.table === "maps") {
+ if (change.type === 1) {
+ // Created
+ const map = change.obj;
+ const state = { ...defaultMapState, mapId: map.id };
+ setMaps((prevMaps) => [map, ...prevMaps]);
+ setMapStates((prevStates) => [state, ...prevStates]);
+ } else if (change.type === 3) {
+ // Deleted
+ const id = change.key;
+ setMaps((prevMaps) => {
+ const filtered = prevMaps.filter((map) => map.id !== id);
+ return filtered;
+ });
+ setMapStates((prevMapsStates) => {
+ const filtered = prevMapsStates.filter(
+ (state) => state.mapId !== id
+ );
+ return filtered;
+ });
+ }
+ }
+ }
+ }
+
+ database.on("changes", handleMapChanges);
+
+ return () => {
+ database.on("changes").unsubscribe(handleMapChanges);
+ };
+ }, [database, databaseStatus]);
+
const ownedMaps = maps.filter((map) => map.owner === userId);
const value = {
@@ -301,6 +330,7 @@ export function MapDataProvider({ children }) {
getMap,
getMapFromDB,
mapsLoading,
+ getMapStateFromDB,
};
return (
{children}
diff --git a/src/contexts/TokenDataContext.js b/src/contexts/TokenDataContext.js
index 03c52fc..b87166c 100644
--- a/src/contexts/TokenDataContext.js
+++ b/src/contexts/TokenDataContext.js
@@ -115,7 +115,6 @@ export function TokenDataProvider({ children }) {
const addToken = useCallback(
async (token) => {
await database.table("tokens").add(token);
- setTokens((prevTokens) => [token, ...prevTokens]);
if (token.owner !== userId) {
await updateCache();
}
@@ -126,10 +125,6 @@ export function TokenDataProvider({ children }) {
const removeToken = useCallback(
async (id) => {
await database.table("tokens").delete(id);
- setTokens((prevTokens) => {
- const filtered = prevTokens.filter((token) => token.id !== id);
- return filtered;
- });
},
[database]
);
@@ -137,10 +132,6 @@ export function TokenDataProvider({ children }) {
const removeTokens = useCallback(
async (ids) => {
await database.table("tokens").bulkDelete(ids);
- setTokens((prevTokens) => {
- const filtered = prevTokens.filter((token) => !ids.includes(token.id));
- return filtered;
- });
},
[database]
);
@@ -230,6 +221,38 @@ export function TokenDataProvider({ children }) {
});
}, []);
+ // Create DB observable to sync creating and deleting
+ useEffect(() => {
+ if (!database || databaseStatus === "loading") {
+ return;
+ }
+
+ function handleMapChanges(changes) {
+ for (let change of changes) {
+ if (change.table === "tokens") {
+ if (change.type === 1) {
+ // Created
+ const token = change.obj;
+ setTokens((prevTokens) => [token, ...prevTokens]);
+ } else if (change.type === 3) {
+ // Deleted
+ const id = change.key;
+ setTokens((prevTokens) => {
+ const filtered = prevTokens.filter((token) => token.id !== id);
+ return filtered;
+ });
+ }
+ }
+ }
+ }
+
+ database.on("changes", handleMapChanges);
+
+ return () => {
+ database.on("changes").unsubscribe(handleMapChanges);
+ };
+ }, [database, databaseStatus]);
+
const ownedTokens = tokens.filter((token) => token.owner === userId);
const tokensById = tokens.reduce((obj, token) => {
diff --git a/src/database.js b/src/database.js
index 9a8b84d..7a9c4d6 100644
--- a/src/database.js
+++ b/src/database.js
@@ -1,5 +1,6 @@
// eslint-disable-next-line no-unused-vars
import Dexie, { Version, DexieOptions } from "dexie";
+import "dexie-observable";
import blobToBuffer from "./helpers/blobToBuffer";
import { getGridDefaultInset } from "./helpers/grid";
@@ -391,9 +392,13 @@ const versions = {
});
});
},
+ // 1.8.0 - Upgrade for Dexie.Observable
+ 21(v) {
+ v.stores({});
+ },
};
-const latestVersion = 20;
+const latestVersion = 21;
/**
* Load versions onto a database up to a specific version number
diff --git a/src/modals/EditMapModal.js b/src/modals/EditMapModal.js
index a89ade8..ad38c8c 100644
--- a/src/modals/EditMapModal.js
+++ b/src/modals/EditMapModal.js
@@ -147,7 +147,7 @@ function EditMapModal({ isOpen, onDone, mapId }) {
- {isLoading ? (
+ {isLoading || !map ? (
Edit token
- {isLoading ? (
+ {isLoading || !token ? (