mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-22 05:09:05 +00:00
layout and design improvements
This commit is contained in:
101
www/app/transcripts/topicList.tsx
Normal file
101
www/app/transcripts/topicList.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faChevronRight,
|
||||
faChevronDown,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { formatTime } from "../lib/time";
|
||||
import ScrollToBottom from "./scrollToBottom";
|
||||
import { Topic } from "./webSocketTypes";
|
||||
|
||||
type TopicListProps = {
|
||||
topics: Topic[];
|
||||
useActiveTopic: [
|
||||
Topic | null,
|
||||
React.Dispatch<React.SetStateAction<Topic | null>>,
|
||||
];
|
||||
};
|
||||
|
||||
export function TopicList({ topics, useActiveTopic }: TopicListProps) {
|
||||
const [activeTopic, setActiveTopic] = useActiveTopic;
|
||||
const [autoscrollEnabled, setAutoscrollEnabled] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoscrollEnabled) scrollToBottom();
|
||||
console.log(topics);
|
||||
}, [topics.length]);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
const topicsDiv = document.getElementById("topics-div");
|
||||
|
||||
if (!topicsDiv)
|
||||
console.error("Could not find topics div to scroll to bottom");
|
||||
else topicsDiv.scrollTop = topicsDiv.scrollHeight;
|
||||
};
|
||||
|
||||
const handleScroll = (e) => {
|
||||
const bottom =
|
||||
e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
|
||||
if (!bottom && autoscrollEnabled) {
|
||||
setAutoscrollEnabled(false);
|
||||
} else if (bottom && !autoscrollEnabled) {
|
||||
setAutoscrollEnabled(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="relative w-full h-full bg-blue-400/20 rounded-lg md:rounded-xl px-2 md:px-4 flex flex-col justify-center align-center">
|
||||
{topics.length > 0 ? (
|
||||
<>
|
||||
<ScrollToBottom
|
||||
visible={!autoscrollEnabled}
|
||||
handleScrollBottom={scrollToBottom}
|
||||
/>
|
||||
|
||||
<div
|
||||
id="topics-div"
|
||||
className="overflow-y-auto py-2 h-full"
|
||||
onScroll={handleScroll}
|
||||
>
|
||||
{topics.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="border-b border-blue-300 last:border-none p-2 hover:bg-blue-400/20"
|
||||
role="button"
|
||||
onClick={() =>
|
||||
setActiveTopic(activeTopic?.id == item.id ? null : item)
|
||||
}
|
||||
>
|
||||
<div className="flex justify-between items-center rounded-lg md:rounded-xl text-lg md:text-xl font-bold">
|
||||
<p>
|
||||
<span className="font-light font-mono text-slate-500 pr-1 text-base md:text-lg">
|
||||
[{formatTime(item.timestamp)}]
|
||||
</span>
|
||||
|
||||
<span className="pr-1">{item.title}</span>
|
||||
</p>
|
||||
<FontAwesomeIcon
|
||||
className="transform transition-transform duration-200 ml-2"
|
||||
icon={
|
||||
activeTopic?.id == item.id
|
||||
? faChevronDown
|
||||
: faChevronRight
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{activeTopic?.id == item.id && (
|
||||
<div className="px-2">{item.transcript}</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="text-center text-gray-500 p-4">
|
||||
Discussion topics will appear here after you start recording. It may
|
||||
take up to 5 minutes of conversation for the first topic to appear.
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user