react-native-maplibre-lite 0.1.9 → 0.2.1
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/README.md +92 -6
- package/lib/module/components/MapView.js +167 -48
- package/lib/module/components/MapView.js.map +1 -1
- package/lib/module/components/NavigatorHud.js +152 -0
- package/lib/module/components/NavigatorHud.js.map +1 -0
- package/lib/module/components/NavigatorRecenterButton.js +48 -0
- package/lib/module/components/NavigatorRecenterButton.js.map +1 -0
- package/lib/module/components/NavigatorVoiceControl.js +173 -0
- package/lib/module/components/NavigatorVoiceControl.js.map +1 -0
- package/lib/module/components/navigatorChromeTheme.js +98 -0
- package/lib/module/components/navigatorChromeTheme.js.map +1 -0
- package/lib/module/components/navigatorManeuverIcon.js +210 -0
- package/lib/module/components/navigatorManeuverIcon.js.map +1 -0
- package/lib/module/components/navigatorVoiceCatalog.js +225 -0
- package/lib/module/components/navigatorVoiceCatalog.js.map +1 -0
- package/lib/module/components/navigatorVoiceKeys.js +14 -0
- package/lib/module/components/navigatorVoiceKeys.js.map +1 -0
- package/lib/module/components/navigatorVoicePlayer.js +100 -0
- package/lib/module/components/navigatorVoicePlayer.js.map +1 -0
- package/lib/module/components/navigatorVoiceStrings.js +31 -0
- package/lib/module/components/navigatorVoiceStrings.js.map +1 -0
- package/lib/module/components/types.js +47 -0
- package/lib/module/components/types.js.map +1 -1
- package/lib/module/components/useNavigatorVoice.js +78 -0
- package/lib/module/components/useNavigatorVoice.js.map +1 -0
- package/lib/module/components/utils.js +26 -0
- package/lib/module/components/utils.js.map +1 -1
- package/lib/module/components/webMapBuild.js +1 -1
- package/lib/module/components/webMapBuild.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/components/MapView.d.ts +15 -2
- package/lib/typescript/src/components/MapView.d.ts.map +1 -1
- package/lib/typescript/src/components/NavigatorHud.d.ts +13 -0
- package/lib/typescript/src/components/NavigatorHud.d.ts.map +1 -0
- package/lib/typescript/src/components/NavigatorRecenterButton.d.ts +11 -0
- package/lib/typescript/src/components/NavigatorRecenterButton.d.ts.map +1 -0
- package/lib/typescript/src/components/NavigatorVoiceControl.d.ts +20 -0
- package/lib/typescript/src/components/NavigatorVoiceControl.d.ts.map +1 -0
- package/lib/typescript/src/components/navigatorChromeTheme.d.ts +19 -0
- package/lib/typescript/src/components/navigatorChromeTheme.d.ts.map +1 -0
- package/lib/typescript/src/components/navigatorManeuverIcon.d.ts +20 -0
- package/lib/typescript/src/components/navigatorManeuverIcon.d.ts.map +1 -0
- package/lib/typescript/src/components/navigatorVoiceCatalog.d.ts +50 -0
- package/lib/typescript/src/components/navigatorVoiceCatalog.d.ts.map +1 -0
- package/lib/typescript/src/components/navigatorVoiceKeys.d.ts +10 -0
- package/lib/typescript/src/components/navigatorVoiceKeys.d.ts.map +1 -0
- package/lib/typescript/src/components/navigatorVoicePlayer.d.ts +15 -0
- package/lib/typescript/src/components/navigatorVoicePlayer.d.ts.map +1 -0
- package/lib/typescript/src/components/navigatorVoiceStrings.d.ts +19 -0
- package/lib/typescript/src/components/navigatorVoiceStrings.d.ts.map +1 -0
- package/lib/typescript/src/components/types.d.ts +205 -12
- package/lib/typescript/src/components/types.d.ts.map +1 -1
- package/lib/typescript/src/components/useNavigatorVoice.d.ts +20 -0
- package/lib/typescript/src/components/useNavigatorVoice.d.ts.map +1 -0
- package/lib/typescript/src/components/utils.d.ts +9 -0
- package/lib/typescript/src/components/utils.d.ts.map +1 -1
- package/lib/typescript/src/components/webMapBuild.d.ts +1 -1
- package/lib/typescript/src/components/webMapBuild.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +16 -7
- package/resources/README.md +62 -0
- package/resources/map.html +797 -0
- package/src/components/MapView.tsx +209 -58
- package/src/components/NavigatorHud.tsx +166 -0
- package/src/components/NavigatorRecenterButton.tsx +45 -0
- package/src/components/NavigatorVoiceControl.tsx +198 -0
- package/src/components/navigatorChromeTheme.ts +118 -0
- package/src/components/navigatorManeuverIcon.tsx +177 -0
- package/src/components/navigatorVoiceCatalog.ts +275 -0
- package/src/components/navigatorVoiceKeys.ts +132 -0
- package/src/components/navigatorVoicePlayer.tsx +126 -0
- package/src/components/navigatorVoiceStrings.ts +42 -0
- package/src/components/types.ts +198 -16
- package/src/components/useNavigatorVoice.ts +96 -0
- package/src/components/utils.ts +28 -0
- package/src/components/webMapBuild.ts +1 -1
- package/src/index.tsx +19 -0
package/src/components/types.ts
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
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
|
-
|
|
18
|
-
|
|
21
|
+
/** RN → Web: `addPolygon` (`MapLiteController.PolygonParams`). */
|
|
22
|
+
export type MapLitePolygonParams = {
|
|
19
23
|
uniqueId: string,
|
|
20
24
|
coordinates: [number, number][],
|
|
21
25
|
fillColor?: string,
|
|
@@ -23,24 +27,33 @@ 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
|
|
37
|
+
export type MarkerProps = MapLiteMarkerParams & {
|
|
30
38
|
ignoreFitBounds?: boolean,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
onPress?: () => void,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type PolygonProps = MapLitePolygonParams & {
|
|
43
|
+
ignoreFitBounds?: boolean,
|
|
44
|
+
}
|
|
35
45
|
|
|
46
|
+
export type PolylineProps = MapLitePolylineParams & {
|
|
47
|
+
ignoreFitBounds?: boolean,
|
|
36
48
|
}
|
|
37
49
|
|
|
50
|
+
/** Web → RN: `postToNative` payload (`webProject/src/map/types.ts`). */
|
|
38
51
|
export type EventParams = {
|
|
39
52
|
center?: {
|
|
40
53
|
lng: number,
|
|
41
|
-
lat: number
|
|
42
|
-
},
|
|
43
|
-
zoom?: number
|
|
54
|
+
lat: number,
|
|
55
|
+
} | null,
|
|
56
|
+
zoom?: number | null,
|
|
44
57
|
}
|
|
45
58
|
|
|
46
59
|
export type NavigatorLang = 'ru' | 'en'
|
|
@@ -113,7 +126,176 @@ export type NavigatorPositionSetParams = {
|
|
|
113
126
|
distanceFromRouteMeters: number,
|
|
114
127
|
}
|
|
115
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
|
+
|
|
116
168
|
export type MapLiteWebError = {
|
|
117
169
|
target: string,
|
|
118
170
|
message: string,
|
|
119
|
-
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Parsed MapLibre style JSON — `InitParams.mapStyle` / `UpdateParams.mapStyle` в WebView. */
|
|
174
|
+
export type MapLiteStyleSpecification = Record<string, unknown>
|
|
175
|
+
|
|
176
|
+
/** RN → Web: `init` (`MapLiteController.InitParams`). */
|
|
177
|
+
export type MapLiteInitParams = {
|
|
178
|
+
mapStyle: MapLiteStyleSpecification,
|
|
179
|
+
center: [number, number],
|
|
180
|
+
zoom: number,
|
|
181
|
+
minZoom?: number,
|
|
182
|
+
maxZoom?: number,
|
|
183
|
+
zoomEnabled?: boolean,
|
|
184
|
+
scrollEnabled?: boolean,
|
|
185
|
+
antialias?: boolean,
|
|
186
|
+
crossSourceCollisions?: boolean,
|
|
187
|
+
fadeDuration?: number,
|
|
188
|
+
pixelRatio?: number,
|
|
189
|
+
simplifyStyle?: boolean,
|
|
190
|
+
aggressiveSimplifyStyle?: boolean,
|
|
191
|
+
maxPitch?: number,
|
|
192
|
+
renderWorldCopies?: boolean,
|
|
193
|
+
turboWhileMoving?: boolean,
|
|
194
|
+
debugMode?: boolean,
|
|
195
|
+
navigator?: boolean,
|
|
196
|
+
graphhopperUrl?: string,
|
|
197
|
+
navigatorLang?: NavigatorLang,
|
|
198
|
+
navigatorProfile?: NavigatorProfile | string,
|
|
199
|
+
navigatorChrome?: NavigatorChromeParams,
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** RN → Web: `update` (`MapLiteController.UpdateParams`). */
|
|
203
|
+
export type MapLiteUpdateParams = {
|
|
204
|
+
minZoom?: number,
|
|
205
|
+
maxZoom?: number,
|
|
206
|
+
zoomEnabled?: boolean,
|
|
207
|
+
scrollEnabled?: boolean,
|
|
208
|
+
mapStyle?: MapLiteStyleSpecification,
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** RN → Web: `fitBounds`. */
|
|
212
|
+
export type MapLiteFitBoundsParams = {
|
|
213
|
+
bounds: [[number, number], [number, number]],
|
|
214
|
+
padding?: number,
|
|
215
|
+
duration?: number,
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** RN → Web: `flyTo`. */
|
|
219
|
+
export type MapLiteFlyToParams = {
|
|
220
|
+
center: [number, number],
|
|
221
|
+
zoom: number,
|
|
222
|
+
duration?: number,
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** RN → Web: `setNavigatorPoint`. */
|
|
226
|
+
export type MapLiteSetNavigatorPointParams = {
|
|
227
|
+
latitude: number,
|
|
228
|
+
longitude: number,
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* RN → Web: `setNavigatorPosition`.
|
|
233
|
+
* `accuracy` (м) включает прод-режим off-route на стороне WebView.
|
|
234
|
+
*/
|
|
235
|
+
export type MapLiteSetNavigatorPositionParams = {
|
|
236
|
+
latitude: number,
|
|
237
|
+
longitude: number,
|
|
238
|
+
accuracy?: number,
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** RN → Web: JSON в `WebView.postMessage` (`webProject/src/map/MapLiteController.receive`). */
|
|
242
|
+
export type NativeToWebCommand =
|
|
243
|
+
| { function: 'init', params: MapLiteInitParams }
|
|
244
|
+
| { function: 'update', params: MapLiteUpdateParams }
|
|
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 }
|
|
251
|
+
| { function: 'fitBounds', params: MapLiteFitBoundsParams }
|
|
252
|
+
| { function: 'flyTo', params: MapLiteFlyToParams }
|
|
253
|
+
| { function: 'setNavigatorPoint', params: MapLiteSetNavigatorPointParams }
|
|
254
|
+
| { function: 'advanceNavigatorInstruction', params: Record<string, never> }
|
|
255
|
+
| { function: 'setNavigatorPosition', params: MapLiteSetNavigatorPositionParams }
|
|
256
|
+
| { function: 'pickNavigatorPosition', params: Record<string, never> }
|
|
257
|
+
| { function: 'recenterNavigatorCamera', params: Record<string, never> }
|
|
258
|
+
|
|
259
|
+
/** Web → RN: `postToNative` (`webProject/src/map/types.ts`). */
|
|
260
|
+
export type WebToNativeMessage =
|
|
261
|
+
| { type: 'scriptReady' }
|
|
262
|
+
| { type: 'inited' }
|
|
263
|
+
| { type: 'event', event: string, params: unknown }
|
|
264
|
+
| { type: 'markerClick', uniqueId: string }
|
|
265
|
+
| {
|
|
266
|
+
type: 'error',
|
|
267
|
+
data: MapLiteWebError,
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Имена `event` в `{ type: 'event', event, params }` из WebView. */
|
|
271
|
+
export type MapLiteMapEventName =
|
|
272
|
+
| 'movestart'
|
|
273
|
+
| 'moveend'
|
|
274
|
+
| 'zoomstart'
|
|
275
|
+
| 'zoomend'
|
|
276
|
+
| 'idle'
|
|
277
|
+
| 'error'
|
|
278
|
+
| 'navigatorRouteSet'
|
|
279
|
+
| 'navigatorInstruction'
|
|
280
|
+
| 'navigatorPositionSet'
|
|
281
|
+
| 'navigatorHud'
|
|
282
|
+
| 'navigatorVoice'
|
|
283
|
+
|
|
284
|
+
export type MapLiteMapErrorEventParams = {
|
|
285
|
+
message: string,
|
|
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
|
+
}
|
package/src/components/utils.ts
CHANGED
|
@@ -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
|
|