diff --git a/client/src/mobile/screens/trip/map/MMapArea.tsx b/client/src/mobile/screens/trip/map/MMapArea.tsx index c3e6d4e9e..b3d5abea1 100644 --- a/client/src/mobile/screens/trip/map/MMapArea.tsx +++ b/client/src/mobile/screens/trip/map/MMapArea.tsx @@ -282,22 +282,25 @@ export default function MMapArea({ planner, shell }: MMapAreaProps) { * sets overlap: the same petrol station found twice would be two pins on one roof. */ /** - * The vias the phone map draws, minus the night pauses. + * The vias the phone map draws: on a stage, only the night that belongs to it. * - * A night pause is a pill with a moon and a day number, drawn beside the boundary where - * one travel day ends. On the desktop it is a handle: it carries a hint and can be - * dragged to move the boundary. A phone has no hover to explain it and no room to drag - * it, so all it does there is sit on the map, and it sits there for EVERY day at once — - * the markers come from the whole drive (`automaticPoints`), not from the stage on - * screen, so day 1 shows day 2's pill as well. Two labels the day filter does not reach - * read as part of the map rather than as a control. + * A night pause is a pill with a moon and a day number, drawn where one travel day + * ends. The markers are built from the WHOLE drive (`automaticPoints`), which is right + * for the desktop rail and for the all-days view here, but a stage shows one day: with + * the unfiltered list, day 1 carried day 2's pill as well, in the middle of a map that + * is otherwise entirely day 1. Two ends on a map that draws one is a question, not a + * label. * - * Both lists go through the same filter: the plan tab's vias carry night pauses too. + * So on a stage the pill is kept only where its day is the day on screen, and off a + * stage the list is left alone, because in the all-days view every night does belong to + * a line that is drawn. `nightPause.day` is the day number the marker was built from + * (see `useAutomaticDayPoints`), which is the same number the stage carries. */ - const mapVias = useMemo( - () => (onStage ? planner.roadtripMapVias : planner.routeVias)?.filter(v => !v.nightPause), - [onStage, planner.roadtripMapVias, planner.routeVias], - ) + const mapVias = useMemo(() => { + const vias = onStage ? planner.roadtripMapVias : planner.routeVias + if (!vias || !stage) return vias + return vias.filter(v => !v.nightPause || v.nightPause.day === stage.dayNumber) + }, [onStage, planner.roadtripMapVias, planner.routeVias, stage]) const pois = useMergedMapPois( onStage ? planner.roadtripCorridor.visible : null, diff --git a/client/tests/unit/mobile/trip/MMapArea.test.tsx b/client/tests/unit/mobile/trip/MMapArea.test.tsx index 7abe5b0d2..4b57af9b8 100644 --- a/client/tests/unit/mobile/trip/MMapArea.test.tsx +++ b/client/tests/unit/mobile/trip/MMapArea.test.tsx @@ -538,26 +538,27 @@ describe('MMapArea', () => { expect(mocks.props.focusPoints).toBe(shown) }) - it('FE-MOB-MAPAREA-036: the phone map draws no night pause, on either tab', () => { - // A night pause is the moon pill beside a day boundary. On the desktop it is a drag - // handle with a hint; a phone has neither hover nor room to drag, and the markers come - // from the whole drive rather than the stage, so day 1 showed day 2's pill too. - const nightPause = { day: 2, atPlace: false } - const vias = [ - { lat: 53.55, lng: 9.99, tone: 'default' as const, nightPause }, - { lat: 53.87, lng: 10.69, tone: 'default' as const, label: 'Rest stop' }, - ] + it('FE-MOB-MAPAREA-036: a stage keeps its own night pause and drops the other days', () => { + // A night pause is the moon pill where a travel day ends. The markers are built from + // the whole drive, so day 1 used to carry day 2's pill as well, in the middle of a map + // that draws day 1 only. `stagePlanner(3)` is day 1 of the drive (stageDay). + const own = { lat: 53.87, lng: 10.69, tone: 'default' as const, nightPause: { day: 1, atPlace: false } } + const other = { lat: 53.55, lng: 9.99, tone: 'default' as const, nightPause: { day: 2, atPlace: false } } + const plain = { lat: 53.6, lng: 10.2, tone: 'default' as const, label: 'Rest stop' } + const vias = [own, other, plain] const stage = renderArea( { trTab: 'roadtrip', mapFront: true }, { ...stagePlanner(3), roadtripMapVias: vias } as unknown as Partial, ) - expect(mocks.props.routeVias).toEqual([vias[1]]) + // Its own night and everything that is not one; day 2's pill stays off this map. + expect(mocks.props.routeVias).toEqual([own, plain]) stage.unmount() - // The plan tab's own vias carry night pauses too, so they go through the same filter. + // Off a stage the list is left alone: in the all-days view every night belongs to a + // line that is actually drawn. renderArea({ trTab: 'plan' }, { routeVias: vias }) - expect(mocks.props.routeVias).toEqual([vias[1]]) + expect(mocks.props.routeVias).toBe(vias) }) it('FE-MOB-MAPAREA-026: the map layer carries no credit corner on either tab', () => {