From 69ae5b281e67090fe23dc8c4675d7bc586bb9bfc Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 18 Jan 2024 14:05:34 +0100 Subject: [PATCH] refactor past meeting --- www/app/[domain]/browse/page.tsx | 1 + .../{ => [transcriptId]}/finalSummary.tsx | 118 +++++++--------- .../transcripts/[transcriptId]/page.tsx | 132 ++++++++---------- www/app/[domain]/transcripts/shareLink.tsx | 9 +- .../[domain]/transcripts/shareTranscript.tsx | 108 ++++++++++++++ .../[domain]/transcripts/useTranscriptList.ts | 1 + www/app/lib/time.ts | 2 + 7 files changed, 219 insertions(+), 152 deletions(-) rename www/app/[domain]/transcripts/{ => [transcriptId]}/finalSummary.tsx (54%) create mode 100644 www/app/[domain]/transcripts/shareTranscript.tsx diff --git a/www/app/[domain]/browse/page.tsx b/www/app/[domain]/browse/page.tsx index 211c927b..16321f9b 100644 --- a/www/app/[domain]/browse/page.tsx +++ b/www/app/[domain]/browse/page.tsx @@ -100,6 +100,7 @@ export default function TranscriptBrowser() { api .v1TranscriptDelete(transcriptToDeleteId) .then(() => { + refetch(); setDeletionLoading(false); refetch(); onCloseDeletion(); diff --git a/www/app/[domain]/transcripts/finalSummary.tsx b/www/app/[domain]/transcripts/[transcriptId]/finalSummary.tsx similarity index 54% rename from www/app/[domain]/transcripts/finalSummary.tsx rename to www/app/[domain]/transcripts/[transcriptId]/finalSummary.tsx index 6ad90b14..8d7311f1 100644 --- a/www/app/[domain]/transcripts/finalSummary.tsx +++ b/www/app/[domain]/transcripts/[transcriptId]/finalSummary.tsx @@ -1,25 +1,38 @@ -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import React from "react"; import Markdown from "react-markdown"; -import "../../styles/markdown.css"; -import { featureEnabled } from "../domainContext"; -import { UpdateTranscript } from "../../api"; -import useApi from "../../lib/useApi"; +import "../../../styles/markdown.css"; +import { UpdateTranscript } from "../../../api"; +import useApi from "../../../lib/useApi"; +import useTranscript from "../useTranscript"; +import useTopics from "../useTopics"; +import { Box, Flex, IconButton, Modal, ModalContent } from "@chakra-ui/react"; +import { FaShare } from "react-icons/fa"; +import ShareTranscript from "../shareTranscript"; type FinalSummaryProps = { - summary: string; - fullTranscript: string; transcriptId: string; - openZulipModal: () => void; }; export default function FinalSummary(props: FinalSummaryProps) { + const transcript = useTranscript(props.transcriptId); + const topics = useTopics(props.transcriptId); + const finalSummaryRef = useRef(null); - const [isCopiedSummary, setIsCopiedSummary] = useState(false); - const [isCopiedTranscript, setIsCopiedTranscript] = useState(false); + const [isEditMode, setIsEditMode] = useState(false); - const [preEditSummary, setPreEditSummary] = useState(props.summary); - const [editedSummary, setEditedSummary] = useState(props.summary); + const [preEditSummary, setPreEditSummary] = useState(""); + const [editedSummary, setEditedSummary] = useState(""); + + const [showShareModal, setShowShareModal] = useState(false); + + useEffect(() => { + setEditedSummary(transcript.response?.long_summary || ""); + }, [transcript.response?.long_summary]); + + if (!topics.topics || !transcript.response) { + return null; + } const updateSummary = async (newSummary: string, transcriptId: string) => { try { @@ -37,28 +50,6 @@ export default function FinalSummary(props: FinalSummaryProps) { } }; - const onCopySummaryClick = () => { - let text_to_copy = finalSummaryRef.current?.innerText; - - text_to_copy && - navigator.clipboard.writeText(text_to_copy).then(() => { - setIsCopiedSummary(true); - // Reset the copied state after 2 seconds - setTimeout(() => setIsCopiedSummary(false), 2000); - }); - }; - - const onCopyTranscriptClick = () => { - let text_to_copy = props.fullTranscript; - - text_to_copy && - navigator.clipboard.writeText(text_to_copy).then(() => { - setIsCopiedTranscript(true); - // Reset the copied state after 2 seconds - setTimeout(() => setIsCopiedTranscript(false), 2000); - }); - }; - const onEditClick = () => { setPreEditSummary(editedSummary); setIsEditMode(true); @@ -119,17 +110,6 @@ export default function FinalSummary(props: FinalSummaryProps) { {!isEditMode && ( <> - {featureEnabled("sendToZulip") && ( - - )} - - - + } + onClick={() => setShowShareModal(true)} + aria-label="Share" + /> + {showShareModal && ( + setShowShareModal(false)} + size="xl" + > + + + + + )} )} @@ -177,9 +153,9 @@ export default function FinalSummary(props: FinalSummaryProps) { /> ) : ( -

+

{editedSummary} -

+
)} ); diff --git a/www/app/[domain]/transcripts/[transcriptId]/page.tsx b/www/app/[domain]/transcripts/[transcriptId]/page.tsx index d0389fd9..1efb6c43 100644 --- a/www/app/[domain]/transcripts/[transcriptId]/page.tsx +++ b/www/app/[domain]/transcripts/[transcriptId]/page.tsx @@ -8,7 +8,7 @@ import { TopicList } from "../topicList"; import { Topic } from "../webSocketTypes"; import React, { useEffect, useState } from "react"; import "../../../styles/button.css"; -import FinalSummary from "../finalSummary"; +import FinalSummary from "./finalSummary"; import ShareLink from "../shareLink"; import QRCode from "react-qr-code"; import TranscriptTitle from "../transcriptTitle"; @@ -17,7 +17,16 @@ import Player from "../player"; import WaveformLoading from "../waveformLoading"; import { useRouter } from "next/navigation"; import { featureEnabled } from "../../domainContext"; -import { toShareMode } from "../../../lib/shareMode"; +import { + Box, + Button, + Flex, + Grid, + GridItem, + IconButton, + Text, +} from "@chakra-ui/react"; +import { FaPen } from "react-icons/fa"; type TranscriptDetails = { params: { @@ -34,7 +43,6 @@ export default function TranscriptDetails(details: TranscriptDetails) { const waveform = useWaveform(transcriptId); const useActiveTopic = useState(null); const mp3 = useMp3(transcriptId); - const [showModal, setShowModal] = useState(false); useEffect(() => { const statusToRedirect = ["idle", "recording", "processing"]; @@ -43,18 +51,11 @@ export default function TranscriptDetails(details: TranscriptDetails) { // Shallow redirection does not work on NextJS 13 // https://github.com/vercel/next.js/discussions/48110 // https://github.com/vercel/next.js/discussions/49540 - router.push(newUrl, undefined); + router.replace(newUrl); // history.replaceState({}, "", newUrl); } }, [transcript.response?.status]); - const fullTranscript = - topics.topics - ?.map((topic) => topic.transcript) - .join("\n\n") - .replace(/ +/g, " ") - .trim() || ""; - if (transcript.error || topics?.error) { return ( - {featureEnabled("sendToZulip") && ( - setShowModal(v)} - /> - )} -
- {transcript?.response?.title && ( - + + + + + } aria-label="Edit Transcript Title" /> + + - )} + {transcript.response.long_summary ? ( + <> + + + ) : ( + +
+ {transcript.response.status == "processing" ? ( + Loading Transcript + ) : ( + + There was an error generating the final summary, please come + back later + + )} +
+
+ )} +
{waveform.waveform && mp3.media ? ( )} -
-
- - -
-
- {transcript.response.long_summary ? ( - setShowModal(true)} - /> - ) : ( -
- {transcript.response.status == "processing" ? ( -

Loading Transcript

- ) : ( -

- There was an error generating the final summary, please come - back later -

- )} -
- )} -
- -
-
- -
-
- -
-
-
-
- + + ); } diff --git a/www/app/[domain]/transcripts/shareLink.tsx b/www/app/[domain]/transcripts/shareLink.tsx index 7e0d592d..57b53d3a 100644 --- a/www/app/[domain]/transcripts/shareLink.tsx +++ b/www/app/[domain]/transcripts/shareLink.tsx @@ -10,9 +10,10 @@ import { faSpinner } from "@fortawesome/free-solid-svg-icons"; import { UpdateTranscript } from "../../api"; import { ShareMode, toShareMode } from "../../lib/shareMode"; import useApi from "../../lib/useApi"; + type ShareLinkProps = { transcriptId: string; - userId: string | null; + transcriptUserId: string | null; shareMode: ShareMode; }; @@ -24,16 +25,16 @@ const ShareLink = (props: ShareLinkProps) => { const [isOwner, setIsOwner] = useState(false); const [shareMode, setShareMode] = useState(props.shareMode); const [shareLoading, setShareLoading] = useState(false); - const userinfo = useFiefUserinfo(); const api = useApi(); + const userId = useFiefUserinfo()?.sub; useEffect(() => { setCurrentUrl(window.location.href); }, []); useEffect(() => { - setIsOwner(!!(requireLogin && userinfo?.sub === props.userId)); - }, [userinfo, props.userId]); + setIsOwner(!!(requireLogin && userId === props.transcriptUserId)); + }, [userId, props.transcriptUserId]); const handleCopyClick = () => { if (inputRef.current) { diff --git a/www/app/[domain]/transcripts/shareTranscript.tsx b/www/app/[domain]/transcripts/shareTranscript.tsx new file mode 100644 index 00000000..5a61461e --- /dev/null +++ b/www/app/[domain]/transcripts/shareTranscript.tsx @@ -0,0 +1,108 @@ +import { useState } from "react"; +import { featureEnabled } from "../domainContext"; +import ShareModal from "./[transcriptId]/shareModal"; +import ShareLink from "./shareLink"; +import QRCode from "react-qr-code"; +import { toShareMode } from "../../lib/shareMode"; +import { GetTranscript, GetTranscriptTopic } from "../../api"; + +type ShareTranscriptProps = { + finalSummaryRef: any; + transcriptResponse: GetTranscript; + topicsResponse: GetTranscriptTopic[]; +}; + +export default function ShareTranscript(props: ShareTranscriptProps) { + const [showModal, setShowModal] = useState(false); + const [isCopiedSummary, setIsCopiedSummary] = useState(false); + const [isCopiedTranscript, setIsCopiedTranscript] = useState(false); + + const onCopySummaryClick = () => { + let text_to_copy = props.finalSummaryRef.current?.innerText; + + text_to_copy && + navigator.clipboard.writeText(text_to_copy).then(() => { + setIsCopiedSummary(true); + // Reset the copied state after 2 seconds + setTimeout(() => setIsCopiedSummary(false), 2000); + }); + }; + + const onCopyTranscriptClick = () => { + let text_to_copy = + props.topicsResponse + ?.map((topic) => topic.transcript) + .join("\n\n") + .replace(/ +/g, " ") + .trim() || ""; + + text_to_copy && + navigator.clipboard.writeText(text_to_copy).then(() => { + setIsCopiedTranscript(true); + // Reset the copied state after 2 seconds + setTimeout(() => setIsCopiedTranscript(false), 2000); + }); + }; + + return ( +
+ <> + {featureEnabled("sendToZulip") && ( + + )} + + + + {featureEnabled("sendToZulip") && ( + setShowModal(v)} + /> + )} + + + + + +
+ ); +} diff --git a/www/app/[domain]/transcripts/useTranscriptList.ts b/www/app/[domain]/transcripts/useTranscriptList.ts index 2cfab374..1e55cf7a 100644 --- a/www/app/[domain]/transcripts/useTranscriptList.ts +++ b/www/app/[domain]/transcripts/useTranscriptList.ts @@ -20,6 +20,7 @@ const useTranscriptList = (page: number): TranscriptList => { const [refetchCount, setRefetchCount] = useState(0); const refetch = () => { + setLoading(true); setRefetchCount(refetchCount + 1); }; diff --git a/www/app/lib/time.ts b/www/app/lib/time.ts index 28d5d330..de383f37 100644 --- a/www/app/lib/time.ts +++ b/www/app/lib/time.ts @@ -1,3 +1,5 @@ +// TODO format duraction in be ? + export const formatTime = (seconds: number): string => { let hours = Math.floor(seconds / 3600); let minutes = Math.floor((seconds % 3600) / 60);