Skip to content

Commit 39727ba

Browse files
fix: show whole trip on map load (#192)
* fix: show whole route on map load * refactor: always show whole route if mapLegs is defined * refactor: getMapBounds return type * refactor: map component prop type
1 parent 8e8eed1 commit 39727ba

File tree

3 files changed

+62
-30
lines changed

3 files changed

+62
-30
lines changed

src/components/map/map.tsx

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Button } from '@atb/components/button';
77
import { MonoIcon } from '@atb/components/icon';
88
import { ComponentText, useTranslation } from '@atb/translations';
99
import { FocusScope } from '@react-aria/focus';
10-
import { ZOOM_LEVEL, defaultPosition } from './utils';
10+
import { ZOOM_LEVEL, defaultPosition, getMapBounds } from './utils';
1111
import { useMapInteractions } from './use-map-interactions';
1212
import { useFullscreenMap } from './use-fullscreen-map';
1313
import { useMapPin } from './use-map-pin';
@@ -17,25 +17,31 @@ import { MapLegType, Position } from './types';
1717
import { useMapTariffZones } from './use-map-tariff-zones';
1818

1919
export type MapProps = {
20-
position?: Position;
2120
layer?: string;
2221
onSelectStopPlace?: (id: string) => void;
23-
mapLegs?: MapLegType[];
24-
initialZoom?: number;
25-
};
22+
} & (
23+
| {
24+
position: Position;
25+
initialZoom: number;
26+
}
27+
| {
28+
mapLegs: MapLegType[];
29+
}
30+
| {}
31+
);
2632

27-
export function Map({
28-
position = defaultPosition,
29-
layer,
30-
onSelectStopPlace,
31-
mapLegs,
32-
initialZoom = ZOOM_LEVEL,
33-
}: MapProps) {
33+
export function Map({ layer, onSelectStopPlace, ...props }: MapProps) {
3434
const mapWrapper = useRef<HTMLDivElement>(null);
3535
const mapContainer = useRef<HTMLDivElement>(null);
3636
const map = useRef<mapboxgl.Map>();
3737
const { t } = useTranslation();
3838

39+
const mapLegs = hasMapLegs(props) ? props.mapLegs : undefined;
40+
const { position, initialZoom } = hasInitialPosition(props)
41+
? props
42+
: { position: defaultPosition, initialZoom: ZOOM_LEVEL };
43+
const bounds = mapLegs ? getMapBounds(mapLegs) : undefined;
44+
3945
useEffect(() => {
4046
if (!mapContainer.current) return;
4147

@@ -48,6 +54,7 @@ export function Map({
4854
style: mapboxData.style,
4955
center: position,
5056
zoom: initialZoom,
57+
bounds, // If bounds is specified, it overrides center and zoom constructor options.
5158
});
5259

5360
return () => map.current?.remove();
@@ -62,16 +69,6 @@ export function Map({
6269
useMapLegs(map, mapLegs);
6370
useMapTariffZones(map);
6471

65-
useEffect(() => {
66-
if (map.current) {
67-
map.current.flyTo({
68-
center: position,
69-
zoom: initialZoom,
70-
speed: 2,
71-
});
72-
}
73-
}, [position, initialZoom]);
74-
7572
return (
7673
<div className={style.map} aria-hidden="true">
7774
<Button
@@ -122,3 +119,13 @@ export function Map({
122119
</div>
123120
);
124121
}
122+
123+
function hasInitialPosition(
124+
a: any,
125+
): a is { position: Position; initialZoom: number } {
126+
return a.position && a.initialZoom;
127+
}
128+
129+
function hasMapLegs(a: any): a is { mapLegs: MapLegType[] } {
130+
return a.mapLegs;
131+
}

src/components/map/utils.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,35 @@ const findIndex = (
9191
{ index: -1, distance: 100 },
9292
).index;
9393
};
94+
95+
export const getMapBounds = (
96+
mapLegs: MapLegType[],
97+
): [[number, number], [number, number]] => {
98+
const lineLongitudes = mapLegs
99+
.map((leg) => leg.points.map((point) => point[0]))
100+
.flat();
101+
const lineLatitudes = mapLegs
102+
.map((leg) => leg.points.map((point) => point[1]))
103+
.flat();
104+
105+
const westernMost = Math.min(...lineLongitudes);
106+
const easternMost = Math.max(...lineLongitudes);
107+
const northernMost = Math.max(...lineLatitudes);
108+
const southernMost = Math.min(...lineLatitudes);
109+
110+
// Dividing by 3 here is arbitrary, seems to work
111+
// like a fine value for "padding"
112+
const latPadding = (northernMost - southernMost) / 3;
113+
const lonPadding = (westernMost - easternMost) / 3;
114+
115+
const sw: [number, number] = [
116+
southernMost - latPadding,
117+
westernMost + lonPadding,
118+
];
119+
const ne: [number, number] = [
120+
northernMost + latPadding,
121+
easternMost - lonPadding,
122+
];
123+
124+
return [sw, ne];
125+
};

src/page-modules/assistant/details/index.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,7 @@ export function AssistantDetails({ tripPattern }: AssistantDetailsProps) {
4747
<DetailsHeader tripPattern={tripPattern} />
4848
</div>
4949
<div className={style.mapContainer}>
50-
<Map
51-
position={{
52-
lon: tripPattern.legs[0].fromPlace.longitude,
53-
lat: tripPattern.legs[0].fromPlace.latitude,
54-
}}
55-
initialZoom={13.5}
56-
mapLegs={mapLegs}
57-
/>
50+
<Map mapLegs={mapLegs} />
5851
<div className={style.tripDetails}>
5952
<div className={style.duration}>
6053
<MonoIcon icon="time/Duration" />

0 commit comments

Comments
 (0)