File size: 2,701 Bytes
53ea588
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: BSD 2-Clause License

import { useEffect, useRef } from "react";

import { useState } from "react";

interface Props {
  websocket: WebSocket | null;
}

interface IncomingMessage {
  text: string;
  actor: string;
  message_id: string;
}

interface AugmentedMessage extends IncomingMessage {
  timestamp: Date;
}

export function Transcripts(props: Props) {
  const [transcripts, setTranscripts] = useState<AugmentedMessage[]>([]);
  const bottomRef = useRef<HTMLDivElement>(null);

  // Clear transcripts when a new WebSocket connection is established
  useEffect(() => {
    if (props.websocket) {
      console.log("New WebSocket connection detected, clearing old transcripts");
      setTranscripts([]);
    }
  }, [props.websocket]);

  useEffect(() => {
    function onMessage(event: MessageEvent) {
      const message = JSON.parse(event.data) as IncomingMessage;
      console.log(event.data, message);
      setTranscripts((prev) => {
        const existingMessage = prev.find(
          (t) =>
            t.actor === message.actor && t.message_id === message.message_id
        );
        if (existingMessage) {
          existingMessage.text = message.text;
        } else {
          prev.push({ ...message, timestamp: new Date() });
        }
        return [...prev];
      });
    }

    props.websocket?.addEventListener("message", onMessage);
    return () => {
      props.websocket?.removeEventListener("message", onMessage);
    };
  }, [props.websocket]);

  useEffect(() => {
    // Scroll to the bottom of the transcripts every time a new transcript is added
    bottomRef.current?.scrollIntoView();
  }, [transcripts]);

  const filteredTranscripts = transcripts.filter((transcript) => {
    const actor = transcript.actor?.toLowerCase()?.trim();
    const isSystem = actor === "system";
    return !isSystem;
  });
    
  return filteredTranscripts.map((transcript) => (
    <div
      className="font-mono text-lg flex items-start mb-2"
      key={transcript.actor + transcript.message_id}
    >
      {transcript.timestamp.toTimeString().slice(0, 8)}
      <div className="flex items-center ml-3 mr-3 min-w-[60px]">
        <div
          className={`rounded-lg text-white text-sm p-1 flex justify-center items-center min-w-full ${
            transcript.actor === "bot" ? "bg-nvidia" : "bg-cyan-700"
          }`}
        >
          {transcript.actor}
        </div>
      </div>
      <div>:</div>
      <div className="pl-3"> </div>
      <div className="flex-1">{transcript.text}</div>
      <div ref={bottomRef} />
    </div>
  ));
}