Thises
Thises
Project Report On
Real Time Chatting Application
Submitted in partial fulfilment of the requirements for the award of degree
From
Pt. Ravishankar Shukla University, Raipur (C.G.)
Submitted to
Disha College
Pt. Ravishankar Shukla University, Raipur (C.G.)
1|Page
CERTIFICATE OF APPROVAL
This is to certify that the Project work entitled “Real Time Chatting
Application” is carried out by Aryan Dewangan a student of BCA-III
year at Disha College is here by approved as a credible work in the
discipline of Computer Science & Information Technology for the award
of degree of Bachelor of Computer Application during the year 2022-23
from Pt. Ravishankar Shukla University, Raipur (C.G.).
2|Page
CERTIFICATE
This is to certify that the Project work entitled “Real Time Chatting
Application” Submitted to Disha College by Aryan Dewangan, Roll
No_____________ in partial fulfilment for the requirements relating to
nature and standard of the award of Bachelor of Computer Application
degree by Pt. Ravishankar Shukla University, Raipur(C.G.) for the
academic year 2022-23.
This project work has been carried out under my guidance.
Guide
Miss Pooja Singh
Asst. Professor(CS)
Disha College, Raipur
3|Page
CERTIFICATE OF EVALUATION
This is to certify that the Project work entitled “Real Time Chatting
Application” is carried out by Aryan Dewangan Roll no_____________
a student of BCA-III year at Disha College after my proper evaluation and
examination, is here by approved as a credible work in the discipline of
Computer Science & Information Technology for the award of degree of
Bachelor of Computer Application during the year 2022-23 from Pt.
Ravishankar Shukla University, Raipur (C.G.).
4|Page
DECLARATION
This is to certify that the project work entitled “Real Time Chatting
Application” submitted by me in the partial fulfilment for the award of the
degree of Bachelor of Computer Application to Disha College,
comprises the original work carried out by me.
I further declare that the work reported in this project has not been
submitted and will not be submitted, either in part or in full for the award
of any other degree or diploma in this Institute or University.
5|Page
ACKNOWLEDGEMENT
ARYAN DEWANGAN
BCA – III
6|Page
INDEX
7|Page
1.1 Objective of the Project
Our goal is to build a web chat that holds a single chat room. Any user can connect to
it from an open window/tab each connected user will see instantly any message sent,
and new connected users will see the last 10 messages sent. MongoDB makes use of
records which are made up of documents that contain a data structure composed of
field and value pairs. Documents are the basic unit of data in MongoDB. Express
does is that it enables you to easily create web applications by providing a slightly
simpler interface for creating your request endpoints, handling cookies, etc. than
vanilla Node. React is an open-source, component-based JavaScript library used to
create quick and interactive interfaces or UI components for users for web and
mobile-based applications.
It is a declarative and highly accurate library that provides reusable code, which
enhances the efficiency and flexibility of single-page applications.Node.js is an open-
source and cross-platform JavaScript runtime environment. Node.js with Express.js
can also be used to create classic web applications on the server-side.
8|Page
1.2 Scope of the Project
The scope of the project should be broken-down and the system should be declared
before advancing further. The scope are as follows:
1. The design and the construction of this application is aimed to at building a
web-based application and mobile application.
2. This system is developed using React.js And Node.js.
3. The database of this system implemented using MongoDB.
9|Page
2. Theoretical Background Of Project
This project is designed with HTML, CSS, JavaScript, React.js (Front-End) and
Express.js, Node.js, MongoDB, Socket.io (Back-End).
HTML is an acronym which stands for Hyper Text Markup Language which is
used for creating web pages and web applications. Let's see what is meant by
Hypertext Markup Language, and Web page.
Hyper Text: HyperText simply means "Text within Text." A text has a link within it,
is a hypertext. Whenever you click on a link which brings you to a new webpage, you
have clicked on a hypertext. HyperText is a way to link two or more web pages
(HTML documents) with each other.
Web Page: A web page is a document which is commonly written in HTML and
translated by a web browser. A web page can be identified by entering an URL. A
Web page can be of the static or dynamic type. With the help of HTML only, we
can create static web pages.
Syntax –
<!DOCTYPE html>
<html>
<head>
<title>title page</title>
</head>
<body>
<h1>heading</h1>
10 | P a g e
<p>paragraph</p>
</body>
</html>
Advantages Of CSS –
CSS saves time − You can write CSS once and then reuse same sheet in
multiple HTML pages. You can define a style for each HTML element
and apply it to as many Web pages as you want.
Pages load faster − If you are using CSS, you do not need to write
HTML tag attributes every time. Just write one CSS rule of a tag and
apply it to all the occurrences of that tag. So less code means faster
download times.
11 | P a g e
Multiple Device Compatibility − Style sheets allow content to be
optimized for more than one type of device. By using the same HTML
document, different versions of a website can be presented for handheld
devices such as PDAs and cell phones or for printing.
Syntax -
<style>
P{
Align-item: center;
Font-size: 15px;
Color: pink;
}
</style>
12 | P a g e
Complementary to and integrated with Java.
Complementary to and integrated with HTML.
Open and cross-platform
Advantages Of JavaScripts –
Immediate feedback to the visitors − They don't have to wait for a page
reload to see if they have forgotten to enter something.
Increased interactivity − You can create interfaces that react when the
user hovers over them with a mouse or activates them via the keyboard.
Limitations of JavaScript -
We cannot treat JavaScript as a full-fledged programming language. It lacks the
following important features −
Client-side JavaScript does not allow the reading or writing of files. This
has been kept for security reason.
JavaScript cannot be used for networking applications because there is
no such support available.
JavaScript doesn't have any multi-threading or multiprocessor
capabilities.
Once again, JavaScript is a lightweight, interpreted programming language that
allows you to build interactivity into otherwise static HTML pages.
Syntax –
<script>
13 | P a g e
var x = 5;
var y = 6;
var z = x + y;
document.getElementById("demo").innerHTML =
"The value of z is: " + z;
</script>
ReactJS is one of the most popular JavaScript front-end libraries which has a strong
foundation and a large community.
Our ReactJS tutorial includes all the topics which help to learn ReactJS. These are
ReactJS Introduction, ReactJS Features, ReactJS Installation, Pros and Cons of
ReactJS, ReactJS JSX, ReactJS Components, ReactJS State, ReactJS Props, ReactJS
Forms, ReactJS Events, ReactJS Animation and many more.
React Features –
Currently, ReactJS gaining quick popularity as the best JavaScript framework among
web developers. It is playing an essential role in the front-end ecosystem. The
important features of ReactJS are as following.
JSX
Components
One – way data binding
Virtual DOM
Simplicity
14 | P a g e
Performance
JSX –
JSX stands for JavaScript XML. It is a JavaScript syntax extension. Its an XML or
HTML like syntax used by ReactJS. This syntax is processed into JavaScript calls of
React Framework. It extends the ES6 so that HTML like text can co-exist with
JavaScript react code. It is not necessary to use JSX, but it is recommended to use in
ReactJS.
Components –
ReactJS is all about components. ReactJS application is made up of multiple
components, and each component has its own logic and controls. These components
can be reusable which help you to maintain the code when working on larger scale
projects.
Virtual DOM –
A virtual DOM object is a representation of the original DOM object. It works like a
one-way data binding. Whenever any modifications happen in the web application,
the entire UI is re-rendered in virtual DOM representation. Then it checks the
difference between the previous DOM representation and new DOM. Once it has
done, the real DOM will update only the things that have actually changed. This
makes the application faster, and there is no wastage of memory.
Simplicity –
ReactJS uses JSX file which makes the application simple and to code as well as
understand. We know that ReactJS is a component-based approach which makes the
code reusable as your need. This makes it simple to use and learn.
Performance –
15 | P a g e
ReactJS is known to be a great performer. This feature makes it much better than
other frameworks out there today. The reason behind this is that it manages a virtual
DOM. The DOM is a cross-platform and programming API which deals with HTML,
XML or XHTML. The DOM exists entirely in memory. Due to this, when we create
a component, we did not write directly to the DOM. Instead, we are writing virtual
components that will turn into the DOM leading to smoother and faster performance.
Syntax -
import React, { Component } from 'react';
class App extends Component{
render(){
return(
<div>
<h1>JavaTpoint</h1>
<h2>Training Institutes</h2>
<p>This website contains the best CS tutorials.</p>
</div>
);
}
}
export default App;
Express is a fast, assertive, essential and moderate web framework of Node.js. You
can assume express as a layer built on the top of the Node.js that helps manage a
server and routes. It provides a robust set of features to develop web and mobile
applications.
some of the core features of Express framework:
It can be used to design single-page, multi-page and hybrid web applications.
It allows to setup middlewares to respond to HTTP Requests.
It defines a routing table which is used to perform different actions based on
HTTP method and URL.
16 | P a g e
It allows to dynamically render HTML Pages based on passing arguments to
templates.
Syntax –
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
console.log('Example app listening at http://%s:%s', host, port);
});
Node.js provides a runtime environment outside of the browser. It's also built on
the Chrome V8 JavaScript engine. This makes it possible to build back-end
applications using the same JavaScript programming language you may be familiar
with.
17 | P a g e
Concepts Of Node.js -
Features of Node.js –
Asynchronous and Event Driven − All APIs of Node.js library are
asynchronous, that is, non-blocking. It essentially means a Node.js based
server never waits for an API to return data. The server moves to the next API
after calling it and a notification mechanism of Events of Node.js helps the
server to get a response from the previous API call.
Single Threaded but Highly Scalable − Node.js uses a single threaded model
with event looping. Event mechanism helps the server to respond in a non-
blocking way and makes the server highly scalable as opposed to traditional
servers which create limited threads to handle requests. Node.js uses a single
threaded program and the same program can provide service to a much larger
number of requests than traditional servers like Apache HTTP Server.
No Buffering − Node.js applications never buffer any data. These applications
simply output the data in chunks.
18 | P a g e
2.7 What is MongoDB ?
Features of MongoDB –
2.8 Socket.io
Socket.io has two parts: client-side and server-side. Both parts have an identical API.
The server-side library runs in node.js.
The client-side library runs in the browser.
20 | P a g e
Socket.IO is quite popular and companies like Trello, Yammer, Amazon, Zendesk,
and several others use it to develop robust real-time applications. Socket.io is a very
popular JavaScript framework on GitHub and is heavily dependent on the NPM
plugin. It runs on every browser or platform and focuses equally on speed and
reliability.
Features of Socket.IO –
Reliability: It relies on Engine.IO, which establishes a long-running polling
connection before attempting to upgrade to better "testing" transports, such as
WebSocket.
Auto-reconnection support: The disconnected client keeps trying to
reconnect until the server is available again.
Disconnection detection: The heartbeat mechanism of the socket.io is
engine.io. It lets both the server and the client know when no one else is
responding.
Binary support: Any serializable data structures can be emitted, including:
ArrayBuffer and Blob in the browser
ArrayBuffer and Buffer in Node.js
21 | P a g e
3. Definition Of Problem
This project is to create chat application with a server and users to unable the
user to chat with each other.
To develop an instant messaging solution to unable users to seamlessly
communicate with each other.
The project should be very easy to use enabling even a novice person to use it.
This project can play an important role in organizational field where employees
can connect through LAN.
The main purpose of this project is to provide multi chatting functionality
through network.
22 | P a g e
4. System Analysis Design
Based on the user requirements and the detailed analysis of the existing system, the
new system must be designed. This is the phase of system designing. It is the most
crucial phase in the developments of a system. The logical system design arrived at as
a result of systems analysis is converted into physical system design. Normally, the
design proceeds in two stages:
Preliminary or General Design: In the preliminary or general design, the
features of the new system are specified. The costs of implementing these
features and the benefits to be derived are estimated. If the project is still
considered to be feasible, we move to the detailed design stage.
Database Design –
There is only one database used for accomplishing the project. Following are the
tables included in the database:
Login
Register
User
Messages
Avatar Images ID
Emoji
24 | P a g e
1. Login Details: Details of all login users
25 | P a g e
2. Register Details: Details of all Register users
26 | P a g e
4. Message Details: Details of all users.
27 | P a g e
5. Avatar Image Id Details: Details of all users.
28 | P a g e
5. Methodology adopted and Detail of Hardware & Software
Used
29 | P a g e
5.1 Methodology Adopted
Firstly, we will be doing the requirement and analysis part of the development cycle,
in which we will find out our project’s final goals and what will get in the long run.
Then, we will move onto the designing phase of the cycle which will be deciding the
designing and look of it. Then we’ll deep dive into the implementation part which
consists of frontend and back-end development.
We’ll first start from the back-end of the project with the help of the Java script and
try to build the minimum valued product first which will set the base of our working
project and then we will add other backlogs of the product and try to develop in their
sprint. If a few backlogs will not be completed in their mentioned sprint, then we’ll
add it to the next sprint and try to finish it in that one. During the development of the
back-end of the product, we will be using only the React JS for the front-end which
will be showing the info on the browser.
Database part will be developed parallelly with the back-end development and
MongoDB will be used for the database. If the back-end of the project gets
complicated, we will move on to the front-end development fully. It will be
developed by HTML, CSS , JavaScript and React.js .When this all gets done, we will
run some tests in the testing phase of the project and then will manage the
documentation which we’ve maintained during the whole implementation and
development phase.
6.1 Maintenance
31 | P a g e
The IEEE 1219-1998 software standards document defines software maintenance as
"the modification of a software product after delivery to correct faults, to improve
performance or other attributes, or to adapt the product to a modified environment."
Software maintenance is the concluding part of the software development process or
"life cycle." They categorized maintenance activities into four classes:
5.2 Evaluation
aa bb cc dd
2.4 1.05 2.5 0.38
Benefits of chat includes many companies and schools rely on live chat today
because it has the following benefits.
33 | P a g e
Faster support: It is easy to approach students, colleagues and customers by
live chat. Generally, it takes less time to solve the customer issue when using
live chat.
Real-time text examine: It is one of the benefits between customer and agent.
A customer sends the request for a solution and an agent views and think
about the solution of the issue and replies to the customer immediately.
Instant customer feedback: Customer can rate the company service right
after using the chat service.
On a browser site: The customer and agent conversation take place on the
website. During a chat, the agent can see where the customer is currently
looking the issue so the agent can easily guide the user by copying the link or
screenshot image.
File transfer: A customer can provide file, document and images of the
questioned issue upon asking by the company agent.
24/7 Support Service: A company is available for the customers 24/7 without
any time zone restrictions. Customers can talk to a chatbot even out of office
hours.
Less costs: Live chat is cheaper than the traditional phone call for the
customer to access the company agent for questioning and solving issues.
Calculation of Break-Even Point:
The software provides an approximate profit of 6500/- (yearly) to the institution:-
34 | P a g e
Assuming break even point = 4 years.
So profit = cost/beak even point = 26000/4 = 6500(yearly).
The software development charge = 26000/-
Total Profit generated in 4 years = 4*6500 = 26000
Break-Even Point = 4 years
8.1 ERD
35 | P a g e
8.1
DFD
36 | P a g e
8.2 Input And Output Screen Design
37 | P a g e
Login Screen:
38 | P a g e
Registration Screen:
39 | P a g e
Set Avatar Screen:
Welcome Screen:
40 | P a g e
Chatting Screen:
41 | P a g e
8.3 Process Involved
Waterfall Model:
The waterfall model is a sequential (non-iterative) design process, used in software
development processes, in which progress is seen as flowing steadily downwards
(like a waterfall) through the phases of conception, initiation, analysis, design,
construction, testing, production/implementation and maintenance.
The following is the diagram of waterfall model:
Requirement
Design
Implementation
and unit testing
Integration and
system testing
Operating system
42 | P a g e
Requirement analysis: In this phase, I gathered requirements from my neighbor who
is a shopkeeper. He told me everything what he needed for the Supermarket
management .so that he can store the all the data in a more easier manner and keep
the detailsof the customers and stock,bill,payments etc.
System feasibility: In this phase, after gathering requirements I checked whether the
project “Supermarket Management System” can be made or not.
System design: The project “Supermarket Management System” keeps the details of
customer, Dealers,Sales,Purchase,Stock, bill.
The design of the project “Real Time Chatting Application” consists of the following
forms:
Login Form
Register Form
Avatar Selection
Welcome Window
Profile List
Chatting Window
Logout Button
Coding and unit testing: In this phase, you write code for the modules that make up
the system. You also review the code and individually test the functionality of each
module.
Integration and system testing: In this phase, you integrate all of the modules in the
system and test them as a single system for all of the use cases, making sure that the
modules meet the requirements.
Deployment and maintenance: In this phase, you deploy the software system in the
production environment. You then correct any errors that are identified in this phase,
and add or modify functionality based on the updated requirements.
The waterfall model has the following advantages:
It allows you to compartmentalize the life cycle into various phases, which allows
you to plan the resources and effort required through the development process.
It enforces testing in every stage in the form of reviews and unit testing. You conduct
design reviews, code reviews, unit testing, and integration testing during the stages of
the life cycle.
It allows you to set expectations for deliverables after each phase.
The waterfall model has the following disadvantages:
43 | P a g e
You do not see a working version of the software until late in the life cycle. For this
reason, you can fail to detect problems until the system testing phase.
Problems may be more costly to fix in this phase than they would have been earlier in
the life cycle.
When an application is in the system testing phase, it is difficult to change something
that was not carefully considered in the system design phase.
The emphasis on early planning tends to delay or restrict the amount of change that
the testing effort can instigate, which is not the case when a working model is tested
for immediate feedback.
For a phase to begin the preceding phase must be complete; for example, the system
design phase cannot begin until the requirement analysis phase is complete and the
requirements are frozen. As a result, the waterfall model is not able to accommodate
uncertainties that may persist after a phase is completed. These uncertainties may
lead to delays and extended project schedules.
Testing:
Testing is very vital for any system to be successfully implemented. The common
view is that it is performed to prove that there are no errors in a program. Therefore
the most useful and practical approach is with the explicit intention of finding the
errors. The system is tested experimentally to ensure that the software does not fail.
The system is run according to its specifications and in the way the user expects.
Following testing practices are used. The system will process as normal input
preparation of test-sample data.
The methodology used for testing the software is White Box Testing.
White Box Testing :
White box testing: Testing based on an analysis of the internal structure of the
component or system. Procedure to derive or select test cases based on an analysis of
the internal structure of a component or system. White-box testing is verification
technique software engineers can use to examine if their Code works as expected.
White-box testing is also known as structural testing, clear box testing, and glass box
testing (Beizer, 1995). The connotations of “clear box” and “glass box” appropriately
44 | P a g e
indicate that you have full visibility of the internal workings of the software product,
specifically, the logic and the structure of the code.
Levels:
Unit testing: White-box testing is done during unit testing to ensure that the
code is working as intended, before any integration happens with previously
tested code. White-box testing during unit testing catches any defects early on
and aids in any defects that happen later on after the code is integrated with the
rest of the application and therefore prevents any type of errors later on.
Integration testing: White-box testing at this level is written to test the
interactions of each interface with each other. The Unit level testing made sure
that each code was tested and working accordingly in an isolated environment
and integration examines the correctness of the behaviour in an open
environment through the use of white-box testing for any interactions of
interfaces that are known to the programmer.
Basic Procudeure
White-box testing's basic procedures involve the understanding of the source code
that you are testing at a deep level to be able to test them. The programmer must have
a deep understanding of the application to know what kinds of test cases to create so
that every visible path is exercised for testing. Once the source code is understood
then the source code can be analyzed for test cases to be created. These are the three
basic steps that white-box testing takes in order to create test cases:
Input, involves different types of requirements, functional specifications,
detailed designing of documents, proper source code, security specifications.
This is the preparation stage of white-box testing to layout all of the basic
information.
Processing Unit involves performing risk analysis to guide whole testing
process, proper test plan, execute test cases and communicate results. This is
the phase of building test cases to make sure they thoroughly test the
application the given results are recorded accordingly.
Output; prepare final report that encompasses all of the above preparations and
results.
Advantages:
White-box testing is one of the two biggest testing methodologies used today. It
primarily has three advantages:
45 | P a g e
Side effects of having the knowledge of the source code are beneficial to
thorough testing.
Optimization of code by revealing hidden errors and being able to remove
these possible defects.
Gives the programmer introspection because developers carefully describe any
new implementation.
Disadvantages:
Although White-box testing has great advantages, it is not perfect and contains some
disadvantages. It has two disadvantages:
White-box testing brings complexity to testing because to be able to test every
important aspect of the program, you must have great knowledge of the
program. White-box testing requires a programmer with a high-level of
knowledge due to the complexity of the level of testing that needs to be done.
On some occasions, it is not realistic to be able to test every single existing
condition of the application and some conditions will be untested.
Front-End Codes(Client-side):
Pages:
Login.jsx-
import React, { useState, useEffect } from "react";
import axios from "axios";
import styled from "styled-components";
import { useNavigate, Link } from "react-router-dom";
import Logo from "../assets/logo.svg";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { loginRoute } from "../utils/APIRoutes";
47 | P a g e
const { data } = await axios.post(loginRoute, {
username,
password,
});
if (data.status === false) {
toast.error(data.msg, toastOptions);
}
if (data.status === true) {
localStorage.setItem(
process.env.REACT_APP_LOCALHOST_KEY,
JSON.stringify(data.user)
);
navigate("/");
}
}
};
return (
<>
<FormContainer>
<form action="" onSubmit={(event) => handleSubmit(event)}>
<div className="brand">
<img src={Logo} alt="logo" />
<h1>snappy</h1>
</div>
<input
type="text"
placeholder="Username"
name="username"
onChange={(e) => handleChange(e)}
min="3"
/>
<input
48 | P a g e
type="password"
placeholder="Password"
name="password"
onChange={(e) => handleChange(e)}
/>
<button type="submit">Log In</button>
<span>
Don't have an account ? <Link to="/register">Create One.</Link>
</span>
</form>
</FormContainer>
<ToastContainer />
</>
);
}
49 | P a g e
color: white;
text-transform: uppercase;
}
}
form {
display: flex;
flex-direction: column;
gap: 2rem;
background-color: #00000076;
border-radius: 2rem;
padding: 5rem;
}
input {
background-color: transparent;
padding: 1rem;
border: 0.1rem solid #4e0eff;
border-radius: 0.4rem;
color: white;
width: 100%;
font-size: 1rem;
&:focus {
border: 0.1rem solid #997af0;
outline: none;
}
}
button {
background-color: #4e0eff;
color: white;
padding: 1rem 2rem;
border: none;
font-weight: bold;
cursor: pointer;
border-radius: 0.4rem;
50 | P a g e
font-size: 1rem;
text-transform: uppercase;
&:hover {
background-color: #4e0eff;
}
}
span {
color: white;
text-transform: uppercase;
a{
color: #4e0eff;
text-decoration: none;
font-weight: bold;
}
}
`;
Register.jsx-
import React, { useState, useEffect } from "react";
import axios from "axios";
import styled from "styled-components";
import { useNavigate, Link } from "react-router-dom";
import Logo from "../assets/logo.svg";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { registerRoute } from "../utils/APIRoutes";
51 | P a g e
pauseOnHover: true,
draggable: true,
theme: "dark",
};
const [values, setValues] = useState({
username: "",
email: "",
password: "",
confirmPassword: "",
});
useEffect(() => {
if (localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)) {
navigate("/");
}
}, []);
52 | P a g e
return false;
} else if (password.length < 8) {
toast.error(
"Password should be equal or greater than 8 characters.",
toastOptions
);
return false;
} else if (email === "") {
toast.error("Email is required.", toastOptions);
return false;
}
return true;
};
53 | P a g e
}
}
};
return (
<>
<FormContainer>
<form action="" onSubmit={(event) => handleSubmit(event)}>
<div className="brand">
<img src={Logo} alt="logo" />
<h1>snappy</h1>
</div>
<input
type="text"
placeholder="Username"
name="username"
onChange={(e) => handleChange(e)}
/>
<input
type="email"
placeholder="Email"
name="email"
onChange={(e) => handleChange(e)}
/>
<input
type="password"
placeholder="Password"
name="password"
onChange={(e) => handleChange(e)}
/>
<input
type="password"
placeholder="Confirm Password"
name="confirmPassword"
54 | P a g e
onChange={(e) => handleChange(e)}
/>
<button type="submit">Create User</button>
<span>
Already have an account ? <Link to="/login">Login.</Link>
</span>
</form>
</FormContainer>
<ToastContainer />
</>
);
}
55 | P a g e
}
form {
display: flex;
flex-direction: column;
gap: 2rem;
background-color: #00000076;
border-radius: 2rem;
padding: 3rem 5rem;
}
input {
background-color: transparent;
padding: 1rem;
border: 0.1rem solid #4e0eff;
border-radius: 0.4rem;
color: white;
width: 100%;
font-size: 1rem;
&:focus {
border: 0.1rem solid #997af0;
outline: none;
}
}
button {
background-color: #4e0eff;
color: white;
padding: 1rem 2rem;
border: none;
font-weight: bold;
cursor: pointer;
border-radius: 0.4rem;
font-size: 1rem;
text-transform: uppercase;
&:hover {
56 | P a g e
background-color: #4e0eff;
}
}
span {
color: white;
text-transform: uppercase;
a{
color: #4e0eff;
text-decoration: none;
font-weight: bold;
}
}
`;
Chat.jsx-
import React, { useEffect, useState, useRef } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { io } from "socket.io-client";
import styled from "styled-components";
import { allUsersRoute, host } from "../utils/APIRoutes";
import ChatContainer from "../components/ChatContainer";
import Contacts from "../components/Contacts";
import Welcome from "../components/Welcome";
57 | P a g e
if (!localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)) {
navigate("/login");
} else {
setCurrentUser(
await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
)
);
}
}, []);
useEffect(() => {
if (currentUser) {
socket.current = io(host);
socket.current.emit("add-user", currentUser._id);
}
}, [currentUser]);
useEffect(async () => {
if (currentUser) {
if (currentUser.isAvatarImageSet) {
const data = await axios.get(`${allUsersRoute}/${currentUser._id}`);
setContacts(data.data);
} else {
navigate("/setAvatar");
}
}
}, [currentUser]);
const handleChatChange = (chat) => {
setCurrentChat(chat);
};
return (
<>
<Container>
<div className="container">
58 | P a g e
<Contacts contacts={contacts} changeChat={handleChatChange} />
{currentChat === undefined ? (
<Welcome />
):(
<ChatContainer currentChat={currentChat} socket={socket} />
)}
</div>
</Container>
</>
);
}
59 | P a g e
Components:
ChatContainer.jsx-
import React, { useState, useEffect, useRef } from "react";
import styled from "styled-components";
import ChatInput from "./ChatInput";
import Logout from "./Logout";
import { v4 as uuidv4 } from "uuid";
import axios from "axios";
import { sendMessageRoute, recieveMessageRoute } from "../utils/APIRoutes";
useEffect(async () => {
const data = await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
);
const response = await axios.post(recieveMessageRoute, {
from: data._id,
to: currentChat._id,
});
setMessages(response.data);
}, [currentChat]);
useEffect(() => {
const getCurrentChat = async () => {
if (currentChat) {
await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
)._id;
}
60 | P a g e
};
getCurrentChat();
}, [currentChat]);
useEffect(() => {
if (socket.current) {
socket.current.on("msg-recieve", (msg) => {
setArrivalMessage({ fromSelf: false, message: msg });
});
}
}, []);
useEffect(() => {
arrivalMessage && setMessages((prev) => [...prev, arrivalMessage]);
61 | P a g e
}, [arrivalMessage]);
useEffect(() => {
scrollRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
return (
<Container>
<div className="chat-header">
<div className="user-details">
<div className="avatar">
<img
src={`data:image/svg+xml;base64,${currentChat.avatarImage}`}
alt=""
/>
</div>
<div className="username">
<h3>{currentChat.username}</h3>
</div>
</div>
<Logout />
</div>
<div className="chat-messages">
{messages.map((message) => {
return (
<div ref={scrollRef} key={uuidv4()}>
<div
className={`message ${
message.fromSelf ? "sended" : "recieved"
}`}
>
<div className="content ">
<p>{message.message}</p>
</div>
62 | P a g e
</div>
</div>
);
})}
</div>
<ChatInput handleSendMsg={handleSendMsg} />
</Container>
);
}
63 | P a g e
color: white;
}
}
}
}
.chat-messages {
padding: 1rem 2rem;
display: flex;
flex-direction: column;
gap: 1rem;
overflow: auto;
&::-webkit-scrollbar {
width: 0.2rem;
&-thumb {
background-color: #ffffff39;
width: 0.1rem;
border-radius: 1rem;
}
}
.message {
display: flex;
align-items: center;
.content {
max-width: 40%;
overflow-wrap: break-word;
padding: 1rem;
font-size: 1.1rem;
border-radius: 1rem;
color: #d1d1d1;
@media screen and (min-width: 720px) and (max-width: 1080px) {
max-width: 70%;
}
}
}
64 | P a g e
.sended {
justify-content: flex-end;
.content {
background-color: #4f04ff21;
}
}
.recieved {
justify-content: flex-start;
.content {
background-color: #9900ff20;
}
}
}
`;
ChatInput.jsx-
import React, { useState } from "react";
import { BsEmojiSmileFill } from "react-icons/bs";
import { IoMdSend } from "react-icons/io";
import styled from "styled-components";
import Picker from "emoji-picker-react";
65 | P a g e
setMsg(message);
};
return (
<Container>
<div className="button-container">
<div className="emoji">
<BsEmojiSmileFill onClick={handleEmojiPickerhideShow} />
{showEmojiPicker && <Picker onEmojiClick={handleEmojiClick} />}
</div>
</div>
<form className="input-container" onSubmit={(event) => sendChat(event)}>
<input
type="text"
placeholder="type your message here"
onChange={(e) => setMsg(e.target.value)}
value={msg}
/>
<button type="submit">
<IoMdSend />
</button>
</form>
</Container>
);
}
66 | P a g e
const Container = styled.div`
display: grid;
align-items: center;
grid-template-columns: 5% 95%;
background-color: #080420;
padding: 0 2rem;
@media screen and (min-width: 720px) and (max-width: 1080px) {
padding: 0 1rem;
gap: 1rem;
}
.button-container {
display: flex;
align-items: center;
color: white;
gap: 1rem;
.emoji {
position: relative;
svg {
font-size: 1.5rem;
color: #ffff00c8;
cursor: pointer;
}
.emoji-picker-react {
position: absolute;
top: -350px;
background-color: #080420;
box-shadow: 0 5px 10px #9a86f3;
border-color: #9a86f3;
.emoji-scroll-wrapper::-webkit-scrollbar {
background-color: #080420;
width: 5px;
&-thumb {
background-color: #9a86f3;
}
67 | P a g e
}
.emoji-categories {
button {
filter: contrast(0);
}
}
.emoji-search {
background-color: transparent;
border-color: #9a86f3;
}
.emoji-group:before {
background-color: #080420;
}
}
}
}
.input-container {
width: 100%;
border-radius: 2rem;
display: flex;
align-items: center;
gap: 2rem;
background-color: #ffffff34;
input {
width: 90%;
height: 60%;
background-color: transparent;
color: white;
border: none;
padding-left: 1rem;
font-size: 1.2rem;
&::selection {
background-color: #9a86f3;
68 | P a g e
}
&:focus {
outline: none;
}
}
button {
padding: 0.3rem 2rem;
border-radius: 2rem;
display: flex;
justify-content: center;
align-items: center;
background-color: #9a86f3;
border: none;
@media screen and (min-width: 720px) and (max-width: 1080px) {
padding: 0.3rem 1rem;
svg {
font-size: 1rem;
}
}
svg {
font-size: 2rem;
color: white;
}
}
}
`;
Contacts.jsx-
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import Logo from "../assets/logo.svg";
69 | P a g e
export default function Contacts({ contacts, changeChat }) {
const [currentUserName, setCurrentUserName] = useState(undefined);
const [currentUserImage, setCurrentUserImage] = useState(undefined);
const [currentSelected, setCurrentSelected] = useState(undefined);
useEffect(async () => {
const data = await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
);
setCurrentUserName(data.username);
setCurrentUserImage(data.avatarImage);
}, []);
const changeCurrentChat = (index, contact) => {
setCurrentSelected(index);
changeChat(contact);
};
return (
<>
{currentUserImage && currentUserImage && (
<Container>
<div className="brand">
<img src={Logo} alt="logo" />
<h3>snappy</h3>
</div>
<div className="contacts">
{contacts.map((contact, index) => {
return (
<div
key={contact._id}
className={`contact ${
index === currentSelected ? "selected" : ""
}`}
onClick={() => changeCurrentChat(index, contact)}
>
<div className="avatar">
70 | P a g e
<img
src={`data:image/svg+xml;base64,${contact.avatarImage}`}
alt=""
/>
</div>
<div className="username">
<h3>{contact.username}</h3>
</div>
</div>
);
})}
</div>
<div className="current-user">
<div className="avatar">
<img
src={`data:image/svg+xml;base64,${currentUserImage}`}
alt="avatar"
/>
</div>
<div className="username">
<h2>{currentUserName}</h2>
</div>
</div>
</Container>
)}
</>
);
}
const Container = styled.div`
display: grid;
grid-template-rows: 10% 75% 15%;
overflow: hidden;
background-color: #080420;
.brand {
71 | P a g e
display: flex;
align-items: center;
gap: 1rem;
justify-content: center;
img {
height: 2rem;
}
h3 {
color: white;
text-transform: uppercase;
}
}
.contacts {
display: flex;
flex-direction: column;
align-items: center;
overflow: auto;
gap: 0.8rem;
&::-webkit-scrollbar {
width: 0.2rem;
&-thumb {
background-color: #ffffff39;
width: 0.1rem;
border-radius: 1rem;
}
}
.contact {
background-color: #ffffff34;
min-height: 5rem;
cursor: pointer;
width: 90%;
border-radius: 0.2rem;
padding: 0.4rem;
display: flex;
72 | P a g e
gap: 1rem;
align-items: center;
transition: 0.5s ease-in-out;
.avatar {
img {
height: 3rem;
}
}
.username {
h3 {
color: white;
}
}
}
.selected {
background-color: #9a86f3;
}
}
.current-user {
background-color: #0d0d30;
display: flex;
justify-content: center;
align-items: center;
gap: 2rem;
.avatar {
img {
height: 4rem;
max-inline-size: 100%;
}
}
.username {
h2 {
color: white;
73 | P a g e
}
}
@media screen and (min-width: 720px) and (max-width: 1080px) {
gap: 0.5rem;
.username {
h2 {
font-size: 1rem;
}
}
}
}
`;
Logout.jsx-
import React from "react";
import { useNavigate } from "react-router-dom";
import { BiPowerOff } from "react-icons/bi";
import styled from "styled-components";
import axios from "axios";
import { logoutRoute } from "../utils/APIRoutes";
export default function Logout() {
const navigate = useNavigate();
const handleClick = async () => {
const id = await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
)._id;
const data = await axios.get(`${logoutRoute}/${id}`);
if (data.status === 200) {
localStorage.clear();
navigate("/login");
}
};
74 | P a g e
return (
<Button onClick={handleClick}>
<BiPowerOff />
</Button>
);
}
SetAvatar.jsx-
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import axios from "axios";
import { Buffer } from "buffer";
import loader from "../assets/loader.gif";
import { ToastContainer, toast } from "react-toastify";
75 | P a g e
import "react-toastify/dist/ReactToastify.css";
import { useNavigate } from "react-router-dom";
import { setAvatarRoute } from "../utils/APIRoutes";
export default function SetAvatar() {
const api = `https://api.multiavatar.com/4645646`;
const navigate = useNavigate();
const [avatars, setAvatars] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [selectedAvatar, setSelectedAvatar] = useState(undefined);
const toastOptions = {
position: "bottom-right",
autoClose: 8000,
pauseOnHover: true,
draggable: true,
theme: "dark",
};
useEffect(async () => {
if (!localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY))
navigate("/login");
}, []);
76 | P a g e
if (data.isSet) {
user.isAvatarImageSet = true;
user.avatarImage = data.image;
localStorage.setItem(
process.env.REACT_APP_LOCALHOST_KEY,
JSON.stringify(user)
);
navigate("/");
} else {
toast.error("Error setting avatar. Please try again.", toastOptions);
}
}
};
useEffect(async () => {
const data = [];
for (let i = 0; i < 4; i++) {
const image = await axios.get(
`${api}/${Math.round(Math.random() * 1000)}`
);
const buffer = new Buffer(image.data);
data.push(buffer.toString("base64"));
}
setAvatars(data);
setIsLoading(false);
}, []);
return (
<>
{isLoading ? (
<Container>
<img src={loader} alt="loader" className="loader" />
</Container>
):(
<Container>
77 | P a g e
<div className="title-container">
<h1>Pick an Avatar as your profile picture</h1>
</div>
<div className="avatars">
{avatars.map((avatar, index) => {
return (
<div
className={`avatar ${
selectedAvatar === index ? "selected" : ""
}`}
>
<img
src={`data:image/svg+xml;base64,${avatar}`}
alt="avatar"
key={avatar}
onClick={() => setSelectedAvatar(index)}
/>
</div>
);
})}
</div>
<button onClick={setProfilePicture} className="submit-btn">
Set as Profile Picture
</button>
<ToastContainer />
</Container>
)}
</>
);
}
78 | P a g e
align-items: center;
flex-direction: column;
gap: 3rem;
background-color: #131324;
height: 100vh;
width: 100vw;
.loader {
max-inline-size: 100%;
}
.title-container {
h1 {
color: white;
}
}
.avatars {
display: flex;
gap: 2rem;
.avatar {
border: 0.4rem solid transparent;
padding: 0.4rem;
border-radius: 5rem;
display: flex;
justify-content: center;
align-items: center;
transition: 0.5s ease-in-out;
img {
height: 6rem;
transition: 0.5s ease-in-out;
}
}
.selected {
79 | P a g e
border: 0.4rem solid #4e0eff;
}
}
.submit-btn {
background-color: #4e0eff;
color: white;
padding: 1rem 2rem;
border: none;
font-weight: bold;
cursor: pointer;
border-radius: 0.4rem;
font-size: 1rem;
text-transform: uppercase;
&:hover {
background-color: #4e0eff;
}
}
`;
Welcome.jsx-
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import Robot from "../assets/robot.gif";
export default function Welcome() {
const [userName, setUserName] = useState("");
useEffect(async () => {
setUserName(
await JSON.parse(
localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)
).username
);
}, []);
80 | P a g e
return (
<Container>
<img src={Robot} alt="" />
<h1>
Welcome, <span>{userName}!</span>
</h1>
<h3>Please select a chat to Start messaging.</h3>
</Container>
);
}
Utils:
APIRoutes.js –
export const host = "http://localhost:5000";
export const loginRoute = `${host}/api/auth/login`;
export const registerRoute = `${host}/api/auth/register`;
export const logoutRoute = `${host}/api/auth/logout`;
export const allUsersRoute = `${host}/api/auth/allusers`;
81 | P a g e
export const sendMessageRoute = `${host}/api/messages/addmsg`;
export const recieveMessageRoute = `${host}/api/messages/getmsg`;
export const setAvatarRoute = `${host}/api/auth/setavatar`;
App.js:
import React, { Suspense, lazy } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
Index.css:
@import url("https://fonts.googleapis.com/css2?
family=Josefin+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,
200;1,300;1,400;1,500;1,600;1,700&display=swap");
82 | P a g e
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
button,
input {
font-family: "Josefin Sans", sans-serif;
}
body {
max-height: 100vh;
max-width: 100vw;
overflow: hidden;
}
.Toastify__toast-theme--dark {
background-color: #00000076 !important;
}
Index.js:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "./index.css";
ReactDOM.render(
<React.StrictMode>
<App />
83 | P a g e
</React.StrictMode>,
document.getElementById("root")
);
assets:
loader.gif
logo.svg
robot.gif
.env:
REACT_APP_LOCALHOST_KEY="chat-app-current-user"
Package.json:
{
"name": "chat-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.25.0",
"buffer": "^6.0.3",
"emoji-picker-react": "^3.5.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.3.1",
"react-router-dom": "^6.2.1",
"react-scripts": "5.0.0",
"react-toastify": "^8.1.1",
"socket.io-client": "^4.4.1",
"styled-components": "^5.3.3",
84 | P a g e
"uuid": "^8.3.2",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Back-End Code(Server-Side):
85 | P a g e
Controllers:
messageController.js-
const Messages = require("../models/messageModel");
86 | P a g e
});
userController.js-
const User = require("../models/userModel");
const bcrypt = require("bcrypt");
87 | P a g e
if (usernameCheck)
return res.json({ msg: "Username already used", status: false });
const emailCheck = await User.findOne({ email });
if (emailCheck)
return res.json({ msg: "Email already used", status: false });
const hashedPassword = await bcrypt.hash(password, 10);
const user = await User.create({
email,
username,
password: hashedPassword,
});
delete user.password;
return res.json({ status: true, user });
} catch (ex) {
next(ex);
}
};
88 | P a g e
const userId = req.params.id;
const avatarImage = req.body.image;
const userData = await User.findByIdAndUpdate(
userId,
{
isAvatarImageSet: true,
avatarImage,
},
{ new: true }
);
return res.json({
isSet: userData.isAvatarImageSet,
image: userData.avatarImage,
});
} catch (ex) {
next(ex);
}
};
Models:
messageModel.js-
const mongoose = require("mongoose");
89 | P a g e
const MessageSchema = mongoose.Schema(
{
message: {
text: { type: String, required: true },
},
users: Array,
sender: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
},
{
timestamps: true,
}
);
userModel.js-
const mongoose = require("mongoose");
90 | P a g e
required: true,
unique: true,
max: 50,
},
password: {
type: String,
required: true,
min: 8,
},
isAvatarImageSet: {
type: Boolean,
default: false,
},
avatarImage: {
type: String,
default: "",
},
});
routes:
auth.js-
const {
login,
register,
getAllUsers,
setAvatar,
logOut,
} = require("../controllers/userController");
91 | P a g e
router.post("/login", login);
router.post("/register", register);
router.get("/allusers/:id", getAllUsers);
router.post("/setavatar/:id", setAvatar);
router.get("/logout/:id", logOut);
module.exports = router;
messages.js-
const { addMessage, getMessages } = require("../controllers/messageController");
const router = require("express").Router();
router.post("/addmsg/", addMessage);
router.post("/getmsg/", getMessages);
module.exports = router;
.env:
PORT=5000
MONGO_URL="mongodb://localhost:27017/chat"
Index.js:
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");
const authRoutes = require("./routes/auth");
const messageRoutes = require("./routes/messages");
const app = express();
const socket = require("socket.io");
require("dotenv").config();
app.use(cors());
app.use(express.json());
92 | P a g e
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("DB Connetion Successfull");
})
.catch((err) => {
console.log(err.message);
});
app.use("/api/auth", authRoutes);
app.use("/api/messages", messageRoutes);
93 | P a g e
const sendUserSocket = onlineUsers.get(data.to);
if (sendUserSocket) {
socket.to(sendUserSocket).emit("msg-recieve", data.msg);
}
});
});
Packeg.json:
{
"name": "chat-app-backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.1",
"cors": "^2.8.5",
"dotenv": "^16.0.0",
"express": "^4.17.2",
"mongoose": "^6.2.1",
"nodemon": "^2.0.15",
"socket.io": "^4.4.1"
}
}
94 | P a g e
8. User/Operational Manual –Including Security aspects
backup, Access Rights, Controls
Login Page:
95 | P a g e
Register Page:
96 | P a g e
Set Avatar page:
Click any avatar image
Welcome window:
97 | P a g e
Chat window:
Click here to logout
Security Aspects:
The Person Using the application is required to login first or if the person son’t have
any accout then he/she must have to register their username, email, password and
confirm password.
Profile:
A user can set any avatar image as his/her profile image.
Chatting:
A user can chat with any person by selecting their profile and can logout after
conversation by clicking the button which is mentioned upward also users can pick
random emoji during their conversation.
98 | P a g e
10. Conclusion
As a conclusion, I can say that this undergoing project is giving great experience.
Thanks to this project, I am acquiring deeper knowledge concerning my technical
skills but I also personally benefited. Currently MERN stack is a common
technologies of web applications and chat applications, and one of the most popular
technology for development used by developers worldwide. If we surf internet we
can see millions of websites, applications and games built with MERN and MEAN
stack. I am learning to live in a different environment from the one I am used to.
Indeed, I am growing more independent in work and also in everyday life, realizing
that I could do more things than I thought like learning new things by myself.
There are huge opportunities available for the students who want to work in this field.
Many private and public organizations hire web designer and app designer for their
online work and development. With the rapid advent of online industry, the demand
of web development and app development professionals is increasing and this has
created a huge job opportunity for the aspirants in the upcoming days. Also an
experienced person in this field can also work as a freelancer; there are many online
companies which provide online projects to the individuals.
99 | P a g e
11. Reference
Websites:
Stackoverflow - https://stackoverflow.com/
W3school - https://www.w3schools.com/
React.js - https://reactjs.org/
Youtube:
Claver programmer.
Codewithharry
Six pack programmer
Lama code
100 | P a g e