From e136603d8134d62e667d0785d2cb413fdf9cee6f Mon Sep 17 00:00:00 2001 From: nak Date: Mon, 16 Mar 2026 22:08:46 +0000 Subject: [PATCH] Fix Box shape recall --- scripts/manifoldDomain.js | 4 ++- scripts/shelfShape.js | 14 ++++++---- tablet/manifold.html | 59 +++++++++++++++++++++++++++++---------- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/scripts/manifoldDomain.js b/scripts/manifoldDomain.js index 2ee5eac..6e0f6aa 100644 --- a/scripts/manifoldDomain.js +++ b/scripts/manifoldDomain.js @@ -45,7 +45,9 @@ function deleteClonesFor(username) { if (!isReady) return; EntityViewer.queryOctree(); Script.setTimeout(function () { - var ids = Entities.findEntitiesByType("Shape", SCAN_CENTER, SCAN_RADIUS); + // Use untyped findEntities to avoid type-specific visibility issues + // (Box entities are not always returned by findEntitiesByType) + var ids = Entities.findEntities(SCAN_CENTER, SCAN_RADIUS); var deleted = 0; ids.forEach(function (id) { try { diff --git a/scripts/shelfShape.js b/scripts/shelfShape.js index ed2b1fa..2806d87 100644 --- a/scripts/shelfShape.js +++ b/scripts/shelfShape.js @@ -14,7 +14,7 @@ var SHAPE_TYPE = { tetrahedron: "Tetrahedron", - hexahedron: "Cube", + hexahedron: "Box", octahedron: "Octahedron", dodecahedron: "Dodecahedron", icosahedron: "Icosahedron", @@ -92,7 +92,9 @@ } function countLiveClones(username, shapeId) { - var results = Entities.findEntitiesByType("Shape", MyAvatar.position, 100); + // Scan both Shape and Box — hexahedron/cube uses the Box entity type + var results = Entities.findEntitiesByType("Shape", MyAvatar.position, 100) + .concat(Entities.findEntitiesByType("Box", MyAvatar.position, 100)); var count = 0; results.forEach(function (id) { try { @@ -110,9 +112,11 @@ var spawnPos = Vec3.sum(shelfProps.position, Vec3.multiplyQbyV(shelfProps.rotation, SPAWN_OFFSET)); + var shapeType = SHAPE_TYPE[_shapeId] || "Sphere"; + var entityType = (shapeType === "Box") ? "Box" : "Shape"; Entities.addEntity({ - type: "Shape", - shape: SHAPE_TYPE[_shapeId] || "Sphere", + type: entityType, + shape: shapeType, name: "manifold_" + _shapeId + "_" + _username, position: spawnPos, dimensions: { x: 0.25, y: 0.25, z: 0.25 }, @@ -177,7 +181,7 @@ // Mouse this.clickDownOnEntity = function () { onClickDown(); }; - this.clickUpOnEntity = function () { _busy = false; }; + this.clickReleaseOnEntity = function () { _busy = false; }; // Controller — near (<0.3m) and far (>0.3m) // Requires "Triggerable" checkbox enabled on the entity. diff --git a/tablet/manifold.html b/tablet/manifold.html index a9c9dea..366f334 100644 --- a/tablet/manifold.html +++ b/tablet/manifold.html @@ -537,18 +537,34 @@ btn.disabled = true; btn.classList.add("loading"); - fetch(API_BASE + "/purchase", { - method: "POST", - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + state.token, - }, - body: JSON.stringify({ shape: shapeId }), - }) + function doPurchase(token) { + return fetch(API_BASE + "/purchase", { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer " + token, + }, + body: JSON.stringify({ shape: shapeId }), + }); + } + + doPurchase(state.token) .then(function(r) { + if (r.status === 401) { + return refreshSession().then(function(newToken) { + return doPurchase(newToken); + }); + } if (!r.ok) return r.text().then(function(t) { throw new Error(t.trim()); }); return r.json(); }) + .then(function(r) { + // after potential retry, r may still be a Response not yet parsed + if (r && typeof r.json === "function") { + return r.json(); + } + return r; + }) .then(function(d) { btn.classList.remove("loading"); btn.classList.add("success"); @@ -583,13 +599,26 @@ btn.disabled = true; btn.textContent = "recalling..."; - fetch(API_BASE + "/recall", { - method: "POST", - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + state.token, - }, - body: JSON.stringify({ username: state.username }), + function doRecall(token) { + return fetch(API_BASE + "/recall", { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer " + token, + }, + body: JSON.stringify({ username: state.username }), + }); + } + + doRecall(state.token) + .then(function(r) { + if (r.status === 401) { + // Token expired — refresh and retry once + return refreshSession().then(function(newToken) { + return doRecall(newToken); + }); + } + return r; }) .then(function(r) { btn.classList.add("ok");