Skip to content

Commit 71b95ea

Browse files
committed
refactor: react cleanup
1 parent 822a342 commit 71b95ea

6 files changed

Lines changed: 89 additions & 102 deletions

File tree

apps/common-app/src/examples/AudioTag/AudioTag.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import React, { useRef } from 'react';
22
import { Button, View } from 'react-native';
3-
import { Audio, AudioHandle } from 'react-native-audio-api/development/react';
3+
import { Audio, AudioTagHandle } from 'react-native-audio-api/development/react';
44

55
import { Container } from '../../components';
66

77
// const DEMO_AUDIO_URL = 'https://filesamples.com/samples/audio/m4a/sample4.m4a';
88
const DEMO_AUDIO_URL = 'https://filesamples.com/samples/audio/mp3/sample4.mp3';
99

1010
const AudioTag: React.FC = () => {
11-
const audioRef = useRef<AudioHandle>(null);
11+
const audioRef = useRef<AudioTagHandle>(null);
1212

1313
// const handlePlay = () => {
1414
// audioRef.current?.play();
@@ -39,10 +39,9 @@ const AudioTag: React.FC = () => {
3939
onLoadStart={() => console.log('onLoadStart')}
4040
onLoad={() => console.log('onLoad')}
4141
onError={(error) => console.log('onError', error)}
42-
onPositionChanged={(seconds) =>
43-
console.log('onPositionChanged', seconds)
42+
onPositionChange={(seconds) =>
43+
console.log('onPositionChange', seconds)
4444
}
45-
onSeek={(seconds) => console.log('onSeek', seconds)}
4645
onEnded={() => console.log('onEnded')}
4746
onPlay={() => console.log('onPlay')}
4847
onPause={() => console.log('onPause')}

packages/react-native-audio-api/src/development/react/Audio/Audio.tsx

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import React, {
88
} from 'react';
99
import { View, Image, Platform } from 'react-native';
1010

11-
import type { AudioHandle, AudioProps, AudioTagPlaybackState } from './types';
11+
import type {
12+
AudioTagHandle,
13+
AudioProps,
14+
AudioTagPlaybackState,
15+
} from './types';
1216

1317
import { AudioComponentContext } from './AudioTagContext';
1418
import { AudioFileSourceNode } from './AudioFileSourceNode';
@@ -17,7 +21,7 @@ import { NotSupportedError } from '../../../errors';
1721
import { NativeAudioAPIModule } from '../../../specs';
1822
import { AudioControls } from '..';
1923

20-
const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
24+
const Audio = React.forwardRef<AudioTagHandle, AudioProps>((props, ref) => {
2125
const { children } = props;
2226
const {
2327
autoPlay,
@@ -33,16 +37,15 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
3337
onLoadStart,
3438
onLoad,
3539
onError,
36-
onPositionChanged,
37-
onSeek,
40+
onPositionChange,
3841
onEnded: onEndedCallback,
3942
onPlay,
4043
onPause,
4144
onVolumeChange,
4245
} = useStableAudioProps(props);
4346
const audioContext = context ?? null;
44-
const [volumeState, setVolumeState] = useState(volume);
45-
const [mutedState, setMutedState] = useState(muted);
47+
const [volumeState, setVolumeState] = useState<number | null>(null);
48+
const [mutedState, setMutedState] = useState<boolean | null>(null);
4649
const [ready, setReady] = useState(false);
4750

4851
const path = useMemo(() => {
@@ -69,18 +72,24 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
6972
const fileSourceRef = useRef<AudioFileSourceNode>(null);
7073
const sourceRef = useRef<ArrayBuffer | string | null>(null);
7174

72-
const effectiveVolumeRef = useRef(mutedState ? 0 : volumeState);
7375
const lastEffectiveVolumeRef = useRef(muted ? 0 : volume);
7476

7577
const [playbackState, setPlaybackState] =
7678
useState<AudioTagPlaybackState>('idle');
7779
const [currentTime, setCurrentTime] = useState(0);
7880
const [duration, setDuration] = useState(0);
7981

82+
const effectiveMutedState = useMemo(() => {
83+
return mutedState ?? muted;
84+
}, [mutedState, muted]);
85+
86+
const effectiveVolumeState = useMemo(() => {
87+
return effectiveMutedState ? 0 : (volumeState ?? volume);
88+
}, [effectiveMutedState, volumeState, volume]);
89+
8090
useEffect(() => {
81-
effectiveVolumeRef.current = mutedState ? 0 : volumeState;
82-
fileSourceRef.current?.setVolume(effectiveVolumeRef.current);
83-
}, [mutedState, volumeState]);
91+
fileSourceRef.current?.setVolume(effectiveVolumeState);
92+
}, [effectiveVolumeState]);
8493

8594
const play = useCallback(() => {
8695
fileSourceRef.current?.play();
@@ -102,9 +111,9 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
102111
? Math.max(0, Math.min(seconds, duration))
103112
: Math.max(0, seconds);
104113
setCurrentTime(nextTime);
105-
onSeek(nextTime);
114+
onPositionChange(nextTime);
106115
},
107-
[duration, onSeek, setCurrentTime]
116+
[duration, setCurrentTime, onPositionChange]
108117
);
109118

110119
const spawnFileSource = useCallback(() => {
@@ -121,7 +130,7 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
121130
const node = context.context.createFileSource({
122131
source: nextSource,
123132
loop,
124-
volume: effectiveVolumeRef.current,
133+
volume: effectiveVolumeState,
125134
});
126135
if (!node) {
127136
onError(new NotSupportedError('This file format requires FFmpeg build'));
@@ -139,7 +148,7 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
139148
},
140149
});
141150

142-
fileSource.setVolume(effectiveVolumeRef.current);
151+
fileSource.setVolume(effectiveVolumeState);
143152
fileSourceRef.current = fileSource;
144153
setDuration(nextDuration);
145154
onLoad();
@@ -149,7 +158,16 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
149158
setPlaybackState('playing');
150159
onPlay();
151160
}
152-
}, [context, loop, onError, onEndedCallback, onLoad, onPlay, autoPlay]);
161+
}, [
162+
context,
163+
loop,
164+
onError,
165+
onEndedCallback,
166+
onLoad,
167+
onPlay,
168+
autoPlay,
169+
effectiveVolumeState,
170+
]);
153171

