diff --git a/Contributors.md b/Contributors.md old mode 100755 new mode 100644 diff --git a/LICENSE.txt b/LICENSE old mode 100755 new mode 100644 similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/package.json b/package.json old mode 100755 new mode 100644 diff --git a/public/favicon.ico b/public/favicon.ico old mode 100755 new mode 100644 diff --git a/public/index.html b/public/index.html old mode 100755 new mode 100644 diff --git a/public/logo.ico b/public/logo.ico new file mode 100644 index 0000000..f154b89 Binary files /dev/null and b/public/logo.ico differ diff --git a/public/logo192.png b/public/logo192.png old mode 100755 new mode 100644 index 07147d4..c9dd980 Binary files a/public/logo192.png and b/public/logo192.png differ diff --git a/public/logo512.png b/public/logo512.png old mode 100755 new mode 100644 index 52c69c3..a348c3d Binary files a/public/logo512.png and b/public/logo512.png differ diff --git a/public/manifest.json b/public/manifest.json old mode 100755 new mode 100644 diff --git a/public/robots.txt b/public/robots.txt old mode 100755 new mode 100644 diff --git a/src/App.css b/src/App.css old mode 100755 new mode 100644 diff --git a/src/App.js b/src/App.js old mode 100755 new mode 100644 diff --git a/src/StateProvider.js b/src/StateProvider.js new file mode 100644 index 0000000..0fccc6e --- /dev/null +++ b/src/StateProvider.js @@ -0,0 +1,12 @@ +import React, { createContext, useReducer, useContext } from "react"; + +export const StateContext = createContext(); + + + export const StateProvider = ({ reducer, initialState, children }) => ( + + {children} + +); + +export const useStateValue = () => useContext(StateContext); diff --git a/src/components/Chatroom.css b/src/components/Chatroom.css new file mode 100644 index 0000000..270f4d9 --- /dev/null +++ b/src/components/Chatroom.css @@ -0,0 +1,110 @@ +.chatroom { + flex: 0.7; + display: flex; + flex-direction: column; + } + + .chatroom__header { + display: flex; + padding: 15px; + align-items: center; + border-bottom: 1px solid rgb(241, 240, 240); + } + + .chatroom__headerinfoleft { + flex: 1; + padding-left: 15px; + } + + .chatroom__headerinfoleft > p { + color: gray; + } + + .chatroom__header__inforight { + display: flex; + align-items: center; + min-width: 80px; + } + + .chatroom__body { + flex: 1; + background-image: url("https://preview.redd.it/qwd83nc4xxf41.jpg?width=640&crop=smart&auto=webp&s=e82767fdf47158e80604f407ce4938e44afc6c25") !important; + background-repeat: repeat; + padding: 25px; + overflow-y: scroll; + background-position: center; + } + + .chatroom__message { + position: relative; + font-size: 15px; + margin-bottom: 10px; + padding: 10px; + background-color: rgb(243, 240, 240); + border-radius: 15px; + + width: fit-content; + margin-top: 25px; + } + + .chatroom__username { + position: absolute; + top: -15px; + font-weight: bold; + font-size: xx-small; + } + + .chatroom__messagetimestamp { + margin-left: 10px; + font-weight: bold; + font-size: xx-small; + color: black; + } + + .chatroom__messagerecierver { + margin-left: auto; + background-color: rgb(139, 141, 253); + } + + .chatroom__footer { + display: flex; + align-items: center; + justify-content: space-between; + height: 55px; + border-top: 1px solid rgb(223, 222, 222); + } + + .chatroom__footer > form { + flex: 1; + display: flex; + } + + .chatroom__footer > form > input { + flex: 1; + border-radius: 50px; + padding: 15px; + border: none; + width: 90%; + } + + .chatroom__footer > form > button { + border: none; + background-color: rgb(88, 91, 255); + color: white; + padding: 10px; + border-radius: 50%; + display: none; + } + + .chatroom__footer > form > input:focus { + outline-width: 0; + } + .chatroom__footer > form > button:focus { + outline-width: 0; + } + + .chatroom__footer > .MuiSvgIcon-root { + padding: 10px; + color: gray; + } + \ No newline at end of file diff --git a/src/components/Chatroom.js b/src/components/Chatroom.js new file mode 100644 index 0000000..5fdc4d2 --- /dev/null +++ b/src/components/Chatroom.js @@ -0,0 +1,100 @@ +import React, { useState, useEffect } from "react"; +import firebase from "firebase"; +import "./Chatroom.css"; +import { Avatar } from "@material-ui/core"; +import SendIcon from "@material-ui/icons/Send"; + +import SentimentVerySatisfiedIcon from "@material-ui/icons/SentimentVerySatisfied"; +import MicIcon from "@material-ui/icons/Mic"; +import { useParams } from "react-router-dom"; +import { database } from "../firebase"; +import { useStateValue } from "../StateProvider"; +function Chatroom() { + const [input, setinput] = useState(""); + const { roomid } = useParams(); + const [roomname, setroomname] = useState(""); + const [message, setmessages] = useState([]); + const [{ user }, dispatch] = useStateValue(); + + + useEffect(() => { + if (roomid) { + database + .collection("rooms") + .doc(roomid) + .onSnapshot((snapshot) => setroomname(snapshot.data().name)); + database + .collection("rooms") + .doc(roomid) + .collection("messages") + .orderBy("timestamp", "asc") + .onSnapshot((snapshot) => + setmessages(snapshot.docs.map((doc) => doc.data())) + ); + } + }, [roomid]); + + const SendMessage = (event) => { + event.preventDefault(); + + database.collection("rooms").doc(roomid).collection("messages").add({ + message: input, + name: user.displayName, + sendEmail:user.email, + timestamp: firebase.firestore.FieldValue.serverTimestamp(), + + }); + setinput(""); + }; + + return ( +
+
+ +
+

{roomname}

+

+ last seen{" "} + {new Date( + message[message.length - 1]?.timestamp?.toDate() + ).toUTCString()} +

+
+
+ +
+
+
+ {message.map((message) => ( +

+ {message.name} + {message.message} + + {new Date(message.timestamp?.toDate()).toUTCString()} + +

+ ))} +
+
+ +
+ setinput(event.target.value)} + placeholder="Type your message here" + /> + +
+ +
+
+ ); +} + +export default Chatroom; diff --git a/src/components/Chats.css b/src/components/Chats.css new file mode 100644 index 0000000..91aa71d --- /dev/null +++ b/src/components/Chats.css @@ -0,0 +1,25 @@ +.chats { + display: flex; + align-items: center; + padding: 20px; + cursor: pointer; + border: 1px solid rgb(250, 249, 249); + } + + .chats:hover { + background-color: rgb(236, 233, 233); + } + + .chats__info > h3 { + margin-bottom: 8px; + } + + .chats__info { + margin-left: 10px; + } + + a { + text-decoration: none !important; + color: black; + } + \ No newline at end of file diff --git a/src/components/Chats.js b/src/components/Chats.js new file mode 100644 index 0000000..fe1ff71 --- /dev/null +++ b/src/components/Chats.js @@ -0,0 +1,53 @@ + +import React, { useEffect, useState } from "react"; +import "./Chats.css"; +import { Avatar } from "@material-ui/core"; +import { database } from "../firebase"; +import { Link } from "react-router-dom"; + +function Chats({ addChat, id, name }) { + + const [messages, setmessages] = useState(""); + + + useEffect(() => { + if (id) { + database + .collection("rooms") + .doc(id) + .collection("messages") + .orderBy("timestamp", "desc") + .onSnapshot((snapshot) => + setmessages(snapshot.docs.map((doc) => doc.data())) + ); + } + }, [id]); + + const addnewChat = () => { + const chatName = prompt("Enter A name"); + + if (chatName) { + database.collection("rooms").add({ + name: chatName, + }); + } + }; + + return !addChat ? ( + +
+ +
+

{name}

+

{messages[0]?.message}

+
+
+ + ) : ( +
+

Add New Chat

+
+ ); +} + +export default Chats; diff --git a/src/components/Login.css b/src/components/Login.css new file mode 100644 index 0000000..92415b9 --- /dev/null +++ b/src/components/Login.css @@ -0,0 +1,25 @@ +.login__body { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + } + + .login__body > img { + object-fit: contain; + width: 300px; + margin-bottom: 40px; + } + + .login__body > button { + margin-top: 50px; + background-color: rgb(88, 91, 255); + text-transform: inherit; + } + + .login__body > button:hover { + color: black; + background-color: white; + } + \ No newline at end of file diff --git a/src/components/Login.js b/src/components/Login.js new file mode 100644 index 0000000..21f7f79 --- /dev/null +++ b/src/components/Login.js @@ -0,0 +1,41 @@ +import React from "react"; +import "./Login.css"; +import { Button } from "@material-ui/core"; +import { authentication, provider } from "../firebase"; +import { useStateValue } from "../StateProvider"; +import { actionTypes } from "../reducer"; + +function Login() { + const [{ user }, dispatch] = useStateValue(); + + const signIn = () => { + authentication + .signInWithPopup(provider) + .then((result) => { + dispatch({ + type: actionTypes.SET_USER, + user: result.user, + }); + }) + .catch((error) => alert(error.message)); + }; + + return ( +
+
+ React Messenger +
+

Welcome To React Messenger

+
+ + + +
+
+ ); +} + +export default Login; diff --git a/src/components/Sideroom.css b/src/components/Sideroom.css new file mode 100644 index 0000000..b1986e2 --- /dev/null +++ b/src/components/Sideroom.css @@ -0,0 +1,58 @@ +.sidebar { + flex: 0.3; + flex-direction: column; + display: flex; + } + + .sidebar__header { + display: flex; + align-items: center; + justify-content: space-between; + border-right: 1px solid lightgray; + background-color: rgb(88, 91, 255); + padding: 15px; + } + + .sidebar__headerright { + display: flex; + cursor: pointer; + justify-content: space-between; + min-width: 7vw; + margin-left: 7px; + } + + .siebar__search { + display: flex; + background-color: rgb(250, 243, 243); + height: 40px; + align-items: center; + padding: 10px; + } + + .sidebar__searchcontainer { + display: flex; + background-color: white; + width: 100%; + height: 35px; + border-radius: 999px; + align-items: center; + } + + .sidebar__searchcontainer > input { + width: 80%; + border: none; + margin-left: 15px; + color: gray; + } + .sidebar__searchcontainer > .MuiSvgIcon-root { + margin-left: 15px; + color: gray; + font-size: 18px !important; + } + + .sidebar__chhatsGroups { + flex: 1; + background-color: white; + overflow-y: scroll; + } + \ No newline at end of file diff --git a/src/components/Sideroom.js b/src/components/Sideroom.js new file mode 100644 index 0000000..f5cdba9 --- /dev/null +++ b/src/components/Sideroom.js @@ -0,0 +1,58 @@ +import React, { useState, useEffect } from "react"; +import "./Sideroom.css"; +import { Avatar } from "@material-ui/core"; +import ChatIcon from "@material-ui/icons/Chat"; +import DonutLargeIcon from "@material-ui/icons/DonutLarge"; +import MoreVertIcon from "@material-ui/icons/MoreVert"; +import SearchIcon from "@material-ui/icons/Search"; +import Chats from "./Chats"; +import { database } from "../firebase"; +import { useStateValue } from "../StateProvider"; +function Sideroom() { + const [rooms, setrooms] = useState([]); + const [{ user }, dispatch] = useStateValue(); + + + useEffect(() => { + const unsubsctibe = database.collection("rooms").onSnapshot((snapshot) => + setrooms( + snapshot.docs.map((doc) => ({ + id: doc.id, + data: doc.data(), + })) + ) + ); + + return () => { + unsubsctibe(); + }; + }, []); + + return ( +
+
+ +
+ + + +
+
+
+
+ + +
+
+ +
+ + {rooms.map((room) => ( + + ))} +
+
+ ); +} + +export default Sideroom; diff --git a/src/firebase.js b/src/firebase.js old mode 100755 new mode 100644 diff --git a/src/index.css b/src/index.css old mode 100755 new mode 100644 diff --git a/src/index.js b/src/index.js old mode 100755 new mode 100644 diff --git a/src/logo.png b/src/logo.png old mode 100755 new mode 100644 diff --git a/src/reducer.js b/src/reducer.js new file mode 100644 index 0000000..b29f513 --- /dev/null +++ b/src/reducer.js @@ -0,0 +1,24 @@ +export const initialState = { + user: null, + }; + + export const actionTypes = { + SET_USER: "SET_USER", + }; + + const reducer = (state, action) => { + console.log(action); + switch (action.type) { + case actionTypes.SET_USER: + return { + ...state, + user: action.user, + }; + + default: + return state; + } + }; + + export default reducer; + \ No newline at end of file diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js old mode 100755 new mode 100644