diff --git a/containers/libreportal/frontend/core/setup/js/setup-wizard.js b/containers/libreportal/frontend/core/setup/js/setup-wizard.js index 9836123..c63626a 100755 --- a/containers/libreportal/frontend/core/setup/js/setup-wizard.js +++ b/containers/libreportal/frontend/core/setup/js/setup-wizard.js @@ -478,7 +478,19 @@ class SetupWizard { const res = await fetch('/data/system/storage.json', { cache: 'no-store' }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); - this.storageCandidates = Array.isArray(data.candidates) ? data.candidates : []; + // Both halves of the feed. `candidates` is drives that could be added; + // `locations` is the ones already registered — which the step showed as + // nothing at all, so registering a drive made it VANISH from Storage and + // the note went back to claiming only one drive was found. A registered + // location is the clearest case of a usable drive there is. + const registered = (Array.isArray(data.locations) ? data.locations : []) + .filter(l => l && l.path && l.path !== (data.primary || '')) + .map(l => Object.assign({ verdict: l.state === 'ok' ? 'ok' : 'warn', registered: true }, l)); + const unregistered = Array.isArray(data.candidates) ? data.candidates : []; + // A path can legitimately appear in both while a registration settles. + const seen = new Set(registered.map(l => (l.path || '').replace(/\/$/, ''))); + this.storageCandidates = registered.concat( + unregistered.filter(c => !seen.has((c.path || '').replace(/\/$/, '')))); this.storageSystem = data.system || null; } catch (e) { console.log('[setup] storage scan unavailable:', e.message); @@ -601,7 +613,9 @@ class SetupWizard { : (refused ? 'can\u2019t be used' : (c.verdict === 'warn' ? 'needs care' : '')); - const title = o.system ? this._primaryLabel() : c.path; + // A registered location has a name the user chose; an unregistered + // candidate only has a path. + const title = o.system ? this._primaryLabel() : (c.name || c.path); return `
diff --git a/scripts/webui/data/generators/system/webui_storage_candidates.sh b/scripts/webui/data/generators/system/webui_storage_candidates.sh index ec926b6..dc02c9a 100644 --- a/scripts/webui/data/generators/system/webui_storage_candidates.sh +++ b/scripts/webui/data/generators/system/webui_storage_candidates.sh @@ -41,7 +41,19 @@ webuiGenerateStorageCandidates() apps="$(storageAppsOnRoot "$path" 2>/dev/null | paste -sd, -)" (( first )) || locations+="," first=0 - locations+="{\"id\":\"$(_lpJsonEsc "$id")\",\"name\":\"$(_lpJsonEsc "$name")\",\"path\":\"$(_lpJsonEsc "$path")\",\"state\":\"$(_lpJsonEsc "$state")\",\"apps\":\"$(_lpJsonEsc "$apps")\"}" + # Size and free too. Without them the setup wizard renders a registered + # location as a card reading "free of" with both numbers missing — it + # shows the same card as the system disk, which does carry them. + local loc_size="" loc_free="" loc_fs="" loc_pct="" + if command -v findmnt >/dev/null 2>&1 && [[ -d "$path" ]]; then + loc_size=$(findmnt -no SIZE --target "$path" 2>/dev/null | tail -1) + loc_free=$(findmnt -no AVAIL --target "$path" 2>/dev/null | tail -1) + loc_fs=$(findmnt -no FSTYPE --target "$path" 2>/dev/null | tail -1) + fi + loc_pct=$(df -Pk "$path" 2>/dev/null | awk 'NR==2 {gsub("%","",$5); print $5}') + locations+="{\"id\":\"$(_lpJsonEsc "$id")\",\"name\":\"$(_lpJsonEsc "$name")\",\"path\":\"$(_lpJsonEsc "$path")\",\"state\":\"$(_lpJsonEsc "$state")\",\"apps\":\"$(_lpJsonEsc "$apps")\"" + locations+=",\"size\":\"$(_lpJsonEsc "$loc_size")\",\"free\":\"$(_lpJsonEsc "$loc_free")\"" + locations+=",\"fstype\":\"$(_lpJsonEsc "$loc_fs")\",\"used_pct\":${loc_pct:-0},\"removable\":false}" done < <(runStorage verify 2>/dev/null) locations+="]"