react-native-maplibre-lite 0.1.4 → 0.1.6

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.
@@ -1 +1 @@
1
- {"version":3,"file":"webMapBuild.d.ts","sourceRoot":"","sources":["../../../../src/components/webMapBuild.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,0+hzCAA4/4yC,CAAC"}
1
+ {"version":3,"file":"webMapBuild.d.ts","sourceRoot":"","sources":["../../../../src/components/webMapBuild.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,y/qzCAAgyhzC,CAAC"}
@@ -5,5 +5,6 @@ import { Polyline } from './components/Polyline';
5
5
  export { MapView, Marker, Polygon, Polyline };
6
6
  export default MapView;
7
7
  export type { MapViewRef } from './components/MapView';
8
- export type { EventParams, MapLiteWebError, MarkerProps, NavigatorInstructionParams, NavigatorLang, NavigatorLngLat, NavigatorPositionMode, NavigatorPositionSetParams, NavigatorRouteSetParams, PolygonProps, PolylineProps, } from './components/types';
8
+ export type { EventParams, MapLiteWebError, MarkerProps, NavigatorChromeParams, NavigatorInstructionParams, NavigatorLang, NavigatorLngLat, NavigatorProfile, NavigatorPositionMode, NavigatorPositionSetParams, NavigatorRouteSetParams, PolygonProps, PolylineProps, } from './components/types';
9
+ export { NAVIGATOR_PROFILE_IDS } from './components/types';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC9C,eAAe,OAAO,CAAC;AAEvB,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EACR,WAAW,EACX,eAAe,EACf,WAAW,EACX,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,YAAY,EACZ,aAAa,GAChB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC9C,eAAe,OAAO,CAAC;AAEvB,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EACR,WAAW,EACX,eAAe,EACf,WAAW,EACX,qBAAqB,EACrB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,YAAY,EACZ,aAAa,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-maplibre-lite",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Lightweight MapLibre GL JS wrapper using WebView",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -13,6 +13,7 @@
13
13
  "./package.json": "./package.json"
14
14
  },
15
15
  "files": [
16
+ "demo",
16
17
  "src",
17
18
  "lib",
18
19
  "android",
@@ -88,7 +89,9 @@
88
89
  "react-native": "*",
89
90
  "react-native-webview": "*",
90
91
  "@react-native-async-storage/async-storage": "*",
91
- "@types/geojson": "*"
92
+ "@sayem314/react-native-keep-awake": "*",
93
+ "@types/geojson": "*",
94
+ "@react-native-community/geolocation": "*"
92
95
  },
93
96
  "workspaces": [
94
97
  "example"
@@ -1,29 +1,34 @@
1
1
  import {
2
- createContext,
3
- forwardRef,
4
- useContext,
5
- useEffect,
6
- useImperativeHandle,
7
- useRef,
8
- useState,
2
+ createContext,
3
+ forwardRef,
4
+ useContext,
5
+ useEffect,
6
+ useImperativeHandle,
7
+ useRef,
8
+ useState,
9
9
  } from 'react';
10
10
 
11
11
  import {
12
- type StyleProp,
13
- Platform,
14
- View,
15
- type ViewStyle,
12
+ Platform,
13
+ type StyleProp,
14
+ View,
15
+ type ViewStyle,
16
16
  } from 'react-native';
17
17
  import { WebView } from 'react-native-webview';
18
18
 
19
+ import Geolocation from '@react-native-community/geolocation';
20
+ import KeepAwake from '@sayem314/react-native-keep-awake';
21
+
19
22
  import MapPlaceholder from './MapPlaceholder';
20
23
  import MapSelectPoint, { type MapSelectPointType } from './MapSelectPoint';
21
24
  import {
22
25
  type EventParams,
23
26
  type MapLiteWebError,
24
27
  type MarkerProps,
28
+ type NavigatorChromeParams,
25
29
  type NavigatorInstructionParams,
26
30
  type NavigatorLang,
31
+ type NavigatorProfile,
27
32
  type NavigatorPositionSetParams,
28
33
  type NavigatorRouteSetParams,
29
34
  type PolygonProps,
@@ -87,11 +92,24 @@ interface MapViewProps {
87
92
  graphhopperUrl?: string;
88
93
  /** Язык HUD и инструкций навигатора. По умолчанию веб-часть использует `ru`. */
89
94
  navigatorLang?: NavigatorLang;
95
+ /**
96
+ * Профиль GraphHopper для маршрута (`profile` в API).
97
+ * Неизвестная строка или отсутствие — как `car`. Только при `navigator: true`.
98
+ */
99
+ navigatorProfile?: NavigatorProfile | string;
100
+ /**
101
+ * Navigator chrome: route line, arrow accent, HUD colors. All keys optional.
102
+ * Sent once in WebView `init` as `navigatorChrome`.
103
+ */
104
+ navigatorChrome?: NavigatorChromeParams;
90
105
  onNavigatorRouteSet?: (params: NavigatorRouteSetParams) => void;
91
106
  onNavigatorInstruction?: (params: NavigatorInstructionParams) => void;
92
107
  onNavigatorPositionSet?: (params: NavigatorPositionSetParams) => void;
93
108
  /** Ошибки команд WebView (`type: 'error'` из карты). */
94
109
  onMapLiteError?: (err: MapLiteWebError) => void;
110
+
111
+
112
+ developerLocalhostBundleUrl?: string;
95
113
  }
96
114
 
97
115
  export type MapViewRef = {
@@ -151,9 +169,17 @@ const getBoundsFromCoords = (
151
169
  ];
152
170
  };
153
171
 
172
+ /** Минимальный интервал между отправками позиции в WebView (мост RN↔JS). */
173
+ const NAVIGATOR_GPS_FORWARD_MIN_MS = 500;
174
+
154
175
  export const MapView = forwardRef<MapViewRef, MapViewProps>((props, ref) => {
155
176
  const webViewRef = useRef<WebView | null>(null);
156
177
  const [inited, setInited] = useState(false);
178
+ const initedRef = useRef(false);
179
+
180
+ useEffect(() => {
181
+ initedRef.current = inited;
182
+ }, [inited]);
157
183
 
158
184
  const coordsInMapRef = useRef<Record<string, [number, number][]>>({});
159
185
  const markersClickHandlers = useRef<Record<string, () => void>>({});
@@ -171,6 +197,9 @@ export const MapView = forwardRef<MapViewRef, MapViewProps>((props, ref) => {
171
197
  webViewRef.current?.postMessage(JSON.stringify(message));
172
198
  };
173
199
 
200
+ const sendToWebViewRef = useRef(sendToWebView);
201
+ sendToWebViewRef.current = sendToWebView;
202
+
174
203
  const initMap = async () => {
175
204
  if (__DEV__) {
176
205
  console.log('MapView: initMap');
@@ -203,6 +232,8 @@ export const MapView = forwardRef<MapViewRef, MapViewProps>((props, ref) => {
203
232
  navigator: props.navigator === true,
204
233
  graphhopperUrl: props.graphhopperUrl,
205
234
  navigatorLang: props.navigatorLang,
235
+ navigatorProfile: props.navigatorProfile,
236
+ navigatorChrome: props.navigatorChrome,
206
237
  },
207
238
  });
208
239
  };
@@ -419,6 +450,56 @@ export const MapView = forwardRef<MapViewRef, MapViewProps>((props, ref) => {
419
450
  }
420
451
  };
421
452
 
453
+ useEffect(() => {
454
+ if (!props.navigator) {
455
+ return;
456
+ }
457
+
458
+ let lastForwardedAt = 0;
459
+
460
+ const watchId = Geolocation.watchPosition(
461
+ (position) => {
462
+ if (!initedRef.current) {
463
+ return;
464
+ }
465
+
466
+ const lat = position.coords.latitude;
467
+ const lng = position.coords.longitude;
468
+ if (!Number.isFinite(lat) || !Number.isFinite(lng)) {
469
+ return;
470
+ }
471
+
472
+ const now = Date.now();
473
+ if (now - lastForwardedAt < NAVIGATOR_GPS_FORWARD_MIN_MS) {
474
+ return;
475
+ }
476
+ lastForwardedAt = now;
477
+
478
+ sendToWebViewRef.current({
479
+ function: 'setNavigatorPosition',
480
+ params: { latitude: lat, longitude: lng },
481
+ });
482
+ },
483
+ (error) => {
484
+ console.error('MapView: error watching position', error);
485
+ },
486
+ {
487
+ enableHighAccuracy: true,
488
+ /** Android: желаемый интервал обновлений от провайдера. */
489
+ interval: 1000,
490
+ fastestInterval: 1000,
491
+ /** iOS / часть сценариев: не слать, если сдвиг меньше N метров. */
492
+ distanceFilter: 1,
493
+ /** Не опираться на слишком старый кэш при запросе точки. */
494
+ maximumAge: 2000,
495
+ }
496
+ );
497
+
498
+ return () => {
499
+ Geolocation.clearWatch(watchId);
500
+ };
501
+ }, [props.navigator]);
502
+
422
503
  return (
423
504
  <View style={props.style}>
424
505
 
@@ -437,7 +518,7 @@ export const MapView = forwardRef<MapViewRef, MapViewProps>((props, ref) => {
437
518
  ref={webViewRef}
438
519
  style={{ flex: 1, backgroundColor: 'transparent' }}
439
520
  originWhitelist={['*']}
440
- source={{ html: MAP_HTML }}
521
+ source={!!props.developerLocalhostBundleUrl ? { uri: props.developerLocalhostBundleUrl } : { html: MAP_HTML }}
441
522
  onMessage={event => {
442
523
  onReceiveMessageFromWebView(event.nativeEvent.data);
443
524
  }}
@@ -472,6 +553,7 @@ export const MapView = forwardRef<MapViewRef, MapViewProps>((props, ref) => {
472
553
  {!inited && (
473
554
  <MapPlaceholder theme={props.placeholderTheme ?? 'light'} />
474
555
  )}
556
+ {!!props.navigator && <KeepAwake />}
475
557
 
476
558
  </View>
477
559
  );
@@ -45,6 +45,44 @@ export type EventParams = {
45
45
 
46
46
  export type NavigatorLang = 'ru' | 'en'
47
47
 
48
+ /**
49
+ * Navigator look-and-feel (route line, arrow accent, HUD). Passed to WebView `init` as `navigatorChrome`.
50
+ * All fields are optional; defaults match the built-in blue theme.
51
+ */
52
+ export type NavigatorChromeParams = {
53
+ /** Accent in hex (`#rgb` / `#rrggbb`): map arrow gradient and maneuver icon tile in the HUD. */
54
+ accent?: string,
55
+ /** Main route line color (default was `#3b82f6`). */
56
+ routeLine?: string,
57
+ /** Wide route line underlay (default was `#1e3a8a`). */
58
+ routeOutline?: string,
59
+ /** HUD panel background: any valid CSS (`rgba(...)`, `linear-gradient(...)`, etc.). */
60
+ hudBackground?: string,
61
+ /** Primary text color on the HUD. */
62
+ hudForeground?: string,
63
+ /** Secondary text (street, summary, ETA); divider tone is derived from this when it is hex. */
64
+ hudMuted?: string,
65
+ }
66
+
67
+ /** Значения `profile` для GraphHopper `POST …/route` (см. документацию GH). */
68
+ export const NAVIGATOR_PROFILE_IDS = [
69
+ 'car',
70
+ 'car_avoid_motorway',
71
+ 'car_avoid_ferry',
72
+ 'car_avoid_toll',
73
+ 'small_truck',
74
+ 'truck',
75
+ 'scooter',
76
+ 'foot',
77
+ 'hike',
78
+ 'bike',
79
+ 'mtb',
80
+ 'racingbike',
81
+ 'ecargobike',
82
+ ] as const
83
+
84
+ export type NavigatorProfile = (typeof NAVIGATOR_PROFILE_IDS)[number]
85
+
48
86
  /** [longitude, latitude] — как в GeoJSON / GraphHopper. */
49
87
  export type NavigatorLngLat = {
50
88
  lng: number,