past meeting transcript side

This commit is contained in:
Sara
2024-01-22 16:18:04 +01:00
parent 69ae5b281e
commit f36e8bc2cb
4 changed files with 175 additions and 82 deletions

View File

@@ -71,21 +71,30 @@ export default function TranscriptDetails(details: TranscriptDetails) {
return (
<>
<Grid templateColumns="1fr" templateRows="minmax(0, 1fr) auto">
<Grid
templateColumns="1fr"
templateRows="minmax(0, 1fr) auto"
gap={4}
mb={4}
>
<Grid
templateColumns="repeat(2, 1fr)"
templateRows="auto minmax(0, 1fr)"
gap={4}
gap={2}
padding={4}
background="gray.100"
borderRadius={2}
borderRadius={8}
>
<GridItem display="flex" flexDir="row" colSpan={2}>
<GridItem
display="flex"
flexDir="row"
alignItems={"center"}
colSpan={2}
>
<TranscriptTitle
title={transcript.response.title || "Unamed Transcript"}
transcriptId={transcriptId}
/>
<IconButton icon={<FaPen />} aria-label="Edit Transcript Title" />
</GridItem>
<TopicList
topics={topics.topics || []}

View File

@@ -9,6 +9,18 @@ import ScrollToBottom from "./scrollToBottom";
import { Topic } from "./webSocketTypes";
import { generateHighContrastColor } from "../../lib/utils";
import useParticipants from "./useParticipants";
import {
Accordion,
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
Box,
Flex,
Icon,
Text,
} from "@chakra-ui/react";
import { FaChevronDown, FaChevronRight } from "react-icons/fa";
type TopicListProps = {
topics: Topic[];
@@ -75,11 +87,16 @@ export function TopicList({
};
return (
<section className="relative w-full h-full bg-blue-400/20 rounded-lg md:rounded-xl p-1 sm:p-2 md:px-4 flex flex-col justify-center align-center">
<Flex
position={"relative"}
w={"100%"}
h={"100%"}
dir="column"
justify={"center"}
align={"center"}
>
{topics.length > 0 ? (
<>
<h2 className="ml-2 md:text-lg font-bold mb-2">Topics</h2>
{autoscroll && (
<ScrollToBottom
visible={!autoscrollEnabled}
@@ -87,80 +104,95 @@ export function TopicList({
/>
)}
<div
<Accordion
id="topics-div"
className="overflow-y-auto h-full"
overflowY={"auto"}
h={"100%"}
onScroll={handleScroll}
defaultIndex={[
topics.findIndex((topic) => topic.id == activeTopic?.id),
]}
variant="custom"
allowToggle
>
{topics.map((topic, index) => (
<button
<AccordionItem
key={index}
className="rounded-none border-solid border-0 border-bluegrey border-b last:border-none last:rounded-b-lg p-2 hover:bg-blue-400/20 focus-visible:bg-blue-400/20 text-left block w-full"
onClick={() =>
setActiveTopic(activeTopic?.id == topic.id ? null : topic)
}
background={{
base: "light",
_hover: "gray.100",
_focus: "gray.100",
}}
padding={2}
onClick={() => {
setActiveTopic(activeTopic?.id == topic.id ? null : topic);
}}
>
<div className="w-full flex justify-between items-center rounded-lg md:rounded-xl xs:text-base sm:text-lg md:text-xl font-bold leading-tight">
<p>
<span className="font-light font-mono text-slate-500 text-base md:text-lg">
[{formatTime(topic.timestamp)}]&nbsp;
</span>
<span>{topic.title}</span>
</p>
<FontAwesomeIcon
className="transform transition-transform duration-200 ml-2"
icon={
activeTopic?.id == topic.id
? faChevronDown
: faChevronRight
}
/>
</div>
{activeTopic?.id == topic.id && (
<div className="p-2">
{topic.segments ? (
<>
{topic.segments.map((segment, index: number) => (
<p
key={index}
className="text-left text-slate-500 text-sm md:text-base"
<Flex dir="row" letterSpacing={".2"}>
<AccordionButton>
<AccordionIcon />
<Box as="span" textAlign="left" ml="1">
{topic.title}{" "}
<Text
as="span"
color="gray.500"
fontSize="sm"
fontWeight="bold"
>
&nbsp;[{formatTime(topic.timestamp)}]&nbsp;-&nbsp;[
{formatTime(topic.timestamp + (topic.duration || 0))}]
</Text>
</Box>
</AccordionButton>
</Flex>
<AccordionPanel>
{topic.segments ? (
<>
{topic.segments.map((segment, index: number) => (
<Text
key={index}
className="text-left text-slate-500 text-sm md:text-base"
pb={2}
lineHeight={"1.3"}
>
<span className="font-mono text-slate-500">
[{formatTime(segment.start)}]
</span>
<span
className="font-bold text-slate-500"
style={{
color: generateHighContrastColor(
`Speaker ${segment.speaker}`,
[96, 165, 250],
),
}}
>
<span className="font-mono text-slate-500">
[{formatTime(segment.start)}]
</span>
<span
className="font-bold text-slate-500"
style={{
color: generateHighContrastColor(
`Speaker ${segment.speaker}`,
[96, 165, 250],
),
}}
>
{" "}
{getSpeakerName(segment.speaker)}:
</span>{" "}
<span>{segment.text}</span>
</p>
))}
</>
) : (
<>{topic.transcript}</>
)}
</div>
)}
</button>
{" "}
{getSpeakerName(segment.speaker)}:
</span>{" "}
<span>{segment.text}</span>
</Text>
))}
</>
) : (
<>{topic.transcript}</>
)}
</AccordionPanel>
</AccordionItem>
))}
</div>
</Accordion>
</>
) : (
<div className="text-center text-gray-500">
Discussion topics will appear here after you start recording.
<br />
It may take up to 5 minutes of conversation for the first topic to
appear.
</div>
<Box textAlign={"center"} textColor="gray">
<Text>
Discussion topics will appear here after you start recording.
</Text>
<Text>
It may take up to 5 minutes of conversation for the first topic to
appear.
</Text>
</Box>
)}
</section>
</Flex>
);
}

View File

@@ -1,6 +1,8 @@
import { useState } from "react";
import { UpdateTranscript } from "../../api";
import useApi from "../../lib/useApi";
import { Heading, IconButton, Input } from "@chakra-ui/react";
import { FaPen } from "react-icons/fa";
type TranscriptTitle = {
title: string;
@@ -19,7 +21,6 @@ const TranscriptTitle = (props: TranscriptTitle) => {
const requestBody: UpdateTranscript = {
title: newTitle,
};
const api = useApi();
const updatedTranscript = await api?.v1TranscriptUpdate(
transcriptId,
requestBody,
@@ -46,6 +47,12 @@ const TranscriptTitle = (props: TranscriptTitle) => {
}
};
const handleBlur = () => {
if (displayedTitle !== preEditTitle) {
updateTitle(displayedTitle, props.transcriptId);
}
setIsEditing(false);
};
const handleChange = (e) => {
setDisplayedTitle(e.target.value);
};
@@ -63,21 +70,36 @@ const TranscriptTitle = (props: TranscriptTitle) => {
return (
<>
{isEditing ? (
<input
<Input
type="text"
value={displayedTitle}
onChange={handleChange}
onKeyDown={handleKeyDown}
autoFocus
className="text-2xl lg:text-4xl font-extrabold text-center mb-4 w-full border-none bg-transparent overflow-hidden h-[fit-content]"
onBlur={handleBlur}
size={"lg"}
fontSize={"xl"}
fontWeight={"bold"}
// className="text-2xl lg:text-4xl font-extrabold text-center mb-4 w-full border-none bg-transparent overflow-hidden h-[fit-content]"
/>
) : (
<h2
className="text-2xl lg:text-4xl font-extrabold text-center mb-4 cursor-pointer"
onClick={handleTitleClick}
>
{displayedTitle}
</h2>
<>
<Heading
// className="text-2xl lg:text-4xl font-extrabold text-center mb-4 cursor-pointer"
onClick={handleTitleClick}
cursor={"pointer"}
size={"lg"}
noOfLines={1}
>
{displayedTitle}
</Heading>
<IconButton
icon={<FaPen />}
aria-label="Edit Transcript Title"
onClick={handleTitleClick}
fontSize={"15px"}
/>
</>
)}
</>
);

View File

@@ -1,7 +1,34 @@
// 1. Import `extendTheme`
import { extendTheme } from "@chakra-ui/react";
// 2. Call `extendTheme` and pass your custom values
import { accordionAnatomy } from "@chakra-ui/anatomy";
import { createMultiStyleConfigHelpers, defineStyle } from "@chakra-ui/react";
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(accordionAnatomy.keys);
const custom = definePartsStyle({
container: {
border: "0",
borderRadius: "8px",
backgroundColor: "white",
mb: 2,
mr: 2,
},
panel: {
pl: 8,
pb: 0,
},
button: {
justifyContent: "flex-start",
pl: 2,
},
});
const accordionTheme = defineMultiStyleConfig({
variants: { custom },
});
const theme = extendTheme({
colors: {
blue: {
@@ -29,6 +56,9 @@ const theme = extendTheme({
light: "#FFFFFF",
dark: "#0C0D0E",
},
components: {
Accordion: accordionTheme,
},
});
export default theme;