154172
useEffect(() => {
155173
if (!path) {
@@ -205,12 +223,11 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
205223
}, [path, source, spawnFileSource, onError, onLoadStart]);
206224

207225
useEffect(() => {
208-
const effectiveVolume = mutedState ? 0 : volumeState;
209-
if (lastEffectiveVolumeRef.current !== effectiveVolume) {
210-
lastEffectiveVolumeRef.current = effectiveVolume;
211-
onVolumeChange(effectiveVolume);
226+
if (lastEffectiveVolumeRef.current !== effectiveVolumeState) {
227+
lastEffectiveVolumeRef.current = effectiveVolumeState;
228+
onVolumeChange(effectiveVolumeState);
212229
}
213-
}, [mutedState, onVolumeChange, volumeState]);
230+
}, [onVolumeChange, effectiveVolumeState]);
214231

215232
useEffect(() => {
216233
fileSourceRef.current?.setLoop(loop);
@@ -223,13 +240,13 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
223240

224241
fileSourceRef.current?.startPositionTracking((seconds) => {
225242
setCurrentTime(seconds);
226-
onPositionChanged(seconds);
243+
onPositionChange(seconds);
227244
});
228245

229246
return () => {
230247
fileSourceRef.current?.stopPositionTracking();
231248
};
232-
}, [onPositionChanged, playbackState]);
249+
}, [onPositionChange, playbackState]);
233250

