Moved add/remove maps/tokens to Observables to allow for cross session syncing
This commit is contained in:
parent
265472311e
commit
cf9e428447
@ -19,6 +19,7 @@
|
|||||||
"comlink": "^4.3.0",
|
"comlink": "^4.3.0",
|
||||||
"deep-diff": "^1.0.2",
|
"deep-diff": "^1.0.2",
|
||||||
"dexie": "^3.0.3",
|
"dexie": "^3.0.3",
|
||||||
|
"dexie-observable": "^3.0.0-beta.10",
|
||||||
"err-code": "^2.0.3",
|
"err-code": "^2.0.3",
|
||||||
"fake-indexeddb": "^3.1.2",
|
"fake-indexeddb": "^3.1.2",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
@ -112,6 +112,14 @@ export function MapDataProvider({ children }) {
|
|||||||
[database]
|
[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
|
* Keep up to cachedMapMax amount of maps that you don't own
|
||||||
* Sorted by when they we're last used
|
* Sorted by when they we're last used
|
||||||
@ -140,11 +148,10 @@ export function MapDataProvider({ children }) {
|
|||||||
*/
|
*/
|
||||||
const addMap = useCallback(
|
const addMap = useCallback(
|
||||||
async (map) => {
|
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 };
|
const state = { ...defaultMapState, mapId: map.id };
|
||||||
|
await database.table("maps").add(map);
|
||||||
await database.table("states").add(state);
|
await database.table("states").add(state);
|
||||||
setMaps((prevMaps) => [map, ...prevMaps]);
|
|
||||||
setMapStates((prevStates) => [state, ...prevStates]);
|
|
||||||
if (map.owner !== userId) {
|
if (map.owner !== userId) {
|
||||||
await updateCache();
|
await updateCache();
|
||||||
}
|
}
|
||||||
@ -156,14 +163,6 @@ export function MapDataProvider({ children }) {
|
|||||||
async (id) => {
|
async (id) => {
|
||||||
await database.table("maps").delete(id);
|
await database.table("maps").delete(id);
|
||||||
await database.table("states").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]
|
[database]
|
||||||
);
|
);
|
||||||
@ -172,16 +171,6 @@ export function MapDataProvider({ children }) {
|
|||||||
async (ids) => {
|
async (ids) => {
|
||||||
await database.table("maps").bulkDelete(ids);
|
await database.table("maps").bulkDelete(ids);
|
||||||
await database.table("states").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]
|
[database]
|
||||||
);
|
);
|
||||||
@ -284,6 +273,46 @@ export function MapDataProvider({ children }) {
|
|||||||
[database, updateCache, userId]
|
[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 ownedMaps = maps.filter((map) => map.owner === userId);
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
@ -301,6 +330,7 @@ export function MapDataProvider({ children }) {
|
|||||||
getMap,
|
getMap,
|
||||||
getMapFromDB,
|
getMapFromDB,
|
||||||
mapsLoading,
|
mapsLoading,
|
||||||
|
getMapStateFromDB,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<MapDataContext.Provider value={value}>{children}</MapDataContext.Provider>
|
<MapDataContext.Provider value={value}>{children}</MapDataContext.Provider>
|
||||||
|
@ -115,7 +115,6 @@ export function TokenDataProvider({ children }) {
|
|||||||
const addToken = useCallback(
|
const addToken = useCallback(
|
||||||
async (token) => {
|
async (token) => {
|
||||||
await database.table("tokens").add(token);
|
await database.table("tokens").add(token);
|
||||||
setTokens((prevTokens) => [token, ...prevTokens]);
|
|
||||||
if (token.owner !== userId) {
|
if (token.owner !== userId) {
|
||||||
await updateCache();
|
await updateCache();
|
||||||
}
|
}
|
||||||
@ -126,10 +125,6 @@ export function TokenDataProvider({ children }) {
|
|||||||
const removeToken = useCallback(
|
const removeToken = useCallback(
|
||||||
async (id) => {
|
async (id) => {
|
||||||
await database.table("tokens").delete(id);
|
await database.table("tokens").delete(id);
|
||||||
setTokens((prevTokens) => {
|
|
||||||
const filtered = prevTokens.filter((token) => token.id !== id);
|
|
||||||
return filtered;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
[database]
|
[database]
|
||||||
);
|
);
|
||||||
@ -137,10 +132,6 @@ export function TokenDataProvider({ children }) {
|
|||||||
const removeTokens = useCallback(
|
const removeTokens = useCallback(
|
||||||
async (ids) => {
|
async (ids) => {
|
||||||
await database.table("tokens").bulkDelete(ids);
|
await database.table("tokens").bulkDelete(ids);
|
||||||
setTokens((prevTokens) => {
|
|
||||||
const filtered = prevTokens.filter((token) => !ids.includes(token.id));
|
|
||||||
return filtered;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
[database]
|
[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 ownedTokens = tokens.filter((token) => token.owner === userId);
|
||||||
|
|
||||||
const tokensById = tokens.reduce((obj, token) => {
|
const tokensById = tokens.reduce((obj, token) => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
import Dexie, { Version, DexieOptions } from "dexie";
|
import Dexie, { Version, DexieOptions } from "dexie";
|
||||||
|
import "dexie-observable";
|
||||||
|
|
||||||
import blobToBuffer from "./helpers/blobToBuffer";
|
import blobToBuffer from "./helpers/blobToBuffer";
|
||||||
import { getGridDefaultInset } from "./helpers/grid";
|
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
|
* Load versions onto a database up to a specific version number
|
||||||
|
@ -147,7 +147,7 @@ function EditMapModal({ isOpen, onDone, mapId }) {
|
|||||||
<Label pt={2} pb={1}>
|
<Label pt={2} pb={1}>
|
||||||
Edit map
|
Edit map
|
||||||
</Label>
|
</Label>
|
||||||
{isLoading ? (
|
{isLoading || !map ? (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
@ -84,7 +84,7 @@ function EditTokenModal({ isOpen, onDone, tokenId }) {
|
|||||||
<Label pt={2} pb={1}>
|
<Label pt={2} pb={1}>
|
||||||
Edit token
|
Edit token
|
||||||
</Label>
|
</Label>
|
||||||
{isLoading ? (
|
{isLoading || !token ? (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
@ -160,7 +160,6 @@ function ImportExportModal({ isOpen, onRequestClose }) {
|
|||||||
db.close();
|
db.close();
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
backgroundTaskRunningRef.current = false;
|
backgroundTaskRunningRef.current = false;
|
||||||
window.location.reload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportSelectorFilter(table, value) {
|
function exportSelectorFilter(table, value) {
|
||||||
|
@ -4540,6 +4540,11 @@ detect-port-alt@1.1.6:
|
|||||||
address "^1.0.1"
|
address "^1.0.1"
|
||||||
debug "^2.6.0"
|
debug "^2.6.0"
|
||||||
|
|
||||||
|
dexie-observable@^3.0.0-beta.10:
|
||||||
|
version "3.0.0-beta.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/dexie-observable/-/dexie-observable-3.0.0-beta.10.tgz#ad7a7e136defbb62f9eab9198a5cb9e10bce1c87"
|
||||||
|
integrity sha512-GMPwQMLh1nYqM1MYsOZudsIwSMqDMrAOBxNuw+Y2ijsrQTBPi3nRF2CinY02IdlmffkaU7DsDfnlgdaMEaiHTQ==
|
||||||
|
|
||||||
"dexie@^3.0.0-alpha.5 || ^2.0.4", dexie@^3.0.3:
|
"dexie@^3.0.0-alpha.5 || ^2.0.4", dexie@^3.0.3:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/dexie/-/dexie-3.0.3.tgz#ede63849dfe5f07e13e99bb72a040e8ac1d29dab"
|
resolved "https://registry.yarnpkg.com/dexie/-/dexie-3.0.3.tgz#ede63849dfe5f07e13e99bb72a040e8ac1d29dab"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user