Commit 1ddc3cda authored by Matthias Betz's avatar Matthias Betz
Browse files

fix final review findings: error path, LOD panel focus, zip source name, input reset



Co-Authored-By: default avatarClaude Opus 5.5 (1M context) <noreply@anthropic.com>
parent 38166861
...@@ -57,8 +57,13 @@ export function reportLod(state, layerId, lod) { ...@@ -57,8 +57,13 @@ export function reportLod(state, layerId, lod) {
return updateLayer(state, layerId, l => ({ lods: [...l.lods, lod].sort(compareLods) })); return updateLayer(state, layerId, l => ({ lods: [...l.lods, lod].sort(compareLods) }));
} }
export function finishLayer(state, layerId, vertexCount) { // The optional name replaces the layer name, e.g. with "a.zip/entry.gml".
return updateLayer(state, layerId, () => ({ status: 'ready', progress: 1, vertexCount })); export function finishLayer(state, layerId, vertexCount, name) {
return updateLayer(state, layerId, () => (
name === undefined
? { status: 'ready', progress: 1, vertexCount }
: { status: 'ready', progress: 1, vertexCount, name }
));
} }
export function failLayer(state, layerId, message) { export function failLayer(state, layerId, message) {
......
...@@ -31,10 +31,10 @@ function open(file) { ...@@ -31,10 +31,10 @@ function open(file) {
onBlock: (block, getSummary) => viewer.addBlock(layerId, block, getSummary), onBlock: (block, getSummary) => viewer.addBlock(layerId, block, getSummary),
onLod: lod => store.update(reportLod, layerId, lod), onLod: lod => store.update(reportLod, layerId, lod),
onProgress: fraction => store.update(reportProgress, layerId, fraction), onProgress: fraction => store.update(reportProgress, layerId, fraction),
}).then(({ summary }) => { }).then(({ summary, sourceName }) => {
store.update(finishLayer, layerId, summary.vertexCount); store.update(finishLayer, layerId, summary.vertexCount, sourceName);
viewer.finishLayer(layerId, summary); viewer.finishLayer(layerId, summary);
}, error => { }).catch(error => {
if (error.name === 'AbortError') { if (error.name === 'AbortError') {
return; return;
} }
......
...@@ -10,10 +10,13 @@ export function mountFileInput(container, { onFile, enabled = true }) { ...@@ -10,10 +10,13 @@ export function mountFileInput(container, { onFile, enabled = true }) {
input.disabled = !enabled; input.disabled = !enabled;
input.addEventListener('change', () => { input.addEventListener('change', () => {
const file = input.files && input.files[0]; const file = input.files && input.files[0];
if (file) { try {
onFile(file); if (file) {
onFile(file);
}
} finally {
input.value = '';
} }
input.value = '';
}); });
label.append(input); label.append(input);
container.append(label); container.append(label);
......
...@@ -27,30 +27,36 @@ export function mountLodPanel(container, store) { ...@@ -27,30 +27,36 @@ export function mountLodPanel(container, store) {
const list = document.createElement('div'); const list = document.createElement('div');
container.append(heading, list); container.append(heading, list);
let rendered = null; // The list is rebuilt only when the set of LODs changes; a visibility change
// updates the existing checkboxes so that keyboard focus is kept.
let renderedKey = null;
let boxes = new Map();
function render(state) { function render(state) {
const items = lodItems(state); const items = lodItems(state);
const key = JSON.stringify([state.layers.length, items]); const key = JSON.stringify([state.layers.length === 0, items.map(item => item.lod)]);
if (key === rendered) { if (key !== renderedKey) {
return; // progress updates do not rebuild the checkboxes renderedKey = key;
} boxes = new Map();
rendered = key; list.replaceChildren();
list.replaceChildren(); if (items.length === 0) {
if (items.length === 0) { const message = document.createElement('p');
const message = document.createElement('p'); message.textContent = state.layers.length === 0 ? 'No file loaded' : 'No geometry yet';
message.textContent = state.layers.length === 0 ? 'No file loaded' : 'No geometry yet'; list.append(message);
list.append(message); return;
return; }
for (const item of items) {
const label = document.createElement('label');
const box = document.createElement('input');
box.type = 'checkbox';
box.dataset.lod = String(item.lod);
box.addEventListener('change', () => store.update(setHidden, 'lod', item.lod, !box.checked));
label.append(box, ' ', item.label);
list.append(label);
boxes.set(item.lod, box);
}
} }
for (const item of items) { for (const item of items) {
const label = document.createElement('label'); boxes.get(item.lod).checked = item.visible;
const box = document.createElement('input');
box.type = 'checkbox';
box.checked = item.visible;
box.dataset.lod = String(item.lod);
box.addEventListener('change', () => store.update(setHidden, 'lod', item.lod, !box.checked));
label.append(box, ' ', item.label);
list.append(label);
} }
} }
......
...@@ -76,3 +76,8 @@ test('hidden values survive replacing the layer', () => { ...@@ -76,3 +76,8 @@ test('hidden values survive replacing the layer', () => {
test('compareLods orders 0..4 and puts null last', () => { test('compareLods orders 0..4 and puts null last', () => {
assert.deepEqual([null, 3, 0, 2].sort(compareLods), [0, 2, 3, null]); assert.deepEqual([null, 3, 0, 2].sort(compareLods), [0, 2, 3, null]);
}); });
test('finishLayer can replace the layer name, for example with the zip entry', () => {
assert.equal(finishLayer(loading(), 1, 6, 'a.zip/city.gml').layers[0].name, 'a.zip/city.gml');
assert.equal(finishLayer(loading(), 1, 6).layers[0].name, 'a.gml');
});
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment