react-native-maplibre-lite 0.2.4 → 0.2.5

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,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
3
+ import { forwardRef, useImperativeHandle, useMemo, useRef, useState } from 'react';
4
4
  import Video from 'react-native-video';
5
5
 
6
6
  /**
@@ -8,20 +8,27 @@ import Video from 'react-native-video';
8
8
  * очереди из `webProject/src/map/navigationVoicePlayer.ts` на `react-native-video`:
9
9
  * веб присылает список ключей фраз, нативная часть собирает из них URL и
10
10
  * проигрывает их по очереди с короткой паузой между клипами.
11
+ *
12
+ * Один экземпляр `<Video>` на всю сессию — между клипами меняется только source
13
+ * (или seek(0) при повторе того же URL), без remount.
11
14
  */
12
15
 
13
16
  /** Пауза между клипами (как в веб-плеере). */
14
17
  import { jsx as _jsx } from "react/jsx-runtime";
15
18
  const CLIP_PAUSE_MS = 0;
16
19
  export const NavigatorVoicePlayer = /*#__PURE__*/forwardRef((props, ref) => {
17
- const [current, setCurrent] = useState(null);
20
+ const [sourceUri, setSourceUri] = useState(null);
21
+ const [playing, setPlaying] = useState(false);
18
22
  const [volume, setVolume] = useState(typeof props.initialVolume === 'number' ? Math.min(1, Math.max(0, props.initialVolume)) : 1);
23
+ const videoRef = useRef(null);
19
24
  const queueRef = useRef([]);
20
25
  const indexRef = useRef(0);
21
26
  /** Поколение очереди: рост инвалидирует «хвосты» предыдущих очередей. */
22
27
  const genRef = useRef(0);
23
- /** Меняем токен, чтобы перерисовать `<Video>` даже при том же URL подряд. */
24
- const tokenRef = useRef(0);
28
+ /** gen активного клипа для фильтрации устаревших onEnd/onLoad. */
29
+ const clipGenRef = useRef(0);
30
+ /** URI, уже загруженный в текущий `<Video>`. */
31
+ const loadedUriRef = useRef(null);
25
32
  const pauseTimerRef = useRef(null);
26
33
  const clearPause = () => {
27
34
  if (pauseTimerRef.current != null) {
@@ -29,72 +36,94 @@ export const NavigatorVoicePlayer = /*#__PURE__*/forwardRef((props, ref) => {
29
36
  pauseTimerRef.current = null;
30
37
  }
31
38
  };
32
- const playIndex = () => {
39
+ const playClip = gen => {
40
+ if (gen !== genRef.current) return;
33
41
  const uri = queueRef.current[indexRef.current];
34
42
  if (uri == null) {
35
- setCurrent(null);
43
+ setPlaying(false);
44
+ return;
45
+ }
46
+ clipGenRef.current = gen;
47
+ setPlaying(true);
48
+ if (uri === loadedUriRef.current) {
49
+ videoRef.current?.seek(0);
50
+ videoRef.current?.resume();
36
51
  return;
37
52
  }
38
- tokenRef.current += 1;
39
- setCurrent({
40
- uri,
41
- token: tokenRef.current
42
- });
53
+ loadedUriRef.current = uri;
54
+ setSourceUri(uri);
43
55
  };
44
- const advance = gen => {
56
+ const scheduleNext = gen => {
45
57
  if (gen !== genRef.current) return;
46
58
  indexRef.current += 1;
47
59
  if (indexRef.current >= queueRef.current.length) {
48
- setCurrent(null);
60
+ setPlaying(false);
49
61
  return;
50
62
  }
51
63
  clearPause();
64
+ if (CLIP_PAUSE_MS <= 0) {
65
+ playClip(gen);
66
+ return;
67
+ }
52
68
  pauseTimerRef.current = setTimeout(() => {
53
69
  pauseTimerRef.current = null;
54
- if (gen === genRef.current) playIndex();
70
+ playClip(gen);
55
71
  }, CLIP_PAUSE_MS);
56
72
  };
73
+ const handleEnd = () => {
74
+ scheduleNext(clipGenRef.current);
75
+ };
76
+ const handleLoad = () => {
77
+ if (clipGenRef.current !== genRef.current) return;
78
+ videoRef.current?.seek(0);
79
+ };
57
80
  useImperativeHandle(ref, () => ({
58
81
  playUrls: urls => {
59
82
  clearPause();
60
83
  genRef.current += 1;
84
+ const gen = genRef.current;
61
85
  queueRef.current = urls;
62
86
  indexRef.current = 0;
63
87
  if (urls.length === 0) {
64
- setCurrent(null);
88
+ setPlaying(false);
89
+ videoRef.current?.pause();
65
90
  return;
66
91
  }
67
- playIndex();
92
+ playClip(gen);
68
93
  },
69
94
  stop: () => {
70
95
  clearPause();
71
96
  genRef.current += 1;
72
97
  queueRef.current = [];
73
98
  indexRef.current = 0;
74
- setCurrent(null);
99
+ setPlaying(false);
100
+ videoRef.current?.pause();
75
101
  },
76
102
  setVolume: gain => {
77
103
  setVolume(Math.min(1, Math.max(0, gain)));
78
104
  }
79
105
  }), []);
80
- if (!current) return null;
81
- const gen = genRef.current;
106
+ const source = useMemo(() => ({
107
+ uri: sourceUri,
108
+ shouldCache: true
109
+ }), [sourceUri]);
110
+ if (sourceUri == null) return null;
82
111
  return /*#__PURE__*/_jsx(Video, {
83
- source: {
84
- uri: current.uri
85
- },
86
- paused: false,
112
+ ref: videoRef,
113
+ source: source,
114
+ paused: !playing,
87
115
  volume: volume,
88
116
  repeat: false,
89
117
  ignoreSilentSwitch: "ignore",
90
118
  playInBackground: true,
91
- onEnd: () => advance(gen),
92
- onError: () => advance(gen),
119
+ onLoad: handleLoad,
120
+ onEnd: handleEnd,
121
+ onError: handleEnd,
93
122
  style: {
94
123
  width: 0,
95
124
  height: 0
96
125
  }
97
- }, current.token);
126
+ });
98
127
  });
99
128
  NavigatorVoicePlayer.displayName = 'NavigatorVoicePlayer';
100
129
  //# sourceMappingURL=navigatorVoicePlayer.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","useImperativeHandle","useRef","useState","Video","jsx","_jsx","CLIP_PAUSE_MS","NavigatorVoicePlayer","props","ref","current","setCurrent","volume","setVolume","initialVolume","Math","min","max","queueRef","indexRef","genRef","tokenRef","pauseTimerRef","clearPause","clearTimeout","playIndex","uri","token","advance","gen","length","setTimeout","playUrls","urls","stop","gain","source","paused","repeat","ignoreSilentSwitch","playInBackground","onEnd","onError","style","width","height","displayName"],"sourceRoot":"../../../src","sources":["components/navigatorVoicePlayer.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","useImperativeHandle","useMemo","useRef","useState","Video","jsx","_jsx","CLIP_PAUSE_MS","NavigatorVoicePlayer","props","ref","sourceUri","setSourceUri","playing","setPlaying","volume","setVolume","initialVolume","Math","min","max","videoRef","queueRef","indexRef","genRef","clipGenRef","loadedUriRef","pauseTimerRef","clearPause","current","clearTimeout","playClip","gen","uri","seek","resume","scheduleNext","length","setTimeout","handleEnd","handleLoad","playUrls","urls","pause","stop","gain","source","shouldCache","paused","repeat","ignoreSilentSwitch","playInBackground","onLoad","onEnd","onError","style","width","height","displayName"],"sourceRoot":"../../../src","sources":["components/navigatorVoicePlayer.tsx"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"navigatorVoicePlayer.d.ts","sourceRoot":"","sources":["../../../../src/components/navigatorVoicePlayer.tsx"],"names":[],"mappings":"AAmBA,MAAM,MAAM,uBAAuB,GAAG;IAClC,gEAAgE;IAChE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,qDAAqD;IACrD,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,mCAAmC;IACnC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC7B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,+HA+F/B,CAAC"}
1
+ {"version":3,"file":"navigatorVoicePlayer.d.ts","sourceRoot":"","sources":["../../../../src/components/navigatorVoicePlayer.tsx"],"names":[],"mappings":"AAuBA,MAAM,MAAM,uBAAuB,GAAG;IAClC,gEAAgE;IAChE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,qDAAqD;IACrD,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,mCAAmC;IACnC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC7B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,+HAoI/B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-maplibre-lite",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
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",
@@ -1,17 +1,21 @@
1
1
  import {
2
- forwardRef,
3
- useImperativeHandle,
4
- useRef,
5
- useState,
2
+ forwardRef,
3
+ useImperativeHandle,
4
+ useMemo,
5
+ useRef,
6
+ useState,
6
7
  } from 'react';
7
8
 
8
- import Video from 'react-native-video';
9
+ import Video, { type VideoRef } from 'react-native-video';
9
10
 
10
11
  /**
11
12
  * Последовательный проигрыватель клипов озвучки навигатора. Порт логики
12
13
  * очереди из `webProject/src/map/navigationVoicePlayer.ts` на `react-native-video`:
13
14
  * веб присылает список ключей фраз, нативная часть собирает из них URL и
14
15
  * проигрывает их по очереди с короткой паузой между клипами.
16
+ *
17
+ * Один экземпляр `<Video>` на всю сессию — между клипами меняется только source
18
+ * (или seek(0) при повторе того же URL), без remount.
15
19
  */
16
20
 
17
21
  /** Пауза между клипами (как в веб-плеере). */
@@ -35,19 +39,23 @@ export const NavigatorVoicePlayer = forwardRef<
35
39
  NavigatorVoicePlayerRef,
36
40
  NavigatorVoicePlayerProps
37
41
  >((props, ref) => {
38
- const [current, setCurrent] = useState<{ uri: string; token: number } | null>(null);
42
+ const [sourceUri, setSourceUri] = useState<string | null>(null);
43
+ const [playing, setPlaying] = useState(false);
39
44
  const [volume, setVolume] = useState(
40
45
  typeof props.initialVolume === 'number'
41
46
  ? Math.min(1, Math.max(0, props.initialVolume))
42
47
  : 1
43
48
  );
44
49
 
50
+ const videoRef = useRef<VideoRef>(null);
45
51
  const queueRef = useRef<string[]>([]);
46
52
  const indexRef = useRef(0);
47
53
  /** Поколение очереди: рост инвалидирует «хвосты» предыдущих очередей. */
48
54
  const genRef = useRef(0);
49
- /** Меняем токен, чтобы перерисовать `<Video>` даже при том же URL подряд. */
50
- const tokenRef = useRef(0);
55
+ /** gen активного клипа для фильтрации устаревших onEnd/onLoad. */
56
+ const clipGenRef = useRef(0);
57
+ /** URI, уже загруженный в текущий `<Video>`. */
58
+ const loadedUriRef = useRef<string | null>(null);
51
59
  const pauseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
52
60
 
53
61
  const clearPause = () => {
@@ -57,50 +65,78 @@ export const NavigatorVoicePlayer = forwardRef<
57
65
  }
58
66
  };
59
67
 
60
- const playIndex = () => {
68
+ const playClip = (gen: number) => {
69
+ if (gen !== genRef.current) return;
70
+
61
71
  const uri = queueRef.current[indexRef.current];
62
72
  if (uri == null) {
63
- setCurrent(null);
73
+ setPlaying(false);
74
+ return;
75
+ }
76
+
77
+ clipGenRef.current = gen;
78
+ setPlaying(true);
79
+
80
+ if (uri === loadedUriRef.current) {
81
+ videoRef.current?.seek(0);
82
+ videoRef.current?.resume();
64
83
  return;
65
84
  }
66
- tokenRef.current += 1;
67
- setCurrent({ uri, token: tokenRef.current });
85
+
86
+ loadedUriRef.current = uri;
87
+ setSourceUri(uri);
68
88
  };
69
89
 
70
- const advance = (gen: number) => {
90
+ const scheduleNext = (gen: number) => {
71
91
  if (gen !== genRef.current) return;
72
92
  indexRef.current += 1;
73
93
  if (indexRef.current >= queueRef.current.length) {
74
- setCurrent(null);
94
+ setPlaying(false);
75
95
  return;
76
96
  }
77
97
  clearPause();
98
+ if (CLIP_PAUSE_MS <= 0) {
99
+ playClip(gen);
100
+ return;
101
+ }
78
102
  pauseTimerRef.current = setTimeout(() => {
79
103
  pauseTimerRef.current = null;
80
- if (gen === genRef.current) playIndex();
104
+ playClip(gen);
81
105
  }, CLIP_PAUSE_MS);
82
106
  };
83
107
 
108
+ const handleEnd = () => {
109
+ scheduleNext(clipGenRef.current);
110
+ };
111
+
112
+ const handleLoad = () => {
113
+ if (clipGenRef.current !== genRef.current) return;
114
+ videoRef.current?.seek(0);
115
+ };
116
+
84
117
  useImperativeHandle(
85
118
  ref,
86
119
  () => ({
87
120
  playUrls: (urls: string[]) => {
88
121
  clearPause();
89
122
  genRef.current += 1;
123
+ const gen = genRef.current;
90
124
  queueRef.current = urls;
91
125
  indexRef.current = 0;
92
126
  if (urls.length === 0) {
93
- setCurrent(null);
127
+ setPlaying(false);
128
+ videoRef.current?.pause();
94
129
  return;
95
130
  }
96
- playIndex();
131
+ playClip(gen);
97
132
  },
98
133
  stop: () => {
99
134
  clearPause();
100
135
  genRef.current += 1;
101
136
  queueRef.current = [];
102
137
  indexRef.current = 0;
103
- setCurrent(null);
138
+ setPlaying(false);
139
+ videoRef.current?.pause();
104
140
  },
105
141
  setVolume: (gain: number) => {
106
142
  setVolume(Math.min(1, Math.max(0, gain)));
@@ -109,20 +145,25 @@ export const NavigatorVoicePlayer = forwardRef<
109
145
  []
110
146
  );
111
147
 
112
- if (!current) return null;
148
+ const source = useMemo(
149
+ () => ({ uri: sourceUri!, shouldCache: true as const }),
150
+ [sourceUri]
151
+ );
152
+
153
+ if (sourceUri == null) return null;
113
154
 
114
- const gen = genRef.current;
115
155
  return (
116
156
  <Video
117
- key={current.token}
118
- source={{ uri: current.uri }}
119
- paused={false}
157
+ ref={videoRef}
158
+ source={source}
159
+ paused={!playing}
120
160
  volume={volume}
121
161
  repeat={false}
122
162
  ignoreSilentSwitch="ignore"
123
163
  playInBackground
124
- onEnd={() => advance(gen)}
125
- onError={() => advance(gen)}
164
+ onLoad={handleLoad}
165
+ onEnd={handleEnd}
166
+ onError={handleEnd}
126
167
  style={{ width: 0, height: 0 }}
127
168
  />
128
169
  );