@geops/rvf-mobility-web-component 0.1.32 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/index.html +4 -1
- package/index.js +186 -181
- package/package.json +1 -1
- package/src/NotificationLayer/NotificationLayer.tsx +84 -57
- package/src/NotificationLayer/notificationUtils.ts +191 -23
- package/src/RouteIcon/RouteIcon.tsx +6 -3
- package/src/RouteStopProgress/RouteStopProgress.tsx +12 -7
- package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +158 -23
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +1 -1
- package/src/icons/warning-banner.png +0 -0
- package/src/icons/warning.png +0 -0
- package/src/utils/addSourceAndLayers.ts +24 -2
- package/src/utils/getFeatureInformationTitle.ts +3 -2
- package/src/utils/hooks/useUpdatePermalink.tsx +18 -7
- package/src/utils/hooks/useZoom.tsx +14 -2
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@geops/rvf-mobility-web-component",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
4
|
"description": "Web components for rvf in the domains of mobility and logistics.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.34",
|
|
6
6
|
"homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "index.js",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FeatureCollection } from "geojson";
|
|
1
2
|
import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
|
|
2
3
|
import { MaplibreStyleLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreStyleLayer";
|
|
3
4
|
import { useEffect, useMemo, useState } from "preact/hooks";
|
|
@@ -6,6 +7,7 @@ import useMapContext from "../utils/hooks/useMapContext";
|
|
|
6
7
|
import useZoom from "../utils/hooks/useZoom";
|
|
7
8
|
import {
|
|
8
9
|
addNotificationsLayers,
|
|
10
|
+
getCurrentGraph,
|
|
9
11
|
getNotificationsWithStatus,
|
|
10
12
|
parsePreviewNotification,
|
|
11
13
|
} from "./notificationUtils";
|
|
@@ -16,28 +18,18 @@ interface Metadata {
|
|
|
16
18
|
graphs?: Graphs;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
const
|
|
20
|
-
const {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
notificationat,
|
|
24
|
-
notificationbeforelayerid,
|
|
25
|
-
notificationurl,
|
|
26
|
-
} = useMapContext();
|
|
27
|
-
const zoom = useZoom();
|
|
28
|
-
const [notifications, setNotifications] = useState([]);
|
|
29
|
-
const [previewNotification, setPreviewNotification] = useState(null);
|
|
30
|
-
const [shouldAddPreviewNotifications, setShouldAddPreviewNotifications] =
|
|
31
|
-
useState<boolean>(true);
|
|
21
|
+
const useStyleName = (): string => {
|
|
22
|
+
const { baselayer } = useMapContext();
|
|
23
|
+
return baselayer;
|
|
24
|
+
};
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
const useStyleMetadata = (): Metadata => {
|
|
27
|
+
const { baseLayer } = useMapContext();
|
|
34
28
|
const [styleMetadata, setStyleMetadata] = useState<Metadata>();
|
|
35
|
-
|
|
36
29
|
useEffect(() => {
|
|
37
30
|
if (!baseLayer) {
|
|
38
31
|
return;
|
|
39
32
|
}
|
|
40
|
-
setStyle(baselayer);
|
|
41
33
|
if (!baseLayer.loaded) {
|
|
42
34
|
// @ts-expect-error bad type definition
|
|
43
35
|
baseLayer.once("load", () => {
|
|
@@ -46,24 +38,36 @@ const useNotifications = () => {
|
|
|
46
38
|
} else {
|
|
47
39
|
setStyleMetadata(baseLayer.mapLibreMap?.getStyle()?.metadata);
|
|
48
40
|
}
|
|
49
|
-
}, [baseLayer
|
|
41
|
+
}, [baseLayer]);
|
|
42
|
+
return styleMetadata;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const useGraphMapping = (
|
|
46
|
+
defaultMapping: Record<number, string> = { 1: "osm" },
|
|
47
|
+
): Record<number, string> => {
|
|
48
|
+
const styleMetadata = useStyleMetadata();
|
|
49
|
+
const graphMapping = useMemo(() => {
|
|
50
|
+
return styleMetadata?.graphs || defaultMapping;
|
|
51
|
+
}, [defaultMapping, styleMetadata?.graphs]);
|
|
52
|
+
return graphMapping;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const useNotifications = (): FeatureCollection => {
|
|
56
|
+
const { notificationat, notificationurl } = useMapContext();
|
|
57
|
+
const [notifications, setNotifications] = useState([]);
|
|
58
|
+
const [previewNotification, setPreviewNotification] = useState(null);
|
|
59
|
+
const [shouldAddPreviewNotifications, setShouldAddPreviewNotifications] =
|
|
60
|
+
useState<boolean>(true);
|
|
61
|
+
|
|
62
|
+
const styleName = useStyleName();
|
|
63
|
+
const graphMapping = useGraphMapping();
|
|
50
64
|
|
|
51
65
|
const now = useMemo(() => {
|
|
52
66
|
return notificationat ? new Date(notificationat) : new Date();
|
|
53
67
|
}, [notificationat]);
|
|
54
68
|
|
|
55
|
-
const graphMapping = useMemo(() => {
|
|
56
|
-
return styleMetadata?.graphs || { 1: "osm" };
|
|
57
|
-
}, [styleMetadata]);
|
|
58
|
-
|
|
59
69
|
const graphsString = useMemo(() => {
|
|
60
|
-
return [
|
|
61
|
-
...new Set(
|
|
62
|
-
Object.keys(graphMapping || []).map((key) => {
|
|
63
|
-
return graphMapping[key];
|
|
64
|
-
}),
|
|
65
|
-
),
|
|
66
|
-
].join(",");
|
|
70
|
+
return [...new Set(Object.values(graphMapping))].join(",");
|
|
67
71
|
}, [graphMapping]);
|
|
68
72
|
|
|
69
73
|
useEffect(() => {
|
|
@@ -105,12 +109,12 @@ const useNotifications = () => {
|
|
|
105
109
|
useEffect(() => {
|
|
106
110
|
// Merge notifications with the previewNotification
|
|
107
111
|
const newNotifications = [...notifications];
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
);
|
|
112
|
+
const notifByStyle = previewNotification?.[styleName];
|
|
113
|
+
|
|
114
|
+
if (shouldAddPreviewNotifications && notifByStyle) {
|
|
115
|
+
const parsedPreviewNotification = parsePreviewNotification(notifByStyle);
|
|
112
116
|
const index = newNotifications.findIndex((n) => {
|
|
113
|
-
return n.properties.id ===
|
|
117
|
+
return n.properties.id === notifByStyle.id;
|
|
114
118
|
});
|
|
115
119
|
|
|
116
120
|
if (index > -1) {
|
|
@@ -126,42 +130,47 @@ const useNotifications = () => {
|
|
|
126
130
|
previewNotification,
|
|
127
131
|
notifications,
|
|
128
132
|
shouldAddPreviewNotifications,
|
|
129
|
-
|
|
133
|
+
styleName,
|
|
130
134
|
now,
|
|
131
135
|
]);
|
|
132
136
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
);
|
|
137
|
+
if (previewNotification?.id) {
|
|
138
|
+
const index = notifications.findIndex((n) => {
|
|
139
|
+
return n.properties.id === previewNotification.id;
|
|
140
|
+
});
|
|
141
|
+
if (index > -1) {
|
|
142
|
+
notifications[index].isPreview = true;
|
|
143
|
+
notifications[index].features.forEach((feature) => {
|
|
144
|
+
feature.properties.isPreview = true;
|
|
145
|
+
});
|
|
143
146
|
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const features =
|
|
150
|
+
notifications
|
|
151
|
+
?.map((notification) => {
|
|
152
|
+
return notification.features;
|
|
153
|
+
})
|
|
154
|
+
.flat() || [];
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
features: features,
|
|
158
|
+
type: "FeatureCollection",
|
|
159
|
+
};
|
|
154
160
|
};
|
|
155
161
|
|
|
156
162
|
export default function NotificationLayer(props: MaplibreStyleLayerOptions) {
|
|
157
|
-
useNotifications();
|
|
158
|
-
const { baseLayer, map } = useMapContext();
|
|
163
|
+
const notifications = useNotifications();
|
|
164
|
+
const { baseLayer, map, notificationbeforelayerid } = useMapContext();
|
|
165
|
+
const graphMapping = useGraphMapping();
|
|
166
|
+
const zoom = useZoom();
|
|
159
167
|
|
|
160
168
|
const layer = useMemo(() => {
|
|
161
169
|
if (!baseLayer) {
|
|
162
170
|
return null;
|
|
163
171
|
}
|
|
164
172
|
return new MaplibreStyleLayer({
|
|
173
|
+
beforeId: notificationbeforelayerid,
|
|
165
174
|
isQueryable: true,
|
|
166
175
|
layersFilter: ({ metadata }) => {
|
|
167
176
|
return metadata?.["general.filter"] === "notifications";
|
|
@@ -169,7 +178,25 @@ export default function NotificationLayer(props: MaplibreStyleLayerOptions) {
|
|
|
169
178
|
maplibreLayer: baseLayer,
|
|
170
179
|
...(props || {}),
|
|
171
180
|
});
|
|
172
|
-
}, [baseLayer, props]);
|
|
181
|
+
}, [baseLayer, notificationbeforelayerid, props]);
|
|
182
|
+
|
|
183
|
+
// Update data and style layers
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
if (!baseLayer || !graphMapping) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
const graph = getCurrentGraph(graphMapping, zoom);
|
|
189
|
+
if (!graph) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
addNotificationsLayers(
|
|
193
|
+
baseLayer,
|
|
194
|
+
"notifications",
|
|
195
|
+
notifications,
|
|
196
|
+
notificationbeforelayerid,
|
|
197
|
+
graph,
|
|
198
|
+
);
|
|
199
|
+
}, [baseLayer, graphMapping, notificationbeforelayerid, notifications, zoom]);
|
|
173
200
|
|
|
174
201
|
useEffect(() => {
|
|
175
202
|
if (!map || !layer) {
|
|
@@ -2,6 +2,7 @@ import { FeatureCollection } from "geojson";
|
|
|
2
2
|
import { Feature } from "ol";
|
|
3
3
|
import { getCenter } from "ol/extent";
|
|
4
4
|
import GeoJSON from "ol/format/GeoJSON";
|
|
5
|
+
import { toLonLat } from "ol/proj";
|
|
5
6
|
|
|
6
7
|
import addSourceAndLayers from "../utils/addSourceAndLayers";
|
|
7
8
|
|
|
@@ -19,14 +20,32 @@ export const getTime = (str) => {
|
|
|
19
20
|
*/
|
|
20
21
|
const getNotificationsWithStatus = (notifications, now) => {
|
|
21
22
|
return notifications
|
|
22
|
-
.filter((
|
|
23
|
+
.filter((notification) => {
|
|
23
24
|
// TODO: The backend should be responsible to returns only good notifications.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
let notOutOfDate = notification.properties.affected_time_intervals.some(
|
|
26
|
+
(ati) => {
|
|
27
|
+
return now < new Date(ati.end);
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
if (!notOutOfDate) {
|
|
31
|
+
notOutOfDate = notification.properties.publications.some(
|
|
32
|
+
(publication) => {
|
|
33
|
+
return (
|
|
34
|
+
now >= new Date(publication.visible_from) &&
|
|
35
|
+
now <= new Date(publication.visible_until)
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
}
|
|
27
40
|
return notOutOfDate;
|
|
28
41
|
})
|
|
29
42
|
.map((n) => {
|
|
43
|
+
const isPublished = n.properties.publications.some((publication) => {
|
|
44
|
+
return (
|
|
45
|
+
now >= new Date(publication.visible_from) &&
|
|
46
|
+
now <= new Date(publication.visible_until)
|
|
47
|
+
);
|
|
48
|
+
});
|
|
30
49
|
const isActive = n.properties.affected_time_intervals.some((ati) => {
|
|
31
50
|
const {
|
|
32
51
|
end,
|
|
@@ -88,6 +107,7 @@ const getNotificationsWithStatus = (notifications, now) => {
|
|
|
88
107
|
...n.properties,
|
|
89
108
|
iconRefPoint,
|
|
90
109
|
isActive,
|
|
110
|
+
isPublished,
|
|
91
111
|
starts,
|
|
92
112
|
};
|
|
93
113
|
|
|
@@ -98,6 +118,22 @@ const getNotificationsWithStatus = (notifications, now) => {
|
|
|
98
118
|
};
|
|
99
119
|
});
|
|
100
120
|
|
|
121
|
+
if (iconRefPoint) {
|
|
122
|
+
features.push({
|
|
123
|
+
geometry: {
|
|
124
|
+
coordinates: toLonLat(iconRefPoint),
|
|
125
|
+
type: "Point",
|
|
126
|
+
},
|
|
127
|
+
id: Math.random() + "",
|
|
128
|
+
properties: {
|
|
129
|
+
...properties,
|
|
130
|
+
disruption_type: "whatever",
|
|
131
|
+
isIconRefPoint: true,
|
|
132
|
+
},
|
|
133
|
+
type: "Feature",
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
101
137
|
return {
|
|
102
138
|
...n,
|
|
103
139
|
features,
|
|
@@ -106,7 +142,7 @@ const getNotificationsWithStatus = (notifications, now) => {
|
|
|
106
142
|
});
|
|
107
143
|
};
|
|
108
144
|
|
|
109
|
-
const getCurrentGraph = (mapping: object, zoom: number) => {
|
|
145
|
+
export const getCurrentGraph = (mapping: object, zoom: number) => {
|
|
110
146
|
const breakPoints = Object.keys(mapping).map((k) => {
|
|
111
147
|
return parseFloat(k);
|
|
112
148
|
});
|
|
@@ -116,41 +152,76 @@ const getCurrentGraph = (mapping: object, zoom: number) => {
|
|
|
116
152
|
return mapping[closest || Math.min(...breakPoints)];
|
|
117
153
|
};
|
|
118
154
|
|
|
155
|
+
// export const getDisruptionActiveStyleLayers = (
|
|
156
|
+
// id = "notificationActive",
|
|
157
|
+
// graph,
|
|
158
|
+
// ) => {
|
|
159
|
+
// return [
|
|
160
|
+
// {
|
|
161
|
+
// filter: [
|
|
162
|
+
// "all",
|
|
163
|
+
// ["==", ["get", "isActive"], true],
|
|
164
|
+
// ["==", ["get", "graph"], graph],
|
|
165
|
+
// ["==", ["get", "disruption_type"], "DISRUPTION"],
|
|
166
|
+
// ],
|
|
167
|
+
// id: id,
|
|
168
|
+
// layout: { visibility: "visible" },
|
|
169
|
+
// metadata: {
|
|
170
|
+
// "general.filter": "notifications",
|
|
171
|
+
// },
|
|
172
|
+
// paint: {
|
|
173
|
+
// "line-color": "rgba(255,0,0,1)",
|
|
174
|
+
// "line-dasharray": [2, 2],
|
|
175
|
+
// "line-width": 5,
|
|
176
|
+
// },
|
|
177
|
+
// source: "notifications",
|
|
178
|
+
// type: "line",
|
|
179
|
+
// },
|
|
180
|
+
// ];
|
|
181
|
+
// };
|
|
182
|
+
|
|
119
183
|
/**
|
|
120
184
|
* This function add layers in the mapbox style to show notifications lines.
|
|
121
185
|
*/
|
|
122
186
|
const addNotificationsLayers = (
|
|
123
187
|
mapboxLayer: object,
|
|
124
|
-
|
|
188
|
+
sourceId: string,
|
|
189
|
+
sourceData: FeatureCollection,
|
|
125
190
|
beforeLayerId: string,
|
|
126
|
-
|
|
127
|
-
graphMapping: object,
|
|
191
|
+
graph: number,
|
|
128
192
|
) => {
|
|
129
193
|
if (!mapboxLayer) {
|
|
130
194
|
return;
|
|
131
195
|
}
|
|
132
|
-
|
|
133
|
-
.map((n) => {
|
|
134
|
-
return n.features;
|
|
135
|
-
})
|
|
136
|
-
.flat();
|
|
196
|
+
|
|
137
197
|
addSourceAndLayers(
|
|
138
198
|
mapboxLayer,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
data: {
|
|
142
|
-
features,
|
|
143
|
-
type: "FeatureCollection",
|
|
144
|
-
},
|
|
145
|
-
generateId: true,
|
|
146
|
-
type: "geojson",
|
|
147
|
-
},
|
|
199
|
+
sourceId,
|
|
200
|
+
sourceData,
|
|
148
201
|
[
|
|
202
|
+
// {
|
|
203
|
+
// filter: [
|
|
204
|
+
// "all",
|
|
205
|
+
// ["==", ["get", "isPreview"], true],
|
|
206
|
+
// ["==", ["get", "disruption_type"], "DISRUPTION"],
|
|
207
|
+
// ],
|
|
208
|
+
// id: "notificationsPreviewDisruption",
|
|
209
|
+
// layout: { visibility: "visible" },
|
|
210
|
+
// metadata: {
|
|
211
|
+
// "general.filter": "notifications",
|
|
212
|
+
// },
|
|
213
|
+
// paint: {
|
|
214
|
+
// "line-color": "rgba(255,255,0,0.2)",
|
|
215
|
+
// "line-width": 10,
|
|
216
|
+
// },
|
|
217
|
+
// source: "notifications",
|
|
218
|
+
// type: "line",
|
|
219
|
+
// },
|
|
149
220
|
{
|
|
150
221
|
filter: [
|
|
151
222
|
"all",
|
|
152
223
|
["==", ["get", "isActive"], true],
|
|
153
|
-
["==", ["get", "graph"],
|
|
224
|
+
["==", ["get", "graph"], graph],
|
|
154
225
|
["==", ["get", "disruption_type"], "DISRUPTION"],
|
|
155
226
|
],
|
|
156
227
|
id: "notificationsActive",
|
|
@@ -166,6 +237,103 @@ const addNotificationsLayers = (
|
|
|
166
237
|
source: "notifications",
|
|
167
238
|
type: "line",
|
|
168
239
|
},
|
|
240
|
+
// {
|
|
241
|
+
// filter: [
|
|
242
|
+
// "all",
|
|
243
|
+
// ["==", ["get", "isPreview"], true],
|
|
244
|
+
// // ["==", ["get", "graph"], graph],
|
|
245
|
+
// ["==", ["get", "disruption_type"], "DEVIATION"],
|
|
246
|
+
// ],
|
|
247
|
+
// id: "notificationsPreviewDeviation",
|
|
248
|
+
// layout: { visibility: "visible" },
|
|
249
|
+
// metadata: {
|
|
250
|
+
// "general.filter": "notifications",
|
|
251
|
+
// },
|
|
252
|
+
// paint: {
|
|
253
|
+
// "line-color": "rgba(255,255,0,0.2)",
|
|
254
|
+
// "line-width": 10,
|
|
255
|
+
// },
|
|
256
|
+
// source: "notifications",
|
|
257
|
+
// type: "line",
|
|
258
|
+
// },
|
|
259
|
+
{
|
|
260
|
+
filter: [
|
|
261
|
+
"all",
|
|
262
|
+
["==", ["get", "isActive"], true],
|
|
263
|
+
["==", ["get", "disruption_type"], "DEVIATION"],
|
|
264
|
+
],
|
|
265
|
+
id: "notificationsActiveDeviation",
|
|
266
|
+
layout: { visibility: "visible" },
|
|
267
|
+
paint: {
|
|
268
|
+
"line-color": "#000000",
|
|
269
|
+
"line-dasharray": [2, 2],
|
|
270
|
+
"line-opacity": 0.5,
|
|
271
|
+
"line-width": 5,
|
|
272
|
+
},
|
|
273
|
+
source: "notifications",
|
|
274
|
+
type: "line",
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
filter: [
|
|
278
|
+
"all",
|
|
279
|
+
["==", ["get", "isIconRefPoint"], true],
|
|
280
|
+
// ["==", ["get", "isActive"], true],
|
|
281
|
+
],
|
|
282
|
+
id: "notificationsIconRefPointActive",
|
|
283
|
+
layout: { visibility: "visible" },
|
|
284
|
+
metadata: {
|
|
285
|
+
"general.filter": "notifications",
|
|
286
|
+
},
|
|
287
|
+
paint: {
|
|
288
|
+
"circle-color": "#ff0000",
|
|
289
|
+
"circle-radius": 10,
|
|
290
|
+
},
|
|
291
|
+
source: "notifications",
|
|
292
|
+
type: "circle",
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
{
|
|
296
|
+
filter: [
|
|
297
|
+
"all",
|
|
298
|
+
["==", ["get", "isIconRefPoint"], true],
|
|
299
|
+
["==", ["get", "isActive"], true],
|
|
300
|
+
],
|
|
301
|
+
id: "notificationsIconRefPointActive",
|
|
302
|
+
layout: {
|
|
303
|
+
"icon-image": "warning",
|
|
304
|
+
"icon-size": 0.15,
|
|
305
|
+
visibility: "visible",
|
|
306
|
+
},
|
|
307
|
+
metadata: {
|
|
308
|
+
"general.filter": "notifications",
|
|
309
|
+
},
|
|
310
|
+
paint: {},
|
|
311
|
+
source: "notifications",
|
|
312
|
+
type: "symbol",
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
filter: [
|
|
316
|
+
"all",
|
|
317
|
+
["==", ["get", "isIconRefPoint"], true],
|
|
318
|
+
["==", ["get", "isActive"], false],
|
|
319
|
+
["==", ["get", "isPublished"], true],
|
|
320
|
+
],
|
|
321
|
+
id: "notificationsIconRefPointNonActive",
|
|
322
|
+
layout: {
|
|
323
|
+
"icon-image": "warningbanner",
|
|
324
|
+
"icon-size": 0.15,
|
|
325
|
+
"text-field": ["get", "starts"],
|
|
326
|
+
"text-offset": [1.5, 0],
|
|
327
|
+
"text-size": 8,
|
|
328
|
+
visibility: "visible",
|
|
329
|
+
},
|
|
330
|
+
metadata: {
|
|
331
|
+
"general.filter": "notifications",
|
|
332
|
+
},
|
|
333
|
+
paint: {},
|
|
334
|
+
source: "notifications",
|
|
335
|
+
type: "symbol",
|
|
336
|
+
},
|
|
169
337
|
],
|
|
170
338
|
beforeLayerId,
|
|
171
339
|
);
|
|
@@ -34,7 +34,7 @@ function RouteIcon({
|
|
|
34
34
|
departure?.line ||
|
|
35
35
|
stopSequence?.line ||
|
|
36
36
|
trajectory?.properties?.line;
|
|
37
|
-
const type = stopSequence?.type || trajectory?.type;
|
|
37
|
+
const type = lineToUse?.type || stopSequence?.type || trajectory?.type;
|
|
38
38
|
const backgroundColor = getMainColorForVehicle(
|
|
39
39
|
line || departure || stopSequence || trajectory,
|
|
40
40
|
);
|
|
@@ -46,7 +46,10 @@ function RouteIcon({
|
|
|
46
46
|
|
|
47
47
|
const fontSize = fontSizesByNbLetters[text.length] || 12;
|
|
48
48
|
const font = getTextFontForVehicle(fontSize, text);
|
|
49
|
-
|
|
49
|
+
|
|
50
|
+
// RealtimeIcon only for stopsequence for now
|
|
51
|
+
const hasRealtime = stopSequence?.has_realtime_journey === true;
|
|
52
|
+
const showNoRealtimeIcon = !!stopSequence;
|
|
50
53
|
const isCancelled = stopSequence?.stations[0]?.state === "JOURNEY_CANCELLED";
|
|
51
54
|
|
|
52
55
|
if (borderColor === backgroundColor) {
|
|
@@ -67,7 +70,7 @@ function RouteIcon({
|
|
|
67
70
|
>
|
|
68
71
|
{children || text}
|
|
69
72
|
|
|
70
|
-
{!isCancelled && !hasRealtime && (
|
|
73
|
+
{showNoRealtimeIcon && !isCancelled && !hasRealtime && (
|
|
71
74
|
<NoRealtime className={"absolute -left-2 -top-2"} />
|
|
72
75
|
)}
|
|
73
76
|
</span>
|
|
@@ -6,11 +6,16 @@ import useMapContext from "../utils/hooks/useMapContext";
|
|
|
6
6
|
import useRouteStop from "../utils/hooks/useRouteStop";
|
|
7
7
|
|
|
8
8
|
export type RouteStopProgressProps = {
|
|
9
|
+
lineColor?: string;
|
|
9
10
|
svgProps?: JSX.HTMLAttributes<SVGElement> & PreactDOMAttributes;
|
|
10
11
|
} & JSX.HTMLAttributes<HTMLDivElement> &
|
|
11
12
|
PreactDOMAttributes;
|
|
12
13
|
|
|
13
|
-
function RouteStopProgress({
|
|
14
|
+
function RouteStopProgress({
|
|
15
|
+
lineColor,
|
|
16
|
+
svgProps,
|
|
17
|
+
...props
|
|
18
|
+
}: RouteStopProgressProps) {
|
|
14
19
|
const { stopSequence } = useMapContext();
|
|
15
20
|
const { invertColor, status } = useRouteStop();
|
|
16
21
|
const { isBoarding, isFirst, isLast, isLeft, isPassed, progress } = status;
|
|
@@ -19,16 +24,16 @@ function RouteStopProgress({ svgProps, ...props }: RouteStopProgressProps) {
|
|
|
19
24
|
const yDone = `${progress}%`;
|
|
20
25
|
|
|
21
26
|
const greyColor = "rgb(156, 163, 175)";
|
|
22
|
-
const
|
|
27
|
+
const lineColorr = lineColor || getMainColorForVehicle(stopSequence);
|
|
23
28
|
|
|
24
|
-
let colorScheme = isPassed ? greyColor :
|
|
25
|
-
let invertColorScheme = isPassed ?
|
|
29
|
+
let colorScheme = isPassed ? greyColor : lineColorr;
|
|
30
|
+
let invertColorScheme = isPassed ? lineColorr : greyColor;
|
|
26
31
|
let progressDoneColor = greyColor;
|
|
27
32
|
|
|
28
33
|
if (invertColor) {
|
|
29
|
-
colorScheme = isPassed ?
|
|
30
|
-
invertColorScheme = isPassed ? greyColor :
|
|
31
|
-
progressDoneColor =
|
|
34
|
+
colorScheme = isPassed ? lineColorr : greyColor;
|
|
35
|
+
invertColorScheme = isPassed ? greyColor : lineColorr;
|
|
36
|
+
progressDoneColor = lineColorr;
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
const circleColor =
|