Fiks desimalkomma i delingsteksten sin geo:-URI ved norsk locale

share_body brukte %3$.6f/%4$.6f, og Resources.getString() formaterer med
ressurs-locale — nb/nn gir desimalkomma, så delingsteksten inneholdt
"geo:59,918829,10,734887" (ugyldig URI) og en tvetydig koordinatlinje.
Bekreftet med jshell (Formatter + Locale nb) og på emulator.

Fiks: shareShelter() pre-formaterer lat/lon med Locale.US og sender dem
som %3$s/%4$s. Samme regel som openInMapApp() (daf8b62). PWA-en var
ikke rammet (toFixed er locale-uavhengig).

Verifisert i delingsarket på emulator (nb): "geo:59.918829,10.734887".

Forgejo: #20

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FrDGDmN2WAXvNPS85rWJGK
This commit is contained in:
Ole-Morten Duesund 2026-08-17 13:02:18 +02:00
commit 32af7e04c4
5 changed files with 12 additions and 5 deletions

View file

@ -1,3 +1,4 @@
{"id":"tilfluktsrom-rxu","title":"Android: share_body gir desimalkomma i geo:-URI ved norsk locale","description":"Mirror av Forgejo-issue #20.\n\nshare_body bruker %3$.6f/%4$.6f; Resources.getString formaterer med ressurs-locale → nb/nn gir 'geo:59,912345,10,738991' (ugyldig). Bekreftet med jshell. PWA ikke rammet (toFixed).\n\nFiks: formatér lat/lon med Locale.US i shareShelter() og bruk %3$s/%4$s i share_body (en/nb/nn).\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/20","acceptance_criteria":"Delingstekst med nb-locale inneholder 'geo:59.918829,10.734887' (punktum). Enhets-/manuell verifisering.","status":"closed","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-08-17T11:01:06Z","created_by":"Ole-Morten Duesund","updated_at":"2026-08-17T11:02:18Z","started_at":"2026-08-17T11:01:20Z","closed_at":"2026-08-17T11:02:18Z","close_reason":"Fikset: lat/lon pre-formateres med Locale.US i shareShelter(), share_body bruker %3$s/%4$s i en/nb/nn. Verifisert i delingsarket på emulator med nb-locale: geo:59.918829,10.734887.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"tilfluktsrom-vu2","title":"PWA: dyplenke feiler ved kald førstelast — relativ shelters.json-sti","description":"Mirror av Forgejo-issue #19.\n\nshelter-repository.ts bruker relativ sti './data/shelters.json'. Under /shelter/{romnr} løses den til /shelter/data/shelters.json → SPA-fallback gir index.html → JSON-parse feiler → loadData() avbryter → 'Fant ikke tilfluktsrommet'. Dyplenker virker dermed kun for brukere som allerede har data i IndexedDB.\n\nFiks: absolutt sti via import.meta.env.BASE_URL + 'data/shelters.json'.\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/19","acceptance_criteria":"Kald førstelast (tom IndexedDB, ingen SW) av /shelter/1681 i nettleser laster shelters.json, viser lista og velger rommet. Verifisert i Playwright med ny browser-kontekst.","status":"closed","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-08-17T10:49:11Z","created_by":"Ole-Morten Duesund","updated_at":"2026-08-17T10:50:55Z","started_at":"2026-08-17T10:49:22Z","closed_at":"2026-08-17T10:50:55Z","close_reason":"Fikset: SHELTERS_JSON_PATH bruker import.meta.env.BASE_URL; manifest/ikon-lenker i index.html og start_url/scope/icons i manifest.webmanifest gjort absolutte. Verifisert kald førstelast av /shelter/1681 i ny Playwright-kontekst.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"tilfluktsrom-7zc","title":"Badge-kontrast under WCAG 2.2 AA — bytt shelter_primary til warning_bg","description":"Mirror av Forgejo-issue #18.\n\nBadge introdusert i 1fb9f14 (#13) bruker hvit fet 11sp tekst på shelter_primary (#FF6B35). Målt kontrast: ~2.84:1.\n\nWCAG 2.2 AA SC 1.4.3:\n- Normaltekst: ≥4.5:1\n- Large text (≥14pt fet eller ≥18pt regular): ≥3.0:1\n\n11sp fet teller som normaltekst → feiler AA-terskelen, og marginalt også 3:1 for large text.\n\nFiks: én linje i app/src/main/res/layout/item_shelter.xml — bytt @color/shelter_primary til @color/warning_bg (#BF360C, dokumentert ~5.5:1 vs hvit i colors.xml-kommentar).\n\nAlternativer som ikke fungerer:\n- shelter_primary_dark (#E55A2B) ~3.6:1 — fortsatt under AA normaltekst\n- Svart tekst på orange — ~7:1, men bryter visuell konsistens\n\nRelevant for offentlig-sektor-godkjenning (Uutilsynet/WAD/EN 301 549).\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/18","acceptance_criteria":"Badge-bakgrunnen på item_shelter.xml outsideNearestBadge er endret til warning_bg. Visuelt verifisert at hvit fet 11sp tekst på den nye bakgrunnen gir ≥4.5:1 målt kontrast (med en kontrast-sjekker eller WCAG-verktøy).","status":"closed","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-04-29T14:54:00Z","created_by":"Ole-Morten Duesund","updated_at":"2026-04-29T14:55:09Z","started_at":"2026-04-29T14:54:56Z","closed_at":"2026-04-29T14:55:09Z","close_reason":"Bytta @color/shelter_primary til @color/warning_bg på outsideNearestBadge i item_shelter.xml. Kontrast: ~2.84:1 → ~5.6:1 (over WCAG 2.2 AA SC 1.4.3 4.5:1-terskel). Visuell verifisering på enhet/emulator gjenstår.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"id":"tilfluktsrom-efo","title":"PWA: dyplenket tilfluktsrom utenfor topp-N vises som om det er nærmest","description":"Mirror av Forgejo-issue #17.\n\nParallell til Android-fiksen i 1fb9f14 (#13).\n\nNåværende oppførsel: når dyplenken peker på et tilfluktsrom utenfor de N nærmeste, gjør pwa/src/app.ts:266-285 unshift() inn på indeks 0 og setter selectedShelterIndex=0. Resultat: det dyplenkede vises *som om* det er det nærmeste — uten badge, uten separator, uten forklaring. Lista bryter sin egen sort-på-avstand-invariant.\n\nHybrid-fiks (parallell til Android):\n1. Append (push) i stedet for unshift på app.ts:274\n2. Badge i shelter-list.ts på den appendede raden — bruk samme nøkkel shelter_outside_nearest_badge i pwa/src/i18n/{en,nb,nn}.ts\n3. updateList() får outsideNearestRomnr-parameter (eller wrap-objekt parallelt med Android sin ShelterListItem)\n4. Badge-teksten suffikses i aria-label (skjermleser-paritet med Android)\n5. selectedItem.scrollIntoView({block:'nearest', behavior:'smooth'}) etter updateList\n6. Tilgjengelighet: badge ≥4.5:1 kontrast (WCAG 2.2 AA SC 1.4.3). #FF6B35+hvit tekst er ~3.5:1 — *under terskel*. Bruk shelter_primary_dark #E55A2B som badge-bakgrunn, eller svart tekst på orange (~7:1)\n\nUt av skopet: endring av selve dyplenke-formatet (fortsatt /shelter/{romnr}), klyngevisning (#10).\n\nForgejo: https://kode.naiv.no/olemd/tilfluktsrom/issues/17","acceptance_criteria":"Dyplenket tilfluktsrom utenfor topp-N appendes på siste rad i lista (ikke unshift). Den appendede raden har et synlig 'Valgt utenfor nærområdet'-badge med ≥4.5:1 kontrast. Lista scroller automatisk til valgt rad. Skjermleser leser badge-teksten som del av aria-label. Verifisert manuelt med en deep-link til et tilfluktsrom langt fra brukerens posisjon.","status":"closed","priority":2,"issue_type":"bug","assignee":"Ole-Morten Duesund","owner":"olemd@glemt.net","created_at":"2026-04-29T14:52:08Z","created_by":"Ole-Morten Duesund","updated_at":"2026-08-17T10:48:32Z","started_at":"2026-08-17T10:42:26Z","closed_at":"2026-08-17T10:48:32Z","close_reason":"Fikset: push i stedet for unshift, badge (#BF360C, ~5.6:1) + aria-prefiks + scrollIntoView i shelter-list.ts. Verifisert i Chromium via Playwright med dyplenke /shelter/1681 fra Oslo-posisjon.","dependency_count":0,"dependent_count":0,"comment_count":0}

View file

@ -808,12 +808,18 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
// upstream re-rolls lokalId on every Geonorge export, which would
// break cross-device links. See pendingDeepLinkRomnr comment.
val deepLink = "https://${BuildConfig.DEEP_LINK_DOMAIN}/shelter/${shelter.romnr}"
// Pre-format coordinates with Locale.US and pass them as %s. Letting
// getString() format %.6f itself would use the resource locale, and
// nb/nn produce a decimal comma — turning the geo: line into an
// unparsable "geo:59,912345,10,738991". Same rule as openInMapApp().
val lat = String.format(Locale.US, "%.6f", shelter.latitude)
val lon = String.format(Locale.US, "%.6f", shelter.longitude)
val body = getString(
R.string.share_body,
shelter.adresse,
shelter.plasser,
shelter.latitude,
shelter.longitude,
lat,
lon,
deepLink
)

View file

@ -57,7 +57,7 @@
<!-- Deling -->
<string name="share_subject">Tilfluktsrom</string>
<string name="share_body">Tilfluktsrom: %1$s\n%2$d plasser\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s</string>
<string name="share_body">Tilfluktsrom: %1$s\n%2$d plasser\n%3$s, %4$s\ngeo:%3$s,%4$s\n%5$s</string>
<string name="share_no_shelter">Ingen tilfluktsrom valgt</string>
<string name="navigate_no_map_app">Fant ingen kartapp koordinater kopiert: %1$s</string>

View file

@ -57,7 +57,7 @@
<!-- Deling -->
<string name="share_subject">Tilfluktsrom</string>
<string name="share_body">Tilfluktsrom: %1$s\n%2$d plassar\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s</string>
<string name="share_body">Tilfluktsrom: %1$s\n%2$d plassar\n%3$s, %4$s\ngeo:%3$s,%4$s\n%5$s</string>
<string name="share_no_shelter">Ingen tilfluktsrom valt</string>
<string name="navigate_no_map_app">Fann ingen kartapp koordinatar kopierte: %1$s</string>

View file

@ -57,7 +57,7 @@
<!-- Sharing -->
<string name="share_subject">Emergency shelter</string>
<string name="share_body">Shelter: %1$s\n%2$d places\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s</string>
<string name="share_body">Shelter: %1$s\n%2$d places\n%3$s, %4$s\ngeo:%3$s,%4$s\n%5$s</string>
<string name="share_no_shelter">No shelter selected</string>
<string name="navigate_no_map_app">No map app found coordinates copied: %1$s</string>