Optimise token database sync and add loading indicator for multiple token hiding

This commit is contained in:
Mitchell McCaffrey 2021-06-14 15:18:07 +10:00
parent 0fbd837449
commit 1e26193457
4 changed files with 72 additions and 46 deletions

View File

@ -20,21 +20,25 @@ function MapTiles({ mapsById, onMapEdit, onMapSelect, subgroup }) {
function renderTile(group) { function renderTile(group) {
if (group.type === "item") { if (group.type === "item") {
const map = mapsById[group.id]; const map = mapsById[group.id];
const isSelected = selectedGroupIds.includes(group.id); if (map) {
const canEdit = const isSelected = selectedGroupIds.includes(group.id);
isSelected && selectMode === "single" && selectedGroupIds.length === 1; const canEdit =
return ( isSelected &&
<MapTile selectMode === "single" &&
key={map.id} selectedGroupIds.length === 1;
map={map} return (
isSelected={isSelected} <MapTile
onSelect={onGroupSelect} key={map.id}
onEdit={onMapEdit} map={map}
onDoubleClick={() => canEdit && onMapSelect(group.id)} isSelected={isSelected}
canEdit={canEdit} onSelect={onGroupSelect}
badges={[`${map.grid.size.x}x${map.grid.size.y}`]} onEdit={onMapEdit}
/> onDoubleClick={() => canEdit && onMapSelect(group.id)}
); canEdit={canEdit}
badges={[`${map.grid.size.x}x${map.grid.size.y}`]}
/>
);
}
} else { } else {
const isSelected = selectedGroupIds.includes(group.id); const isSelected = selectedGroupIds.includes(group.id);
const items = getGroupItems(group); const items = getGroupItems(group);

View File

@ -48,7 +48,14 @@ function TokenEditBar({ disabled, onLoad }) {
async function handleTokensHide(hideInSidebar) { async function handleTokensHide(hideInSidebar) {
const selectedTokens = getSelectedTokens(); const selectedTokens = getSelectedTokens();
const selectedTokenIds = selectedTokens.map((token) => token.id); const selectedTokenIds = selectedTokens.map((token) => token.id);
updateTokensHidden(selectedTokenIds, hideInSidebar); // Show loading indicator if hiding more than 10 tokens
if (selectedTokenIds.length > 10) {
onLoad(true);
await updateTokensHidden(selectedTokenIds, hideInSidebar);
onLoad(false);
} else {
updateTokensHidden(selectedTokenIds, hideInSidebar);
}
} }
/** /**

View File

@ -21,24 +21,28 @@ function TokenTiles({ tokensById, onTokenEdit, subgroup }) {
function renderTile(group) { function renderTile(group) {
if (group.type === "item") { if (group.type === "item") {
const token = tokensById[group.id]; const token = tokensById[group.id];
const isSelected = selectedGroupIds.includes(group.id); if (token) {
const canEdit = const isSelected = selectedGroupIds.includes(group.id);
isSelected && selectMode === "single" && selectedGroupIds.length === 1; const canEdit =
isSelected &&
selectMode === "single" &&
selectedGroupIds.length === 1;
return ( return (
<TokenTile <TokenTile
key={token.id} key={token.id}
token={token} token={token}
isSelected={isSelected} isSelected={isSelected}
onSelect={onGroupSelect} onSelect={onGroupSelect}
onTokenEdit={onTokenEdit} onTokenEdit={onTokenEdit}
canEdit={canEdit} canEdit={canEdit}
badges={[ badges={[
`${token.defaultSize}x`, `${token.defaultSize}x`,
<TokenHiddenBadge hidden={token.hideInSidebar} />, <TokenHiddenBadge hidden={token.hideInSidebar} />,
]} ]}
/> />
); );
}
} else { } else {
const isSelected = selectedGroupIds.includes(group.id); const isSelected = selectedGroupIds.includes(group.id);
const items = getGroupItems(group); const items = getGroupItems(group);

View File

@ -115,30 +115,24 @@ export function TokenDataProvider({ children }) {
} }
function handleTokenChanges(changes) { function handleTokenChanges(changes) {
// Pool token changes together to call a single state update at the end
let tokensCreated = [];
let tokensUpdated = {};
let tokensDeleted = [];
for (let change of changes) { for (let change of changes) {
if (change.table === "tokens") { if (change.table === "tokens") {
if (change.type === 1) { if (change.type === 1) {
// Created // Created
const token = change.obj; const token = change.obj;
setTokens((prevTokens) => [token, ...prevTokens]); tokensCreated.push(token);
} else if (change.type === 2) { } else if (change.type === 2) {
// Updated // Updated
const token = change.obj; const token = change.obj;
setTokens((prevTokens) => { tokensUpdated[token.id] = token;
const newTokens = [...prevTokens];
const i = newTokens.findIndex((t) => t.id === token.id);
if (i > -1) {
newTokens[i] = token;
}
return newTokens;
});
} else if (change.type === 3) { } else if (change.type === 3) {
// Deleted // Deleted
const id = change.key; const id = change.key;
setTokens((prevTokens) => { tokensDeleted.push(id);
const filtered = prevTokens.filter((token) => token.id !== id);
return filtered;
});
} }
} }
if (change.table === "groups") { if (change.table === "groups") {
@ -149,6 +143,23 @@ export function TokenDataProvider({ children }) {
} }
} }
} }
const tokensUpdatedArray = Object.values(tokensUpdated);
if (
tokensCreated.length > 0 ||
tokensUpdatedArray.length > 0 ||
tokensDeleted.length > 0
) {
setTokens((prevTokens) => {
let newTokens = [...tokensCreated, ...prevTokens];
for (let token of tokensUpdatedArray) {
const tokenIndex = newTokens.findIndex((t) => t.id === token.id);
if (tokenIndex > -1) {
newTokens[tokenIndex] = token;
}
}
return newTokens.filter((token) => !tokensDeleted.includes(token.id));
});
}
} }
database.on("changes", handleTokenChanges); database.on("changes", handleTokenChanges);