Skip to content

Commit

Permalink
one to one msg send added
Browse files Browse the repository at this point in the history
  • Loading branch information
anshu4sharma committed Feb 1, 2024
1 parent 0e70150 commit 57090f7
Show file tree
Hide file tree
Showing 18 changed files with 232 additions and 52 deletions.
1 change: 0 additions & 1 deletion public/ads.txt

This file was deleted.

5 changes: 0 additions & 5 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>iMessage</title>
<script
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4780451799247980"
crossOrigin="anonymous"
></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
67 changes: 45 additions & 22 deletions src/App.js → src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,73 @@
import React, { useState, useEffect, Suspense, lazy } from "react";
import io from "socket.io-client";
import { Routes, Route, BrowserRouter, Navigate } from "react-router-dom";
import LoadingBar from "react-top-loading-bar";
import {
ProtectedPages,
ProtectedAuthPages,
} from "./components/ProtectedPages";
import { useSocket } from "./context/Socket";
import Loader from "./components/Loader";
import { Toaster } from "react-hot-toast";
import { decodeToken } from "react-jwt";
import { authtoken } from "./constants";
import ChatToUser from "./pages/ChatToUser";
import { useUserContext } from "./context/UserDetails";
const Home = lazy(() => import("./pages/Home"));
const SignUp = lazy(() => import("./pages/SignUp"));
const LoginPage = lazy(() => import("./pages/LoginPage"));
const VerifyOtp = lazy(() => import("./pages/VerifyOtp"));
const socket = io(process.env.REACT_APP_SOCKET_URL);
const token = localStorage.getItem("authtoken");

