mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 14:06:27 +00:00
fix(mobile): booking routes on the phone map follow the day they run on
A booking switched on with "On map" stayed drawn on every day of the phone's plan map, so a flight from the first day crossed the map of the third, although a day chip frames one day and drops the other days' pins. The plan map now draws such a booking only on the days it runs on, the arrival day of an overnight one included, and the all-days view still shows every booking that is switched on. The switch itself stays trip-wide, and the desktop, collections and the road trip stage draw exactly as before. "On map" in a booking's sheet now reads as on only where the plan map draws the route. From any other day a tap takes the map to the booking's day, switching the route on when it is off, instead of hiding a route that is not drawn there anyway. The phone settings also gain the "Always show booking routes" switch the desktop already had. As on the desktop it sets the default for trips not yet touched on this device, so a trip where a route was switched on or off by hand keeps that choice.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { hopIsVisible, isRoutableReservation, labelFloorPx, lineFloorPx, visibleRouteReservations } from './reservationRoutes'
|
||||
import { hopIsVisible, isRoutableReservation, labelFloorPx, lineFloorPx, runsOnDay, visibleRouteReservations } from './reservationRoutes'
|
||||
import type { Day, Reservation, ReservationEndpoint } from '../types'
|
||||
|
||||
function endpoint(role: 'from' | 'to', lat: number, lng: number): ReservationEndpoint {
|
||||
@@ -117,6 +117,92 @@ describe('visibleRouteReservations with a selected day', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// The phone's plan map shows one day, so it asks for the per-item toggle to follow the
|
||||
// selected day the way the transit toggle does. The span rule is the transit one.
|
||||
describe('visibleRouteReservations with the per-item toggle scoped to the day', () => {
|
||||
const twoStop = [endpoint('from', 1, 2), endpoint('to', 3, 4)]
|
||||
const days = [
|
||||
{ id: 10, trip_id: 1, day_number: 1 },
|
||||
{ id: 11, trip_id: 1, day_number: 2 },
|
||||
{ id: 20, trip_id: 1, day_number: 3 },
|
||||
] as Day[]
|
||||
|
||||
function booking(overrides: Partial<Reservation>): Reservation {
|
||||
return reservation({ id: 5, type: 'flight', endpoints: twoStop, ...overrides })
|
||||
}
|
||||
|
||||
const drawn = (r: Reservation, selectedDayId: number | null | undefined, onDays: Day[] = days) =>
|
||||
visibleRouteReservations([r], {
|
||||
visibleConnectionIds: [r.id], showTransitRoutes: false, selectedDayId, days: onDays, scopeConnectionsToDay: true,
|
||||
})
|
||||
|
||||
it('leaves out a booking switched on for another day', () => {
|
||||
expect(drawn(booking({ day_id: 20, end_day_id: 20 }), 10)).toEqual([])
|
||||
})
|
||||
|
||||
it('draws a booking on the day it runs on', () => {
|
||||
const r = booking({ day_id: 10, end_day_id: 10 })
|
||||
expect(drawn(r, 10)).toEqual([r])
|
||||
})
|
||||
|
||||
it('keeps an overnight booking on both of its days and off the rest', () => {
|
||||
const r = booking({ day_id: 10, end_day_id: 11 })
|
||||
expect(drawn(r, 10)).toEqual([r])
|
||||
expect(drawn(r, 11)).toEqual([r])
|
||||
expect(drawn(r, 20)).toEqual([])
|
||||
})
|
||||
|
||||
it('keeps a multi-day booking on the days in between', () => {
|
||||
const r = booking({ day_id: 10, end_day_id: 20 })
|
||||
expect(drawn(r, 11)).toEqual([r])
|
||||
})
|
||||
|
||||
it('goes by day order, not by day id', () => {
|
||||
const reordered = [
|
||||
{ id: 20, trip_id: 1, day_number: 1 },
|
||||
{ id: 11, trip_id: 1, day_number: 2 },
|
||||
{ id: 10, trip_id: 1, day_number: 3 },
|
||||
] as Day[]
|
||||
const r = booking({ day_id: 20, end_day_id: 11 })
|
||||
expect(drawn(r, 11, reordered)).toEqual([r])
|
||||
expect(drawn(r, 10, reordered)).toEqual([])
|
||||
})
|
||||
|
||||
it('keeps a booking that is bound to no day', () => {
|
||||
const r = booking({ day_id: null, end_day_id: null })
|
||||
expect(drawn(r, 10)).toEqual([r])
|
||||
})
|
||||
|
||||
it('keeps every switched-on booking while no day is selected', () => {
|
||||
const r = booking({ day_id: 20, end_day_id: 20 })
|
||||
expect(drawn(r, undefined)).toEqual([r])
|
||||
expect(drawn(r, null)).toEqual([r])
|
||||
})
|
||||
|
||||
it('still draws nothing that was not switched on', () => {
|
||||
const r = booking({ day_id: 10, end_day_id: 10 })
|
||||
expect(visibleRouteReservations([r], {
|
||||
visibleConnectionIds: [], showTransitRoutes: false, selectedDayId: 10, days, scopeConnectionsToDay: true,
|
||||
})).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('runsOnDay', () => {
|
||||
const days = [
|
||||
{ id: 10, trip_id: 1, day_number: 1 },
|
||||
{ id: 11, trip_id: 1, day_number: 2 },
|
||||
] as Day[]
|
||||
|
||||
it('reads a booking with only an arrival day as running on that day', () => {
|
||||
expect(runsOnDay({ day_id: null, end_day_id: 11 }, 11, days)).toBe(true)
|
||||
expect(runsOnDay({ day_id: null, end_day_id: 11 }, 10, days)).toBe(false)
|
||||
})
|
||||
|
||||
it('does not rule a booking out for a selected day it cannot find', () => {
|
||||
expect(runsOnDay({ day_id: 10, end_day_id: 10 }, 99, days)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('hopIsVisible (#2275)', () => {
|
||||
// A flat projection: one unit of lat or lng is one pixel.
|
||||
const px = (p: readonly [number, number]) => ({ x: p[1], y: p[0] })
|
||||
|
||||
@@ -22,10 +22,17 @@ export interface RouteVisibilityOptions {
|
||||
selectedDayId?: number | null
|
||||
/** The trip's days, needed to order them — day ids are not monotonic once days have been reordered. */
|
||||
days?: Day[]
|
||||
/**
|
||||
* Hold the per-item toggle to the selected day as well. Off unless asked for: the desktop
|
||||
* keeps a booking it was told to draw on every day, since switching it on is a deliberate
|
||||
* act (#2019). The phone's plan map shows one day at a time, and a flight from another
|
||||
* day drawn across it reads as part of that day.
|
||||
*/
|
||||
scopeConnectionsToDay?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this transit journey actually run on the selected day? `showTransitRoutes` is one
|
||||
* Does this journey actually run on the selected day? `showTransitRoutes` is one
|
||||
* day's toggle but the reservation list is trip-wide, so without this every automated
|
||||
* transport in the trip drew its geometry as soon as any day's route was switched on (#2019).
|
||||
*
|
||||
@@ -34,7 +41,11 @@ export interface RouteVisibilityOptions {
|
||||
* A journey bound to no day keeps drawing; hiding something that legitimately belongs
|
||||
* to today is the worse failure.
|
||||
*/
|
||||
function transitRunsOnDay(r: Reservation, selectedDayId: number | null | undefined, days: Day[]): boolean {
|
||||
export function runsOnDay(
|
||||
r: Pick<Reservation, 'day_id' | 'end_day_id'>,
|
||||
selectedDayId: number | null | undefined,
|
||||
days: Day[],
|
||||
): boolean {
|
||||
if (selectedDayId == null) return true
|
||||
const startDayId = r.day_id ?? r.end_day_id
|
||||
if (startDayId == null) return true
|
||||
@@ -45,11 +56,11 @@ function transitRunsOnDay(r: Reservation, selectedDayId: number | null | undefin
|
||||
|
||||
/** Which reservations should draw a route on the map, combining the two independent toggles above. */
|
||||
export function visibleRouteReservations(reservations: Reservation[], options: RouteVisibilityOptions): Reservation[] {
|
||||
const { visibleConnectionIds, showTransitRoutes, selectedDayId, days } = options
|
||||
const { visibleConnectionIds, showTransitRoutes, selectedDayId, days, scopeConnectionsToDay } = options
|
||||
const set = new Set(visibleConnectionIds || [])
|
||||
return reservations.filter(r =>
|
||||
(r.type === 'transit' && showTransitRoutes && transitRunsOnDay(r, selectedDayId, days || [])) ||
|
||||
set.has(r.id)
|
||||
(r.type === 'transit' && showTransitRoutes && runsOnDay(r, selectedDayId, days || [])) ||
|
||||
(set.has(r.id) && (!scopeConnectionsToDay || runsOnDay(r, selectedDayId, days || [])))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user