react-native-maplibre-lite 0.2.0 → 0.2.2

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.
Files changed (78) hide show
  1. package/README.md +92 -6
  2. package/lib/module/components/MapView.js +116 -14
  3. package/lib/module/components/MapView.js.map +1 -1
  4. package/lib/module/components/NavigatorHud.js +152 -0
  5. package/lib/module/components/NavigatorHud.js.map +1 -0
  6. package/lib/module/components/NavigatorRecenterButton.js +48 -0
  7. package/lib/module/components/NavigatorRecenterButton.js.map +1 -0
  8. package/lib/module/components/NavigatorVoiceControl.js +173 -0
  9. package/lib/module/components/NavigatorVoiceControl.js.map +1 -0
  10. package/lib/module/components/navigatorChromeTheme.js +98 -0
  11. package/lib/module/components/navigatorChromeTheme.js.map +1 -0
  12. package/lib/module/components/navigatorManeuverIcon.js +210 -0
  13. package/lib/module/components/navigatorManeuverIcon.js.map +1 -0
  14. package/lib/module/components/navigatorVoiceCatalog.js +261 -0
  15. package/lib/module/components/navigatorVoiceCatalog.js.map +1 -0
  16. package/lib/module/components/navigatorVoiceKeys.js +14 -0
  17. package/lib/module/components/navigatorVoiceKeys.js.map +1 -0
  18. package/lib/module/components/navigatorVoicePlayer.js +100 -0
  19. package/lib/module/components/navigatorVoicePlayer.js.map +1 -0
  20. package/lib/module/components/navigatorVoiceStrings.js +31 -0
  21. package/lib/module/components/navigatorVoiceStrings.js.map +1 -0
  22. package/lib/module/components/types.js +22 -0
  23. package/lib/module/components/types.js.map +1 -1
  24. package/lib/module/components/useNavigatorVoice.js +78 -0
  25. package/lib/module/components/useNavigatorVoice.js.map +1 -0
  26. package/lib/module/components/utils.js +26 -0
  27. package/lib/module/components/utils.js.map +1 -1
  28. package/lib/module/components/webMapBuild.js +1 -1
  29. package/lib/module/components/webMapBuild.js.map +1 -1
  30. package/lib/module/index.js.map +1 -1
  31. package/lib/typescript/src/components/MapView.d.ts +14 -1
  32. package/lib/typescript/src/components/MapView.d.ts.map +1 -1
  33. package/lib/typescript/src/components/NavigatorHud.d.ts +13 -0
  34. package/lib/typescript/src/components/NavigatorHud.d.ts.map +1 -0
  35. package/lib/typescript/src/components/NavigatorRecenterButton.d.ts +11 -0
  36. package/lib/typescript/src/components/NavigatorRecenterButton.d.ts.map +1 -0
  37. package/lib/typescript/src/components/NavigatorVoiceControl.d.ts +20 -0
  38. package/lib/typescript/src/components/NavigatorVoiceControl.d.ts.map +1 -0
  39. package/lib/typescript/src/components/navigatorChromeTheme.d.ts +19 -0
  40. package/lib/typescript/src/components/navigatorChromeTheme.d.ts.map +1 -0
  41. package/lib/typescript/src/components/navigatorManeuverIcon.d.ts +20 -0
  42. package/lib/typescript/src/components/navigatorManeuverIcon.d.ts.map +1 -0
  43. package/lib/typescript/src/components/navigatorVoiceCatalog.d.ts +50 -0
  44. package/lib/typescript/src/components/navigatorVoiceCatalog.d.ts.map +1 -0
  45. package/lib/typescript/src/components/navigatorVoiceKeys.d.ts +10 -0
  46. package/lib/typescript/src/components/navigatorVoiceKeys.d.ts.map +1 -0
  47. package/lib/typescript/src/components/navigatorVoicePlayer.d.ts +15 -0
  48. package/lib/typescript/src/components/navigatorVoicePlayer.d.ts.map +1 -0
  49. package/lib/typescript/src/components/navigatorVoiceStrings.d.ts +19 -0
  50. package/lib/typescript/src/components/navigatorVoiceStrings.d.ts.map +1 -0
  51. package/lib/typescript/src/components/types.d.ts +83 -17
  52. package/lib/typescript/src/components/types.d.ts.map +1 -1
  53. package/lib/typescript/src/components/useNavigatorVoice.d.ts +20 -0
  54. package/lib/typescript/src/components/useNavigatorVoice.d.ts.map +1 -0
  55. package/lib/typescript/src/components/utils.d.ts +9 -0
  56. package/lib/typescript/src/components/utils.d.ts.map +1 -1
  57. package/lib/typescript/src/components/webMapBuild.d.ts +1 -1
  58. package/lib/typescript/src/components/webMapBuild.d.ts.map +1 -1
  59. package/lib/typescript/src/index.d.ts +1 -1
  60. package/lib/typescript/src/index.d.ts.map +1 -1
  61. package/package.json +16 -7
  62. package/resources/README.md +62 -0
  63. package/resources/map.html +797 -0
  64. package/src/components/MapView.tsx +154 -8
  65. package/src/components/NavigatorHud.tsx +166 -0
  66. package/src/components/NavigatorRecenterButton.tsx +45 -0
  67. package/src/components/NavigatorVoiceControl.tsx +198 -0
  68. package/src/components/navigatorChromeTheme.ts +118 -0
  69. package/src/components/navigatorManeuverIcon.tsx +177 -0
  70. package/src/components/navigatorVoiceCatalog.ts +316 -0
  71. package/src/components/navigatorVoiceKeys.ts +132 -0
  72. package/src/components/navigatorVoicePlayer.tsx +126 -0
  73. package/src/components/navigatorVoiceStrings.ts +42 -0
  74. package/src/components/types.ts +87 -18
  75. package/src/components/useNavigatorVoice.ts +96 -0
  76. package/src/components/utils.ts +28 -0
  77. package/src/components/webMapBuild.ts +1 -1
  78. package/src/index.tsx +8 -0