function App() {
const myDecodedToken = decodeToken(token);
const { user } = useUserContext();
const [msg, setMsg] = useState("");
const [room, setRoom] = useState("");
const [msgRec, setmsgRec] = useState([]);
const [pvtmsg, setpvtmsg] = useState([]);
let UserName = localStorage?.getItem("name") ?? "";
const [Usrname, setmUserName] = useState(UserName);
const [userCount, setUserCount] = useState(0);
// const [socket, setSocket] = useState(null);
const { socket } = useSocket();
const sendMsg = async () => {
socket.emit("send_msg", { msg, Usrname, id:myDecodedToken.id });
socket.emit("send_msg", { msg, Usrname, id: user.id });
setMsg("");
};
const sendPvtMsg = async () => {
socket.emit("send_pvt_msg", { msg, room, Usrname, id:myDecodedToken.id });
socket.emit("send_pvt_msg", { msg, room, Usrname, id: user.id });
setMsg("");
};
const set_old_messages_Messages = async (data) => {
setmsgRec(data);
};
const getAllMessages = async (data) => {
setmsgRec((prev) => [...prev, data]);
};
const getAll_PVT_Messages = async (data) => {
// this will braodcast message to other open another window to see result
setpvtmsg((prev) => [...prev, data]);
};
const get_user_count = (data) => {
setUserCount(data);
};
const sendJWT = () => {
socket.emit("jwtToken", authtoken);
};

useEffect(() => {
socket.on("all_messages", async (data) => {
setmsgRec(data);
});
socket.on("received_msg", async (data) => {
setmsgRec((prev) => [...prev, data]);
});
socket.on("pvt_received_msg", async (data) => {
// this will braodcast message to other open another window to see result
setpvtmsg((prev) => [...prev, data]);
});
socket.on("userCount", (data) => {
setUserCount(data);
});
// eslint-disable-next-line
if (!socket) {
return;
}
socket.on("old_messages", set_old_messages_Messages);
socket.on("received_msg", getAllMessages);
socket.on("pvt_received_msg", getAll_PVT_Messages);
socket.on("userCount", get_user_count);
socket.on("connect", sendJWT);
return () => {
socket.off("old_messages", set_old_messages_Messages);
socket.off("received_msg", getAllMessages);
socket.off("pvt_received_msg", getAll_PVT_Messages);
socket.off("userCount", get_user_count);
};
}, [socket]);
const joinRoom = () => {
if (room !== "") {
Expand All @@ -56,6 +77,7 @@ function App() {
socket.emit("join_room", room);
}
};

return (
<>
<LoadingBar
Expand All @@ -76,9 +98,9 @@ function App() {
<Route path="/signup" element={<SignUp />} />
<Route path="/verify" element={<VerifyOtp />} />
</Route>
<Route element={<ProtectedPages />}>
<Route path="/chat" element={<ProtectedPages />}>
<Route
path="/chat"
index
element={
<Home
room={room}
Expand All @@ -97,6 +119,7 @@ function App() {
/>
}
/>
<Route path=":receiverId" element={<ChatToUser msgRec={msgRec} />} />
</Route>
<Route path="*" element={<Navigate to={"/"} />} />
</Routes>
Expand Down
5 changes: 3 additions & 2 deletions src/components/ChatPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { useRef } from "react";
import moment from "moment";
import { Container } from "@nextui-org/react";
import { decodeToken } from "react-jwt";
const token = localStorage.getItem("authtoken");
import {authtoken} from "../constants"

const ChatPage = ({ msgRec, pvtmsg, room }) => {
const myDecodedToken = decodeToken(token);
const myDecodedToken = decodeToken(authtoken);
const msgref = useRef();
const scrolltoView = () => {
let windowHeight = window.innerHeight;
Expand Down
8 changes: 7 additions & 1 deletion src/components/MessageForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import React, { useRef } from "react";
import { Input, Container } from "@nextui-org/react";
import { SendButton } from "./SendButton.jsx";
import { SendIcon } from "./SendIcon.jsx";
const MessageForm = ({ msg, sendMsg, setMsg, room, sendPvtMsg }) => {
const MessageForm = ({
msg,
sendMsg = () => {},
setMsg,
room = "",
sendPvtMsg = () => {},
}) => {
const msgInput = useRef(null);
const appendElem = () => {
const para = document.createElement("p");
Expand Down
7 changes: 4 additions & 3 deletions src/components/Navbar/NavbarReact.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
import React, { useEffect, useState } from "react";
import { decodeToken } from "react-jwt";
import { useNavigate } from "react-router-dom";
const token = localStorage.getItem("authtoken");
import {authtoken} from "../../constants"

export default function NavbarReact({
room,
setRoom,
Expand All @@ -32,7 +33,7 @@ export default function NavbarReact({
};
useEffect(() => {
const fetchUserDetails = async () => {
const myDecodedToken = decodeToken(token);
const myDecodedToken = decodeToken(authtoken);
try {
if (myDecodedToken.name) {
setmUserName(myDecodedToken.name);
Expand All @@ -45,7 +46,7 @@ export default function NavbarReact({
navigate(0);
}
};
if (token !== undefined || null) {
if (authtoken !== undefined || null) {
fetchUserDetails();
}
}, [navigate, setmUserName]);
Expand Down
11 changes: 0 additions & 11 deletions src/components/ProtectedPages.js

This file was deleted.

11 changes: 11 additions & 0 deletions src/components/ProtectedPages.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";
import { Outlet, Navigate } from "react-router-dom";
import {authtoken} from "../constants"

export const ProtectedPages = () => {
return authtoken ? <Outlet /> : <Navigate to={"/"} />;
};

export const ProtectedAuthPages = () => {
return authtoken ? <Navigate to={"/chat"} /> : <Outlet />;
};
1 change: 1 addition & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const authtoken = localStorage.getItem("authtoken")
30 changes: 30 additions & 0 deletions src/context/Socket.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useContext, useEffect, useState } from "react";
import { io } from "socket.io-client";

const SocketContext = React.createContext(null);

export const useSocket = () => {
const state = useContext(SocketContext);
if (!state) throw new Error(`state is undefined`);
return state;
};

// useCallback hook to prevent unneccesary rerender

export const SocketProvider = ({ children }) => {
const [socket, setSocket] = useState(null);
useEffect(() => {
const _socket = io(process.env.REACT_APP_SOCKET_URL);
setSocket(_socket);
return () => {
_socket.disconnect();
setSocket(undefined);
};
}, []);

return (
<SocketContext.Provider value={{socket}}>
{children}
</SocketContext.Provider>
);
};
23 changes: 23 additions & 0 deletions src/context/UserDetails.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React, { useContext, useState } from "react";
import { decodeToken } from "react-jwt";
import { authtoken } from "../constants";

const UserContext = React.createContext(null);

export const useUserContext = () => {
const state = useContext(UserContext);
if (!state) throw new Error(`state is undefined`);
return state;
};

// useCallback hook to prevent unneccesary rerender

export const UserDetails = ({ children }) => {
console.log(decodeToken(authtoken));
const [user, setUser] = useState(decodeToken(authtoken));
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
};
1 change: 1 addition & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ body {
height: 100vh;
position: relative;
user-select: none;
width: 100%;
}

.modal-header .btn-close {
Expand Down
12 changes: 9 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ import "bootstrap/dist/css/bootstrap.min.css";
import "./index.css";
import * as serviceWorkerRegistration from "./serviceWorkerRegistration";
import { NextUIProvider } from "@nextui-org/react";
import { SocketProvider } from "./context/Socket";
import { UserDetails } from "./context/UserDetails";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<NextUIProvider>
<App />
</NextUIProvider>
<NextUIProvider>
<SocketProvider>
<UserDetails>
<App />
</UserDetails>
</SocketProvider>
</NextUIProvider>
);

// If you want your app to work offline and load faster, you can change
Expand Down
95 changes: 95 additions & 0 deletions src/pages/ChatToUser/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useEffect, useState } from "react";
import { useRef } from "react";
import moment from "moment";
import { Container } from "@nextui-org/react";
import { decodeToken } from "react-jwt";
import { authtoken } from "../../constants";
import { SocketProvider, useSocket } from "../../context/Socket";
import { useUserContext } from "../../context/UserDetails";
import MessageForm from "../../components/MessageForm";
import { useParams } from "react-router-dom";
const Index = ({ }) => {
const { socket } = useSocket();
const { user } = useUserContext();
const [msg, setMsg] = useState("");
const { receiverId } = useParams();
const [msgRec,setmsgRec] = useState([])
const msgref = useRef();
const scrolltoView = () => {
let windowHeight = window.innerHeight;
if (msgref.current?.lastChild) {
msgref.current?.lastChild.scrollIntoView() ||
window.scrollTo(0, windowHeight * windowHeight);
}
};
const tapToScroll = (event) => {
if (msgref.current?.contains(event.target)) {
scrolltoView();
}
};
useEffect(() => {
scrolltoView();
}, [msgRec, msgref.current?.lastChild]);

const sendMsg = async () => {
socket.emit("send_personal_msg", { msg, Usrname:user.name, receiverId, id: user.id });
setMsg("");
};
useEffect(() => {
if (!socket) {
return;
}
// Send message to specific user
// socket.on("send_personal_msg", async (data) => {
// const { id, msg, Usrname } = data;
// let socketIdTosend = onlineUser.get(id);
// const newMsg = new Msg(data);
// await newMsg.save();
// });

socket.on("received_personal_msg", (data) => {
console.log(data);
setmsgRec((prev) => [...prev, data]);
});
return () => {};
}, [socket]);

return (
<>
<div className="home-page">
<Container className=" message-container">
<div
ref={msgref}
className="my-1 msg-container"
id="message-container-child"
onClick={tapToScroll}
>
{msgRec?.map((data, index) => {
return (
<div
className={
data?.id === user?.id
? "outgoing-msg"
: "upcoming-message"
}
key={index}
>
<span className="recMsgusername" style={{ fontSize: "12px" }}>
{data?.Usrname}
</span>
<li> {data?.msg}</li>
<span className="messageTimestamp">
{moment(data?.timeStamp).format("LTS").toString()}
</span>
</div>
);
})}
</div>
</Container>
</div>
<MessageForm sendMsg={sendMsg} setMsg={setMsg} msg={msg} />
</>
);
};

export default Index;
Loading

0 comments on commit 57090f7

Please sign in to comment.