react-native-maplibre-lite 0.2.3 → 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
- const CLIP_PAUSE_MS = 300;
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":";;AAAA,SAASA,UAAU,EAAEC,mBAAmB,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAEzE,OAAOC,KAAK,MAAM,oBAAoB;;AAEtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AAAA,SAAAC,GAAA,IAAAC,IAAA;AACA,MAAMC,aAAa,GAAG,GAAG;AAgBzB,OAAO,MAAMC,oBAAoB,gBAAGR,UAAU,CAG5C,CAACS,KAAK,EAAEC,GAAG,KAAK;EACd,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAGT,QAAQ,CAAwC,IAAI,CAAC;EACnF,MAAM,CAACU,MAAM,EAAEC,SAAS,CAAC,GAAGX,QAAQ,CAChC,OAAOM,KAAK,CAACM,aAAa,KAAK,QAAQ,GACjCC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAED,IAAI,CAACE,GAAG,CAAC,CAAC,EAAET,KAAK,CAACM,aAAa,CAAC,CAAC,GAC7C,CACV,CAAC;EAED,MAAMI,QAAQ,GAAGjB,MAAM,CAAW,EAAE,CAAC;EACrC,MAAMkB,QAAQ,GAAGlB,MAAM,CAAC,CAAC,CAAC;EAC1B;EACA,MAAMmB,MAAM,GAAGnB,MAAM,CAAC,CAAC,CAAC;EACxB;EACA,MAAMoB,QAAQ,GAAGpB,MAAM,CAAC,CAAC,CAAC;EAC1B,MAAMqB,aAAa,GAAGrB,MAAM,CAAuC,IAAI,CAAC;EAExE,MAAMsB,UAAU,GAAGA,CAAA,KAAM;IACrB,IAAID,aAAa,CAACZ,OAAO,IAAI,IAAI,EAAE;MAC/Bc,YAAY,CAACF,aAAa,CAACZ,OAAO,CAAC;MACnCY,aAAa,CAACZ,OAAO,GAAG,IAAI;IAChC;EACJ,CAAC;EAED,MAAMe,SAAS,GAAGA,CAAA,KAAM;IACpB,MAAMC,GAAG,GAAGR,QAAQ,CAACR,OAAO,CAACS,QAAQ,CAACT,OAAO,CAAC;IAC9C,IAAIgB,GAAG,IAAI,IAAI,EAAE;MACbf,UAAU,CAAC,IAAI,CAAC;MAChB;IACJ;IACAU,QAAQ,CAACX,OAAO,IAAI,CAAC;IACrBC,UAAU,CAAC;MAAEe,GAAG;MAAEC,KAAK,EAAEN,QAAQ,CAACX;IAAQ,CAAC,CAAC;EAChD,CAAC;EAED,MAAMkB,OAAO,GAAIC,GAAW,IAAK;IAC7B,IAAIA,GAAG,KAAKT,MAAM,CAACV,OAAO,EAAE;IAC5BS,QAAQ,CAACT,OAAO,IAAI,CAAC;IACrB,IAAIS,QAAQ,CAACT,OAAO,IAAIQ,QAAQ,CAACR,OAAO,CAACoB,MAAM,EAAE;MAC7CnB,UAAU,CAAC,IAAI,CAAC;MAChB;IACJ;IACAY,UAAU,CAAC,CAAC;IACZD,aAAa,CAACZ,OAAO,GAAGqB,UAAU,CAAC,MAAM;MACrCT,aAAa,CAACZ,OAAO,GAAG,IAAI;MAC5B,IAAImB,GAAG,KAAKT,MAAM,CAACV,OAAO,EAAEe,SAAS,CAAC,CAAC;IAC3C,CAAC,EAAEnB,aAAa,CAAC;EACrB,CAAC;EAEDN,mBAAmB,CACfS,GAAG,EACH,OAAO;IACHuB,QAAQ,EAAGC,IAAc,IAAK;MAC1BV,UAAU,CAAC,CAAC;MACZH,MAAM,CAACV,OAAO,IAAI,CAAC;MACnBQ,QAAQ,CAACR,OAAO,GAAGuB,IAAI;MACvBd,QAAQ,CAACT,OAAO,GAAG,CAAC;MACpB,IAAIuB,IAAI,CAACH,MAAM,KAAK,CAAC,EAAE;QACnBnB,UAAU,CAAC,IAAI,CAAC;QAChB;MACJ;MACAc,SAAS,CAAC,CAAC;IACf,CAAC;IACDS,IAAI,EAAEA,CAAA,KAAM;MACRX,UAAU,CAAC,CAAC;MACZH,MAAM,CAACV,OAAO,IAAI,CAAC;MACnBQ,QAAQ,CAACR,OAAO,GAAG,EAAE;MACrBS,QAAQ,CAACT,OAAO,GAAG,CAAC;MACpBC,UAAU,CAAC,IAAI,CAAC;IACpB,CAAC;IACDE,SAAS,EAAGsB,IAAY,IAAK;MACzBtB,SAAS,CAACE,IAAI,CAACC,GAAG,CAAC,CAAC,EAAED,IAAI,CAACE,GAAG,CAAC,CAAC,EAAEkB,IAAI,CAAC,CAAC,CAAC;IAC7C;EACJ,CAAC,CAAC,EACF,EACJ,CAAC;EAED,IAAI,CAACzB,OAAO,EAAE,OAAO,IAAI;EAEzB,MAAMmB,GAAG,GAAGT,MAAM,CAACV,OAAO;EAC1B,oBACIL,IAAA,CAACF,KAAK;IAEFiC,MAAM,EAAE;MAAEV,GAAG,EAAEhB,OAAO,CAACgB;IAAI,CAAE;IAC7BW,MAAM,EAAE,KAAM;IACdzB,MAAM,EAAEA,MAAO;IACf0B,MAAM,EAAE,KAAM;IACdC,kBAAkB,EAAC,QAAQ;IAC3BC,gBAAgB;IAChBC,KAAK,EAAEA,CAAA,KAAMb,OAAO,CAACC,GAAG,CAAE;IAC1Ba,OAAO,EAAEA,CAAA,KAAMd,OAAO,CAACC,GAAG,CAAE;IAC5Bc,KAAK,EAAE;MAAEC,KAAK,EAAE,CAAC;MAAEC,MAAM,EAAE;IAAE;EAAE,GAT1BnC,OAAO,CAACiB,KAUhB,CAAC;AAEV,CAAC,CAAC;AAEFpB,oBAAoB,CAACuC,WAAW,GAAG,sBAAsB","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":"AAcA,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.3",
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,16 +1,25 @@
1
- import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
1
+ import {
2
+ forwardRef,
3
+ useImperativeHandle,
4
+ useMemo,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
2
8
 
3
- import Video from 'react-native-video';
9
+ import Video, { type VideoRef } from 'react-native-video';
4
10
 
5
11
  /**
6
12
  * Последовательный проигрыватель клипов озвучки навигатора. Порт логики
7
13
  * очереди из `webProject/src/map/navigationVoicePlayer.ts` на `react-native-video`:
8
14
  * веб присылает список ключей фраз, нативная часть собирает из них URL и
9
15
  * проигрывает их по очереди с короткой паузой между клипами.
16
+ *
17
+ * Один экземпляр `<Video>` на всю сессию — между клипами меняется только source
18
+ * (или seek(0) при повторе того же URL), без remount.
10
19
  */
11
20
 
12
21
  /** Пауза между клипами (как в веб-плеере). */
13
- const CLIP_PAUSE_MS = 300;
22
+ const CLIP_PAUSE_MS = 0;
14
23
 
15
24
  export type NavigatorVoicePlayerRef = {
16
25
  /** Проиграть очередь URL подряд (прерывает текущую очередь). */
@@ -30,19 +39,23 @@ export const NavigatorVoicePlayer = forwardRef<
30
39
  NavigatorVoicePlayerRef,
31
40
  NavigatorVoicePlayerProps
32
41
  >((props, ref) => {
33
- const [current, setCurrent] = useState<{ uri: string; token: number } | null>(null);
42
+ const [sourceUri, setSourceUri] = useState<string | null>(null);
43
+ const [playing, setPlaying] = useState(false);
34
44
  const [volume, setVolume] = useState(
35
45
  typeof props.initialVolume === 'number'
36
46
  ? Math.min(1, Math.max(0, props.initialVolume))
37
47
  : 1
38
48
  );
39
49
 
50
+ const videoRef = useRef<VideoRef>(null);
40
51
  const queueRef = useRef<string[]>([]);
41
52
  const indexRef = useRef(0);
42
53
  /** Поколение очереди: рост инвалидирует «хвосты» предыдущих очередей. */
43
54
  const genRef = useRef(0);
44
- /** Меняем токен, чтобы перерисовать `<Video>` даже при том же URL подряд. */
45
- const tokenRef = useRef(0);
55
+ /** gen активного клипа для фильтрации устаревших onEnd/onLoad. */
56
+ const clipGenRef = useRef(0);
57
+ /** URI, уже загруженный в текущий `<Video>`. */
58
+ const loadedUriRef = useRef<string | null>(null);
46
59
  const pauseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
47
60
 
48
61
  const clearPause = () => {
@@ -52,50 +65,78 @@ export const NavigatorVoicePlayer = forwardRef<
52
65
  }
53
66
  };
54
67
 
55
- const playIndex = () => {
68
+ const playClip = (gen: number) => {
69
+ if (gen !== genRef.current) return;
70
+
56
71
  const uri = queueRef.current[indexRef.current];
57
72
  if (uri == null) {
58
- 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();
59
83
  return;
60
84
  }
61
- tokenRef.current += 1;
62
- setCurrent({ uri, token: tokenRef.current });
85
+
86
+ loadedUriRef.current = uri;
87
+ setSourceUri(uri);
63
88
  };
64
89
 
65
- const advance = (gen: number) => {
90
+ const scheduleNext = (gen: number) => {
66
91
  if (gen !== genRef.current) return;
67
92
  indexRef.current += 1;
68
93
  if (indexRef.current >= queueRef.current.length) {
69
- setCurrent(null);
94
+ setPlaying(false);
70
95
  return;
71
96
  }
72
97
  clearPause();
98
+ if (CLIP_PAUSE_MS <= 0) {
99
+ playClip(gen);
100
+ return;
101
+ }
73
102
  pauseTimerRef.current = setTimeout(() => {
74
103
  pauseTimerRef.current = null;
75
- if (gen === genRef.current) playIndex();
104
+ playClip(gen);
76
105
  }, CLIP_PAUSE_MS);
77
106
  };
78
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
+
79
117
  useImperativeHandle(
80
118
  ref,
81
119
  () => ({
82
120
  playUrls: (urls: string[]) => {
83
121
  clearPause();
84
122
  genRef.current += 1;
123
+ const gen = genRef.current;
85
124
  queueRef.current = urls;
86
125
  indexRef.current = 0;
87
126
  if (urls.length === 0) {
88
- setCurrent(null);
127
+ setPlaying(false);
128
+ videoRef.current?.pause();
89
129
  return;
90
130
  }
91
- playIndex();
131
+ playClip(gen);
92
132
  },
93
133
  stop: () => {
94
134
  clearPause();
95
135
  genRef.current += 1;
96
136
  queueRef.current = [];
97
137
  indexRef.current = 0;
98
- setCurrent(null);
138
+ setPlaying(false);
139
+ videoRef.current?.pause();
99
140
  },
100
141
  setVolume: (gain: number) => {
101
142
  setVolume(Math.min(1, Math.max(0, gain)));
@@ -104,20 +145,25 @@ export const NavigatorVoicePlayer = forwardRef<
104
145
  []
105
146
  );
106
147
 
107
- 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;
108
154
 
109
- const gen = genRef.current;
110
155
  return (
111
156
  <Video
112
- key={current.token}
113
- source={{ uri: current.uri }}
114
- paused={false}
157
+ ref={videoRef}
158
+ source={source}
159
+ paused={!playing}
115
160
  volume={volume}
116
161
  repeat={false}
117
162
  ignoreSilentSwitch="ignore"
118
163
  playInBackground
119
- onEnd={() => advance(gen)}
120
- onError={() => advance(gen)}
164
+ onLoad={handleLoad}
165
+ onEnd={handleEnd}
166
+ onError={handleEnd}
121
167
  style={{ width: 0, height: 0 }}
122
168
  />
123
169
  );