diff --git a/CHANGELOG.md b/CHANGELOG.md index dda84b6..427bf90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13388,3 +13388,47 @@ Neste steg: **Rullet ut 2026-08-20** -- bruker bekreftet. Ren frontend. `docker compose build teecup_frontend && up -d`, rene logger, 200 OK. + +136. **Score-fanen: mindre luft under RoundHeader, 2026-08-20.** Bruker + viste et skjermbilde fra live: unødvendig stort tomrom mellom + fanerad-headeren og "Hull 1"-boksen når ingen varsel-banner + (offline/pending-sync) var synlig. Årsak: `
` sin egen + `py-6 sm:py-8`-toppadding la seg OVENPÅ hull-seksjonens allerede + eksisterende `mt-5` lenger ned i stedet for å erstatte den -- disse + stablet seg til 44-52px kombinert, mens resten av siden bruker en + tettere rytme (16-20px). Rettet: `round-detail.tsx` sin `
` + bruker nå `pt-3 sm:pt-4` (matcher RoundHeader sin egen interne + `py-3 sm:py-4`-rytme) i stedet for `py-6 sm:py-8` -- kun toppen + redusert, bunnpadding uendret. + +137. **Hindringer bak spilleren skal ikke lenger vises, 2026-08-20.** + Bruker påpekte (uavhengig av skjermbildet over): avstander til + hindringer skal kun vises når hindringen faktisk ligger MELLOM + spilleren og greenen -- en hindring spilleren allerede har gått forbi + er unødvendig informasjon. + + `hole-target-distance.tsx`: + - `groupDiagramHazards()` (brukt av det vanlige diagram-sporet, når + banen har tee-koordinater) tar nå imot spillerens `alongPercent` + (posisjon langs tee-green-aksen) og filtrerer bort enhver hindring + der YTTERSTE kant (bakkanten for et parret forkant+bakkant-hinder, + selve punktet for et enkeltstående) ligger BAK spilleren. Et parret + hinder regnes altså som passert først når spilleren er forbi BEGGE + kantene, ikke bare forkanten. En liten toleranse + (`HAZARD_PASSED_TOLERANCE_PCT = 1,5`) hindrer at en hindring rett + ved spillerens fot blinker inn/ut mellom to GPS-oppdateringer. + - Den sjeldnere fallback-listen (bane uten tee-koordinater, ingen + akse å projisere langs) filtrerer med en enklere proxy: hindringen + må ligge nærmere green-midten enn spilleren selv gjør. + + **Verifisert i scratch:** en frittstående forhåndsvisning av + `HoleTargetDistance` (compact + full) med stubbet `navigator. + geolocation.watchPosition` (synkron, deterministisk testposisjon -- + ikke Chrome DevTools sin posisjons-emulering, som var upålitelig + tidligere i denne økten) og to hindringer på rett linje langs hullet, + én bak og én foran en fast spillerposisjon. Bekreftet: kun hindringen + foran spilleren ("Vannhinder") vises, i BÅDE kompakt liste og fullt + diagram -- hindringen bak ("Fjellknaus") er helt fraværende i begge. + `tsc --noEmit` rent. + + **Ikke rullet ut ennå** -- venter på bekreftelse fra bruker. diff --git a/frontend/components/hole-target-distance.tsx b/frontend/components/hole-target-distance.tsx index 00ccd02..d2f3d50 100644 --- a/frontend/components/hole-target-distance.tsx +++ b/frontend/components/hole-target-distance.tsx @@ -95,17 +95,32 @@ const _HAZARD_KIND: Record = { stone_fence: "stone_fence", } +// Hvor mange prosent av hull-lengden en hindring får "henge igjen" etter at +// spilleren i teorien har passert den (ADR-085, brukerønske 2026-08-20: +// hindringer bak spilleren er unødvendig informasjon -- skal ikke lenger +// vises). Ren GPS-støy-margin, ikke en spilleregel -- uten denne ville en +// hindring rett ved spillerens fot kunne blinke inn/ut av listen mellom to +// GPS-oppdateringer idet spilleren går forbi. +const HAZARD_PASSED_TOLERANCE_PCT = 1.5 + // Grupperer rå hindringspunkter til hindrings-ENTITETER for diagrammet. // VIKTIG (bruker-rettelse, ADR-084): to punkter er KUN samme fysiske // hindring hvis de deler samme, ikke-null hazard_group -- ALDRI basert // på poi_type+side_fairway alene (ville feilaktig slått sammen to // atskilte hindringer av samme type på samme side). Punkter med // hazard_group=null forblir alltid enkeltstående. +// `playerAlongPercent` (ADR-085) -- en hindring vises KUN hvis den fortsatt +// ligger MELLOM spilleren og greenen (brukerønske: passerte hindringer er +// unødvendig informasjon). For et parret forkant+bakkant-hinder brukes +// bakkanten (den ytterste kanten, nærmest green) -- hele hindringen regnes +// som passert først når spilleren er forbi BEGGE kantene, ikke bare +// forkanten. function groupDiagramHazards( hazardPoints: ApiTargetPoint[], livePosition: LatLng, teeRef: LatLng, greenRef: LatLng, + playerAlongPercent: number, ) { const grouped = new Map() const standalone: ApiTargetPoint[] = [] @@ -148,6 +163,8 @@ function groupDiagramHazards( const kind = _HAZARD_KIND[primary.poi_type] if (!kind) continue const alongValues = [front, back].filter((p): p is ApiTargetPoint => !!p).map(along) + const farEdgeAlong = Math.max(...alongValues) + if (farEdgeAlong < playerAlongPercent - HAZARD_PASSED_TOLERANCE_PCT) continue entities.push({ key: `group-${groupKey}`, kind, @@ -162,6 +179,7 @@ function groupDiagramHazards( for (const p of standalone) { const kind = _HAZARD_KIND[p.poi_type] if (!kind) continue + if (along(p) < playerAlongPercent - HAZARD_PASSED_TOLERANCE_PCT) continue entities.push({ key: `point-${p.latitude}-${p.longitude}-${p.poi_type}`, kind, @@ -300,7 +318,16 @@ export function HoleTargetDistance({ // spilleren først. Avstandene er ALLTID live fra spilleren, uavhengig av // om et geometrisk diagram kan tegnes under. const hazardPoints = points.filter((p) => p.poi_type in _HAZARD_LABELS) - const hazards = hazardPoints + // ADR-085 (brukerønske 2026-08-20): passerte hindringer skal ikke vises. + // Denne (tee-referanse mangler) grenen har ingen akse å projisere langs, + // så "mellom spiller og green" tilnærmes med "nærmere green enn + // spilleren selv" -- mindre presist enn along-percent-varianten under + // (tar ikke hensyn til sideveis avstand), men fungerer som en fornuftig + // proxy for det sjeldne tilfellet en bane mangler tee-koordinater. + const hazardPointsAhead = hazardPoints.filter( + (h) => haversineMeters({ lat: h.latitude, lng: h.longitude }, { lat: middle.latitude, lng: middle.longitude }) < distances.middle, + ) + const hazards = hazardPointsAhead .map((h) => { const base = _HAZARD_LABELS[h.poi_type] const label = @@ -330,7 +357,7 @@ export function HoleTargetDistance({ if (teeRef) { const greenRef = { lat: middle.latitude, lng: middle.longitude } const player = projectOntoAxis(teeRef, greenRef, livePosition) - const diagramHazards = groupDiagramHazards(hazardPoints, livePosition, teeRef, greenRef) + const diagramHazards = groupDiagramHazards(hazardPoints, livePosition, teeRef, greenRef, player.alongPercent) return ( -
+ {/* pt redusert fra py-6/py-8 (2026-08-20, brukerfunn: unødvendig + luft under RoundHeader når ingen varsel-banner vises -- padding + her la seg OVENPÅ hull-seksjonens egen mt-5 lenger ned i stedet + for å erstatte den). Kun toppen redusert, bunnen uendret. */} +
{conflictNotice && (