-
Notifications
You must be signed in to change notification settings - Fork 99
/
Copy pathTranscriptionTile.tsx
111 lines (105 loc) · 2.9 KB
/
TranscriptionTile.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { ChatMessageType, ChatTile } from "@/components/chat/ChatTile";
import {
TrackReferenceOrPlaceholder,
useChat,
useLocalParticipant,
useTrackTranscription,
} from "@livekit/components-react";
import {
LocalParticipant,
Participant,
Track,
TranscriptionSegment,
} from "livekit-client";
import { useEffect, useState } from "react";
export function TranscriptionTile({
agentAudioTrack,
accentColor,
}: {
agentAudioTrack: TrackReferenceOrPlaceholder;
accentColor: string;
}) {
const agentMessages = useTrackTranscription(agentAudioTrack);
const localParticipant = useLocalParticipant();
const localMessages = useTrackTranscription({
publication: localParticipant.microphoneTrack,
source: Track.Source.Microphone,
participant: localParticipant.localParticipant,
});
const [transcripts, setTranscripts] = useState<Map<string, ChatMessageType>>(
new Map()
);
const [messages, setMessages] = useState<ChatMessageType[]>([]);
const { chatMessages, send: sendChat } = useChat();
// store transcripts
useEffect(() => {
agentMessages.segments.forEach((s) =>
transcripts.set(
s.id,
segmentToChatMessage(
s,
transcripts.get(s.id),
agentAudioTrack.participant
)
)
);
localMessages.segments.forEach((s) =>
transcripts.set(
s.id,
segmentToChatMessage(
s,
transcripts.get(s.id),
localParticipant.localParticipant
)
)
);
const allMessages = Array.from(transcripts.values());
for (const msg of chatMessages) {
const isAgent =
msg.from?.identity === agentAudioTrack.participant?.identity;
const isSelf =
msg.from?.identity === localParticipant.localParticipant.identity;
let name = msg.from?.name;
if (!name) {
if (isAgent) {
name = "Agent";
} else if (isSelf) {
name = "You";
} else {
name = "Unknown";
}
}
allMessages.push({
name,
message: msg.message,
timestamp: msg.timestamp,
isSelf: isSelf,
});
}
allMessages.sort((a, b) => a.timestamp - b.timestamp);
setMessages(allMessages);
}, [
transcripts,
chatMessages,
localParticipant.localParticipant,
agentAudioTrack.participant,
agentMessages.segments,
localMessages.segments,
]);
return (
<ChatTile messages={messages} accentColor={accentColor} onSend={sendChat} />
);
}
function segmentToChatMessage(
s: TranscriptionSegment,
existingMessage: ChatMessageType | undefined,
participant: Participant
): ChatMessageType {
const msg: ChatMessageType = {
message: s.final ? s.text : `${s.text} ...`,
name: participant instanceof LocalParticipant ? "You" : "Agent",
isSelf: participant instanceof LocalParticipant,
timestamp: existingMessage?.timestamp ?? Date.now(),
};
return msg;
}