kamejosh / owlbear-hp-tracker

HP Tracker Extension for Owlbear
MIT License
8 stars 6 forks source link

Bug: deleting an item doesn't delete remove health bar on other devices #16

Closed SeamusFinlayson closed 1 year ago

SeamusFinlayson commented 1 year ago

https://github.com/kamejosh/owlbear-hp-tracker/assets/77430559/99e72f0a-2c25-415c-8964-56bc2540465d

Top is GM view, bottom is player. I'm working on this bug for my own extension, I'll update if I can fix it. Reloading does fix it because the health bar is only in local.

kamejosh commented 1 year ago

yeah, i encountered it on saturday. Haven't had time to fix it yet but I'm probably gonna fix it by moving the HP Bar to global Items.

The problem is, that local Items don't get considered on the remote screen when changing a global item. And because contrary to the text the HP Bar could be global (because it's mainly a player feature, I don't intend it for GM only view, when active it will always be shown to players) so that would solve lots of problems (but would need some refactoring).

SeamusFinlayson commented 1 year ago

My solution is to poll for changes in the global items and delete the health bars (which i have given specific ids) for any deleted global items, I'm probably gonna convert this to run when the OBR.scene.items.onChange() method executes but i think that might be more specific to my code.

 //delete health bars that don't get deleted when their parent token is deleted
  var itemIds: String[] = [];
  for(const item of items) {
      itemIds.push(item.id);
  }
  deleteOrphanHealthBars(itemIds);

async function deleteOrphanHealthBars(oldItemIds: String[]) {

    //get all items on map that could have health bars
    const newItems: Image[] = await OBR.scene.items.getItems(
        (item) => (item.layer === "CHARACTER" || item.layer === "MOUNT" || item.layer === "PROP") && isImage(item)
    );
    var newItemIds: String[] = [];
    for(const item of newItems) {
        newItemIds.push(item.id);
    }

    //check for old health bars
    for(const oldId of oldItemIds) {
        if(!newItemIds.includes(oldId)) {

            // delete  old health bar
            await OBR.scene.local.deleteItems([oldId + "health-background", oldId + "health"]);
        }
    }

    //use timeout to repeat call with fresh item list
    setTimeout(function() {deleteOrphanHealthBars(newItemIds);}, 500);
}
kamejosh commented 1 year ago

I have a fix for this now: https://github.com/kamejosh/owlbear-hp-tracker/pull/18

I moved to only global items, and no longer listen for item Changes to update the UI. This is more work coding but makes the state more predictable 😁

You could test the beta version here: https://hp-tracker-pr-18.onrender.com/manifest.json

SeamusFinlayson commented 1 year ago

I saw in the discord, nice work.