├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── image │ ├── 11871handsome-young-man-with-new-stylish-haircut_176420-19637.jpg │ ├── 1644693238444ariyan.jpg │ ├── 1644693323234female.png │ ├── 1644694261336download.jpg │ ├── 16446942901042021-10-05_13-14-15-5ec767e8c787a460d63a25d2e882b56b.gif │ ├── 1644872279800codeIgniter.png │ ├── 1644872312639course1.png │ ├── 1645465668655course1.png │ ├── 1645465689887ariyan.jpg │ ├── 1645465858846ariyan.jpg │ ├── 1645467231476ariyan.jpg │ ├── 1645479125412download.jpg │ ├── 1645481841394cakephp.png │ ├── 20003ariyan.jpg │ ├── 26615121859823-male-avatar-icon-or-portrait-handsome-young-man-face-with-beard-vector-illustration-.jpg │ ├── 4575download.jpg │ ├── 46668businessman-icon-vector-male-avatar-profile-image-profile-businessman-icon-vector-male-avatar-profile-image-182095609.jpg │ ├── 66127ariyan.jpg │ ├── 78695default-profile-picture1.jpg │ ├── 81424ariyan.jpg │ ├── 87287ariyan.jpg │ ├── 90702handsome-young-man-with-new-stylish-haircut_176420-19637.jpg │ ├── 95295female.png │ ├── 9544male-avatar-profile-picture-purple-member-vector-5351353.jpg │ └── 99987businessman-icon-vector-male-avatar-profile-image-profile-businessman-icon-vector-male-avatar-profile-image-182095609.jpg ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt └── src ├── App.css ├── App.js ├── App.test.js ├── audio ├── notification.mp3 └── sending.mp3 ├── components ├── ActiveFriend.jsx ├── FriendInfo.jsx ├── Friends.jsx ├── Login.jsx ├── Message.jsx ├── MessageSend.jsx ├── Messenger.jsx ├── ProtectRoute.jsx ├── Register.jsx └── RightSide.jsx ├── index.css ├── index.js ├── logo.svg ├── main.scss ├── reportWebVitals.js ├── sass ├── base │ └── _reset.scss ├── components │ ├── _activeFriend.scss │ ├── _friendInfo.scss │ ├── _friends.scss │ ├── _message.scss │ ├── _messageSend.scss │ ├── _messenger.scss │ ├── _register.scss │ └── _rightSide.scss ├── layout │ └── _grid.scss └── utils │ └── _utils.scss ├── setupTests.js └── store ├── actions ├── authAction.js └── messengerAction.js ├── index.js ├── reducers ├── authReducer.js └── messengerReducer.js └── types ├── authType.js └── messengerType.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.1", 7 | "@testing-library/react": "^12.1.2", 8 | "@testing-library/user-event": "^13.5.0", 9 | "axios": "^0.25.0", 10 | "icons": "^1.0.0", 11 | "jwt-decode": "^3.1.2", 12 | "moment": "^2.29.1", 13 | "node-sass": "^7.0.1", 14 | "react": "^17.0.2", 15 | "react-alert": "^7.0.3", 16 | "react-alert-template-basic": "^1.0.2", 17 | "react-dom": "^17.0.2", 18 | "react-hot-toast": "^2.2.0", 19 | "react-icons": "^4.3.1", 20 | "react-redux": "^7.2.6", 21 | "react-router-dom": "^6.2.1", 22 | "react-scripts": "5.0.0", 23 | "redux": "^4.1.2", 24 | "redux-thunk": "^2.4.1", 25 | "socket.io-client": "^4.4.1", 26 | "use-sound": "^4.0.1", 27 | "web-vitals": "^2.1.4" 28 | }, 29 | "scripts": { 30 | "start": "react-scripts start", 31 | "build": "react-scripts build", 32 | "test": "react-scripts test", 33 | "eject": "react-scripts eject" 34 | }, 35 | "eslintConfig": { 36 | "extends": [ 37 | "react-app", 38 | "react-app/jest" 39 | ] 40 | }, 41 | "browserslist": { 42 | "production": [ 43 | ">0.2%", 44 | "not dead", 45 | "not op_mini all" 46 | ], 47 | "development": [ 48 | "last 1 chrome version", 49 | "last 1 firefox version", 50 | "last 1 safari version" 51 | ] 52 | }, 53 | "proxy": "http://localhost:5000/" 54 | } 55 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/favicon.ico -------------------------------------------------------------------------------- /public/image/11871handsome-young-man-with-new-stylish-haircut_176420-19637.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/11871handsome-young-man-with-new-stylish-haircut_176420-19637.jpg -------------------------------------------------------------------------------- /public/image/1644693238444ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1644693238444ariyan.jpg -------------------------------------------------------------------------------- /public/image/1644693323234female.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1644693323234female.png -------------------------------------------------------------------------------- /public/image/1644694261336download.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1644694261336download.jpg -------------------------------------------------------------------------------- /public/image/16446942901042021-10-05_13-14-15-5ec767e8c787a460d63a25d2e882b56b.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/16446942901042021-10-05_13-14-15-5ec767e8c787a460d63a25d2e882b56b.gif -------------------------------------------------------------------------------- /public/image/1644872279800codeIgniter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1644872279800codeIgniter.png -------------------------------------------------------------------------------- /public/image/1644872312639course1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1644872312639course1.png -------------------------------------------------------------------------------- /public/image/1645465668655course1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1645465668655course1.png -------------------------------------------------------------------------------- /public/image/1645465689887ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1645465689887ariyan.jpg -------------------------------------------------------------------------------- /public/image/1645465858846ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1645465858846ariyan.jpg -------------------------------------------------------------------------------- /public/image/1645467231476ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1645467231476ariyan.jpg -------------------------------------------------------------------------------- /public/image/1645479125412download.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1645479125412download.jpg -------------------------------------------------------------------------------- /public/image/1645481841394cakephp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/1645481841394cakephp.png -------------------------------------------------------------------------------- /public/image/20003ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/20003ariyan.jpg -------------------------------------------------------------------------------- /public/image/26615121859823-male-avatar-icon-or-portrait-handsome-young-man-face-with-beard-vector-illustration-.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/26615121859823-male-avatar-icon-or-portrait-handsome-young-man-face-with-beard-vector-illustration-.jpg -------------------------------------------------------------------------------- /public/image/4575download.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/4575download.jpg -------------------------------------------------------------------------------- /public/image/46668businessman-icon-vector-male-avatar-profile-image-profile-businessman-icon-vector-male-avatar-profile-image-182095609.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/46668businessman-icon-vector-male-avatar-profile-image-profile-businessman-icon-vector-male-avatar-profile-image-182095609.jpg -------------------------------------------------------------------------------- /public/image/66127ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/66127ariyan.jpg -------------------------------------------------------------------------------- /public/image/78695default-profile-picture1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/78695default-profile-picture1.jpg -------------------------------------------------------------------------------- /public/image/81424ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/81424ariyan.jpg -------------------------------------------------------------------------------- /public/image/87287ariyan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/87287ariyan.jpg -------------------------------------------------------------------------------- /public/image/90702handsome-young-man-with-new-stylish-haircut_176420-19637.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/90702handsome-young-man-with-new-stylish-haircut_176420-19637.jpg -------------------------------------------------------------------------------- /public/image/95295female.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/95295female.png -------------------------------------------------------------------------------- /public/image/9544male-avatar-profile-picture-purple-member-vector-5351353.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/9544male-avatar-profile-picture-purple-member-vector-5351353.jpg -------------------------------------------------------------------------------- /public/image/99987businessman-icon-vector-male-avatar-profile-image-profile-businessman-icon-vector-male-avatar-profile-image-182095609.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/image/99987businessman-icon-vector-male-avatar-profile-image-profile-businessman-icon-vector-male-avatar-profile-image-182095609.jpg -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { 2 | BrowserRouter, 3 | Routes, 4 | Route 5 | } from "react-router-dom"; 6 | import Login from "./components/Login"; 7 | import Messenger from "./components/Messenger"; 8 | import ProtectRoute from "./components/ProtectRoute"; 9 | import Register from "./components/Register"; 10 | 11 | function App() { 12 | return ( 13 |
14 | 15 | 16 | } /> 17 | } /> 18 | 19 | } /> 20 | 21 | 22 | 23 | , 24 | 25 |
26 | ); 27 | } 28 | 29 | export default App; 30 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/audio/notification.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/src/audio/notification.mp3 -------------------------------------------------------------------------------- /src/audio/sending.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easylearningbd/messenger-chat-app-frontend/66c4377db546c4662b6b9f6a7b40d551f63bfe3a/src/audio/sending.mp3 -------------------------------------------------------------------------------- /src/components/ActiveFriend.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const ActiveFriend = ({user,setCurrentFriend}) => { 4 | return ( 5 |
setCurrentFriend({ 6 | _id : user.userInfo.id, 7 | email: user.userInfo.email, 8 | image : user.userInfo.image, 9 | userName : user.userInfo.userName 10 | })} className='active-friend'> 11 |
12 | 13 |
14 | 15 |
16 |
17 | 18 | 19 | 20 | 21 |
22 | 23 |
24 | ) 25 | }; 26 | 27 | export default ActiveFriend; 28 | -------------------------------------------------------------------------------- /src/components/FriendInfo.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FaCaretSquareDown,FaEdit,FaSistrix } from "react-icons/fa"; 3 | 4 | const FriendInfo = ({currentfriend,activeUser,message}) => { 5 | return ( 6 |
7 | 8 |
9 |
10 | 11 |
12 | { 13 | activeUser && activeUser.length > 0 && activeUser.some(u => u.userId === currentfriend._id) ?
Active
: '' 14 | } 15 | 16 | 17 | 18 |
19 |

{currentfriend.userName}

20 |
21 |
22 | 23 | 24 |
25 |
26 |

Coustomise Chat

27 | 28 |
29 | 30 |
31 |

Privacy and Support

32 | 33 |
34 | 35 |
36 |

Shared Media

37 | 38 |
39 |
40 | 41 |
42 | { 43 | message && message.length>0 ? message.map((m,index)=>m.message.image && ) : '' 44 | } 45 |
46 | 47 |
48 | ) 49 | }; 50 | 51 | export default FriendInfo; 52 | -------------------------------------------------------------------------------- /src/components/Friends.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import moment from 'moment'; 3 | import { FaRegCheckCircle } from "react-icons/fa"; 4 | 5 | const Friends = (props) => { 6 | const {fndInfo,msgInfo} = props.friend; 7 | const myId = props.myId; 8 | const {activeUser} = props; 9 | 10 | 11 | 12 | return ( 13 |
14 |
15 |
16 | 17 | { 18 | activeUser && activeUser.length > 0 && activeUser.some(u => u.userId === fndInfo._id ) ?
: '' 19 | } 20 | 21 |
22 |
23 | 24 |
25 |
26 |

{fndInfo.userName}

27 | 28 | 29 | 30 |
31 | { 32 | msgInfo && msgInfo.senderId === myId ? You : {fndInfo.userName + ' '} 33 | } 34 | { 35 | msgInfo && msgInfo.message.text ? {msgInfo.message.text.slice(0, 10)} : msgInfo && msgInfo.message.image ? Send A image : Connect You 36 | } 37 | {msgInfo ? moment(msgInfo.createdAt).startOf('mini').fromNow() : moment(fndInfo.createdAt).startOf('mini').fromNow()} 38 | 39 |
40 |
41 | 42 | { 43 | myId === msgInfo?.senderId ? 44 |
45 | { 46 | msgInfo.status === 'seen' ? 47 | : msgInfo.status === 'delivared' ?
:
48 | } 49 | 50 |
: 51 |
52 | { 53 | msgInfo?.status !== undefined && msgInfo?.status !== 'seen'?
: '' 54 | } 55 | 56 | 57 |
58 | } 59 | 60 | 61 |
62 | 63 |
64 | ) 65 | }; 66 | 67 | export default Friends; 68 | -------------------------------------------------------------------------------- /src/components/Login.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState,useEffect } from 'react'; 2 | import { Link,useNavigate } from 'react-router-dom'; 3 | import { userLogin } from '../store/actions/authAction'; 4 | import { useAlert } from 'react-alert'; 5 | import {useDispatch,useSelector} from "react-redux" 6 | import { ERROR_CLEAR, SUCCESS_MESSAGE_CLEAR } from '../store/types/authType'; 7 | 8 | const Login = () => { 9 | 10 | const navigate = useNavigate(); 11 | 12 | const alert = useAlert(); 13 | 14 | const {loading,authenticate,error,successMessage,myInfo} = useSelector(state=>state.auth); 15 | 16 | 17 | const dispatch = useDispatch(); 18 | 19 | const [state, setState] = useState({ 20 | email: '', 21 | password : '' 22 | }); 23 | 24 | const inputHendle = e => { 25 | setState({ 26 | ...state, 27 | [e.target.name] : e.target.value 28 | }) 29 | } 30 | 31 | const login = (e) => { 32 | e.preventDefault(); 33 | dispatch(userLogin(state)) 34 | } 35 | 36 | useEffect(()=>{ 37 | if(authenticate){ 38 | navigate('/'); 39 | } 40 | if(successMessage){ 41 | alert.success(successMessage); 42 | dispatch({type : SUCCESS_MESSAGE_CLEAR }) 43 | } 44 | if(error){ 45 | error.map(err=>alert.error(err)); 46 | dispatch({type : ERROR_CLEAR }) 47 | } 48 | 49 | },[successMessage,error]) 50 | 51 | return ( 52 |
53 |
54 |
55 |

Login

56 |
57 | 58 |
59 |
60 | 61 | 62 |
63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 |
71 | 72 | 73 |
74 | 75 |
76 | 77 | 78 |
79 | Don't have any Account 80 |
81 |
82 |
83 | 84 | 85 |
86 | 87 |
88 | 89 | ) 90 | }; 91 | 92 | export default Login; 93 | -------------------------------------------------------------------------------- /src/components/Message.jsx: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | import React from 'react'; 3 | import { useSelector } from 'react-redux'; 4 | import { FaRegCheckCircle } from "react-icons/fa"; 5 | 6 | const Message = ({message,currentfriend,scrollRef,typingMessage}) => { 7 | const {myInfo} = useSelector(state=>state.auth); 8 | return ( 9 | <> 10 |
11 | { 12 | message && message.length > 0 ? message.map((m, index) => 13 | m.senderId === myInfo.id ?
14 |
15 |
16 |

{m.message.text === '' ? : m.message.text }

17 | 18 | { 19 | index === message.length -1 && m.senderId === myInfo.id ? m.status === 'seen' ? : m.status === 'delivared' ? : : '' 20 | } 21 | 22 | 23 |
24 |
25 |
26 | {moment(m.createdAt).startOf('mini').fromNow() } 27 |
28 |
:
29 |
30 | 31 |
32 |
33 |

{m.message.text === '' ? : m.message.text }

34 |
35 |
36 | {moment(m.createdAt).startOf('mini').fromNow() } 37 |
38 |
39 |
40 |
41 | ) :
42 | 43 |

{currentfriend.userName} Connect You

44 | {moment(currentfriend.createdAt).startOf('mini').fromNow() } 45 |
46 | } 47 | 48 | 49 |
50 | { 51 | typingMessage && typingMessage.msg && typingMessage.senderId === currentfriend._id ?
52 |
53 |
54 | 55 |
56 |
57 |

Typing Message....

58 |
59 | 60 |
61 |
62 |
63 | 64 |
: '' 65 | } 66 | 67 | 68 | 69 | 70 | ) 71 | }; 72 | 73 | export default Message; 74 | -------------------------------------------------------------------------------- /src/components/MessageSend.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FaPlusCircle,FaFileImage,FaGift,FaPaperPlane } from "react-icons/fa"; 3 | 4 | const MessageSend = ({inputHendle,newMessage,sendMessage,emojiSend,ImageSend}) => { 5 | 6 | const emojis = [ 7 | '😀', '😃', '😄', '😁', 8 | '😆', '😅', '😂', '🤣', 9 | '😊', '😇', '🙂', '🙃', 10 | '😉', '😌', '😍', '😝', 11 | '😜', '🧐', '🤓', '😎', 12 | '😕', '🤑', '🥴', '😱' 13 | ] 14 | 15 | 16 | return ( 17 | 18 |
19 | 20 |
21 |
22 | Add Attachment 23 |
24 | 25 |
26 | 27 |
28 |
29 | Add Image 30 |
31 | 32 | 33 |
34 | 35 |
36 |
37 | Add gift 38 |
39 | 40 |
41 | 42 |
43 | 44 | 45 |
46 | 47 |
48 |
49 | 50 |
51 | 52 |
53 | 54 |
55 |
56 | { 57 | emojis.map(e => emojiSend(e)} >{e}) 58 | } 59 | 60 |
61 | 62 |
63 | 64 | 65 |
66 | 67 | ) 68 | }; 69 | 70 | export default MessageSend; 71 | -------------------------------------------------------------------------------- /src/components/Messenger.jsx: -------------------------------------------------------------------------------- 1 | import React,{ useEffect,useState,useRef } from 'react'; 2 | import { FaEllipsisH,FaEdit,FaSistrix,FaSignOutAlt } from "react-icons/fa"; 3 | import ActiveFriend from './ActiveFriend'; 4 | import Friends from './Friends'; 5 | import RightSide from './RightSide'; 6 | import {useDispatch ,useSelector } from 'react-redux'; 7 | import { getFriends,messageSend,getMessage,ImageMessageSend,seenMessage,updateMessage,getTheme,themeSet } from '../store/actions/messengerAction'; 8 | import {userLogout } from '../store/actions/authAction'; 9 | 10 | import toast,{Toaster} from 'react-hot-toast'; 11 | import {io} from 'socket.io-client'; 12 | import useSound from 'use-sound'; 13 | import notificationSound from '../audio/notification.mp3'; 14 | import sendingSound from '../audio/sending.mp3'; 15 | 16 | const Messenger = () => { 17 | 18 | const [notificationSPlay] = useSound(notificationSound); 19 | const [sendingSPlay] = useSound(sendingSound); 20 | 21 | const scrollRef = useRef(); 22 | const socket = useRef(); 23 | 24 | 25 | const {friends,message,mesageSendSuccess,message_get_success,themeMood,new_user_add} = useSelector(state => state.messenger ); 26 | const {myInfo} = useSelector(state => state.auth); 27 | 28 | const [currentfriend, setCurrentFriend] = useState(''); 29 | const [newMessage, setNewMessage] = useState(''); 30 | 31 | const [activeUser, setActiveUser] = useState([]); 32 | const [socketMessage, setSocketMessage] = useState(''); 33 | const [typingMessage, setTypingMessage] = useState(''); 34 | 35 | useEffect(() => { 36 | socket.current = io('ws://localhost:8000'); 37 | socket.current.on('getMessage',(data) => { 38 | setSocketMessage(data); 39 | }) 40 | 41 | socket.current.on('typingMessageGet',(data) => { 42 | setTypingMessage(data); 43 | }) 44 | 45 | socket.current.on('msgSeenResponse', msg => { 46 | dispatch({ 47 | type : 'SEEN_MESSAGE', 48 | payload : { 49 | msgInfo : msg 50 | } 51 | }) 52 | }) 53 | 54 | socket.current.on('msgDelivaredResponse', msg => { 55 | dispatch({ 56 | type : 'DELIVARED_MESSAGE', 57 | payload : { 58 | msgInfo : msg 59 | } 60 | }) 61 | }) 62 | 63 | socket.current.on('seenSuccess', data => { 64 | dispatch({ 65 | type : 'SEEN_ALL', 66 | payload : data 67 | }) 68 | }) 69 | 70 | },[]); 71 | 72 | 73 | useEffect(() => { 74 | if(socketMessage && currentfriend){ 75 | if(socketMessage.senderId === currentfriend._id && socketMessage.reseverId === myInfo.id){ 76 | dispatch({ 77 | type: 'SOCKET_MESSAGE', 78 | payload : { 79 | message: socketMessage 80 | } 81 | }) 82 | dispatch(seenMessage(socketMessage)); 83 | socket.current.emit('messageSeen',socketMessage); 84 | dispatch({ 85 | type: 'UPDATE_FRIEND_MESSAGE', 86 | payload : { 87 | msgInfo : socketMessage, 88 | status : 'seen' 89 | } 90 | }) 91 | } 92 | } 93 | setSocketMessage('') 94 | },[socketMessage]); 95 | 96 | 97 | 98 | useEffect(() => { 99 | socket.current.emit('addUser', myInfo.id, myInfo) 100 | },[]); 101 | 102 | useEffect(() => { 103 | socket.current.on('getUser', (users)=>{ 104 | const filterUser = users.filter(u => u.userId !== myInfo.id) 105 | setActiveUser(filterUser); 106 | }) 107 | 108 | socket.current.on('new_user_add',data => { 109 | dispatch({ 110 | type : 'NEW_USER_ADD', 111 | payload : { 112 | new_user_add : data 113 | } 114 | }) 115 | }) 116 | 117 | 118 | 119 | },[]); 120 | 121 | useEffect(() => { 122 | if(socketMessage && socketMessage.senderId !== currentfriend._id && socketMessage.reseverId === myInfo.id){ 123 | notificationSPlay(); 124 | toast.success(`${socketMessage.senderName} Send a New Message`) 125 | dispatch(updateMessage(socketMessage)); 126 | socket.current.emit('delivaredMessage',socketMessage); 127 | dispatch({ 128 | type: 'UPDATE_FRIEND_MESSAGE', 129 | payload : { 130 | msgInfo : socketMessage, 131 | status : 'delivared' 132 | } 133 | }) 134 | 135 | } 136 | },[socketMessage]); 137 | 138 | 139 | 140 | 141 | const inputHendle = (e) => { 142 | setNewMessage(e.target.value); 143 | 144 | socket.current.emit('typingMessage',{ 145 | senderId : myInfo.id, 146 | reseverId : currentfriend._id, 147 | msg : e.target.value 148 | }) 149 | 150 | } 151 | 152 | const sendMessage = (e) => { 153 | e.preventDefault(); 154 | sendingSPlay(); 155 | const data = { 156 | senderName : myInfo.userName, 157 | reseverId : currentfriend._id, 158 | message : newMessage ? newMessage : '❤' 159 | } 160 | 161 | 162 | socket.current.emit('typingMessage',{ 163 | senderId : myInfo.id, 164 | reseverId : currentfriend._id, 165 | msg : '' 166 | }) 167 | 168 | dispatch(messageSend(data)); 169 | setNewMessage('') 170 | } 171 | 172 | 173 | useEffect(() => { 174 | if(mesageSendSuccess){ 175 | socket.current.emit('sendMessage', message[message.length -1 ]); 176 | dispatch({ 177 | type: 'UPDATE_FRIEND_MESSAGE', 178 | payload : { 179 | msgInfo : message[message.length -1] 180 | } 181 | }) 182 | dispatch({ 183 | type: 'MESSAGE_SEND_SUCCESS_CLEAR' 184 | }) 185 | } 186 | },[mesageSendSuccess]); 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | const dispatch = useDispatch(); 195 | useEffect(() => { 196 | dispatch(getFriends()); 197 | dispatch({type:'NEW_USER_ADD_CLEAR'}) 198 | },[new_user_add]); 199 | 200 | useEffect(() => { 201 | if(friends && friends.length > 0) 202 | setCurrentFriend(friends[0].fndInfo) 203 | 204 | },[friends]); 205 | 206 | 207 | useEffect(() => { 208 | dispatch(getMessage(currentfriend._id)); 209 | if(friends.length > 0){ 210 | 211 | } 212 | },[ currentfriend?._id]); 213 | 214 | 215 | useEffect(() => { 216 | if(message.length > 0){ 217 | if(message[message.length -1].senderId !== myInfo.id && message[message.length -1].status !== 'seen'){ 218 | dispatch({ 219 | type: 'UPDATE', 220 | payload : { 221 | id : currentfriend._id 222 | } 223 | }) 224 | socket.current.emit('seen', { senderId: currentfriend._id, reseverId: myInfo.id }) 225 | dispatch(seenMessage({ _id: message[message.length -1]._id })) 226 | } 227 | } 228 | dispatch ({ 229 | type: 'MESSAGE_GET_SUCCESS_CLEAR' 230 | }) 231 | 232 | },[ message_get_success]); 233 | 234 | 235 | 236 | useEffect(() => { 237 | scrollRef.current?.scrollIntoView({behavior: 'smooth'}) 238 | },[ message]); 239 | 240 | 241 | const emojiSend = (emu) => { 242 | setNewMessage(`${newMessage}`+ emu); 243 | socket.current.emit('typingMessage',{ 244 | senderId : myInfo.id, 245 | reseverId : currentfriend._id, 246 | msg : emu 247 | }) 248 | } 249 | 250 | const ImageSend = (e) => { 251 | 252 | if(e.target.files.length !== 0){ 253 | sendingSPlay(); 254 | const imagename = e.target.files[0].name; 255 | const newImageName = Date.now() + imagename; 256 | 257 | socket.current.emit('sendMessage',{ 258 | senderId: myInfo.id, 259 | senderName: myInfo.userName, 260 | reseverId: currentfriend._id, 261 | time: new Date(), 262 | message : { 263 | text : '', 264 | image : newImageName 265 | } 266 | }) 267 | 268 | const formData = new FormData(); 269 | 270 | formData.append('senderName',myInfo.userName); 271 | formData.append('imageName',newImageName); 272 | formData.append('reseverId',currentfriend._id); 273 | formData.append('image', e.target.files[0]); 274 | dispatch(ImageMessageSend(formData)); 275 | 276 | } 277 | 278 | } 279 | 280 | const [hide, setHide] = useState(true); 281 | 282 | const logout = () => { 283 | dispatch(userLogout()); 284 | socket.current.emit('logout', myInfo.id); 285 | } 286 | 287 | useEffect(() => { 288 | dispatch(getTheme()); 289 | },[ ]); 290 | 291 | const search = (e) => { 292 | 293 | const getFriendClass = document.getElementsByClassName('hover-friend'); 294 | const frienNameClass = document.getElementsByClassName('Fd_name'); 295 | for (var i = 0; i < getFriendClass.length, i < frienNameClass.length; i++) { 296 | let text = frienNameClass[i].innerText.toLowerCase(); 297 | if (text.indexOf(e.target.value.toLowerCase()) > -1) { 298 | getFriendClass[i].style.display = ''; 299 | } else { 300 | getFriendClass[i].style.display = 'none'; 301 | } 302 | } 303 | } 304 | 305 | 306 | return ( 307 |
308 | 318 | 319 | 320 |
321 |
322 |
323 |
324 |
325 |
326 | 327 | 328 |
329 |
330 |

{myInfo.userName}

331 |
332 |
333 | 334 |
335 |
setHide(!hide) } className='icon'> 336 | 337 |
338 |
339 | 340 |
341 | 342 |
343 |

Dark Mode

344 |
345 | 346 | dispatch(themeSet(e.target.value)) } type="radio" value="dark" name="theme" id="dark" /> 347 |
348 | 349 |
350 | 351 | dispatch(themeSet(e.target.value)) } type="radio" value="white" name="theme" id="white" /> 352 |
353 | 354 |
355 | Logout 356 |
357 | 358 | 359 | 360 |
361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 |
370 |
371 | 372 |
373 |
374 | 375 | 376 |
377 |
378 | 379 | {/*
380 | { 381 | activeUser && activeUser.length > 0 ? activeUser.map(u => ) : '' 382 | } 383 | 384 |
*/} 385 | 386 |
387 | { 388 | friends && friends.length>0 ? friends.map((fd) =>
setCurrentFriend(fd.fndInfo)} className={currentfriend._id === fd.fndInfo._id ? 'hover-friend active' : 'hover-friend' }> 389 | 390 |
) : 'No Friend' 391 | } 392 | 393 | 394 | 395 |
396 | 397 |
398 | 399 |
400 | 401 | { 402 | currentfriend ? : 'Please Select your Friend' 414 | } 415 | 416 | 417 |
418 | 419 |
420 | ) 421 | }; 422 | 423 | export default Messenger; 424 | -------------------------------------------------------------------------------- /src/components/ProtectRoute.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import { Navigate } from 'react-router-dom'; 4 | 5 | const ProtectRoute = ({children}) => { 6 | 7 | const {authenticate} = useSelector(state=>state.auth); 8 | return authenticate ? children : 9 | 10 | 11 | 12 | }; 13 | 14 | export default ProtectRoute; 15 | 16 | -------------------------------------------------------------------------------- /src/components/Register.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState,useEffect } from 'react'; 2 | import { Link,useNavigate } from 'react-router-dom'; 3 | import {useDispatch,useSelector} from "react-redux" 4 | import { userRegister } from '../store/actions/authAction'; 5 | import { useAlert } from 'react-alert'; 6 | import { ERROR_CLEAR, SUCCESS_MESSAGE_CLEAR } from '../store/types/authType'; 7 | 8 | const Register = () => { 9 | 10 | const navigate = useNavigate(); 11 | const alert = useAlert(); 12 | 13 | const {loading,authenticate,error,successMessage,myInfo} = useSelector(state=>state.auth); 14 | console.log(myInfo); 15 | 16 | const dispatch = useDispatch(); 17 | 18 | const [state,setstate] = useState({ 19 | userName : '', 20 | email:'', 21 | password:'', 22 | confirmPassword : '', 23 | image : '' 24 | }) 25 | 26 | const [loadImage, setLoadImage] = useState(''); 27 | 28 | const inputHendle = e => { 29 | setstate({ 30 | ...state, 31 | [e.target.name] : e.target.value 32 | }) 33 | } 34 | 35 | const fileHendle = e =>{ 36 | if(e.target.files.length !==0){ 37 | setstate({ 38 | ...state, 39 | [e.target.name] : e.target.files[0] 40 | }) 41 | } 42 | 43 | const reader = new FileReader(); 44 | reader.onload = () => { 45 | setLoadImage(reader.result); 46 | } 47 | reader.readAsDataURL(e.target.files[0]); 48 | } 49 | 50 | const register = e =>{ 51 | 52 | const {userName,email,password,confirmPassword, image} = state; 53 | e.preventDefault(); 54 | 55 | const formData = new FormData(); 56 | 57 | formData.append('userName',userName); 58 | formData.append('email',email); 59 | formData.append('password',password); 60 | formData.append('confirmPassword',confirmPassword); 61 | formData.append('image',image); 62 | 63 | dispatch(userRegister(formData)); 64 | } 65 | 66 | useEffect(()=>{ 67 | if(authenticate){ 68 | navigate('/'); 69 | } 70 | if(successMessage){ 71 | alert.success(successMessage); 72 | dispatch({type : SUCCESS_MESSAGE_CLEAR }) 73 | } 74 | if(error){ 75 | error.map(err=>alert.error(err)); 76 | dispatch({type : ERROR_CLEAR }) 77 | } 78 | 79 | },[successMessage,error]) 80 | 81 | 82 | return ( 83 |
84 |
85 |
86 |

Register

87 |
88 | 89 |
90 |
91 |
92 | 93 | 94 |
95 | 96 |
97 | 98 | 99 |
100 | 101 |
102 | 103 | 104 |
105 | 106 | 107 |
108 | 109 | 110 |
111 | 112 |
113 |
114 |
115 | {loadImage ? : '' } 116 |
117 |
118 | 119 | 120 |
121 | 122 |
123 |
124 | 125 |
126 | 127 |
128 | 129 | 130 |
131 | Login Your Account 132 |
133 |
134 |
135 | 136 | 137 |
138 | 139 |
140 | 141 | ) 142 | }; 143 | 144 | export default Register; 145 | -------------------------------------------------------------------------------- /src/components/RightSide.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FaPhoneAlt,FaVideo,FaRocketchat } from "react-icons/fa"; 3 | import FriendInfo from './FriendInfo'; 4 | import Message from './Message'; 5 | import MessageSend from './MessageSend'; 6 | 7 | const RightSide = (props) => { 8 | 9 | const {currentfriend,inputHendle,newMessage,sendMessage,message,scrollRef,emojiSend,ImageSend,activeUser,typingMessage} = props; 10 | 11 | 12 | 13 | return ( 14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 |
22 |
23 | 24 | 25 | { 26 | activeUser && activeUser.length > 0 && activeUser.some(u => u.userId === currentfriend._id) ?
: '' 27 | } 28 | 29 | 30 |
31 |
32 |

{currentfriend.userName}

33 | 34 |
35 |
36 | 37 |
38 |
39 | 40 |
41 | 42 |
43 | 44 |
45 | 46 |
47 | 48 |
49 | 50 |
51 |
52 | 53 | 59 | 60 | 67 | 68 | 69 |
70 |
71 | 72 |
73 | 74 |
75 | 76 | 77 |
78 |
79 |
80 | ) 81 | }; 82 | 83 | export default RightSide; 84 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import './main.scss'; 6 | import {Provider} from 'react-redux'; 7 | import store from './store/index.js'; 8 | 9 | import { positions, transitions, Provider as AlertProvider} from 'react-alert'; 10 | import alertTemplate from 'react-alert-template-basic'; 11 | 12 | const options = { 13 | timeout : 5000, 14 | positions: positions.BOTTOM_CENTER, 15 | transitions : transitions.SCALE 16 | } 17 | 18 | ReactDOM.render( 19 | 20 | 21 | 22 | 23 | 24 | , 25 | document.getElementById('root') 26 | ); -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main.scss: -------------------------------------------------------------------------------- 1 | @import './sass/base/reset'; 2 | @import './sass/components/register'; 3 | @import './sass/utils/utils'; 4 | 5 | @import './sass/components/messenger'; 6 | @import './sass/layout/grid'; 7 | @import './sass/components/activeFriend'; 8 | @import './sass/components/friends'; 9 | @import './sass/components/rightSide'; 10 | @import './sass/components/message'; 11 | @import './sass/components/messageSend'; 12 | @import './sass/components/friendInfo'; 13 | 14 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/sass/base/_reset.scss: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0px; 3 | padding: 0px; 4 | box-sizing: border-box; 5 | } 6 | :root{ 7 | --text-white: #fff; 8 | --bg-color : #FFFFFF; 9 | --text-color : #050505; 10 | --icon-bg-color : #F5F5F5; 11 | --icon-color : #414141; 12 | --search-bg : #868e991a; 13 | --active-color : #0000000a; 14 | --border-color : #E5E5E5; 15 | --message-icon-color : #0099FF; 16 | --fd-message-bg : #E5E5E5; 17 | --my-message-bg : #0084FF; 18 | --my-message-color : #fff; 19 | --fd-message-color : #050505; 20 | --image-border-color : rgb(155, 153, 153); 21 | --active-icon-color : #5AD539; 22 | --hover-color : #bcbcc091; 23 | } 24 | body{ 25 | background-color: #041a4dbf; 26 | font-family: 'Roboto',sans-serif; 27 | } 28 | 29 | .messenger.theme{ 30 | background-color: #041a4dbf; 31 | --text-color : #fff; 32 | --bg-color : #141b2bf0; 33 | --border-color : #213156bf; 34 | --icon-bg-color: #0a0a1357; 35 | --active-color : #2b335591; 36 | --hover-color : #323a5c91; 37 | --fd-message-bg : #28324ed9; 38 | --my-message-bg : #28324ed9; 39 | --search-bg : #15162559; 40 | --text-white : #fff; 41 | --text-dark : #404040; 42 | --icon-color : #fff; 43 | --message-icon-color : #fff; 44 | --my-message-color : #fff; 45 | --fd-message-color : #fff; 46 | --active-icon-color : #5AD539; 47 | --image-border-color : #fff; 48 | } 49 | a{ 50 | text-decoration: none; 51 | } 52 | li{ 53 | list-style: none; 54 | } -------------------------------------------------------------------------------- /src/sass/components/_activeFriend.scss: -------------------------------------------------------------------------------- 1 | .active-friends{ 2 | .active-friend{ 3 | overflow: hidden; 4 | .image-active-icon{ 5 | overflow-x: scroll; 6 | display: flex; 7 | &::-webkit-scrollbar{ 8 | overflow: hidden; 9 | } 10 | .image{ 11 | margin: 5px; 12 | position: relative; 13 | img{ 14 | width: 38px; 15 | height: 38px; 16 | border-radius: 50%; 17 | } 18 | .active-icon{ 19 | position: absolute; 20 | bottom: 3px; 21 | right: 3px; 22 | width: 10px; 23 | height: 10px; 24 | border-radius: 50%; 25 | background-color: rgb(27, 223, 53); 26 | } 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/sass/components/_friendInfo.scss: -------------------------------------------------------------------------------- 1 | .friend-info{ 2 | padding: 12px 15px; 3 | display: flex; 4 | justify-content: start; 5 | height: 100%; 6 | flex-direction: column; 7 | .image-name{ 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | flex-direction: column; 12 | .image{ 13 | height: 70px; 14 | width: 70px; 15 | border-radius: 50%; 16 | overflow: hidden; 17 | img{ 18 | width: 100%; 19 | height: 100%; 20 | } 21 | margin-bottom: 5px; 22 | } 23 | .active-user{ 24 | color: rgb(27, 238, 27); 25 | margin-bottom: 3px; 26 | } 27 | .name{ 28 | h4{ 29 | font-weight: 600; 30 | color: var(--text-color); 31 | margin-bottom: 8px; 32 | } 33 | } 34 | } 35 | .others{ 36 | display: flex; 37 | flex-direction: column; 38 | margin: 10px 0px; 39 | .custom-chat,.privacy,.media{ 40 | display: flex; 41 | flex-direction: row; 42 | justify-content: space-between; 43 | margin: 4px 0px; 44 | color: var(--text-color); 45 | cursor: pointer; 46 | h3{ 47 | font-size: 14px; 48 | } 49 | label{ 50 | cursor: pointer; 51 | color: var(--text-color); 52 | } 53 | } 54 | } 55 | .gallery{ 56 | display: grid; 57 | grid-template-columns: repeat(2,1fr); 58 | grid-gap: 5px; 59 | overflow-y: auto; 60 | display: none; 61 | &::-webkit-scrollbar{ 62 | display: none; 63 | } 64 | img{ 65 | width: 100%; 66 | height: 100%; 67 | } 68 | } 69 | #gallery{ 70 | display: none; 71 | } 72 | #gallery:checked ~ .gallery{ 73 | display: grid; 74 | } 75 | } -------------------------------------------------------------------------------- /src/sass/components/_friends.scss: -------------------------------------------------------------------------------- 1 | .friends{ 2 | display: flex; 3 | flex-direction: column; 4 | background-color: var(--border-color); 5 | height: 100%; 6 | overflow-y: auto; 7 | &::-webkit-scrollbar{ 8 | display: none; 9 | } 10 | .hover-friend.active{ 11 | background-color: var(--search-bg); 12 | } 13 | .hover-friend{ 14 | cursor: pointer; 15 | &:hover{ 16 | background-color: #017aff; 17 | } 18 | .friend{ 19 | display: flex; 20 | width: 100%; 21 | padding: 7px 15px; 22 | .friend-image{ 23 | .image{ 24 | margin-right: 8px; 25 | position: relative; 26 | img{ 27 | width: 50px; 28 | height: 50px; 29 | border-radius: 50%; 30 | border: 1px solid var(--text-color); 31 | } 32 | .active_icon{ 33 | position: absolute; 34 | width: 13px; 35 | height: 13px; 36 | border-radius: 50%; 37 | background-color: rgb(43, 228, 43); 38 | right: -2px; 39 | bottom: 6px; 40 | border: 1px solid #fff; 41 | } 42 | } 43 | } 44 | .friend-name-seen{ 45 | width: 100%; 46 | display: flex; 47 | justify-content: space-between; 48 | align-items: center; 49 | .friend-name{ 50 | display: flex; 51 | align-items: flex-start; 52 | justify-content: center; 53 | flex-direction: column; 54 | h4.unseen_message{ 55 | font-weight: 700 !important; 56 | } 57 | h4{ 58 | color: var(--text-color); 59 | font-weight: 300; 60 | } 61 | .msg-time{ 62 | span.unseen_message{ 63 | font-weight: 700 !important; 64 | } 65 | span{ 66 | font-size: 12px; 67 | color: var(--text-color); 68 | } 69 | } 70 | } 71 | .seen-unseen-icon{ 72 | display: flex; 73 | justify-content: center; 74 | align-items: center; 75 | img{ 76 | width: 15px; 77 | height: 15px; 78 | border-radius: 50%; 79 | } 80 | .unseen,.delivared{ 81 | color: var(--text-color); 82 | } 83 | .seen-icon{ 84 | width: 15px; 85 | height: 15px; 86 | border-radius: 50%; 87 | background-color: #1e6bbd; 88 | } 89 | } 90 | } 91 | 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/sass/components/_message.scss: -------------------------------------------------------------------------------- 1 | .message-show{ 2 | height: 100%; 3 | padding: 10px; 4 | overflow-y: auto; 5 | &::-webkit-scrollbar{ 6 | overflow:hidden; 7 | } 8 | .friend_connect{ 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: center; 12 | align-items: center; 13 | margin-top: 10px; 14 | color: var(--text-color); 15 | img{ 16 | width: 100px; 17 | height: 100px; 18 | border-radius: 50%; 19 | } 20 | h3{ 21 | margin-top: 10px; 22 | } 23 | } 24 | .my-message{ 25 | float: right; 26 | .my-text{ 27 | display: flex; 28 | align-items: flex-end; 29 | justify-content: flex-end; 30 | width: 370px; 31 | flex-direction: column; 32 | img.img,span{ 33 | width: 14px; 34 | height: 14px; 35 | border-radius: 50%; 36 | margin: 3px 0px 0px 0px; 37 | color: var(--text-color); 38 | } 39 | .my{ 40 | background-color: var(--my-message-bg); 41 | color: var(--text-white); 42 | } 43 | .message-text{ 44 | text-align: end; 45 | padding: 10px; 46 | border-radius: 10px; 47 | img{ 48 | width: 220px; 49 | height: 270px; 50 | margin-right: 0px; 51 | border-radius: 5px; 52 | overflow: hidden; 53 | object-fit: cover; 54 | 55 | } 56 | } 57 | } 58 | .time{ 59 | text-align: end; 60 | padding: 5px 0px; 61 | color: #727272d9; 62 | font-size: 12px; 63 | } 64 | } 65 | .fd-message{ 66 | float: left; 67 | .fd-text{ 68 | display: flex; 69 | align-items: flex-end; 70 | justify-content: flex-start; 71 | width: 370px; 72 | .fd{ 73 | background-color: var(--fd-message-bg); 74 | color: var(--text-color); 75 | } 76 | .message-text{ 77 | text-align: start; 78 | border-radius: 10px; 79 | img{ 80 | width: 220px; 81 | height: 270px; 82 | margin-right: 0px; 83 | border-radius: 5px; 84 | overflow: hidden; 85 | object-fit: cover; 86 | 87 | } 88 | } 89 | } 90 | } 91 | } 92 | .image-message-time,.image-message{ 93 | display: flex; 94 | img{ 95 | width: 32px; 96 | height: 32px; 97 | border-radius: 50%; 98 | overflow: hidden; 99 | margin-right: 10px; 100 | } 101 | .message-text{ 102 | padding: 8px; 103 | color: #fff; 104 | background-color: #017aff; 105 | font-size: 14px; 106 | font-weight: 400; 107 | } 108 | .time{ 109 | padding: 5px 0px; 110 | color: #727272d9; 111 | font-size: 12px; 112 | } 113 | } 114 | .typing-message{ 115 | padding: 0px 10px; 116 | } -------------------------------------------------------------------------------- /src/sass/components/_messageSend.scss: -------------------------------------------------------------------------------- 1 | .message-send-section{ 2 | position: relative; 3 | display: flex; 4 | justify-content: space-between; 5 | align-items: center; 6 | padding: 5px; 7 | .file{ 8 | display: flex; 9 | padding: 8px; 10 | font-size: 20px; 11 | cursor: pointer; 12 | color: var(--icon-color); 13 | label{ 14 | display: flex; 15 | align-items: center; 16 | margin-bottom: 0px; 17 | cursor: pointer; 18 | color: var(--icon-color); 19 | } 20 | #pic{ 21 | display: none; 22 | } 23 | .add-image,.add-attachment,.add-gift{ 24 | position: fixed; 25 | padding: 4px; 26 | background: #212d44; 27 | font-size: 14px; 28 | bottom: 44px; 29 | display: none; 30 | color: var(--text-white); 31 | } 32 | } 33 | .hover-attachment{ 34 | position: relative; 35 | &:hover{ 36 | .add-attachment{ 37 | display: block; 38 | } 39 | } 40 | } 41 | .hover-image{ 42 | position: relative; 43 | &:hover{ 44 | .add-image{ 45 | display: block; 46 | } 47 | } 48 | } 49 | .hover-gift{ 50 | position: relative; 51 | &:hover{ 52 | .add-gift{ 53 | display: block; 54 | } 55 | } 56 | } 57 | .message-type{ 58 | display: flex; 59 | width: 70%; 60 | height: 40px; 61 | background-color: #dfdfdf; 62 | border-radius: 50px; 63 | border: none; 64 | align-items: center; 65 | .form-control{ 66 | width: 100%; 67 | border-bottom-left-radius: 50px; 68 | border-top-left-radius: 50px; 69 | background-color: transparent; 70 | border: none; 71 | &::placeholder{ 72 | color: var(--text-color); 73 | } 74 | } 75 | label{ 76 | font-size: 20px; 77 | margin-right: 5px; 78 | cursor: pointer; 79 | } 80 | } 81 | .emoji-section{ 82 | width: 200px; 83 | background: #0e131d; 84 | position: absolute; 85 | right: 60px; 86 | padding: 6px; 87 | bottom: 50px; 88 | border-radius: 8px; 89 | border-bottom-right-radius: 0px; 90 | display: none; 91 | .emoji{ 92 | display: grid; 93 | grid-template-columns: repeat(7,1fr); 94 | grid-gap: 4px; 95 | span{ 96 | cursor: pointer; 97 | } 98 | } 99 | } 100 | #emoji{ 101 | display: none; 102 | } 103 | #emoji:checked ~ .emoji-section{ 104 | display: block; 105 | } 106 | } -------------------------------------------------------------------------------- /src/sass/components/_messenger.scss: -------------------------------------------------------------------------------- 1 | .messenger{ 2 | width: 100%; 3 | height: 100vh; 4 | background-color: #ffffff; 5 | .row{ 6 | height: 100%; 7 | .col-3{ 8 | .left-side{ 9 | padding: 5px 0px; 10 | border-right: 1px solid var(--border-color); 11 | display: flex; 12 | flex-direction: column; 13 | height: 100%; 14 | justify-content: start; 15 | .top{ 16 | display: flex; 17 | flex-direction: row; 18 | align-items: center; 19 | justify-content: space-between; 20 | margin: 12px 8px; 21 | .image-name{ 22 | display: flex; 23 | cursor: pointer; 24 | .image{ 25 | width: 40px; 26 | height: 40px; 27 | border-radius: 50%; 28 | overflow: hidden; 29 | img{ 30 | width: 100%; 31 | height: 100%; 32 | object-fit: cover; 33 | } 34 | } 35 | .name{ 36 | display: flex; 37 | justify-content: center; 38 | align-items: center; 39 | h3{ 40 | padding-left: 10px; 41 | font-weight: 600; 42 | color: var(--text-color); 43 | } 44 | } 45 | } 46 | .icons{ 47 | display: flex; 48 | position: relative; 49 | .theme_logout.show{ 50 | transform: scale(1); 51 | } 52 | .theme_logout{ 53 | width: 200px; 54 | background-color: rgb(20, 24, 59); 55 | transform: scale(0); 56 | position: absolute; 57 | transition: all .6s; 58 | top: 100%; 59 | padding: 10px; 60 | color: #fff; 61 | .on,.of{ 62 | label{ 63 | cursor: pointer; 64 | color: #fff; 65 | } 66 | display: flex; 67 | justify-content: space-between; 68 | margin-top: 10px; 69 | } 70 | .logout{ 71 | display: flex; 72 | align-items: center; 73 | margin-top: 10px; 74 | cursor: pointer; 75 | } 76 | } 77 | .icon{ 78 | width: 33px; 79 | height: 33px; 80 | display: flex; 81 | justify-content: center; 82 | align-items: center; 83 | background-color: var(--icon-bg-color); 84 | margin-left: 8px; 85 | border-radius: 24px; 86 | color: var(--icon-color); 87 | cursor: pointer; 88 | } 89 | } 90 | } 91 | .friend-search{ 92 | padding: 0px 8px; 93 | .search{ 94 | display: flex; 95 | width: 100%; 96 | height: 40px; 97 | background-color: var(--search-bg); 98 | border-radius: 50px; 99 | margin: 20px 0px; 100 | button{ 101 | padding: 12px; 102 | border-bottom-left-radius: 50px; 103 | border-top-left-radius: 50px; 104 | border: none; 105 | color: var( --text-color); 106 | font-size: 20px; 107 | background-color: transparent; 108 | } 109 | .form-control{ 110 | width: 100%; 111 | padding-left: 0px; 112 | border-bottom-right-radius: 50px; 113 | border-top-right-radius: 50pc; 114 | background-color: #fff0; 115 | border: none; 116 | color: var(--text-color); 117 | &::placeholder{ 118 | color: var( --text-color); 119 | } 120 | } 121 | } 122 | } 123 | } 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /src/sass/components/_register.scss: -------------------------------------------------------------------------------- 1 | .register{ 2 | width: 100%; 3 | height: 100vh; 4 | background-color: azure; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | .card{ 9 | .card-header{ 10 | h3{ 11 | text-align: center; 12 | color: #fff; 13 | } 14 | } 15 | .card-body{ 16 | .form-group{ 17 | .form-control{ 18 | color: #fff; 19 | } 20 | &:last-child{ 21 | margin-bottom: 0px; 22 | } 23 | span{ 24 | text-align: center; 25 | a{ 26 | color: #fff; 27 | } 28 | } 29 | .file-image{ 30 | display: flex; 31 | .image{ 32 | width: 50px; 33 | height: 50px; 34 | border-radius: 50%; 35 | border : 1px solid rgb(199, 195, 195); 36 | overflow: hidden; 37 | img{ 38 | width: 100%; 39 | height: 100%; 40 | object-fit: cover; 41 | } 42 | } 43 | .file{ 44 | display: flex; 45 | flex-direction: column; 46 | justify-content: center; 47 | align-items: center; 48 | .form-control{ 49 | display: none; 50 | } 51 | label{ 52 | background-color: #0a0e1585; 53 | padding: 8px; 54 | margin-bottom: 0px; 55 | width: 120px; 56 | text-align: center; 57 | border-radius: 50px; 58 | margin-left: 10px; 59 | cursor: pointer; 60 | } 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /src/sass/components/_rightSide.scss: -------------------------------------------------------------------------------- 1 | .col-9{ 2 | .right-side{ 3 | height: 100%; 4 | .row{ 5 | height: 100%; 6 | .col-8{ 7 | transition: all .5s; 8 | .message-send-show{ 9 | height: 100vh; 10 | border-right: 1px solid var(--border-color); 11 | display: flex; 12 | flex-direction: column; 13 | justify-content: space-between; 14 | .header{ 15 | display: flex; 16 | flex-direction: row; 17 | align-items: center; 18 | justify-content: space-between; 19 | padding: 12px 10px; 20 | border-bottom: 1px solid var(--border-color); 21 | .image-name{ 22 | display: flex; 23 | .image{ 24 | position: relative; 25 | width: 40px; 26 | height: 40px; 27 | 28 | img{ 29 | width: 40px; 30 | height: 40px; 31 | border-radius: 50%; 32 | } 33 | .active-icon{ 34 | position: absolute; 35 | width: 10px; 36 | height: 10px; 37 | border-radius: 50%; 38 | background-color: rgb(28, 212, 28); 39 | right: 0px; 40 | bottom: 0pc; 41 | } 42 | } 43 | .name{ 44 | display: flex; 45 | justify-content: center; 46 | align-items: center; 47 | h3{ 48 | padding-left: 10px; 49 | color: var(--text-color); 50 | } 51 | } 52 | } 53 | .icons{ 54 | display: flex; 55 | .icon{ 56 | height: 35px; 57 | width: 35px; 58 | border-radius: 50%; 59 | margin-left: 8px; 60 | border-radius: 24px; 61 | color: var(--icon-color); 62 | cursor: pointer; 63 | background-color: var(--icon-bg-color); 64 | display: flex; 65 | justify-content: center; 66 | align-items: center; 67 | label{ 68 | display: flex; 69 | margin-bottom: 0px; 70 | cursor: pointer; 71 | color: var(--icon-color);; 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | } 80 | #dot{ 81 | display: none; 82 | } 83 | #dot:checked ~ .row .col-4{ 84 | display: none; 85 | } 86 | #dot:checked ~ .row .col-8{ 87 | width: 100%; 88 | } 89 | #dot:checked ~ .row .col-8 .message-show .my-message .my-text{ 90 | width: 500px; 91 | } 92 | #dot:checked ~ .row .col-8 .message-show .fd-message .fd-text{ 93 | width: 500px; 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /src/sass/layout/_grid.scss: -------------------------------------------------------------------------------- 1 | .row{ 2 | display: flex; 3 | width: 100%; 4 | } 5 | @for $i from 1 through 12{ 6 | .col-#{$i}{ 7 | width: 100%/12*$i; 8 | } 9 | } -------------------------------------------------------------------------------- /src/sass/utils/_utils.scss: -------------------------------------------------------------------------------- 1 | .card{ 2 | width: 375px; 3 | padding: 15px 20px; 4 | background-color: #1c3f8fd4; 5 | box-shadow: 0px 8px 25px #f5f0f0; 6 | } 7 | .form-group{ 8 | margin: 10px 0px; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | .form-control{ 13 | padding: 12px; 14 | border: none; 15 | outline: none; 16 | background-color: #0a0e1585; 17 | &::placeholder{ 18 | color: #fff; 19 | font-weight: 400; 20 | } 21 | } 22 | label{ 23 | margin-bottom: 5px; 24 | color: #fff; 25 | font-weight: 500; 26 | } 27 | .btn{ 28 | outline: none; 29 | color: #fff; 30 | text-transform: uppercase; 31 | padding: 12px; 32 | text-align: center; 33 | background-color: #101a23eb; 34 | border: none; 35 | cursor: pointer; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/store/actions/authAction.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import {REGISTER_FAIL,REGISTER_SUCCESS,USER_LOGIN_SUCCESS,USER_LOGIN_FAIL} from "../types/authType"; 3 | 4 | export const userRegister = (data) => { 5 | return async (dispatch) => { 6 | 7 | const config = { 8 | headers: { 9 | 'Content-Type':'application/josn' 10 | } 11 | } 12 | try{ 13 | const response = await axios.post('/api/messenger/user-register',data,config); 14 | localStorage.setItem('authToken',response.data.token); 15 | 16 | dispatch({ 17 | type : REGISTER_SUCCESS, 18 | payload:{ 19 | successMessage: response.data.successMessage, 20 | token : response.data.token 21 | } 22 | }) 23 | 24 | } catch(error){ 25 | dispatch({ 26 | type: REGISTER_FAIL, 27 | payload:{ 28 | error : error.response.data.error.errorMessage 29 | } 30 | }) 31 | } 32 | 33 | } 34 | } 35 | 36 | export const userLogin = (data) => { 37 | return async (dispath) => { 38 | 39 | const config = { 40 | headers: { 41 | 'Content-Type': 'application/json' 42 | } 43 | } 44 | 45 | try { 46 | const response = await axios.post('/api/messenger/user-login', data, config); 47 | localStorage.setItem('authToken', response.data.token); 48 | dispath({ 49 | type: USER_LOGIN_SUCCESS, 50 | payload: { 51 | successMessage: response.data.successMessage, 52 | token: response.data.token 53 | } 54 | }) 55 | } catch (error) { 56 | dispath({ 57 | type: USER_LOGIN_FAIL, 58 | payload: { 59 | error: error.response.data.error.errorMessage 60 | } 61 | }) 62 | } 63 | } 64 | } 65 | 66 | export const userLogout = () => async(dispatch) => { 67 | try{ 68 | const response = await axios.post('/api/messenger/user-logout'); 69 | if(response.data.success){ 70 | localStorage.removeItem('authToken'); 71 | dispatch({ 72 | type : 'LOGOUT_SUCCESS' 73 | }) 74 | } 75 | 76 | }catch (error) { 77 | 78 | } 79 | } 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/store/actions/messengerAction.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import {FRIEND_GET_SUCCESS,MESSAGE_GET_SUCCESS,MESSAGE_SEND_SUCCESS,THEME_GET_SUCCESS,THEME_SET_SUCCESS} from "../types/messengerType"; 3 | 4 | export const getFriends = () => async(dispatch) => { 5 | try{ 6 | const response = await axios.get('/api/messenger/get-friends'); 7 | dispatch({ 8 | type: FRIEND_GET_SUCCESS, 9 | payload : { 10 | friends : response.data.friends 11 | } 12 | }) 13 | 14 | }catch (error){ 15 | console.log(error.response.data); 16 | } 17 | } 18 | 19 | export const messageSend = (data) => async(dispatch) => { 20 | try{ 21 | const response = await axios.post('/api/messenger/send-message',data); 22 | dispatch({ 23 | type : MESSAGE_SEND_SUCCESS, 24 | payload : { 25 | message : response.data.message 26 | } 27 | }) 28 | }catch (error){ 29 | console.log(error.response.data); 30 | } 31 | } 32 | 33 | 34 | export const getMessage = (id) => { 35 | return async(dispatch) => { 36 | try{ 37 | const response = await axios.get(`/api/messenger/get-message/${id}`) 38 | dispatch({ 39 | type : MESSAGE_GET_SUCCESS, 40 | payload : { 41 | message : response.data.message 42 | } 43 | }) 44 | }catch (error){ 45 | console.log(error.response.data) 46 | } 47 | } 48 | } 49 | 50 | 51 | export const ImageMessageSend = (data) => async(dispatch)=>{ 52 | 53 | try{ 54 | const response = await axios.post('/api/messenger/image-message-send',data); 55 | dispatch({ 56 | type: MESSAGE_SEND_SUCCESS, 57 | payload : { 58 | message : response.data.message 59 | } 60 | }) 61 | }catch (error){ 62 | console.log(error.response.data); 63 | 64 | } 65 | 66 | } 67 | 68 | export const seenMessage = (msg) => async(dispatch)=> { 69 | try{ 70 | const response = await axios.post('/api/messenger/seen-message',msg); 71 | console.log(response.data); 72 | }catch (error){ 73 | console.log(error.response.message) 74 | 75 | } 76 | } 77 | 78 | 79 | export const updateMessage = (msg) => async(dispatch)=> { 80 | try{ 81 | const response = await axios.post('/api/messenger/delivared-message',msg); 82 | console.log(response.data); 83 | }catch (error){ 84 | console.log(error.response.message) 85 | 86 | } 87 | } 88 | 89 | 90 | export const getTheme = () => async(dispatch) => { 91 | 92 | const theme = localStorage.getItem('theme'); 93 | dispatch({ 94 | type: "THEME_GET_SUCCESS", 95 | payload : { 96 | theme : theme? theme : 'white' 97 | } 98 | }) 99 | 100 | } 101 | 102 | 103 | export const themeSet = (theme) => async(dispatch) => { 104 | 105 | localStorage.setItem('theme',theme); 106 | dispatch({ 107 | type: "THEME_SET_SUCCESS", 108 | payload : { 109 | theme : theme 110 | } 111 | }) 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import {createStore,compose,combineReducers,applyMiddleware} from 'redux'; 2 | 3 | import thunkMiddleware from 'redux-thunk'; 4 | import { authReducer } from './reducers/authReducer'; 5 | import {messengerReducer} from './reducers/messengerReducer'; 6 | 7 | const rootReducer = combineReducers({ 8 | auth: authReducer, 9 | messenger : messengerReducer 10 | }) 11 | 12 | const middleware = [thunkMiddleware]; 13 | 14 | const store = createStore(rootReducer,compose(applyMiddleware(...middleware), 15 | // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 16 | 17 | )); 18 | 19 | export default store; -------------------------------------------------------------------------------- /src/store/reducers/authReducer.js: -------------------------------------------------------------------------------- 1 | import { REGISTER_FAIL,REGISTER_SUCCESS,SUCCESS_MESSAGE_CLEAR,ERROR_CLEAR,USER_LOGIN_FAIL,USER_LOGIN_SUCCESS,LOGOUT_SUCCESS } from "../types/authType"; 2 | import deCodeToken from 'jwt-decode'; 3 | 4 | const authState = { 5 | loading : true, 6 | authenticate : false, 7 | error : '', 8 | successMessage: '', 9 | myInfo : '' 10 | } 11 | 12 | const tokenDecode = (token) =>{ 13 | const tokenDecoded = deCodeToken(token); 14 | const expTime = new Date(tokenDecoded.exp*1000); 15 | if(new Date() > expTime){ 16 | return null; 17 | } 18 | return tokenDecoded; 19 | 20 | } 21 | 22 | const getToken = localStorage.getItem('authToken'); 23 | if(getToken){ 24 | const getInfo = tokenDecode(getToken); 25 | if(getInfo){ 26 | authState.myInfo = getInfo; 27 | authState.authenticate = true; 28 | authState.loading = false; 29 | } 30 | } 31 | console.log(getToken); 32 | 33 | export const authReducer = (state = authState, action) => { 34 | const {payload,type} = action; 35 | 36 | if(type === REGISTER_FAIL || type === USER_LOGIN_FAIL){ 37 | return { 38 | ...state, 39 | error : payload.error, 40 | authenticate : false, 41 | myInfo : '', 42 | loading : true 43 | } 44 | } 45 | 46 | if(type === REGISTER_SUCCESS || type === USER_LOGIN_SUCCESS){ 47 | const myInfo = tokenDecode(payload.token); 48 | return{ 49 | ...state, 50 | myInfo : myInfo, 51 | successMessage : payload.successMessage, 52 | error : '', 53 | authenticate : true, 54 | loading: false 55 | 56 | } 57 | 58 | } 59 | 60 | 61 | if(type === SUCCESS_MESSAGE_CLEAR){ 62 | return { 63 | ...state, 64 | successMessage : '' 65 | } 66 | } 67 | 68 | if(type === ERROR_CLEAR){ 69 | return { 70 | ...state, 71 | error : '' 72 | } 73 | } 74 | 75 | 76 | if(type === 'LOGOUT_SUCCESS'){ 77 | return { 78 | ...state, 79 | authenticate : false, 80 | myInfo : '', 81 | successMessage: 'Logout Successfull', 82 | 83 | } 84 | } 85 | 86 | 87 | return state; 88 | } -------------------------------------------------------------------------------- /src/store/reducers/messengerReducer.js: -------------------------------------------------------------------------------- 1 | import {FRIEND_GET_SUCCESS,MESSAGE_GET_SUCCESS,MESSAGE_SEND_SUCCESS,SOCKET_MESSAGE,UPDATE_FRIEND_MESSAGE,MESSAGE_SEND_SUCCESS_CLEAR,SEEN_MESSAGE,DELIVARED_MESSAGE,UPDATE,MESSAGE_GET_SUCCESS_CLEAR,SEEN_ALL} from "../types/messengerType"; 2 | 3 | const messengerState = { 4 | friends : [], 5 | message : [], 6 | mesageSendSuccess : false, 7 | message_get_success : false, 8 | themeMood : '', 9 | new_user_add : '' 10 | } 11 | 12 | export const messengerReducer = (state=messengerState,action) => { 13 | const {type,payload} = action; 14 | 15 | 16 | if(type === 'THEME_GET_SUCCESS' || type === 'THEME_SET_SUCCESS'){ 17 | return { 18 | ...state, 19 | themeMood : payload.theme 20 | } 21 | } 22 | 23 | 24 | 25 | 26 | 27 | if(type === FRIEND_GET_SUCCESS){ 28 | return { 29 | ...state, 30 | friends : payload.friends 31 | } 32 | } 33 | 34 | if(type === MESSAGE_GET_SUCCESS){ 35 | return { 36 | ...state, 37 | message_get_success : true, 38 | message : payload.message 39 | } 40 | } 41 | 42 | if(type === MESSAGE_SEND_SUCCESS){ 43 | return { 44 | ...state, 45 | mesageSendSuccess : true, 46 | message : [...state.message,payload.message] 47 | } 48 | } 49 | 50 | if(type === SOCKET_MESSAGE){ 51 | return { 52 | ...state, 53 | message : [...state.message,payload.message] 54 | } 55 | } 56 | 57 | if(type === UPDATE_FRIEND_MESSAGE){ 58 | const index = state.friends.findIndex(f=>f.fndInfo._id === payload.msgInfo.reseverId || f.fndInfo._id === payload.msgInfo.senderId); 59 | state.friends[index].msgInfo = payload.msgInfo; 60 | state.friends[index].msgInfo.status = payload.status; 61 | return state; 62 | } 63 | 64 | 65 | 66 | if(type === MESSAGE_SEND_SUCCESS_CLEAR){ 67 | return { 68 | ...state, 69 | mesageSendSuccess : false 70 | } 71 | } 72 | 73 | 74 | if(type === SEEN_MESSAGE){ 75 | const index = state.friends.findIndex(f=>f.fndInfo._id === payload.msgInfo.reseverId || f.fndInfo._id === payload.msgInfo.senderId); 76 | state.friends[index].msgInfo.status = 'seen'; 77 | return { 78 | ...state 79 | }; 80 | } 81 | 82 | if(type === DELIVARED_MESSAGE){ 83 | const index = state.friends.findIndex(f=>f.fndInfo._id === payload.msgInfo.reseverId || f.fndInfo._id === payload.msgInfo.senderId); 84 | state.friends[index].msgInfo.status = 'delivared'; 85 | return { 86 | ...state 87 | }; 88 | } 89 | 90 | 91 | if(type === UPDATE){ 92 | const index = state.friends.findIndex(f=>f.fndInfo._id === payload.id); 93 | if(state.friends[index].msgInfo){ 94 | state.friends[index].msgInfo.status = 'seen'; 95 | } 96 | return { 97 | ...state 98 | } 99 | } 100 | 101 | if(type === MESSAGE_GET_SUCCESS_CLEAR){ 102 | return { 103 | ...state, 104 | message_get_success : false 105 | } 106 | } 107 | 108 | if(type === 'SEEN_ALL'){ 109 | const index = state.friends.findIndex(f=>f.fndInfo._id === payload.reseverId); 110 | state.friends[index].msgInfo.status = 'seen'; 111 | return { 112 | ...state 113 | } 114 | } 115 | 116 | if(type === 'LOGOUT_SUCCESS'){ 117 | return { 118 | ...state, 119 | friends : [], 120 | message : [], 121 | mesageSendSuccess : false, 122 | message_get_success : false, 123 | 124 | } 125 | } 126 | 127 | if(type === 'NEW_USER_ADD'){ 128 | return{ 129 | ...state, 130 | new_user_add : payload.new_user_add 131 | } 132 | } 133 | 134 | if(type === 'NEW_USER_ADD_CLEAR'){ 135 | return{ 136 | ...state, 137 | new_user_add : '' 138 | } 139 | } 140 | 141 | 142 | 143 | return state; 144 | } -------------------------------------------------------------------------------- /src/store/types/authType.js: -------------------------------------------------------------------------------- 1 | export const REGISTER_FAIL = 'REGISTER_FAIL' 2 | export const REGISTER_SUCCESS = 'REGISTER_SUCCESS' 3 | export const SUCCESS_MESSAGE_CLEAR = 'SUCCESS_MESSAGE_CLEAR' 4 | export const ERROR_CLEAR = 'ERROR_CLEAR' 5 | export const USER_LOGIN_SUCCESS = 'USER_LOGIN_SUCCESS' 6 | export const USER_LOGIN_FAIL = 'USER_LOGIN_FAIL' 7 | export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS' 8 | 9 | -------------------------------------------------------------------------------- /src/store/types/messengerType.js: -------------------------------------------------------------------------------- 1 | export const FRIEND_GET_SUCCESS = 'FRIEND_GET_SUCCESS' 2 | export const MESSAGE_GET_SUCCESS = 'MESSAGE_GET_SUCCESS' 3 | export const MESSAGE_SEND_SUCCESS = 'MESSAGE_SEND_SUCCESS' 4 | export const SOCKET_MESSAGE = 'SOCKET_MESSAGE' 5 | export const UPDATE_FRIEND_MESSAGE = 'UPDATE_FRIEND_MESSAGE' 6 | export const MESSAGE_SEND_SUCCESS_CLEAR = 'MESSAGE_SEND_SUCCESS_CLEAR' 7 | export const SEEN_MESSAGE = 'SEEN_MESSAGE' 8 | export const DELIVARED_MESSAGE = 'DELIVARED_MESSAGE' 9 | export const UPDATE = 'UPDATE' 10 | export const MESSAGE_GET_SUCCESS_CLEAR = 'MESSAGE_GET_SUCCESS_CLEAR' 11 | export const SEEN_ALL = 'SEEN_ALL' 12 | export const THEME_GET_SUCCESS = 'THEME_GET_SUCCESS' 13 | export const THEME_SET_SUCCESS = 'THEME_SET_SUCCESS' 14 | 15 | 16 | 17 | 18 | --------------------------------------------------------------------------------