MapInstance.res.mjs
1// Generated by ReScript, PLEASE EDIT WITH CARE
2
3import * as Log from "../utils/Log.res.mjs";
4import * as Route from "../ffi/Route.res.mjs";
5import * as State from "../State.res.mjs";
6import * as Style from "../ffi/Style.res.mjs";
7import * as Preact from "../ffi/Preact.res.mjs";
8import * as Window from "../ffi/Window.res.mjs";
9import * as MapEvents from "./MapEvents.res.mjs";
10import * as ContextMenu from "./ContextMenu.res.mjs";
11import * as Core__Option from "@rescript/core/lib/es6/src/Core__Option.res.mjs";
12import * as Hooks from "preact/hooks";
13import * as LucidePreact from "lucide-preact";
14import * as Signals from "@preact/signals";
15import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
16import * as JsxRuntime from "preact/jsx-runtime";
17import * as ReactMaplibre from "@vis.gl/react-maplibre";
18
19function MapInstance$WaypointMarker(props) {
20 let lat = props.lat;
21 let lon = props.lon;
22 let id = props.id;
23 return JsxRuntime.jsxs(JsxRuntime.Fragment, {
24 children: [
25 JsxRuntime.jsx(ReactMaplibre.Marker, {
26 longitude: lon,
27 latitude: lat,
28 children: JsxRuntime.jsx(LucidePreact.LocateFixed, {
29 size: 24,
30 color: props.error.length === 0 ? "var(--color-blue)" : "var(--color-red)",
31 strokeWidth: 3,
32 className: "rounded-full bg-[#FFFFFF66]"
33 }),
34 anchor: "center",
35 opacity: 1.0,
36 opacityWhenCovered: 1.0
37 }, id),
38 State.zoom.value > 3.0 ? JsxRuntime.jsx(ReactMaplibre.Marker, {
39 longitude: lon,
40 latitude: lat,
41 children: JsxRuntime.jsx("div", {
42 children: props.label,
43 className: "bg-[#333333] text-white rounded-sm px-1"
44 }),
45 anchor: "top-left",
46 offset: [
47 6,
48 6
49 ],
50 color: "#333333",
51 opacity: 1.0,
52 opacityWhenCovered: 1.0
53 }, id + "-text") : null
54 ]
55 });
56}
57
58let WaypointMarker = {
59 make: MapInstance$WaypointMarker
60};
61
62let popup = Signals.signal(undefined);
63
64let initialRender = Signals.signal(true);
65
66function MapInstance(props) {
67 let doc = props.doc;
68 let waypoints = State.getOrCreateWaypointsSignal(doc);
69 let cmap = Hooks.useRef(null);
70 let flyToPoint = (point, padding) => {
71 let match = cmap.current;
72 if (!(match == null)) {
73 if (padding !== undefined) {
74 match.flyTo({
75 center: point,
76 padding: {
77 bottom: padding[0],
78 left: padding[1],
79 top: 0,
80 right: 0
81 }
82 });
83 } else {
84 match.flyTo({
85 center: point
86 });
87 }
88 return;
89 }
90 };
91 let routeHashes = Route.extractRouteHashes(waypoints.value);
92 let currentWaypoints = waypoints.value;
93 let len = currentWaypoints.length;
94 let tmp;
95 if (len !== 1) {
96 tmp = len !== 0 ? currentWaypoints.map(wp => {
97 let match = wp.point;
98 return JsxRuntime.jsx(MapInstance$WaypointMarker, {
99 id: wp.id,
100 lon: match[0],
101 lat: match[1],
102 label: wp.label,
103 error: Core__Option.getOr(wp.error, [])
104 });
105 }) : JsxRuntime.jsx(JsxRuntime.Fragment, {});
106 } else {
107 let wp1 = currentWaypoints[0];
108 let match = wp1.point;
109 if (Window.isMobile.value) {
110 let size = Window.getSize();
111 if (size !== undefined) {
112 flyToPoint(wp1.point, [
113 size.height / 4 | 0,
114 0
115 ]);
116 } else {
117 flyToPoint(wp1.point, undefined);
118 }
119 } else {
120 let size$1 = Window.getSize();
121 if (size$1 !== undefined) {
122 flyToPoint(wp1.point, [
123 0,
124 size$1.width / 4 | 0
125 ]);
126 } else {
127 flyToPoint(wp1.point, undefined);
128 }
129 }
130 tmp = JsxRuntime.jsx(MapInstance$WaypointMarker, {
131 id: wp1.id,
132 lon: match[0],
133 lat: match[1],
134 label: wp1.label,
135 error: Core__Option.getOr(wp1.error, [])
136 });
137 }
138 return JsxRuntime.jsxs(ReactMaplibre.Map, {
139 id: "map",
140 cursor: "crosshair",
141 mapStyle: Primitive_option.some(Style.rtwStyle),
142 initialViewState: {
143 longitude: 83.85382,
144 latitude: 27.70972,
145 zoom: 8.0
146 },
147 interactiveLayerIds: routeHashes.map(hash => `route-layer-` + hash),
148 onLoad: event => {
149 if (initialRender.value && currentWaypoints.length > 0) {
150 let map = event.target;
151 let lats = currentWaypoints.map(p => p.point[1]);
152 let lons = currentWaypoints.map(p => p.point[0]);
153 let bbox_0 = Math.min(...lons);
154 let bbox_1 = Math.min(...lats);
155 let bbox_2 = Math.max(...lons);
156 let bbox_3 = Math.max(...lats);
157 let bbox = [
158 bbox_0,
159 bbox_1,
160 bbox_2,
161 bbox_3
162 ];
163 let isSinglePoint = currentWaypoints.length === 1;
164 if (Window.isMobile.value) {
165 let match = Window.getSize();
166 if (match !== undefined) {
167 if (isSinglePoint) {
168 Core__Option.getOr(Core__Option.map(currentWaypoints[0], wp => flyToPoint(wp.point, [
169 match.height / 2 | 0,
170 0
171 ])), undefined);
172 } else {
173 map.fitBounds(bbox, {
174 padding: {
175 bottom: (match.height / 2 | 0) + 50 | 0,
176 left: 50,
177 top: 50,
178 right: 50
179 }
180 });
181 }
182 } else {
183 map.fitBounds(bbox);
184 }
185 } else {
186 let match$1 = Window.getSize();
187 if (match$1 !== undefined) {
188 if (isSinglePoint) {
189 Core__Option.getOr(Core__Option.map(currentWaypoints[0], wp => flyToPoint(wp.point, [
190 0,
191 match$1.width / 4 | 0
192 ])), undefined);
193 } else {
194 map.fitBounds(bbox, {
195 padding: {
196 bottom: 50,
197 left: match$1.width / 4 | 0,
198 top: 50,
199 right: 50
200 }
201 });
202 }
203 } else {
204 map.fitBounds(bbox);
205 }
206 }
207 }
208 initialRender.value = false;
209 let center = event.target.getCenter();
210 State.center.value = [
211 center.lng,
212 center.lat
213 ];
214 State.zoom.value = event.target.getZoom();
215 cmap.current = event.target;
216 },
217 onMouseEnter: event => MapEvents.handleDistance(event, popup, currentWaypoints),
218 onMouseLeave: _event => {
219 popup.value = undefined;
220 },
221 onContextMenu: evt => {
222 ContextMenu.show.value = evt;
223 },
224 onMoveEnd: event => {
225 State.center.value = [
226 event.viewState.longitude,
227 event.viewState.latitude
228 ];
229 State.zoom.value = event.viewState.zoom;
230 Log.debug("move", {
231 lat: event.viewState.latitude.toFixed(6),
232 lng: event.viewState.longitude.toFixed(6),
233 zoom: event.viewState.zoom.toFixed(1)
234 });
235 },
236 children: [
237 routeHashes.map(hash => {
238 let paintDict = {};
239 return JsxRuntime.jsxs(JsxRuntime.Fragment, {
240 children: [
241 JsxRuntime.jsx(ReactMaplibre.Source, {
242 id: `route-` + hash,
243 type: "geojson",
244 data: Route.getGeoJSONUrl(hash)
245 }),
246 JsxRuntime.jsx(ReactMaplibre.Layer, {
247 id: `route-layer-` + hash,
248 type: "line",
249 source: `route-` + hash,
250 paint: (paintDict["line-color"] = "#205ea6", paintDict["line-width"] = 8.0, paintDict)
251 })
252 ]
253 }, `route-fragment-` + hash);
254 }),
255 tmp,
256 Preact.option(popup.value),
257 JsxRuntime.jsx(ContextMenu.make, {
258 doc: doc
259 })
260 ]
261 });
262}
263
264let make = MapInstance;
265
266export {
267 WaypointMarker,
268 popup,
269 initialRender,
270 make,
271}
272/* popup Not a pure module */