fix(street-level): a new sequence load drops the last one's error; framing survives a detached navigation

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-08 16:21:13 +04:00
1 parent bd57cf5f43
commit 4682757e71
4 files changed
+15 -2

No files matched your search

+2 -1
View File
@@ -44,7 +44,8 @@ export function createCameraFraming({ state }) {
function frame(ticket) {
const { position, bearing, altitude } = state.street;
if (!ticket || !position || !state.viewer) return;
if (ticket.generation !== null && !navigation.reassert(ticket.generation))
// Detached (shell teardown) since the ticket was issued: nothing to frame for.
if (ticket.generation !== null && !navigation?.reassert(ticket.generation))
return;
const ground = groundHeightAt(position.lon, position.lat, altitude);
// Owned before the call: starting it cancels the previous flight (ours
@@ -177,3 +177,12 @@ test('a refused claim (cockpit) does not frame the photo', () => {
framing.frame(framing.begin());
assert.equal(flights.length, 0);
});
test('a photo that loads after the navigation was detached does not frame', () => {
const { framing, state, flights } = setup({ sampled: 160 });
framing.attachNavigation(navigationFor(state));
const ticket = framing.begin();
framing.attachNavigation(null);
assert.doesNotThrow(() => framing.frame(ticket));
assert.equal(flights.length, 0);
});
@@ -131,6 +131,8 @@ export function createSequences({ state, source, parts }) {
const controller = new AbortController();
state.sequence.abort = controller;
state.sequence.loading = true;
// An earlier sequence's error does not belong to this one.
state.sequence.error = null;
notify();
try {
const records = await source.getSequenceImages(sequenceId, {
@@ -101,9 +101,10 @@ test('a failed sequence load leaves no stale cones and can be retried', async ()
assert.equal(highlights.at(-1), null);
assert.equal(state.sequence.error, 'Sequence images unavailable');
// Clicking B again asks again.
// Clicking B again asks again, without the old error.
sequences.select('B');
assert.equal(source.calls.filter((c) => c.sequenceId === 'B').length, 2);
assert.equal(state.sequence.error, null, 'not shown while B loads again');
source.last('B').resolve(records('B'));
await settle();
assert.deepEqual(drawn(), ['B-0', 'B-1']);