completed Audio frontend
This commit is contained in:
82
apps/dispatch/app/_store/audioStore.ts
Normal file
82
apps/dispatch/app/_store/audioStore.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import {
|
||||
handleActiveSpeakerChange,
|
||||
handleDisconnect,
|
||||
handleLocalTrackUnpublished,
|
||||
handleTrackSubscribed,
|
||||
handleTrackUnsubscribed,
|
||||
} from "helpers/liveKitEventHandler";
|
||||
import { ConnectionQuality, Room, RoomEvent } from "livekit-client";
|
||||
import { create } from "zustand";
|
||||
|
||||
let interval: NodeJS.Timeout;
|
||||
|
||||
type TalkState = {
|
||||
isTalking: boolean;
|
||||
state: "connecting" | "connected" | "disconnected";
|
||||
connectionQuality: ConnectionQuality;
|
||||
remoteParticipants: number;
|
||||
toggleTalking: () => void;
|
||||
|
||||
connect: (roomName: string) => void;
|
||||
disconnect: () => void;
|
||||
room: Room | null;
|
||||
};
|
||||
const getToken = async (roomName: string) => {
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_DISPATCH_SERVER_URL}/livekit/token?roomName=${roomName}`,
|
||||
);
|
||||
const data = await response.json();
|
||||
return data.token;
|
||||
};
|
||||
|
||||
export const useAudioStore = create<TalkState>((set, get) => ({
|
||||
isTalking: false,
|
||||
state: "disconnected",
|
||||
remoteParticipants: 0,
|
||||
connectionQuality: ConnectionQuality.Unknown,
|
||||
room: null,
|
||||
toggleTalking: () => set((state) => ({ isTalking: !state.isTalking })),
|
||||
connect: async (roomName) => {
|
||||
const connectedRoom = get().room;
|
||||
if (interval) clearInterval(interval);
|
||||
if (connectedRoom) {
|
||||
connectedRoom.disconnect();
|
||||
connectedRoom.removeAllListeners();
|
||||
}
|
||||
set({ state: "connecting" });
|
||||
const url = process.env.NEXT_PUBLIC_LIVEKIT_URL;
|
||||
if (!url) return console.error("NEXT_PUBLIC_LIVEKIT_URL not set");
|
||||
const token = await getToken(roomName);
|
||||
const room = new Room();
|
||||
await room.prepareConnection(url, token);
|
||||
room
|
||||
// Connection events
|
||||
.on(RoomEvent.Connected, () => {
|
||||
set({ state: "connected", room });
|
||||
})
|
||||
.on(RoomEvent.Disconnected, () => {
|
||||
set({ state: "disconnected" });
|
||||
|
||||
handleDisconnect();
|
||||
})
|
||||
.on(RoomEvent.ConnectionQualityChanged, (connectionQuality) =>
|
||||
set({ connectionQuality }),
|
||||
)
|
||||
|
||||
// Track events
|
||||
.on(RoomEvent.TrackSubscribed, handleTrackSubscribed)
|
||||
.on(RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed)
|
||||
.on(RoomEvent.ActiveSpeakersChanged, handleActiveSpeakerChange)
|
||||
.on(RoomEvent.LocalTrackUnpublished, handleLocalTrackUnpublished);
|
||||
await room.connect(url, token);
|
||||
interval = setInterval(() => {
|
||||
set({
|
||||
remoteParticipants:
|
||||
room.numParticipants === 0 ? 0 : room.numParticipants - 1, // Unreliable and delayed
|
||||
});
|
||||
}, 500);
|
||||
},
|
||||
disconnect: () => {
|
||||
get().room?.disconnect();
|
||||
},
|
||||
}));
|
||||
@@ -12,7 +12,7 @@ interface ConnectionStore {
|
||||
disconnect: () => void;
|
||||
}
|
||||
|
||||
export const connectionStore = create<ConnectionStore>((set) => ({
|
||||
export const useConnectionStore = create<ConnectionStore>((set) => ({
|
||||
isConnected: false,
|
||||
selectedZone: "LST_01",
|
||||
connect: async (uid, selectedZone, logoffTime) =>
|
||||
@@ -34,8 +34,8 @@ export const connectionStore = create<ConnectionStore>((set) => ({
|
||||
}));
|
||||
|
||||
socket.on("connect", () => {
|
||||
connectionStore.setState({ isConnected: true });
|
||||
useConnectionStore.setState({ isConnected: true });
|
||||
});
|
||||
socket.on("disconnect", () => {
|
||||
connectionStore.setState({ isConnected: false });
|
||||
useConnectionStore.setState({ isConnected: false });
|
||||
});
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { create } from "zustand";
|
||||
|
||||
type TalkState = {
|
||||
isTalking: boolean;
|
||||
toggleTalking: () => void;
|
||||
};
|
||||
|
||||
export const useTalkStore = create<TalkState>((set) => ({
|
||||
isTalking: false,
|
||||
toggleTalking: () => set((state) => ({ isTalking: !state.isTalking })),
|
||||
}));
|
||||
Reference in New Issue
Block a user