@@ -1,21 +1,25 @@
1
-
2
- export type MarkerProps = {
3
- ignoreFitBounds?: boolean,
1
+ /** RN → Web: `addMarker` (`MapLiteController.MarkerParams`). */
2
+ export type MapLiteMarkerParams = {
4
3
  uniqueId: string,
5
- onPress?: () => void,
6
4
  latitude: number,
7
5
  longitude: number,
8
6
  color?: string,
9
-
10
7
  iconUrl?: string,
11
8
  iconWidth?: number,
12
9
  iconHeight?: number,
13
10
  html?: string,
11
+ }
14
12
 
13
+ /** RN → Web: `addPolyline` (`MapLiteController.PolylineParams`). */
14
+ export type MapLitePolylineParams = {
15
+ uniqueId: string,
16
+ coordinates: [number, number][],
17
+ color?: string,
18
+ width?: number,
15
19
  }
16
20
 
17
- export type PolygonProps = {
18
- ignoreFitBounds?: boolean,
21
+ /** RN Web: `addPolygon` (`MapLiteController.PolygonParams`). */
22
+ export type MapLitePolygonParams = {
19
23
  uniqueId: string,
20
24
  coordinates: [number, number][],
21
25
  fillColor?: string,
@@ -23,16 +27,24 @@ export type PolygonProps = {
23
27
  strokeColor?: string,
24
28
  strokeOpacity?: number,
25
29
  strokeWidth?: number,
30
+ }
26
31
 
32
+ /** RN → Web: `removeMarker` / `removePolyline` / `removePolygon`. */
33
+ export type MapLiteRemoveOverlayParams = {
34
+ uniqueId: string,
27
35
  }
28
36
 
29
- export type PolylineProps = {
37
+ export type MarkerProps = MapLiteMarkerParams & {
30
38
  ignoreFitBounds?: boolean,
31
- uniqueId: string,
32
- color?: string,
33
- width?: number,
34
- coordinates: [number, number][],
39
+ onPress?: () => void,
40
+ }
35
41
 
42
+ export type PolygonProps = MapLitePolygonParams & {
43
+ ignoreFitBounds?: boolean,
44
+ }
45
+
46
+ export type PolylineProps = MapLitePolylineParams & {
47
+ ignoreFitBounds?: boolean,
36
48
  }
37
49
 
38
50
  /** Web → RN: `postToNative` payload (`webProject/src/map/types.ts`). */
@@ -114,6 +126,45 @@ export type NavigatorPositionSetParams = {
114
126
  distanceFromRouteMeters: number,
115
127
  }
116
128
 
129
+ /**
130
+ * Web → RN: `navigatorHud` event. View-model панели маршрута (HUD).
131
+ * Все строки уже локализованы/отформатированы в вебе — RN рисует «как есть».
132
+ */
133
+ export type NavigatorHudState = {
134
+ /** Показывать ли панель. */
135
+ visible: boolean,
136
+ /** Режим «кликни по карте, чтобы задать позицию» (dev): показать подсказку. */
137
+ pick?: boolean,
138
+ /** Состояние «Вы приехали». */
139
+ arrived?: boolean,
140
+ /** Код манёвра GraphHopper для иконки. */
141
+ sign?: number,
142
+ /** Крупная строка: дистанция / «Прибытие» / заголовок прибытия. */
143
+ distanceLabel?: string,
144
+ /** Текст манёвра / подзаголовок. */
145
+ maneuverText?: string,
146
+ /** Имя улицы после манёвра. */
147
+ streetName?: string,
148
+ /** Сводка маршрута («До конца: …»). */
149
+ summaryText?: string,
150
+ /** Доп. строка (подъём/спуск). */
151
+ extrasText?: string,
152
+ /** Ограничение скорости (км/ч) или null. */
153
+ speedLimitKmh?: number | null,
154
+ }
155
+
156
+ /** Действие озвучки в событии `navigatorVoice`. */
157
+ export type NavigatorVoiceAction = 'play' | 'prefetch' | 'stop'
158
+
159
+ /**
160
+ * Web → RN: `navigatorVoice` event. Веб шлёт абстрактные ключи фраз;
161
+ * нативная часть мапит их в URL клипов и воспроизводит.
162
+ */
163
+ export type NavigatorVoicePlayParams = {
164
+ action: NavigatorVoiceAction,
165
+ keys: string[],
166
+ }
167
+
117
168
  export type MapLiteWebError = {
118
169
  target: string,
119
170
  message: string,
@@ -191,18 +242,19 @@ export type MapLiteSetNavigatorPositionParams = {
191
242
  export type NativeToWebCommand =
192
243
  | { function: 'init', params: MapLiteInitParams }
193
244
  | { function: 'update', params: MapLiteUpdateParams }
194
- | { function: 'addMarker', params: MarkerProps }
195
- | { function: 'removeMarker', params: MarkerProps }
196
- | { function: 'addPolyline', params: PolylineProps }
197
- | { function: 'removePolyline', params: PolylineProps }
198
- | { function: 'addPolygon', params: PolygonProps }
199
- | { function: 'removePolygon', params: PolygonProps }
245
+ | { function: 'addMarker', params: MapLiteMarkerParams }
246
+ | { function: 'removeMarker', params: MapLiteRemoveOverlayParams }
247
+ | { function: 'addPolyline', params: MapLitePolylineParams }
248
+ | { function: 'removePolyline', params: MapLiteRemoveOverlayParams }
249
+ | { function: 'addPolygon', params: MapLitePolygonParams }
250
+ | { function: 'removePolygon', params: MapLiteRemoveOverlayParams }
200
251
  | { function: 'fitBounds', params: MapLiteFitBoundsParams }
201
252
  | { function: 'flyTo', params: MapLiteFlyToParams }
202
253
  | { function: 'setNavigatorPoint', params: MapLiteSetNavigatorPointParams }
203
254
  | { function: 'advanceNavigatorInstruction', params: Record<string, never> }
204
255
  | { function: 'setNavigatorPosition', params: MapLiteSetNavigatorPositionParams }
205
256
  | { function: 'pickNavigatorPosition', params: Record<string, never> }
257
+ | { function: 'recenterNavigatorCamera', params: Record<string, never> }
206
258
 
207
259
  /** Web → RN: `postToNative` (`webProject/src/map/types.ts`). */
208
260
  export type WebToNativeMessage =
@@ -226,7 +278,24 @@ export type MapLiteMapEventName =
226
278
  | 'navigatorRouteSet'
227
279
  | 'navigatorInstruction'
228
280
  | 'navigatorPositionSet'
281
+ | 'navigatorHud'
282
+ | 'navigatorVoice'
229
283
 
230
284
  export type MapLiteMapErrorEventParams = {
231
285
  message: string,
232
286
  }
287
+
288
+ /** `params` для `{ type: 'event', event, params }` по имени события. */
289
+ export type MapLiteMapEventParamsMap = {
290
+ movestart: EventParams,
291
+ moveend: EventParams,
292
+ zoomstart: EventParams,
293
+ zoomend: EventParams,
294
+ idle: EventParams,
295
+ error: MapLiteMapErrorEventParams,
296
+ navigatorRouteSet: NavigatorRouteSetParams,
297
+ navigatorInstruction: NavigatorInstructionParams,
298
+ navigatorPositionSet: NavigatorPositionSetParams,
299
+ navigatorHud: NavigatorHudState,
300
+ navigatorVoice: NavigatorVoicePlayParams,
301
+ }
@@ -0,0 +1,96 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+
3
+ import {
4
+ loadVoiceRuntime,
5
+ readVoiceVolumeLevel,
6
+ reloadVoiceForDir,
7
+ writeVoicePref,
8
+ writeVoiceVolumeLevel,
9
+ type VoiceCatalogEntry,
10
+ type VoiceManifest,
11
+ type VoiceRuntime,
12
+ type VoiceVolumeLevel,
13
+ } from './navigatorVoiceCatalog';
14
+
15
+ /**
16
+ * Нативное владение голосом навигатора: загрузка каталога/манифеста,
17
+ * выбор голоса/громкости и персист (AsyncStorage). Веб шлёт только ключи
18
+ * фраз; маппинг в аудио и воспроизведение — на стороне RN.
19
+ */
20
+ export type NavigatorVoiceController = {
21
+ runtime: VoiceRuntime | null;
22
+ catalog: VoiceCatalogEntry[];
23
+ selectedDir: string | null;
24
+ manifest: VoiceManifest | null;
25
+ clipBaseUrl: string | null;
26
+ voiceEnabled: boolean;
27
+ volumeLevel: VoiceVolumeLevel;
28
+ selectVoice: (dir: string) => Promise<void>;
29
+ selectVolume: (level: VoiceVolumeLevel) => void;
30
+ disableVoice: () => Promise<void>;
31
+ };
32
+
33
+ export function useNavigatorVoice(voiceUrl: string | undefined): NavigatorVoiceController {
34
+ const [runtime, setRuntime] = useState<VoiceRuntime | null>(null);
35
+ const [volumeLevel, setVolumeLevel] = useState<VoiceVolumeLevel>(5);
36
+
37
+ useEffect(() => {
38
+ let cancelled = false;
39
+ void readVoiceVolumeLevel().then((lvl) => {
40
+ if (!cancelled) setVolumeLevel(lvl);
41
+ });
42
+ if (!voiceUrl) {
43
+ setRuntime(null);
44
+ return () => {
45
+ cancelled = true;
46
+ };
47
+ }
48
+ void loadVoiceRuntime(voiceUrl)
49
+ .then((rt) => {
50
+ if (!cancelled) setRuntime(rt);
51
+ })
52
+ .catch((err) => {
53
+ console.warn('[maplite] navigator voice catalog failed', err);
54
+ if (!cancelled) setRuntime(null);
55
+ });
56
+ return () => {
57
+ cancelled = true;
58
+ };
59
+ }, [voiceUrl]);
60
+
61
+ const selectVoice = useCallback(
62
+ async (dir: string) => {
63
+ if (!runtime) return;
64
+ try {
65
+ const reloaded = await reloadVoiceForDir(runtime.catalogUrl, runtime.catalog, dir);
66
+ setRuntime((prev) => (prev ? { ...prev, ...reloaded } : prev));
67
+ } catch (err) {
68
+ console.warn('[maplite] failed to switch navigator voice', { dir, err });
69
+ }
70
+ },
71
+ [runtime]
72
+ );
73
+
74
+ const selectVolume = useCallback((level: VoiceVolumeLevel) => {
75
+ setVolumeLevel(level);
76
+ void writeVoiceVolumeLevel(level);
77
+ }, []);
78
+
79
+ const disableVoice = useCallback(async () => {
80
+ await writeVoicePref({ disabled: true });
81
+ setRuntime((prev) => (prev ? { ...prev, enabled: false, manifest: null } : prev));
82
+ }, []);
83
+
84
+ return {
85
+ runtime,
86
+ catalog: runtime?.catalog ?? [],
87
+ selectedDir: runtime?.selectedDir ?? null,
88
+ manifest: runtime?.manifest ?? null,
89
+ clipBaseUrl: runtime?.clipBaseUrl ?? null,
90
+ voiceEnabled: Boolean(runtime?.enabled && runtime.manifest),
91
+ volumeLevel,
92
+ selectVoice,
93
+ selectVolume,
94
+ disableVoice,
95
+ };
96
+ }
@@ -1,7 +1,35 @@
1
1
  import AsyncStorage from '@react-native-async-storage/async-storage';
2
+ import { NativeModules, Platform } from 'react-native';
2
3
 
3
4
  const CACHE_VERSION = 'v1';
4
5
 
6
+ /** Android: `android/app/src/main/assets/map.html`. See `resources/README.md`. */
7
+ export const NATIVE_MAP_HTML_ANDROID_URI = 'file:///android_asset/map.html';
8
+
9
+ /** Имя файла в iOS bundle (Copy Bundle Resources). */
10
+ export const NATIVE_MAP_HTML_IOS_FILENAME = 'map.html';
11
+
12
+ /**
13
+ * URI для `map.html` из нативных ресурсов хост-приложения.
14
+ * Android — assets; iOS — main bundle (через путь к `.app` из `SourceCode.scriptURL`).
15
+ */
16
+ export const getNativeMapHtmlUri = (): string => {
17
+ if (Platform.OS === 'android') {
18
+ return NATIVE_MAP_HTML_ANDROID_URI;
19
+ }
20
+
21
+ if (Platform.OS === 'ios') {
22
+ const scriptURL: unknown = NativeModules.SourceCode?.scriptURL;
23
+ if (typeof scriptURL === 'string' && scriptURL.startsWith('file://')) {
24
+ const bundleDir = scriptURL.substring(0, scriptURL.lastIndexOf('/') + 1);
25
+ return `${bundleDir}${NATIVE_MAP_HTML_IOS_FILENAME}`;
26
+ }
27
+ return NATIVE_MAP_HTML_IOS_FILENAME;
28
+ }
29
+
30
+ return NATIVE_MAP_HTML_ANDROID_URI;
31
+ };
32
+
5
33
  export const loadResources = async (url: string) => {
6
34
  const cacheKey = `${url}@${CACHE_VERSION}`;
7
35