voicebot-react-native-expo
Version:
This is a voicebot-react-native package of Kipps AI voice bot for React Native Expo
115 lines (110 loc) • 4.86 kB
JavaScript
import { ConnectionState, RoomEvent, Track } from 'livekit-client';
import { useEffect, useState } from 'react';
/** @deprecated wrap your components in a <LiveKitRoom> component instead and use more granular hooks to track state you're interested in */
export function useRoom(room, options) {
const [error] = useState();
const [participants, setParticipants] = useState([]);
const [audioTracks, setAudioTracks] = useState([]);
const sortFunc = (options === null || options === void 0 ? void 0 : options.sortParticipants) ?? sortParticipants;
useEffect(() => {
const onParticipantsChanged = () => {
const remotes = Array.from(room.remoteParticipants.values());
const newParticipants = [room.localParticipant];
newParticipants.push(...remotes);
sortFunc(newParticipants, room.localParticipant);
setParticipants(newParticipants);
};
const onSubscribedTrackChanged = track => {
// ordering may have changed, re-sort
onParticipantsChanged();
if (track && track.kind !== Track.Kind.Audio) {
return;
}
const tracks = [];
room.remoteParticipants.forEach(p => {
p.audioTrackPublications.forEach(pub => {
if (pub.audioTrack) {
tracks.push(pub.audioTrack);
}
});
});
setAudioTracks(tracks);
};
const onConnectionStateChanged = state => {
if (state === ConnectionState.Connected) {
onParticipantsChanged();
}
};
room.once(RoomEvent.Disconnected, () => {
room.off(RoomEvent.ParticipantConnected, onParticipantsChanged).off(RoomEvent.ParticipantDisconnected, onParticipantsChanged).off(RoomEvent.ActiveSpeakersChanged, onParticipantsChanged).off(RoomEvent.TrackSubscribed, onSubscribedTrackChanged).off(RoomEvent.TrackUnsubscribed, onSubscribedTrackChanged).off(RoomEvent.LocalTrackPublished, onParticipantsChanged).off(RoomEvent.LocalTrackUnpublished, onParticipantsChanged).off(RoomEvent.AudioPlaybackStatusChanged, onParticipantsChanged).off(RoomEvent.ConnectionStateChanged, onConnectionStateChanged);
});
room.on(RoomEvent.ConnectionStateChanged, onConnectionStateChanged).on(RoomEvent.Reconnected, onParticipantsChanged).on(RoomEvent.ParticipantConnected, onParticipantsChanged).on(RoomEvent.ParticipantDisconnected, onParticipantsChanged).on(RoomEvent.ActiveSpeakersChanged, onParticipantsChanged).on(RoomEvent.TrackSubscribed, onSubscribedTrackChanged).on(RoomEvent.TrackUnsubscribed, onSubscribedTrackChanged).on(RoomEvent.LocalTrackPublished, onParticipantsChanged).on(RoomEvent.LocalTrackUnpublished, onParticipantsChanged)
// trigger a state change by re-sorting participants
.on(RoomEvent.AudioPlaybackStatusChanged, onParticipantsChanged);
onSubscribedTrackChanged();
return () => {
room.disconnect();
};
}, [room, sortFunc]);
return {
error,
participants,
audioTracks
};
}
/**
* Default sort for participants, it'll order participants by:
* 1. dominant speaker (speaker with the loudest audio level)
* 2. local participant
* 3. other speakers that are recently active
* 4. participants with video on
* 5. by joinedAt
*/
export function sortParticipants(participants, localParticipant) {
participants.sort((a, b) => {
var _a$joinedAt, _b$joinedAt;
// loudest speaker first
if (a.isSpeaking && b.isSpeaking) {
return b.audioLevel - a.audioLevel;
}
// speaker goes first
if (a.isSpeaking !== b.isSpeaking) {
if (a.isSpeaking) {
return -1;
} else {
return 1;
}
}
// last active speaker first
if (a.lastSpokeAt !== b.lastSpokeAt) {
var _a$lastSpokeAt, _b$lastSpokeAt;
const aLast = ((_a$lastSpokeAt = a.lastSpokeAt) === null || _a$lastSpokeAt === void 0 ? void 0 : _a$lastSpokeAt.getTime()) ?? 0;
const bLast = ((_b$lastSpokeAt = b.lastSpokeAt) === null || _b$lastSpokeAt === void 0 ? void 0 : _b$lastSpokeAt.getTime()) ?? 0;
return bLast - aLast;
}
// video on
const aVideo = a.videoTrackPublications.size > 0;
const bVideo = b.videoTrackPublications.size > 0;
if (aVideo !== bVideo) {
if (aVideo) {
return -1;
} else {
return 1;
}
}
// joinedAt
return (((_a$joinedAt = a.joinedAt) === null || _a$joinedAt === void 0 ? void 0 : _a$joinedAt.getTime()) ?? 0) - (((_b$joinedAt = b.joinedAt) === null || _b$joinedAt === void 0 ? void 0 : _b$joinedAt.getTime()) ?? 0);
});
if (localParticipant) {
const localIdx = participants.indexOf(localParticipant);
if (localIdx >= 0) {
participants.splice(localIdx, 1);
if (participants.length > 0) {
participants.splice(1, 0, localParticipant);
} else {
participants.push(localParticipant);
}
}
}
}
//# sourceMappingURL=useRoom.js.map