refactor with useRef

pull/262/head
Ben Xu 8 months ago
parent 562cfb7206
commit 6d8781ab94

@ -9,7 +9,6 @@ import {
import * as FileSystem from "expo-file-system"; import * as FileSystem from "expo-file-system";
import { Audio } from "expo-av"; import { Audio } from "expo-av";
import { polyfill as polyfillEncoding } from "react-native-polyfill-globals/src/encoding"; import { polyfill as polyfillEncoding } from "react-native-polyfill-globals/src/encoding";
import { create } from "zustand";
import { Animated } from "react-native"; import { Animated } from "react-native";
import useSoundEffect from "../utils/useSoundEffect"; import useSoundEffect from "../utils/useSoundEffect";
import RecordButton from "../utils/RecordButton"; import RecordButton from "../utils/RecordButton";
@ -23,27 +22,6 @@ interface MainProps {
}; };
} }
interface AudioQueueState {
audioQueue: string[]; // Define the audio queue type
addToQueue: (uri: string) => void; // Function to set audio queue
}
const useAudioQueueStore = create<AudioQueueState>((set) => ({
audioQueue: [], // initial state
addToQueue: (uri) =>
set((state) => ({ audioQueue: [...state.audioQueue, uri] })), // action to set audio queue
}));
interface SoundState {
sound: Audio.Sound | null; // Define the sound type
setSound: (newSound: Audio.Sound | null) => void; // Function to set sound
}
const useSoundStore = create<SoundState>((set) => ({
sound: null, // initial state
setSound: (newSound) => set({ sound: newSound }), // action to set sound
}));
const Main: React.FC<MainProps> = ({ route }) => { const Main: React.FC<MainProps> = ({ route }) => {
const { scannedData } = route.params; const { scannedData } = route.params;
const [connectionStatus, setConnectionStatus] = const [connectionStatus, setConnectionStatus] =
@ -53,10 +31,8 @@ const Main: React.FC<MainProps> = ({ route }) => {
const [rescan, setRescan] = useState(false); const [rescan, setRescan] = useState(false);
const [isPressed, setIsPressed] = useState(false); const [isPressed, setIsPressed] = useState(false);
const [recording, setRecording] = useState<Audio.Recording | null>(null); const [recording, setRecording] = useState<Audio.Recording | null>(null);
const addToQueue = useAudioQueueStore((state) => state.addToQueue); const audioQueueRef = useRef<String[]>([]);
const audioQueue = useAudioQueueStore((state) => state.audioQueue); const soundRef = useRef<Audio.Sound | null>(null);
const setSound = useSoundStore((state) => state.setSound);
const sound = useSoundStore((state) => state.sound);
const [soundUriMap, setSoundUriMap] = useState<Map<Audio.Sound, string>>( const [soundUriMap, setSoundUriMap] = useState<Map<Audio.Sound, string>>(
new Map() new Map()
); );
@ -76,6 +52,7 @@ const Main: React.FC<MainProps> = ({ route }) => {
inputRange: [0, 1], inputRange: [0, 1],
outputRange: ["white", "black"], outputRange: ["white", "black"],
}); });
const constructTempFilePath = async (buffer: string) => { const constructTempFilePath = async (buffer: string) => {
try { try {
await dirExists(); await dirExists();
@ -112,37 +89,37 @@ const Main: React.FC<MainProps> = ({ route }) => {
} }
const playNextAudio = useCallback(async () => { const playNextAudio = useCallback(async () => {
if (audioQueue.length > 0 && sound == null) { if (audioQueueRef.current.length > 0 && soundRef.current == null) {
const uri = audioQueue.shift() as string; const uri = audioQueueRef.current.at(0) as string;
try { try {
const { sound: newSound } = await Audio.Sound.createAsync({ uri }); const { sound: newSound } = await Audio.Sound.createAsync({ uri });
setSound(newSound); soundRef.current = newSound;
setSoundUriMap(new Map(soundUriMap.set(newSound, uri))); setSoundUriMap(new Map(soundUriMap.set(newSound, uri)));
await newSound.playAsync(); await newSound.playAsync();
newSound.setOnPlaybackStatusUpdate(_onPlayBackStatusUpdate); newSound.setOnPlaybackStatusUpdate(_onPlayBackStatusUpdate);
} catch (error) { } catch (error) {
console.log("Error playing audio", error); console.log("Error playing audio", error);
playNextAudio();
} }
} else { } else {
// audioQueue is empty or sound is not null // audioQueue is empty or sound is not null
return; return;
} }
}, [audioQueue, sound, soundUriMap]); },[]);
const _onPlayBackStatusUpdate = useCallback( const _onPlayBackStatusUpdate = useCallback(
async (status: any) => { async (status: any) => {
if (status.didJustFinish) { if (status.didJustFinish) {
await sound?.unloadAsync(); audioQueueRef.current.shift();
soundUriMap.delete(sound); await soundRef.current?.unloadAsync();
setSoundUriMap(new Map(soundUriMap)); if (soundRef.current) {
setSound(null); soundUriMap.delete(soundRef.current);
setSoundUriMap(new Map(soundUriMap));
}
soundRef.current = null;
playNextAudio(); playNextAudio();
} }
}, },[]);
[sound, soundUriMap, playNextAudio]
);
useEffect(() => { useEffect(() => {
const backAction = () => { const backAction = () => {
@ -159,14 +136,6 @@ const Main: React.FC<MainProps> = ({ route }) => {
return () => backHandler.remove(); return () => backHandler.remove();
}, [navigation]); }, [navigation]);
useEffect(() => {
if (audioQueue.length > 0 && !sound) {
playNextAudio();
}
}, [audioQueue, sound, playNextAudio]);
useEffect(() => {}, [sound]);
useEffect(() => { useEffect(() => {
let websocket: WebSocket; let websocket: WebSocket;
try { try {
@ -188,7 +157,11 @@ const Main: React.FC<MainProps> = ({ route }) => {
if (buffer && buffer.length > 0) { if (buffer && buffer.length > 0) {
const filePath = await constructTempFilePath(buffer); const filePath = await constructTempFilePath(buffer);
if (filePath !== null) { if (filePath !== null) {
addToQueue(filePath); audioQueueRef.current.push(filePath);
if (audioQueueRef.current.length == 1) {
playNextAudio();
}
} else { } else {
console.error("Failed to create file path"); console.error("Failed to create file path");
} }

Loading…
Cancel
Save