234251
useImperativeHandle(
235252
ref,
@@ -249,10 +266,10 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
249266
pause,
250267
seekToTime,
251268
setVolume: setVolumeState,
252-
volume: volumeState,
269+
volume: effectiveVolumeState,
253270
ready,
254271
setMuted: setMutedState,
255-
muted: mutedState,
272+
muted: effectiveMutedState,
256273
playbackState,
257274
currentTime,
258275
duration,
@@ -271,10 +288,10 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
271288
pause,
272289
seekToTime,
273290
setVolumeState,
274-
volumeState,
291+
effectiveVolumeState,
275292
ready,
276293
setMutedState,
277-
mutedState,
294+
effectiveMutedState,
278295
playbackState,
279296
currentTime,
280297
duration,

packages/react-native-audio-api/src/development/react/Audio/Audio.web.tsx

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ import React, {
88
} from 'react';
99
import { View } from 'react-native';
1010

11-
import type { AudioHandle, AudioProps, AudioTagPlaybackState } from './types';
11+
import type {
12+
AudioTagHandle,
13+
AudioProps,
14+
AudioTagPlaybackState,
15+
} from './types';
1216
import { AudioComponentContext } from './AudioTagContext';
1317
import { useStableAudioProps } from './utils';
1418

15-
const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
19+
const Audio = React.forwardRef<AudioTagHandle, AudioProps>((props, ref) => {
1620
const { children } = props;
1721
const {
1822
autoPlay,
@@ -27,8 +31,7 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
2731
onLoadStart,
2832
onLoad,
2933
onError,
30-
onPositionChanged,
31-
onSeek,
34+
onPositionChange,
3235
onEnded: onEndedCallback,
3336
onPlay,
3437
onPause,
@@ -37,16 +40,25 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
3740

3841
const audioRef = useRef<HTMLAudioElement>(null);
3942
const [volumeState, setVolumeState] = useState(volume);
40-
const [mutedState, setMutedState] = useState(muted);
43+
const [mutedState, setMutedState] = useState<boolean | null>(null);
4144
const [ready, setReady] = useState(false);
4245
const [playbackState, setPlaybackState] =
4346
useState<AudioTagPlaybackState>('idle');
4447
const [currentTime, setCurrentTime] = useState(0);
4548
const [duration, setDuration] = useState(0);
46-
const lastPropMutedRef = useRef(muted);
47-
const lastPropVolumeRef = useRef(volume);
4849
const lastElementVolumeRef = useRef(muted ? 0 : volume);
49-
const isSeekingRef = useRef(false);
50+
51+
const effectiveMutedState = useMemo(() => {
52+
return mutedState ?? muted;
53+
}, [mutedState, muted]);
54+
55+
const effectiveVolumeState = useMemo(() => {
56+
return volumeState ?? volume;
57+
}, [volumeState, volume]);
58+
59+
const reportedVolumeState = useMemo(() => {
60+
return effectiveMutedState ? 0 : effectiveVolumeState;
61+
}, [effectiveMutedState, effectiveVolumeState]);
5062

5163
const path = useMemo(() => {
5264
if (!source) {
@@ -78,53 +90,26 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
7890
if (!el) {
7991
return;
8092
}
81-
el.volume = mutedState ? 0 : volumeState;
82-
}, [mutedState, volumeState]);
93+
el.volume = effectiveVolumeState;
94+
}, [effectiveVolumeState]);
8395

8496
useEffect(() => {
8597
const el = audioRef.current;
8698
if (!el) {
8799
return;
88100
}
89-
el.muted = mutedState;
90-
}, [mutedState]);
91-
92-
useEffect(() => {
93-
if (lastPropVolumeRef.current !== volume) {
94-
lastPropVolumeRef.current = volume;
95-
setVolumeState(volume);
96-
}
97-
}, [volume]);
98-
99-
useEffect(() => {
100-
if (lastPropMutedRef.current !== muted) {
101-
lastPropMutedRef.current = muted;
102-
setMutedState(muted);
103-
}
104-
}, [muted]);
101+
el.muted = effectiveMutedState;
102+
}, [effectiveMutedState]);
105103

106104
useEffect(() => {
107105
const el = audioRef.current;
108106
if (!el) {
109107
return;
110108
}
111109

112-
const handleLoadedMetadata = () => {
113-
setDuration(el.duration);
114-
setCurrentTime(el.currentTime);
115-
};
116-
117110
const handleTimeUpdate = () => {
118-
if (!isSeekingRef.current) {
119-
setCurrentTime(el.currentTime);
120-
onPositionChanged(el.currentTime);
121-
}
122-
};
123-
124-
const handleSeeked = () => {
125111
setCurrentTime(el.currentTime);
126-
onSeek(el.currentTime);
127-
isSeekingRef.current = false;
112+
onPositionChange(el.currentTime);
128113
};
129114

130115
const handleVolumeChange = () => {
@@ -140,21 +125,17 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
140125
}
141126
};
142127

143-
el.addEventListener('loadedmetadata', handleLoadedMetadata);
144128
el.addEventListener('timeupdate', handleTimeUpdate);
145-
el.addEventListener('seeked', handleSeeked);
146129
el.addEventListener('volumechange', handleVolumeChange);
147130
setDuration(el.duration);
148131
setCurrentTime(el.currentTime);
149132
lastElementVolumeRef.current = el.muted ? 0 : el.volume;
150133

151134
return () => {
152-
el.removeEventListener('loadedmetadata', handleLoadedMetadata);
153135
el.removeEventListener('timeupdate', handleTimeUpdate);
154-
el.removeEventListener('seeked', handleSeeked);
155136
el.removeEventListener('volumechange', handleVolumeChange);
156137
};
157-
}, [onPositionChanged, onSeek, onVolumeChange, ready]);
138+
}, [onPositionChange, onVolumeChange, ready]);
158139

159140
const play = useCallback(() => {
160141
audioRef.current?.play();
@@ -174,7 +155,6 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
174155
if (!el) {
175156
return;
176157
}
177-
isSeekingRef.current = true;
178158
const nextTime =
179159
duration > 0
180160
? Math.max(0, Math.min(seconds, duration))
@@ -212,9 +192,9 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
212192
seekToTime,
213193
setVolume,
214194
ready,
215-
volume: volumeState,
195+
volume: reportedVolumeState,
216196
setMuted,
217-
muted: mutedState,
197+
muted: effectiveMutedState,
218198
playbackState,
219199
currentTime,
220200
duration,
@@ -232,9 +212,9 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
232212
seekToTime,
233213
setVolume,
234214
ready,
235-
volumeState,
215+
reportedVolumeState,
236216
setMuted,
237-
mutedState,
217+
effectiveMutedState,
238218
playbackState,
239219
currentTime,
240220
duration,
@@ -254,7 +234,7 @@ const Audio = React.forwardRef<AudioHandle, AudioProps>((props, ref) => {
254234
autoPlay={autoPlay}
255235
controls={controls}
256236
loop={loop}
257-
muted={mutedState}
237+
muted={effectiveMutedState}
258238
preload={preload}
259239
src={path}
260240
ref={audioRef}

packages/react-native-audio-api/src/development/react/Audio/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export { default } from './Audio';
22
export { useAudioTagContext } from './AudioTagContext';
33

44
export type {
5-
AudioHandle,
5+
AudioTagHandle,
66
AudioProps,
77
AudioSource,
88
AudioTagPlaybackState,

0 commit comments

Comments
 (0)