mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(street-level): KartaView PR review — context loss mid-load, chunked reads, source switches, a11y
From the IC8 review of #1121 (2 P2, 7 P3; each with a test that fails on the old code): P2 - A WebGL context lost while a newer panorama loaded left a black viewer and a 'successful' open: the panorama now builds on the new canvas (or falls back to its front view). - The streaming body read every real answer takes was tested with one chunk only: answers split mid-character are reassembled; the shared test fake now streams, so every source test runs the production path. P3 - Lighting another source by its chip (params) now stops a running lookup and clears its spinner and error, as setProviderEnabled did; a restore that changes nothing leaves them alone. - Panoramas decode off the main thread (ImageBitmap, RGBA upload: ~90 ms → ~15 ms at 4,096 px on a phone-class CPU) and are 2,048 px docked, 4,096 once the viewer grows; a closed viewer keeps a 1×1 texture. - The lit KARTAVIEW chip label is #8f8aff (~6:1; #635bff was 3.7:1). - The viewer's keyboard focus ring is drawn above the photo. - Tests: a second context loss and a drag on the new canvas; the look direction kept across a loss; a page's 30 s first try. - The browser gate loses a real WebGL context in the 360° step and checks the 429 lookup was asked again (the fixture counter is reset first). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
97a1a667de
commit
c99eb93174
12 files changed
+512
-26
No files matched your search
@@ -897,3 +897,49 @@ test('KartaView through the core: its own swatch without Selected, its lines cou
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('switching source by params (the chip path) stops a running lookup and clears its spinner and error', async (t) => {
|
||||
const slow = slowLookups();
|
||||
const looking = fakeProvider({ nearestImage: slow.nearestImage });
|
||||
const other = fakeProvider({ id: 'other', pickPrefix: 'oth:' });
|
||||
const { layer } = await enabledLayer(t, [looking, other]);
|
||||
layer.attachViewerHost({});
|
||||
const opening = layer.openNearest({ lat: 1, lon: 1 });
|
||||
await settle();
|
||||
assert.equal(layer.getUIState().street.loading, true);
|
||||
layer.setParams({ mapillary: false, other: true });
|
||||
assert.equal(slow.lookups[0].signal.aborted, true, 'the lookup is stopped');
|
||||
assert.equal(
|
||||
layer.getUIState().street.loading,
|
||||
false,
|
||||
'no spinner left behind',
|
||||
);
|
||||
// The stopped lookup answers late: nothing opens, nothing is reported.
|
||||
slow.lookups[0].answer.resolve('img1');
|
||||
assert.equal(await opening, false);
|
||||
assert.deepEqual(looking.calls.open, []);
|
||||
assert.equal(layer.getUIState().street.error, null);
|
||||
});
|
||||
|
||||
test('switching source by params clears a failed lookup’s error; reapplying the same switches does not', async (t) => {
|
||||
const failing = fakeProvider({
|
||||
nearestImage: async () => {
|
||||
throw new Error('KartaView did not answer in time — try again');
|
||||
},
|
||||
});
|
||||
const { layer: second } = await enabledLayer(t, [
|
||||
failing,
|
||||
fakeProvider({ id: 'other', pickPrefix: 'oth:' }),
|
||||
]);
|
||||
second.attachViewerHost({});
|
||||
await second.openNearest({ lat: 1, lon: 1 });
|
||||
assert.match(second.getUIState().street.error, /did not answer/);
|
||||
second.setParams({ mapillary: false, other: true });
|
||||
assert.equal(second.getUIState().street.error, null);
|
||||
// Reapplying the same switches (a restore) leaves state alone.
|
||||
await second.openNearest({ lat: 1, lon: 1 });
|
||||
const kept = second.getUIState().street.error;
|
||||
assert.match(kept, /No street-level imagery/);
|
||||
second.setParams({ mapillary: false, other: true });
|
||||
assert.equal(second.getUIState().street.error, kept);
|
||||
});
|
||||
Reference in new issue
Block a user