Changed data contexts to use useCallback and fixed performance issues when changing party state
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
import React, { useEffect, useState, useContext } from "react";
|
||||
import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
useContext,
|
||||
useCallback,
|
||||
useRef,
|
||||
} from "react";
|
||||
import * as Comlink from "comlink";
|
||||
|
||||
import AuthContext from "./AuthContext";
|
||||
@@ -12,6 +18,8 @@ const TokenDataContext = React.createContext();
|
||||
|
||||
const cachedTokenMax = 100;
|
||||
|
||||
const worker = Comlink.wrap(new DatabaseWorker());
|
||||
|
||||
export function TokenDataProvider({ children }) {
|
||||
const { database, databaseStatus } = useContext(DatabaseContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
@@ -37,7 +45,6 @@ export function TokenDataProvider({ children }) {
|
||||
}
|
||||
|
||||
async function loadTokens() {
|
||||
const worker = Comlink.wrap(new DatabaseWorker());
|
||||
await worker.loadData("tokens");
|
||||
const storedTokens = await worker.data;
|
||||
const sortedTokens = storedTokens.sort((a, b) => b.created - a.created);
|
||||
@@ -50,82 +57,28 @@ export function TokenDataProvider({ children }) {
|
||||
loadTokens();
|
||||
}, [userId, database, databaseStatus]);
|
||||
|
||||
async function addToken(token) {
|
||||
await database.table("tokens").add(token);
|
||||
setTokens((prevTokens) => [token, ...prevTokens]);
|
||||
if (token.owner !== userId) {
|
||||
await updateCache();
|
||||
}
|
||||
}
|
||||
const tokensRef = useRef(tokens);
|
||||
useEffect(() => {
|
||||
tokensRef.current = tokens;
|
||||
}, [tokens]);
|
||||
|
||||
async function removeToken(id) {
|
||||
await database.table("tokens").delete(id);
|
||||
setTokens((prevTokens) => {
|
||||
const filtered = prevTokens.filter((token) => token.id !== id);
|
||||
return filtered;
|
||||
});
|
||||
}
|
||||
const getToken = useCallback((tokenId) => {
|
||||
return tokensRef.current.find((token) => token.id === tokenId);
|
||||
}, []);
|
||||
|
||||
async function removeTokens(ids) {
|
||||
await database.table("tokens").bulkDelete(ids);
|
||||
setTokens((prevTokens) => {
|
||||
const filtered = prevTokens.filter((token) => !ids.includes(token.id));
|
||||
return filtered;
|
||||
});
|
||||
}
|
||||
|
||||
async function updateToken(id, update) {
|
||||
const change = { ...update, lastModified: Date.now() };
|
||||
await database.table("tokens").update(id, change);
|
||||
setTokens((prevTokens) => {
|
||||
const newTokens = [...prevTokens];
|
||||
const i = newTokens.findIndex((token) => token.id === id);
|
||||
if (i > -1) {
|
||||
newTokens[i] = { ...newTokens[i], ...change };
|
||||
}
|
||||
return newTokens;
|
||||
});
|
||||
}
|
||||
|
||||
async function updateTokens(ids, update) {
|
||||
const change = { ...update, lastModified: Date.now() };
|
||||
await Promise.all(
|
||||
ids.map((id) => database.table("tokens").update(id, change))
|
||||
);
|
||||
setTokens((prevTokens) => {
|
||||
const newTokens = [...prevTokens];
|
||||
for (let id of ids) {
|
||||
const i = newTokens.findIndex((token) => token.id === id);
|
||||
if (i > -1) {
|
||||
newTokens[i] = { ...newTokens[i], ...change };
|
||||
}
|
||||
}
|
||||
return newTokens;
|
||||
});
|
||||
}
|
||||
|
||||
async function putToken(token) {
|
||||
await database.table("tokens").put(token);
|
||||
setTokens((prevTokens) => {
|
||||
const newTokens = [...prevTokens];
|
||||
const i = newTokens.findIndex((t) => t.id === token.id);
|
||||
if (i > -1) {
|
||||
newTokens[i] = { ...newTokens[i], ...token };
|
||||
} else {
|
||||
newTokens.unshift(token);
|
||||
}
|
||||
return newTokens;
|
||||
});
|
||||
if (token.owner !== userId) {
|
||||
await updateCache();
|
||||
}
|
||||
}
|
||||
const getTokenFromDB = useCallback(
|
||||
async (tokenId) => {
|
||||
let token = await database.table("tokens").get(tokenId);
|
||||
return token;
|
||||
},
|
||||
[database]
|
||||
);
|
||||
|
||||
/**
|
||||
* Keep up to cachedTokenMax amount of tokens that you don't own
|
||||
* Sorted by when they we're last used
|
||||
*/
|
||||
async function updateCache() {
|
||||
const updateCache = useCallback(async () => {
|
||||
const cachedTokens = await database
|
||||
.table("tokens")
|
||||
.where("owner")
|
||||
@@ -141,11 +94,96 @@ export function TokenDataProvider({ children }) {
|
||||
return prevTokens.filter((token) => !idsToDelete.includes(token.id));
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [database, userId]);
|
||||
|
||||
function getToken(tokenId) {
|
||||
return tokens.find((token) => token.id === tokenId);
|
||||
}
|
||||
const addToken = useCallback(
|
||||
async (token) => {
|
||||
await database.table("tokens").add(token);
|
||||
setTokens((prevTokens) => [token, ...prevTokens]);
|
||||
if (token.owner !== userId) {
|
||||
await updateCache();
|
||||
}
|
||||
},
|
||||
[database, updateCache, userId]
|
||||
);
|
||||
|
||||
const removeToken = useCallback(
|
||||
async (id) => {
|
||||
await database.table("tokens").delete(id);
|
||||
setTokens((prevTokens) => {
|
||||
const filtered = prevTokens.filter((token) => token.id !== id);
|
||||
return filtered;
|
||||
});
|
||||
},
|
||||
[database]
|
||||
);
|
||||
|
||||
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]
|
||||
);
|
||||
|
||||
const updateToken = useCallback(
|
||||
async (id, update) => {
|
||||
const change = { ...update, lastModified: Date.now() };
|
||||
await database.table("tokens").update(id, change);
|
||||
setTokens((prevTokens) => {
|
||||
const newTokens = [...prevTokens];
|
||||
const i = newTokens.findIndex((token) => token.id === id);
|
||||
if (i > -1) {
|
||||
newTokens[i] = { ...newTokens[i], ...change };
|
||||
}
|
||||
return newTokens;
|
||||
});
|
||||
},
|
||||
[database]
|
||||
);
|
||||
|
||||
const updateTokens = useCallback(
|
||||
async (ids, update) => {
|
||||
const change = { ...update, lastModified: Date.now() };
|
||||
await Promise.all(
|
||||
ids.map((id) => database.table("tokens").update(id, change))
|
||||
);
|
||||
setTokens((prevTokens) => {
|
||||
const newTokens = [...prevTokens];
|
||||
for (let id of ids) {
|
||||
const i = newTokens.findIndex((token) => token.id === id);
|
||||
if (i > -1) {
|
||||
newTokens[i] = { ...newTokens[i], ...change };
|
||||
}
|
||||
}
|
||||
return newTokens;
|
||||
});
|
||||
},
|
||||
[database]
|
||||
);
|
||||
|
||||
const putToken = useCallback(
|
||||
async (token) => {
|
||||
await database.table("tokens").put(token);
|
||||
setTokens((prevTokens) => {
|
||||
const newTokens = [...prevTokens];
|
||||
const i = newTokens.findIndex((t) => t.id === token.id);
|
||||
if (i > -1) {
|
||||
newTokens[i] = { ...newTokens[i], ...token };
|
||||
} else {
|
||||
newTokens.unshift(token);
|
||||
}
|
||||
return newTokens;
|
||||
});
|
||||
if (token.owner !== userId) {
|
||||
await updateCache();
|
||||
}
|
||||
},
|
||||
[database, updateCache, userId]
|
||||
);
|
||||
|
||||
const ownedTokens = tokens.filter((token) => token.owner === userId);
|
||||
|
||||
@@ -166,6 +204,7 @@ export function TokenDataProvider({ children }) {
|
||||
getToken,
|
||||
tokensById,
|
||||
tokensLoading,
|
||||
getTokenFromDB,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user