diff --git a/src/ContextMenuButton.ts b/src/ContextMenuButton.ts index b4d02f2..c666523 100644 --- a/src/ContextMenuButton.ts +++ b/src/ContextMenuButton.ts @@ -32,11 +32,9 @@ export class ContextMenuButton implements ContextMenuItem { const hide = context.items.some((item) => !originalItemMetadata.get(item).hidden); // Show or hide them all. - for (const item of context.items) { - if (hide) - hideItem(item); - else - showItem(item); - } + if (hide) + hideItem(context.items); + else + showItem(context.items); } } diff --git a/src/background.ts b/src/background.ts index 9c10bc6..592ead8 100644 --- a/src/background.ts +++ b/src/background.ts @@ -23,7 +23,7 @@ export function initBackground () { // For the hidden tokens, remove the fake if they have been un-hidden. for (const hiddenToken of hiddenTokens.values()) { if (hiddenToken.visible) - showItem(hiddenToken); + showItem([hiddenToken]); } // Find any fake tokens where the original is deleted or moved. diff --git a/src/itemFunctions.ts b/src/itemFunctions.ts index 173f036..96efc23 100644 --- a/src/itemFunctions.ts +++ b/src/itemFunctions.ts @@ -1,47 +1,62 @@ import { fakeItemMetadata, originalItemMetadata } from './Metadata'; -import OBR, { buildImage, ImageContent, ImageGrid, Item } from '@owlbear-rodeo/sdk'; +import OBR, { buildImage, Image, ImageContent, ImageGrid, isImage, Item } from '@owlbear-rodeo/sdk'; -export async function hideItem (originalItem: Item) { - const metadata = originalItemMetadata.get(originalItem); - const currentlyHidden = metadata.hidden; - if (currentlyHidden) +export async function hideItem (originalItems: Item[]) { + + // Filter out the items that are already hidden, and bail if there are none to hide. + const itemsToHide = originalItems.filter((item) => !originalItemMetadata.get(item).hidden); + if (itemsToHide.length === 0) return; - // Make the fake token. - const fakeToken = buildImage((originalItem as any).image as ImageContent, (originalItem as any).grid as ImageGrid) - .disableHit(true) - .locked(true) - .layer('MAP') - .position(originalItem.position) - .zIndex(originalItem.zIndex - 100) - .build(); - fakeItemMetadata.set(fakeToken, { originalTokenId: originalItem.id }); + // Make the fake tokens. + const fakeTokens = new Map(); + for (const originalItem of originalItems) { + if (!isImage(originalItem)) + continue; + + const fakeToken = buildImage(originalItem.image as ImageContent, originalItem.grid as ImageGrid) + .disableHit(true) + .locked(true) + .layer('MAP') + .position(originalItem.position) + .zIndex(originalItem.zIndex - 100) + .build(); + fakeItemMetadata.set(fakeToken, { originalTokenId: originalItem.id }); + fakeTokens.set(originalItem.id, fakeToken); + } // Hide the original and set the metadata. - await OBR.scene.items.updateItems([originalItem], (items) => { + await OBR.scene.items.updateItems(originalItems, (items) => { for (const originalItem of items) { - originalItem.visible = false; - originalItemMetadata.set(originalItem, { hidden: true, fakeTokenId: fakeToken.id }); + const fakeToken = fakeTokens.get(originalItem.id); + if (fakeToken) { + originalItem.visible = false; + originalItemMetadata.set(originalItem, { hidden: true, fakeTokenId: fakeToken.id }); + } } }); // Add the fake token. Needs to happen after the original token has it's metadata set, otherwise we'll remove it in the onChange handler. - await OBR.scene.items.addItems([fakeToken]); + await OBR.scene.items.addItems([...fakeTokens.values()]); } -export async function showItem (originalItem: Item) { - const metadata = originalItemMetadata.get(originalItem); - const currentlyHidden = metadata.hidden; - if (!currentlyHidden) +export async function showItem (originalItems: Item[]) { + + // Filter out the items that aren't hidden, and bail if there are none to show. + const itemsToShow = originalItems.filter((item) => originalItemMetadata.get(item).hidden); + if (itemsToShow.length === 0) return; - // Find the fake token. - const fakeTokenId = metadata.fakeTokenId; - if (fakeTokenId) - await OBR.scene.items.deleteItems([fakeTokenId]); + // Find the fake token IDs. + const fakeTokenIds = originalItems.map(originalItem => { + const metadata = originalItemMetadata.get(originalItem); + return metadata.fakeTokenId; + }).filter(x => x) as string[]; + + await OBR.scene.items.deleteItems(fakeTokenIds); // Show the original and clear the metadata. - await OBR.scene.items.updateItems([originalItem], (items) => { + await OBR.scene.items.updateItems(originalItems, (items) => { for (const originalItem of items) { originalItem.visible = true; originalItemMetadata.set(originalItem, { hidden: false, fakeTokenId: null });