├── .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 |
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 |
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 |
--------------------------------------------------------------------------------