Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/filesharing is added #44

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
980 changes: 812 additions & 168 deletions public/package-lock.json

Large diffs are not rendered by default.

60 changes: 51 additions & 9 deletions public/src/components/ChatContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useState, useEffect, useRef } from "react";
import styled from "styled-components";
import ChatInput from "./ChatInput";
import ChatInput, { ChatMessage } from "./ChatInput";
import Logout from "./Logout";
import { v4 as uuidv4 } from "uuid";
import axios from "axios";
import { sendMessageRoute, recieveMessageRoute } from "../utils/APIRoutes";
import { sendMessageRoute, recieveMessageRoute, sendFileRoute } from "../utils/APIRoutes"; // Add your file route

export default function ChatContainer({ currentChat, socket }) {
const [messages, setMessages] = useState([]);
Expand All @@ -20,6 +20,7 @@ export default function ChatContainer({ currentChat, socket }) {
to: currentChat._id,
});
setMessages(response.data);
console.log(response.data);
}, [currentChat]);

useEffect(() => {
Expand All @@ -33,26 +34,57 @@ export default function ChatContainer({ currentChat, socket }) {
getCurrentChat();
}, [currentChat]);

const handleSendMsg = async (msg) => {
const handleSendMsg = async (message) => {
const data = await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
);
socket.current.emit("send-msg", {
to: currentChat._id,
from: data._id,
msg,
message,
});
await axios.post(sendMessageRoute, {
from: data._id,
to: currentChat._id,
message: msg,
message: message,
});

const msgs = [...messages];
msgs.push({ fromSelf: true, message: msg });
msgs.push({ fromSelf: true, message: message });
setMessages(msgs);
};

// New function to handle file sending
const handleSendFile = async (file) => {
const data = await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
);
const formData = new FormData();
formData.append("file", file);
formData.append("from", data._id);
formData.append("to", currentChat._id);

try {
const response = await axios.post(sendFileRoute, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});

const fileMessage = {
fromSelf: true,
message: response.data.message, // The file URL sent from the server
fileUrl: response.data.fileUrl, // URL to the uploaded file
};

const msgs = [...messages];
msgs.push(fileMessage);
setMessages(msgs);
} catch (error) {
console.error("Error uploading file", error);
}
};

useEffect(() => {
if (socket.current) {
socket.current.on("msg-recieve", (msg) => {
Expand Down Expand Up @@ -86,7 +118,7 @@ export default function ChatContainer({ currentChat, socket }) {
<Logout />
</div>
<div className="chat-messages">
{messages.map((message) => {
{messages.map((message) => {
return (
<div ref={scrollRef} key={uuidv4()}>
<div
Expand All @@ -95,14 +127,24 @@ export default function ChatContainer({ currentChat, socket }) {
}`}
>
<div className="content ">
<p>{message.message}</p>
{message?.message?.fileUrl ? (
<a href={message?.fileUrl} target="_blank" rel="noopener noreferrer">
{message.message?.fileUrl?.endsWith(".png") || message?.message?.fileUrl.endsWith(".jpg") ? (
<img src={`http://localhost:5000${message?.message?.fileUrl}`} height = {250} width = {250} alt="attachment" />
) : (
"Download File"
)}
</a>
) : (
<p>{message.message.msg }</p>
)}
</div>
</div>
</div>
);
})}
</div>
<ChatInput handleSendMsg={handleSendMsg} />
<ChatInput handleSendMsg={handleSendMsg} handleSendFile={handleSendFile} />
</Container>
);
}
Expand Down
88 changes: 81 additions & 7 deletions public/src/components/ChatInput.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React, { useState } from "react";
import { BsEmojiSmileFill } from "react-icons/bs";
import { IoMdSend } from "react-icons/io";
import { MdAttachFile } from "react-icons/md"; // Import attachment icon
import styled from "styled-components";
import Picker from "emoji-picker-react";
import axios from "axios"; // Import Axios for HTTP requests
import { useEffect } from "react/cjs/react.production.min";

export default function ChatInput({ handleSendMsg }) {
const [msg, setMsg] = useState("");
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
const [file, setFile] = useState(null); // State to handle file

const handleEmojiPickerhideShow = () => {
setShowEmojiPicker(!showEmojiPicker);
};
Expand All @@ -17,11 +22,42 @@ export default function ChatInput({ handleSendMsg }) {
setMsg(message);
};

const sendChat = (event) => {
const handleFileChange = (event) => {
setFile(event.target.files[0]); // Save the selected file to state
};

const sendChat = async (event) => {
event.preventDefault();
if (msg.length > 0) {
handleSendMsg(msg);
setMsg("");

let messageData = {msg} ; // Initialize the message data

// Send file if exists
if (file) {
const formData = new FormData();

formData.append("file", file);

try {
const res = await axios.post("http://127.0.0.1:5000/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});

const fileData = res.data;
console.log("File uploaded successfully: ", fileData);

messageData.fileUrl = fileData.filePath;
setFile(null);
} catch (err) {
console.error("File upload failed: ", err);
}
}

// Send message and file URL to the parent component
if (msg.length > 0 || messageData.fileUrl) {
handleSendMsg(messageData);
setMsg(""); // Clear message after sending
}
};

Expand All @@ -36,10 +72,19 @@ export default function ChatInput({ handleSendMsg }) {
<form className="input-container" onSubmit={(event) => sendChat(event)}>
<input
type="text"
placeholder="type your message here"
placeholder={file ? "File selected" : "Type a message"}
onChange={(e) => setMsg(e.target.value)}
value={msg}
/>
<label htmlFor="file-upload" className="file-attach">
<MdAttachFile />
</label>
<input
id="file-upload"
type="file"
style={{ display: "none" }} // Hide the default file input
onChange={handleFileChange}
/>
<button type="submit">
<IoMdSend />
</button>
Expand All @@ -48,6 +93,28 @@ export default function ChatInput({ handleSendMsg }) {
);
}

export function ChatMessage({ message }) {

return (
<div className="chat-message">
<p>{message?.msg || "Hrllo"}</p>
{message?.fileUrl && (
<div className="file-attachment">
{/* Render the file URL */}
<a href={`http://localhost:5000${message?.fileUrl}`} target="_blank" rel="noopener noreferrer">
{/* {message?.fileUrl?.endsWith(".png") || message?.fileUrl?.endsWith(".jpg") ? (
<img src={`http://localhost:5000${message?.fileUrl}`} alt="attachment" />
) : (
"Download File"
)} */}
</a>
</div>
)}
</div>
);
}


const Container = styled.div`
display: grid;
align-items: center;
Expand Down Expand Up @@ -103,10 +170,10 @@ const Container = styled.div`
border-radius: 2rem;
display: flex;
align-items: center;
gap: 2rem;
gap: 1rem;
background-color: #ffffff34;
input {
width: 90%;
width: 75%;
height: 60%;
background-color: transparent;
color: white;
Expand All @@ -121,6 +188,13 @@ const Container = styled.div`
outline: none;
}
}
.file-attach {
cursor: pointer;
svg {
font-size: 1.5rem;
color: #9a86f3;
}
}
button {
padding: 0.3rem 2rem;
border-radius: 2rem;
Expand Down
2 changes: 2 additions & 0 deletions public/src/utils/APIRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export const allUsersRoute = `${host}/api/auth/allusers`;
export const sendMessageRoute = `${host}/api/messages/addmsg`;
export const recieveMessageRoute = `${host}/api/messages/getmsg`;
export const setAvatarRoute = `${host}/api/auth/setavatar`;

export const sendFileRoute = `${host}/upload`; // Add this
Loading