Anuj-Panthri commited on
Commit
bf65a6c
·
1 Parent(s): d1f9048

worked on making messages work

Browse files
client/src/App.js CHANGED
@@ -4,6 +4,7 @@ import ChatPage from './ChatPage';
4
  import LoginPage from './LoginPage';
5
  import SignupPage from './SignupPage';
6
  import PrivateRoutes from './PrivateRoutes';
 
7
 
8
  function App() {
9
 
@@ -11,18 +12,22 @@ function App() {
11
 
12
  return (
13
  <div className="App">
 
14
  <Router>
15
  <Routes>
16
  <Route element={<LoginPage />} path="/login" />
17
  <Route element={<SignupPage />} path="/signup" />
18
  {/* <Route element={<ChatPage />} path="/" /> */}
19
 
 
20
  <Route element={<PrivateRoutes />}>
21
  <Route element={<ChatPage />} path="/" />
22
  </Route>
 
23
 
24
  </Routes>
25
  </Router>
 
26
 
27
 
28
 
 
4
  import LoginPage from './LoginPage';
5
  import SignupPage from './SignupPage';
6
  import PrivateRoutes from './PrivateRoutes';
7
+ import { UserProvider } from './UserProvider';
8
 
9
  function App() {
10
 
 
12
 
13
  return (
14
  <div className="App">
15
+
16
  <Router>
17
  <Routes>
18
  <Route element={<LoginPage />} path="/login" />
19
  <Route element={<SignupPage />} path="/signup" />
20
  {/* <Route element={<ChatPage />} path="/" /> */}
21
 
22
+
23
  <Route element={<PrivateRoutes />}>
24
  <Route element={<ChatPage />} path="/" />
25
  </Route>
26
+
27
 
28
  </Routes>
29
  </Router>
30
+
31
 
32
 
33
 
client/src/PrivateRoutes.jsx CHANGED
@@ -1,8 +1,12 @@
1
- import React, { useState,useEffect } from 'react'
2
  import { Outlet, Navigate } from "react-router-dom";
3
 
4
  function PrivateRoutes() {
 
5
  const [isAuth, setIsAuth] = useState(undefined);
 
 
 
6
  const getAuthStatus = async () => {
7
 
8
  const res = await fetch(process.env.REACT_APP_BACKEND_URL + "/session", {
@@ -12,12 +16,12 @@ function PrivateRoutes() {
12
  return res.ok;
13
  }
14
 
15
- useEffect(()=>{
16
- getAuthStatus().then((status)=>{
17
  console.log(status);
18
  setIsAuth(status);
19
  })
20
- },[])
21
 
22
 
23
  if (isAuth === undefined) {
@@ -25,12 +29,12 @@ function PrivateRoutes() {
25
  Loading ...
26
  </p>
27
  }
28
- else{
29
 
30
  return (
31
  isAuth ? <Outlet /> : <Navigate to="/login" />
32
  );
33
-
34
  }
35
 
36
  }
 
1
+ import React, { useState, useEffect } from 'react'
2
  import { Outlet, Navigate } from "react-router-dom";
3
 
4
  function PrivateRoutes() {
5
+
6
  const [isAuth, setIsAuth] = useState(undefined);
7
+ // const [user, setUser] = useState(null);
8
+
9
+
10
  const getAuthStatus = async () => {
11
 
12
  const res = await fetch(process.env.REACT_APP_BACKEND_URL + "/session", {
 
16
  return res.ok;
17
  }
18
 
19
+ useEffect(() => {
20
+ getAuthStatus().then((status) => {
21
  console.log(status);
22
  setIsAuth(status);
23
  })
24
+ }, [])
25
 
26
 
27
  if (isAuth === undefined) {
 
29
  Loading ...
30
  </p>
31
  }
32
+ else {
33
 
34
  return (
35
  isAuth ? <Outlet /> : <Navigate to="/login" />
36
  );
37
+
38
  }
39
 
40
  }
client/src/UserProvider.jsx ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { createContext, useEffect, useState } from "react";
2
+
3
+ export const UserContext = createContext();
4
+
5
+ export const UserProvider = ({ children }) => {
6
+ const [user, setUser] = useState(null);
7
+
8
+
9
+ const getUser = async () => {
10
+
11
+ const res = await fetch(process.env.REACT_APP_BACKEND_URL + "/session", {
12
+ credentials: "include"
13
+ })
14
+ var data;
15
+ if(res.ok){
16
+ data = await res.json();
17
+ setUser(data);
18
+ }
19
+ else{
20
+ setUser({});
21
+ }
22
+ console.log("user",data);
23
+
24
+
25
+ }
26
+
27
+ useEffect(()=>{
28
+ getUser();
29
+ },[])
30
+
31
+
32
+
33
+
34
+ return (
35
+ <UserContext.Provider value={user}>
36
+ {children}
37
+ </UserContext.Provider>
38
+ );
39
+ }
client/src/components/Chat/Chat.jsx CHANGED
@@ -1,12 +1,33 @@
1
- import React from 'react';
2
  import "./Chat.css";
3
  import ChatHeader from '../ChatHeader';
4
  import ChatMain from '../ChatMain';
5
  import ChatFooter from '../ChatFooter';
 
6
 
7
  function Chat({
8
  currentContact,
9
  }) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  if (Object.keys(currentContact).length === 0) {
12
 
@@ -19,8 +40,8 @@ function Chat({
19
  return (
20
  <div className='chat'>
21
  <ChatHeader name={currentContact.username} />
22
- <ChatMain />
23
- <ChatFooter />
24
  </div>
25
  )
26
  }
 
1
+ import React, { useContext, useEffect, useState } from 'react';
2
  import "./Chat.css";
3
  import ChatHeader from '../ChatHeader';
4
  import ChatMain from '../ChatMain';
5
  import ChatFooter from '../ChatFooter';
6
+ import { SocketContext } from '../../SocketProvider';
7
 
8
  function Chat({
9
  currentContact,
10
  }) {
11
+ const [messages, setMessages] = useState([]);
12
+ const socket = useContext(SocketContext);
13
+
14
+ const getMessages = async () => {
15
+ const res = await fetch(process.env.REACT_APP_BACKEND_URL + `/messages/${currentContact.id}`, { credentials: "include" });
16
+ const data = await res.json();
17
+ if (res.ok) {
18
+ console.log(data.messages);
19
+ setMessages(data.messages);
20
+ }
21
+ }
22
+
23
+ useEffect(() => {
24
+
25
+ if (Object.keys(currentContact).length === 0) return;
26
+
27
+ getMessages();
28
+
29
+
30
+ }, [currentContact])
31
 
32
  if (Object.keys(currentContact).length === 0) {
33
 
 
40
  return (
41
  <div className='chat'>
42
  <ChatHeader name={currentContact.username} />
43
+ <ChatMain messages={messages} />
44
+ <ChatFooter currentContactId={currentContact.id} setMessages={setMessages} />
45
  </div>
46
  )
47
  }
client/src/components/ChatFooter/ChatFooter.jsx CHANGED
@@ -1,16 +1,46 @@
1
- import React, { useContext, useEffect } from 'react'
2
  import "./ChatFooter.css";
3
  import { PaperAirplaneIcon, PhotoIcon, PaperClipIcon, FaceSmileIcon } from "@heroicons/react/24/solid";
4
  import { SocketContext } from '../../SocketProvider';
5
 
6
- function ChatFooter() {
 
 
 
 
7
  const socket = useContext(SocketContext);
8
- useEffect(()=>{
9
- if(socket){
 
 
10
  console.log(socket);
11
  socket.emit("foobar");
12
  }
13
- },[socket])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  return (
16
  <footer className='chat_footer'>
@@ -20,8 +50,8 @@ function ChatFooter() {
20
  <PhotoIcon className='send_options_btn' />
21
  <PaperClipIcon className='send_options_btn' />
22
  </div>
23
- <input className="text_box" type="text" placeholder='Message' />
24
- <PaperAirplaneIcon className='send_icon' />
25
  </footer>
26
  )
27
  }
 
1
+ import React, { useContext, useEffect, useRef } from 'react'
2
  import "./ChatFooter.css";
3
  import { PaperAirplaneIcon, PhotoIcon, PaperClipIcon, FaceSmileIcon } from "@heroicons/react/24/solid";
4
  import { SocketContext } from '../../SocketProvider';
5
 
6
+ function ChatFooter({
7
+ setMessages,
8
+ currentContactId,
9
+ }) {
10
+
11
  const socket = useContext(SocketContext);
12
+ const messageRef = useRef();
13
+
14
+ useEffect(() => {
15
+ if (socket) {
16
  console.log(socket);
17
  socket.emit("foobar");
18
  }
19
+ }, [socket])
20
+
21
+ const sendMessage = (message) => {
22
+
23
+ const curr_time = Math.floor(new Date().getTime() / 1000);
24
+ const message_bundle= {
25
+ message,
26
+ send_at:curr_time,
27
+ to:currentContactId,
28
+ }
29
+
30
+ setMessages((prev) => [...prev, message_bundle]);
31
+
32
+ if(socket){
33
+
34
+ socket.emit("send_message",message_bundle);
35
+ }
36
+
37
+ }
38
+
39
+ const handleEnter = (e) => {
40
+ if (e.key == "Enter") {
41
+ sendMessage(messageRef.current.value);
42
+ }
43
+ }
44
 
45
  return (
46
  <footer className='chat_footer'>
 
50
  <PhotoIcon className='send_options_btn' />
51
  <PaperClipIcon className='send_options_btn' />
52
  </div>
53
+ <input className="text_box" type="text" placeholder='Message' onKeyUp={handleEnter} ref={messageRef} />
54
+ <PaperAirplaneIcon onClick={() => { sendMessage(messageRef.current.value) }} className='send_icon' />
55
  </footer>
56
  )
57
  }
client/src/components/ChatMain/ChatMain.jsx CHANGED
@@ -2,24 +2,24 @@ import React from 'react'
2
  import Message from '../Message';
3
  import "./ChatMain.css";
4
 
5
- function ChatMain() {
 
 
6
 
7
- const getMessages = () => {
8
-
9
- var messages = [];
10
- for (var i = 0; i < 10; i++) {
11
- messages.push(<Message key={i} message={"Hello"} time="10AM" isReceived={false} />);
12
- }
13
- return messages;
14
  }
 
15
  return (
16
  <div className='chat_main'>
17
  {
18
- getMessages()
 
 
 
19
  }
20
- <Message message={"Hi"} time="11AM" isReceived={true} />
21
- <Message message={"How are you"} time="11:10AM" isReceived={false} />
22
- <Message message={"I am good what about you..."} time="11AM" isReceived={true} />
23
  </div>
24
  )
25
  }
 
2
  import Message from '../Message';
3
  import "./ChatMain.css";
4
 
5
+ function ChatMain({
6
+ messages,
7
+ }) {
8
 
9
+ const timeToReadable = (timestamp)=>{
10
+ var d = new Date(timestamp*1000);
11
+ return d.toLocaleTimeString();
12
+ // return timestamp;
 
 
 
13
  }
14
+
15
  return (
16
  <div className='chat_main'>
17
  {
18
+
19
+ messages.map((message,idx) => (
20
+ <Message key={idx} message={message.message} time={timeToReadable(message.send_at)} isReceived={message.isReceived} />
21
+ ))
22
  }
 
 
 
23
  </div>
24
  )
25
  }
server/index.ts CHANGED
@@ -220,6 +220,27 @@ app.get("/contacts", isAuthAPIMiddleware, async (req, res) => {
220
  res.json({ "contacts": contacts });
221
  })
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  const io = new Server(server, {
224
  cors: {
225
  origin: allowed_origins,
@@ -266,6 +287,37 @@ io.on("connection", async (socket) => {
266
  // an event was received from the client
267
  console.log("received:" + data, socket.data.user);
268
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
 
270
  // upon disconnection
271
  socket.on("disconnect", (reason) => {
 
220
  res.json({ "contacts": contacts });
221
  })
222
 
223
+ // get currentContact's messsages route
224
+ app.get("/messages/:userid", isAuthAPIMiddleware, async (req, res) => {
225
+
226
+ // req.query.id
227
+
228
+ var messages = await db.prepare(`select * from messages
229
+ where (send_to=? and send_from=?)
230
+ or
231
+ (send_to=? and send_from=?)`).all(
232
+ res.locals.user.id,
233
+ req.params.userid,
234
+
235
+ req.params.userid,
236
+ res.locals.user.id,
237
+ );
238
+ // const messages = await db.prepare("select * from messages").all();
239
+
240
+ res.json({ "messages": messages });
241
+ })
242
+
243
+
244
  const io = new Server(server, {
245
  cors: {
246
  origin: allowed_origins,
 
287
  // an event was received from the client
288
  console.log("received:" + data, socket.data.user);
289
  });
290
+ socket.on("send_message", async (data) => {
291
+ // an event was received from the client
292
+
293
+ const msg_id = generateId(15);
294
+
295
+ const stmt = db.prepare("insert into messages(id,message,send_to,send_from,send_at) values(?,?,?,?,?)");
296
+
297
+ await stmt.run(
298
+ msg_id,
299
+ data.message,
300
+ data.to,
301
+ socket.data.user.id,
302
+ data.send_at,
303
+ );
304
+
305
+ console.log("saved message:" , data.message);
306
+
307
+ const sockets = await io.fetchSockets();
308
+
309
+
310
+ sockets.forEach((client)=>{
311
+ if(client.data.user.id==data.to)
312
+ {
313
+ return socket.to(client.data.user.id).emit("receive_message",{
314
+ ...data,
315
+ "from":socket.data.user.id,
316
+ });
317
+ }
318
+ })
319
+
320
+ });
321
 
322
  // upon disconnection
323
  socket.on("disconnect", (reason) => {