mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-11 02:33:51 +08:00
Better Messaging
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
groupRoutesForView,
|
||||
MAX_RENDERED_ROUTES,
|
||||
normalizeRoute,
|
||||
routeMetadataErrorMessage,
|
||||
routeViewRenderKey,
|
||||
} from "/assets/components/recordings/dashcam_routes_helpers.js"
|
||||
|
||||
@@ -738,8 +739,8 @@ async function openOverlay(route) {
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/routes/${route.name}`)
|
||||
if (!response.ok) throw new Error(`Route metadata request failed (${response.status})`)
|
||||
const data = await response.json()
|
||||
const data = await response.json().catch(() => ({}))
|
||||
if (!response.ok) throw new Error(routeMetadataErrorMessage(response.status, data?.error))
|
||||
segments = Array.isArray(data.segment_urls) ? data.segment_urls.filter(url => typeof url === "string") : []
|
||||
const availableCameras = ["forward", "wide", "driver"].filter(camera => data.available_cameras?.includes(camera))
|
||||
if (!segments.length) throw new Error("No video segments are stored for this route")
|
||||
@@ -884,12 +885,15 @@ export function RouteRecordings() {
|
||||
const view = buildRouteView(state.routes, { preservedOnly: state.showPreservedOnly, searchQuery: state.searchQuery, sortOrder: state.sortOrder })
|
||||
const groups = groupRoutesForView(view.visible, state.sortOrder)
|
||||
const renderKey = routeViewRenderKey(view.visible, state.sortOrder, state.viewMode)
|
||||
const hasActiveSearch = Boolean(state.searchQuery.trim())
|
||||
|
||||
return html`
|
||||
<div class="dashcam-results-summary" aria-live="polite">
|
||||
<span>${view.matching.length} matching drive${view.matching.length === 1 ? "" : "s"}</span>
|
||||
${state.loading ? html`<span>Loading ${state.progress} of ${state.total}</span>` : html`<span>${state.routes.length} total local</span>`}
|
||||
</div>
|
||||
${state.loading || hasActiveSearch ? html`
|
||||
<div class="dashcam-results-summary" aria-live="polite">
|
||||
${hasActiveSearch ? html`<span>${view.matching.length} matching drive${view.matching.length === 1 ? "" : "s"}</span>` : ""}
|
||||
${state.loading ? html`<span>Loading routes</span>` : ""}
|
||||
</div>
|
||||
` : ""}
|
||||
${state.error ? html`<p class="screen-recordings-message dashcam-error">${state.error}</p>` : ""}
|
||||
${state.isDeletingAll ? html`<p class="screen-recordings-message">Deleting routes…</p>` : ""}
|
||||
${!view.visible.length && state.loading ? html`<div class="dashcam-loading"><span></span><p>Finding local routes…</p></div>` : ""}
|
||||
|
||||
@@ -264,6 +264,14 @@ export function cameraVideoUrl(segmentUrl, camera, quality) {
|
||||
return quality ? `${url}&quality=${encodeURIComponent(quality)}` : url
|
||||
}
|
||||
|
||||
export function routeMetadataErrorMessage(status, serverError) {
|
||||
if (status === 404) {
|
||||
return "This route is no longer available on this device. Its local video segments may have been deleted or moved."
|
||||
}
|
||||
const detail = String(serverError || "").trim()
|
||||
return detail || `Could not load route details (${status}).`
|
||||
}
|
||||
|
||||
// loggerd only writes qcamera.ts alongside the road camera.
|
||||
export function supportsLowQuality(camera) {
|
||||
return camera === "forward"
|
||||
|
||||
@@ -200,6 +200,17 @@ def test_route_search_input_updates_on_every_keystroke():
|
||||
assert '@input="${event => { state.searchQuery = event.target.value }}"' in source
|
||||
|
||||
|
||||
def test_route_summary_only_shows_loading_or_active_search_status():
|
||||
source = COMPONENT_PATH.read_text(encoding="utf-8")
|
||||
|
||||
assert "const hasActiveSearch = Boolean(state.searchQuery.trim())" in source
|
||||
assert '${state.loading || hasActiveSearch ? html`' in source
|
||||
assert '${hasActiveSearch ? html`<span>${view.matching.length} matching drive' in source
|
||||
assert '${state.loading ? html`<span>Loading routes</span>` : ""}' in source
|
||||
assert "Loading ${state.progress} of ${state.total}" not in source
|
||||
assert "total local" not in source
|
||||
|
||||
|
||||
def test_search_indexes_the_displayed_time_for_every_route():
|
||||
result = evaluate('''
|
||||
const routes = [
|
||||
@@ -368,6 +379,22 @@ def test_camera_video_url_carries_an_optional_quality_tier():
|
||||
assert result["low"] == "/video/0000006a--9f0a7bdf9c--7?camera=forward&quality=low"
|
||||
|
||||
|
||||
def test_route_metadata_errors_explain_missing_local_segments():
|
||||
result = evaluate('''
|
||||
return {
|
||||
missing: routeMetadataErrorMessage(404, "Route not found"),
|
||||
backend: routeMetadataErrorMessage(400, "Invalid route name"),
|
||||
fallback: routeMetadataErrorMessage(503),
|
||||
}
|
||||
''')
|
||||
|
||||
assert result == {
|
||||
"missing": "This route is no longer available on this device. Its local video segments may have been deleted or moved.",
|
||||
"backend": "Invalid route name",
|
||||
"fallback": "Could not load route details (503).",
|
||||
}
|
||||
|
||||
|
||||
def test_only_the_road_camera_has_a_preview():
|
||||
"""loggerd writes qcamera.ts alongside the road camera only."""
|
||||
assert evaluate('return ["forward", "wide", "driver"].map(supportsLowQuality)') == [True, False, False]
|
||||
|
||||
Reference in New Issue
Block a user