diff --git a/package.json b/package.json index ba1e852..84c4d0c 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", - "axios": "^1.6.0", + "axios": "^1.6.2", "bootstrap": "^3.4.1", "pspdfkit": "^2023.5.0", "react": "^18.2.0", diff --git a/src/components/chat-component/Chat.jsx b/src/components/chat-component/Chat.jsx index 89d2623..47ed4ca 100644 --- a/src/components/chat-component/Chat.jsx +++ b/src/components/chat-component/Chat.jsx @@ -58,8 +58,7 @@ function Chat() { // session ended by other user // eslint-disable-next-line react-hooks/exhaustive-deps const sessionEnded = useCallback(() => { - console.log("session ended by other user") - alert("Session was ended by other user"); + console.log("Session ended by other user") clearSessionAndNavigate(); }); @@ -85,6 +84,9 @@ function clearSessionAndNavigate(){ // Clear the messages when the session ends setMessages([]); sessionStorage.removeItem("chatMessages"); + sessionStorage.removeItem("sessionId"); + sessionStorage.removeItem("sessionCode"); + localStorage.removeItem("isSessionActive"); unsubscribeToEndSession(sessionEnded); disconnectWebsocket(); diff --git a/src/components/end-session-component/EndSession.jsx b/src/components/end-session-component/EndSession.jsx index bf3013f..506f9e4 100644 --- a/src/components/end-session-component/EndSession.jsx +++ b/src/components/end-session-component/EndSession.jsx @@ -19,6 +19,7 @@ function EndSession() { const sessionId = sessionStorage.getItem("sessionId"); const [success, setSuccess] = useState(false); const [error, setError] = useState(false); + const [open, setOpen] = useState(true); useEffect(() => emailjs.init("OScF2lHq5ESl_o9lU"), []); const sendEmail = async (e) => { @@ -53,16 +54,40 @@ function EndSession() { emailRef.current.value = ""; // alert("Email successfully sent. Check inbox."); setSuccess(true); - setTimeout(() => setSuccess(false), 5000); + setTimeout(() => setSuccess(false), 2000); } catch (error) { // alert("Oops! Something went wrong while trying to send the email. Please make sure there are messages in the conversation before sending."); console.error('Error fetching transcript or sending email:', error.message); setError(true); - setTimeout(() => setError(false), 5000); + setTimeout(() => setError(false), 2000); } }; + + useEffect(() => { + // Set a timer to hide the Snackbar after 2 seconds + const timer = setTimeout(() => { + setOpen(false); + }, 2000); + + // Cleanup the timer when the component is unmounted + return () => { + clearTimeout(timer); + }; + }, []); + return( + + + Session has been ended + + Your session has now ended. diff --git a/src/helper-components/pdf-manager-component/PdfManager.jsx b/src/helper-components/pdf-manager-component/PdfManager.jsx index e95cd66..839db51 100644 --- a/src/helper-components/pdf-manager-component/PdfManager.jsx +++ b/src/helper-components/pdf-manager-component/PdfManager.jsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo, useRef } from 'react'; +import React, { useState, useMemo, useRef, useEffect, useCallback } from 'react'; import Axios from 'axios'; import PdfViewerComponent from './PdfViewerComponent.jsx'; import DocumentFile from '../../classes/Document.js'; @@ -16,7 +16,7 @@ import { PdfNavbar, Button, } from './PdfManager-styles'; -import { sendDocumentIdWebsocket } from '../../websocket'; +import { sendDocumentIdWebsocket, subscribeToFiles, unsubscribeFromFiles } from '../../websocket'; function PdfFileManager() { const [uploadedPdfs, setUploadedPdfs] = useState([]); @@ -31,12 +31,42 @@ function PdfFileManager() { fileInputRef.current.click(); }; - const openPdf = (event) => { + const openPdf = useCallback((event) => { const selectedPdfId = event.target.value; - const pdf = uploadedPdfs.find(pdf => pdf.id === selectedPdfId); - setSelectedPdf(pdf); - }; + + // Check if the selected PDF is already open + if (selectedPdf && selectedPdf.id === selectedPdfId) { + // Reset the selected PDF to force a refresh + setSelectedPdf(null); + + // Use a timeout to ensure the state is cleared before setting it again + setTimeout(() => { + const pdf = uploadedPdfs.find(pdf => pdf.id === selectedPdfId); + setSelectedPdf(pdf); + }, 0); + } else { + const pdf = uploadedPdfs.find(pdf => pdf.id === selectedPdfId); + setSelectedPdf(pdf); + } + }, [uploadedPdfs, selectedPdf]); + const fetchPdfById = async (pdfId) => { + try { + const response = await Axios.get(`http://localhost:8080/files/${pdfId}`, { + responseType: 'blob' // Expect a binary response + }); + console.log(response); + const pdfBlobUrl = URL.createObjectURL(response.data); // Create a URL from the Blob + return new DocumentFile({ + id: pdfId, + name: `Document-${pdfId}`, // Set an appropriate name + content: pdfBlobUrl // URL to be used by the PDF viewer + }); + } catch (error) { + console.error("Error fetching file:", error); + } + }; + const handleFileChange = (e) => { const file = e.target.files[0]; // Create a FormData object to send the file @@ -96,33 +126,67 @@ function PdfFileManager() { const handleSave = () => { if (pdfViewerInstance && selectedPdf) { pdfViewerInstance.exportPdf().then((blob) => { - console.log(blob); // Check what is being returned here if (!blob) { console.error('No data returned from exportPdf'); return; } const formData = new FormData(); - formData.append("file", blob, `updated_${selectedPdf.name}`); // Ensure blob is a Blob object + formData.append("file", blob, `updated_${selectedPdf.name}`); Axios.put(`http://localhost:8080/files/update/${selectedPdf.id}`, formData) .then(response => { - console.log('PDF updated successfully:', response.data); - setAlertMessage("PDF changes saved successfully"); + console.log('File updated successfully:', response.data); + setAlertMessage("File changes saved successfully"); setAlertSeverity('success'); setAlertOpen(true); - setTimeout(() => setAlertOpen(false), 2000); // Close the alert after 2 seconds + setTimeout(() => setAlertOpen(false), 2000); + + // Send the updated document ID via WebSocket + sendDocumentIdWebsocket(selectedPdf.id); // Example function to send data via WebSocket }) .catch(error => { - console.error('PDF update failed:', error); - setAlertMessage("Error saving PDF changes"); + console.error('File update failed:', error); + setAlertMessage("Error saving file changes"); setAlertSeverity('error'); setAlertOpen(true); - setTimeout(() => setAlertOpen(false), 2000); // Close the alert after 2 seconds + setTimeout(() => setAlertOpen(false), 2000); }); }); } }; + useEffect(() => { + const handleDocumentUpdate = async (documentId) => { + const newDocument = await fetchPdfById(documentId); + if (newDocument) { + setUploadedPdfs(prevPdfs => { + const isExisting = prevPdfs.some(pdf => pdf.id === newDocument.id); + if (isExisting) { + // Replace the existing entry with the updated one + return prevPdfs.map(pdf => pdf.id === newDocument.id ? newDocument : pdf); + } else { + return [...prevPdfs, newDocument]; + } + }); + + if (newDocument.id === selectedPdf?.id) { + setSelectedPdf(newDocument); + // Create a mock event object + const mockEvent = { target: { value: newDocument.id } }; + openPdf(mockEvent); + } + } + }; + + subscribeToFiles(handleDocumentUpdate); + + return () => { + unsubscribeFromFiles(handleDocumentUpdate); + // Cleanup Blob URLs if necessary + uploadedPdfs.forEach(pdf => URL.revokeObjectURL(pdf.content)); + }; + }, [uploadedPdfs, selectedPdf, openPdf]); + return ( - + { - // TODO: Notify observers when a new document arrives console.log(documentid.body); + documentObservable.notifyObservers(documentid.body); }); // subscribe to end session notifications @@ -96,3 +97,11 @@ export function subscribeToEndSession(callback) { export function unsubscribeToEndSession(callback) { endSessionObservable.removeObserver(callback); } + +export function subscribeToFiles(callback) { + documentObservable.addObserver(callback); +} + +export function unsubscribeFromFiles(callback) { + documentObservable.removeObserver(callback); +}