diff --git a/database/conn.js b/database/conn.js index 24d15fe..a1763ce 100644 --- a/database/conn.js +++ b/database/conn.js @@ -7,4 +7,4 @@ mongoose.connect(process.env.MONGO_URL, { }).catch((e) => { console.log("MongoDB not connected"); console.log(e); -}) +}) \ No newline at end of file diff --git a/database/registers.js b/database/registers.js index b66fafe..f760aef 100644 --- a/database/registers.js +++ b/database/registers.js @@ -1,22 +1,20 @@ - const mongoose = require("mongoose"); const chatSchema = new mongoose.Schema({ name: { - type: String, - + type: String, }, message: { - type: String, - required: true + required: true, + type: String, }, email: { - type: String, - required: true + required: true, + type: String, }, time: { - type: String + type: String, } }); -const Message = new mongoose.model("message", chatSchema); -module.exports = Message; +const Message = new mongoose.model("message", chatSchema); +module.exports = Message; \ No newline at end of file diff --git a/database/signupschema.js b/database/signupschema.js index e431e5c..74b80a0 100644 --- a/database/signupschema.js +++ b/database/signupschema.js @@ -20,10 +20,12 @@ const userSchema = new mongoose.Schema({ minlength: [6, "Minimum length should be 6 character"], }, }); + userSchema.pre("save", async function (next) { const salt = await bcrypt.genSalt(); this.password = await bcrypt.hash(this.password, salt); next(); }) + const User = new mongoose.model("user", userSchema); -module.exports = User; +module.exports = User; \ No newline at end of file diff --git a/index.js b/index.js index 34d0bb2..8315f79 100644 --- a/index.js +++ b/index.js @@ -17,26 +17,32 @@ const User = require("./database/signupschema"); const { timeEnd } = require("console"); const nodemailer = require("nodemailer"); + // Load external styles and scripts from folder 'public' app.use(express.static("public")); app.use(express.json()); app.use(cookieParser()); + /******************************************************************************************/ + const port = process.env.PORT || 8080; +const expirationTime = 3 * 24 * 60 * 60; // equivalent to 3 days let users = []; let err1 = { email: "", password: "" }; -let userentered; -let useremail; +let userEntered; +let userEmail; let user1; -/****************************************************************************************/ -const getmessages = async (socket) => { +// Get messages +const getMessages = async (socket) => { const result = await Message.find().sort({ _id: 1 }); - socket.emit("output", { result: result, useremail: useremail }); + socket.emit("output", { result: result, useremail: userEmail }); }; -const storemessage = async (user_name, msg, mail, time) => { + +// Store messages +const storeMessage = async (userName, msg, mail, time) => { const message = new Message({ - name: user_name, + name: userName, message: msg, email: mail, time: time, @@ -44,11 +50,12 @@ const storemessage = async (user_name, msg, mail, time) => { await message.save(); }; -const handlerror = (err) => { +// Handle errors +const handlError = (err) => { let errors = { email: "", password: "" }; if (err.code === 11000) { - errors.email = "email already exist"; + errors.email = "Email already exists"; return errors; } if (err.message.includes("user validation failed")) { @@ -58,14 +65,16 @@ const handlerror = (err) => { } return errors; }; -const maxAge = 3 * 24 * 60 * 60; -const createtoken = (id) => { + +// Create token for user +const createToken = (id) => { return jwt.sign({ id }, "ankitgarg", { - expiresIn: maxAge, + expiresIn: expirationTime, }); }; -const checkuser = (req, res, next) => { +// Check if user has been created +const checkUser = (req, res, next) => { const token = req.cookies.login; if (token) { jwt.verify(token, "ankitgarg", async (err, decodedToken) => { @@ -73,9 +82,7 @@ const checkuser = (req, res, next) => { user1 = null; next(); } else { - console.log(decodedToken); let user = await User.findById(decodedToken.id); - console.log(user); user1 = user; next(); } @@ -85,34 +92,34 @@ const checkuser = (req, res, next) => { next(); } }; + /*******************************************************************************************/ -//to serve favicon +// To serve favicon app.use(favicon(__dirname + "/public/img/favicon.ico")); // Serve the main file -app.get("*", checkuser); +app.get("*", checkUser); app.get("/", requireauth, (req, res) => { - userentered = user1.username; - useremail = user1.email; + userEntered = user1.username; + userEmail = user1.email; res.sendFile(__dirname + "/views/index.html"); }); app.get("/ui", requireauth, (req, res) => { - userentered = user1.username; - useremail = user1.email; + userEntered = user1.username; + userEmail = user1.email; res.sendFile(__dirname + "/tmp/old.index.html"); }); -//handling signup +// Handling signup app.get("/signup", (req, res) => { res.sendFile(__dirname + "/views/signup.html"); }); -//handling sign post request +// Handling sign post request app.post("/signup", async (req, res) => { try { - console.log(req.body); if (req.body.password === req.body.conpassword) { const user = new User({ username: req.body.username, @@ -123,19 +130,18 @@ app.post("/signup", async (req, res) => { res.status(201).json({ user: user._id }); } else { - throw "Password does not matches"; + throw "Password does not match"; } } catch (err) { - if (err != "Password does not matches") { - err1 = handlerror(err); + if (err != "Password does not match") { + err1 = handlError(err); } - if (err == "Password does not matches" && err1.password == "") { - if (err1.email != "email already exist") { - err1.password = "Password does not matches"; + if (err == "Password does not match" && err1.password == "") { + if (err1.email != "Email already exists") { + err1.password = "Password does not match"; } } - console.log(err1); let error = { ...err1 }; err1.password = ""; err1.email = ""; @@ -143,7 +149,7 @@ app.post("/signup", async (req, res) => { } }); -//handling login +// Handling login app.get("/login", (req, res) => { res.sendFile(__dirname + "/views/login.html"); @@ -153,17 +159,13 @@ app.post("/login", async (req, res) => { try { const user = await User.findOne({ email: req.body.email }); if (!user) { - console.log("inside error block"); throw "Invalid Email"; } - if (user) { const auth = await bcrypt.compare(req.body.password, user.password); - if (auth) { - const token = createtoken(user._id); - res.cookie("login", token, { httpOnly: true, maxAge: maxAge * 1000 }); - + const token = createToken(user._id); + res.cookie("login", token, { httpOnly: true, expirationTime: expirationTime * 1000 }); res.status(200).json({ user: user._id }); } else { throw Error("Incorrect Password"); @@ -184,32 +186,28 @@ app.post("/login", async (req, res) => { } }); +// Handling forgetting password +// Create OTP app.post("/otp", async (req, res) => { try { const user = await User.findOne({ email: req.body.email }); if (!user) { throw "Invalid Email"; } else { - var email; - let transporter = nodemailer.createTransport({ host: "smtp.gmail.com", port: 465, secure: true, service: "Gmail", - auth: { user: process.env.EMAIL, pass: process.env.PASSWORD, }, }); - let otp = Math.random(); - otp = otp * 1000000; - otp = parseInt(otp); - console.log(otp); + let otp = parseInt(Math.random() * 1000000); - // send mail with defined transport object - var mailOptions = { + // Send mail with defined transport object + let mailOptions = { from: process.env.EMAIL, to: req.body.email, subject: "Reset Password OTP | ChatApp", @@ -235,6 +233,7 @@ app.post("/otp", async (req, res) => { res.status(400).json({ error }); } }); + app.get("/forgotpassword", (req, res) => { res.sendFile(__dirname + "/views/fpassword.html"); }); @@ -245,7 +244,7 @@ app.post("/forgotpassword", async (req, res) => { if (req.body.otp != parseInt(req.body.userotp)) { throw "Invalid Otp"; } else { - console.log("noerror"); + console.log("No error"); if (req.body.password === req.body.conpassword) { if (req.body.password.length >= 6) { const salt = await bcrypt.genSalt(); @@ -259,21 +258,22 @@ app.post("/forgotpassword", async (req, res) => { throw "Minimum length should be 6 character"; } } else { - throw "Password does not matches"; + throw "Password does not match"; } } } catch (err) { let error = { password: "", otpmessage: "" }; if (err === "Invalid Otp") { error.otpmessage = "Invalid Otp"; - } else if (err === "Password does not matches") { - error.password = "Password does not matches"; + } else if (err === "Password does not match") { + error.password = "Password does not match"; } else if (err === "Minimum length should be 6 character") { error.password = "Minimum length should be 6 character"; } res.status(400).json({ error }); } }); + // Serve list of users app.get("/users", (req, res) => { res.send(users); @@ -289,7 +289,7 @@ app.get("/messages", async (req, res) => { }); app.get("/logout", (req, res) => { - res.cookie("login", "", { maxAge: 1 }); + res.cookie("login", "", { expirationTime: 1 }); res.redirect("/login"); }); @@ -298,37 +298,34 @@ app.get("/logout", (req, res) => { // When a connection is received io.on("connection", (socket) => { if (user1) { - console.log("A user has connected"); io.emit("connected", { id: socket.id, - name: userentered, - email: useremail, + name: userEntered, + email: userEmail, }); - getmessages(socket); + getMessages(socket); socket.name = ""; - let filtered_users = users.filter((user) => user.id == socket.id); - if (filtered_users != []) { + let filteredUsers = users.filter((user) => user.id == socket.id); + if (filteredUsers != []) { users.push({ - name: userentered, + name: userEntered, id: socket.id, - email: useremail, + email: userEmail, }); } // Receiving a chat message from client socket.on("mychat message", (msg, time) => { - console.log("Received a chat message"); - let current_user = users.filter((user) => user.id === socket.id); - const mail = current_user[0].email; - const name = current_user[0].name; + let currentUser = users.filter((user) => user.id === socket.id); + const mail = currentUser[0].email; + const name = currentUser[0].name; socket.name = name; let userList = []; if (msg.substr(0, 3) == "/w ") { msg = msg.substr(3); const idx = msg.indexOf(" "); - if (idx != -1) { const toUsername = msg.substr(0, idx); msg = msg.substr(idx + 1); @@ -348,8 +345,8 @@ io.on("connection", (socket) => { time, user ) - ); - else + ); + else io.emit( "chat message", { name: socket.name, id: socket.id }, @@ -358,29 +355,29 @@ io.on("connection", (socket) => { "null" ); - storemessage(name, msg, mail, time); + storeMessage(name, msg, mail, time); }); - // Received when some client is typing + // Received when user is typing socket.on("typing", (user) => { socket.broadcast.emit("typing", user); }); - // Receiving an image file from client + + // Receiving an image file from user socket.on("base64_file", function (msg, time) { - let current_user = users.filter((user) => user.id === socket.id); - const name = current_user[0].name; + let currentUser = users.filter((user) => user.id === socket.id); + const name = currentUser[0].name; socket.name = name; - console.log(`received base64 file from ${socket.name}`); - var data = {}; + let data = {}; data.fileName = msg.fileName; data.file = msg.file; data.id = socket.id; data.username = socket.name == "" ? "Anonymous" : socket.name; io.sockets.emit("base64_file", data, time); }); + // Sent to all clients when a socket is disconnected socket.on("disconnect", () => { - console.log("A user has disconnected"); users = users.filter((user) => user.id !== socket.id); io.emit("disconnected", socket.id); }); @@ -389,4 +386,4 @@ io.on("connection", (socket) => { server.listen(port, () => { console.log("Listening on:", port); -}); +}); \ No newline at end of file diff --git a/public/css/style.css b/public/css/style.css index 55a9c98..3bedbe8 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,6 +1,5 @@ body { background-color: #f4f7f6; - margin-top: 20px; min-height: 100vh; overflow: hidden; } @@ -9,18 +8,10 @@ body { min-height: 100vh; } -.mh-175px { - min-height: 175px; -} - .details-bg { background-color: #1d8ff229; } -.h-250px { - height: 250px; -} - .border-custom { border: 2px solid #1d8ff2; outline: none; @@ -38,10 +29,6 @@ body { min-height: 75vh; } -.end-10 { - right: 10px; -} - .bottom--10 { bottom: -25px; } @@ -56,7 +43,6 @@ body { .btn-custom { filter: drop-shadow(4px 4px 9px rgba(0, 0, 0, 0.25)); border: none; - color: white; font-size: 20px; border-radius: 49px; cursor: pointer; @@ -65,14 +51,11 @@ body { .card { background: #fff; transition: 0.5s; - border: 0; margin-bottom: 30px; - border-radius: 0.55rem; - position: relative; width: 100%; min-width: 80vw; - box-shadow: 0 1px 2px 0 rgb(0 0 0 / 10%); } + .chat-app .people-list { width: 280px; position: absolute; @@ -110,7 +93,7 @@ body { cursor: pointer; } -.people-list .chat-list li.active { +.people-list .chat-list li .active { background: #efefef; } @@ -118,42 +101,11 @@ body { font-size: 15px; } -.people-list .chat-list img { - width: 45px; - border-radius: 50%; -} - -.people-list img { - float: left; - border-radius: 50%; -} - -.people-list .about { +.people-list .about { float: left; padding-left: 8px; } -.people-list .status { - color: #999; - font-size: 13px; -} - -.chat .chat-header { - padding: 15px 20px; - border-bottom: 2px solid #f4f7f6; -} - -.chat .chat-header img { - float: left; - border-radius: 40px; - width: 40px; -} - -.chat .chat-header .chat-about { - float: left; - padding-left: 10px; -} - .chat .chat-history { padding: 20px; border-bottom: 2px solid #fff; @@ -173,23 +125,7 @@ body { margin-bottom: 0px; } -.chat .chat-history .message-data { - margin-bottom: 15px; -} - -.chat .chat-history .message-data img { - border-radius: 40px; - width: 40px; -} - -.chat .chat-history .message-data-time { - color: #434651; - padding-left: 6px; -} - .chat .chat-history .message { - color: #444; - padding: 18px 20px; line-height: 26px; font-size: 16px; border-radius: 7px; @@ -199,7 +135,6 @@ body { .chat .chat-history .message:after { bottom: 100%; - /* left: 7%; */ border: solid transparent; content: " "; height: 0; @@ -236,8 +171,6 @@ body { .chat .chat-history .other-message:after { border-left-color: #1d8ff2; - /* left: 93% */ - /* right: 20%; */ bottom: 5px; right: -20px; } @@ -246,39 +179,21 @@ body { padding: 20px; } -.online, -.offline, -.me { - margin-right: 2px; - font-size: 8px; - vertical-align: middle; -} - -.online { - color: #86c541; -} - -.offline { - color: #e47297; -} - -.me { - color: #1d8ecd; -} - .float-right { float: right; } .clearfix:after { visibility: hidden; - display: block; font-size: 0; - content: " "; - clear: both; height: 0; } +.wordwrap{ + overflow-wrap: break-word; + max-width: 100%; +} + @media only screen and (max-width: 767px) { .chat-app .people-list { height: 465px; @@ -288,15 +203,11 @@ body { left: -400px; display: none; } - .chat-app .people-list.open { - left: 0; - } + .chat-app .chat { margin: 0; } - .chat-app .chat .chat-header { - border-radius: 0.55rem 0.55rem 0 0; - } + .chat-app .chat-history { height: 300px; overflow-x: auto; @@ -309,52 +220,45 @@ body { min-width: 80vw; overflow-x: auto; } + .chat-app .chat-history { height: calc(100vh - 170px); min-height: 480px; - /* height: 600px; */ overflow-x: auto; } + #online { height: 200px; } } + @media (max-height: 611px){ body{ overflow: auto; } + .chat-app { margin-top: 20px; } } + /* This will work on Firefox */ * { scrollbar-width: thin; - scrollbar-color: blue rgb(250, 248, 244); + scrollbar-color: #0000ff #faf8f4; } -/* Targtes on Chrome, Edge, and Safari */ +/* Targets on Chrome, Edge, and Safari */ *::-webkit-scrollbar { width: 12px; } *::-webkit-scrollbar-track { - background: rgb(239, 238, 235); + background: #efeeeb; } *::-webkit-scrollbar-thumb { - background-color: rgb(33, 100, 243); + background-color: #2164f3; border-radius: 20px; - border: 3px solid rgb(33, 100, 243); -} - -@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 1) { - /* .chat-app .chat-list { - height: 480px; - overflow-x: auto - } - .chat-app .chat-history { - /* height: calc(100vh - 350px); - overflow-x: auto - } */ -} + border: 3px solid #2164f3; +} \ No newline at end of file diff --git a/public/css/login.css b/public/css/views.css similarity index 70% rename from public/css/login.css rename to public/css/views.css index 380b12b..e5cd167 100644 --- a/public/css/login.css +++ b/public/css/views.css @@ -4,6 +4,7 @@ box-sizing: border-box; font-family: "Roboto", sans-serif; } + .container { width: 100vw; display: flex; @@ -12,12 +13,12 @@ .design { width: 30%; background-image: url(../img/signUp.png); - background-position: cover; background-repeat: no-repeat; - padding: 4rem; + padding: 64px; display: flex; height: 100vh; } + .design img { width: 50px; height: 50px; @@ -25,31 +26,43 @@ .design h1 { color: #1374f2; - font-size: 3rem; + font-size: 48px; padding-left: 12px; - font-weight: bold; - margin-bottom: 1rem; - letter-spacing: 0.055em; + margin-bottom: 16px; + letter-spacing: 2.56px; } + .content { width: 70%; height: 100vh; - background-color: rgb(255, 255, 255); + background-color: #fff; position: relative; } -.go-back { - position: absolute; - right: 20px; - top: 20px; -} + .form { height: 500px; - padding: 5.2rem 4rem; + padding: 83.2px 64px; +} + +.heading { + font-size: 64px; + letter-spacing: 2.56px; + color: #475d75; + font-weight: 500; +} + +.secondary-heading { + padding-top: 6.4px; + font-weight: 500; + font-size: 38.4px; + letter-spacing: 1.6px; + color: #1374f2; } form { - padding-top: 2rem; + padding-top: 32px } + .name-input, .email-input, .pass-input, @@ -57,7 +70,15 @@ form { .otp-input { display: flex; flex-direction: column; - margin-bottom: 1rem; + margin-bottom: 16px; +} + +.form-label { + font-size: 20px; + line-height: 23px; + letter-spacing: 0.96px; + color: #475d75; + padding-bottom: 6.4px; } input[type="text"], @@ -69,89 +90,75 @@ input[type="number"] { border: 2px solid #1d8ff2; box-sizing: border-box; border-radius: 14px; - margin-bottom: 1rem; - padding: 1rem; + margin-bottom: 16px; + padding: 16px; outline: none; font-size: 18px; } -.form-label { - font-family: Roboto; - font-style: normal; - font-weight: normal; - font-size: 20px; - line-height: 23px; - letter-spacing: 0.045em; - color: #475d75; - padding-bottom: 0.4rem; -} -.fontsize { +#email-error, +#password-error { + color: #dc3546; font-size: 14px; } -.account, -.naccount { - font-size: 18px; - display: inline-block; - padding-top: 1rem; - letter-spacing: 0.6px; -} -.login, -.signup { - text-decoration: none; - display: inline-block; - color: #1374f2; - text-decoration: none; - border: 2px solid #1374f2; - padding: 0.4rem 0.8rem; - border-radius: 20px; - transition: 0.4s; -} -.signup:hover, -.login:hover { - background-color: #1374f2; - color: white; -} -.heading { - font-size: 4rem; - letter-spacing: 0.055em; - color: #475d75; - font-weight: 500; -} -.secondary-heading { - padding-top: 0.4rem; - font-weight: 500; - font-size: 2.4rem; - letter-spacing: 0.04em; - color: #1374f2; -} .btn-submit { height: 58px; - padding: 0 3rem; + width: 180px; + padding: 4.8px; filter: drop-shadow(4px 4px 9px rgba(0, 0, 0, 0.25)); background-color: #1374f2; border: none; - color: white; + color: #fff; font-size: 24px; border-radius: 49px; cursor: pointer; transition: 0.4s; } + .btn-submit:hover { color: #1374f2; - background-color: white; + background-color: #fff;; border: 2px solid #1374f2; } -#email-error, -#password-error { - color: rgb(220, 53, 69); - font-size: 14px; -} + .forgetpassword { margin-top: 10px; font-size: 18px; } + .fpassword { text-decoration: none; - color: black; + color: #000; } + +.go-back { + position: absolute; + right: 20px; + top: 20px; +} + +.account, +.naccount { + font-size: 18px; + display: inline-block; + padding-top: 16px; + letter-spacing: 0.6px; +} + +.login, +.signup { + text-decoration: none; + display: inline-block; + color: #1374f2; + border: 2px solid #1374f2; + padding: 6.4px 12.8px; + border-radius: 20px; + transition: 0.4s; +} + +.signup:hover, +.login:hover { + background-color: #1374f2; + color: #fff; +} \ No newline at end of file diff --git a/public/js/client.js b/public/js/client.js index dc54d89..d17b5a4 100644 --- a/public/js/client.js +++ b/public/js/client.js @@ -7,15 +7,29 @@ let messages = document.getElementById("messages"); let online = document.getElementById("online"); let sendBtn = document.querySelector(".btn--send"); let list = document.querySelector("#messages"); -let forms = document.forms; +let inputFile = document.getElementById("input_file"); +let searchBar = document.getElementById("search-messages"); +let searchBarInput = document.getElementById("search-messages").querySelector("input"); let users = []; -let selfId, selfMail; +let selfId; +let selfMail; let md; let myId; -let input_file = document.getElementById("input_file"); -let label = document.getElementsByClassName("file"); +// Color for the messages +let colors = [ + "#0080FF", + "#8000FF", + "#FF00FF", + "#FF0080", + "#FF0000", + "#FF8000", + "#80FF00", + "#00FF00", + "#00FF80", +]; +// Markdown for the messages md = window.markdownit({ html: false, xhtmlOut: false, @@ -24,47 +38,21 @@ md = window.markdownit({ breaks: true, }); +// Fetch user fetch("/me") .then((user) => user.json()) .then((data) => { - console.log(data); document.getElementById("username_holder").innerText = data.username; document.getElementById("email_holder").innerText = `<${data.email}>`; myId = data; }); -// Color for the messages -let colors = [ - "#0080FF", - "#8000FF", - "#FF00FF", - "#FF0080", - "#FF0000", - "#FF8000", - "#80FF00", - "#00FF00", - "#00FF80", -]; - -// let coll = document.getElementsByClassName("collapsible"); - -// coll[0].addEventListener("click", function () { -// this.classList.toggle("active"); -// var content = this.nextElementSibling; -// if (content.style.display === "block") { -// content.style.display = "none"; -// } else { -// content.style.display = "block"; -// } -// }) // Add user to collapsible -let addusertolist = (user) => { +let addUserToList = (user) => { let item = document.createElement("li"); - // item.style.color = (selfId) ? user.color : 'blue'; item.className = "clearfix"; - item.innerHTML = - '
' + user.name + "
"; + item.innerHTML = '
' + user.name + "
"; item.id = user.id; item.onclick = handleOnlineClick.bind(null, user.id); online.appendChild(item); @@ -74,59 +62,32 @@ let addusertolist = (user) => { fetch("/users") .then((user) => user.json()) .then((data) => { - console.log("asdasd"); - console.log(data); data.forEach((user) => { user.color = colors[0]; colors = colors.splice(1); - addusertolist(user); + addUserToList(user); }); users = users.concat(data); }); -// Fetch messages as soon as you connect -// fetch("/messages") -// .then((user) => user.json()) -// .then((data) => { -// if (data.length>0) { -// data.map(msg => { -// let item = document.createElement("li"); -// item.className = "clearfix position-relative" - -// if (msg.email == myId.email) { -// item.innerHTML = `
${msg.message}
${msg.name}, ${msg.time} `; -// } -// else { -// item.innerHTML = `
${msg.message}
${msg.name}, ${msg.time} `; - -// } -// messages.appendChild(item); -// }) -// }} -// ) -// Sent a chat message to server when submit a form +// Send a chat message to server when submitting the form form.addEventListener("submit", (e) => { e.preventDefault(); if (input.value) { socket.emit("mychat message", input.value, getTime()); - // console.log("send", input.value); input.value = ""; } - // if (username.readOnly === false) { - // username.readOnly = true; - // username.style.backgroundColor = "gold" - // } }); // Received from server when someone gets connected socket.on("connected", ({ id, name, email }) => { - // update user's (socket) id when reconnected + // Update user's (socket) id when reconnected if (selfMail === email) { const userIdx = users.findIndex((u) => u.email === email); users[userIdx].id = id; selfId = id; return; - } + } if (selfId) { let item = document.createElement("li"); @@ -143,7 +104,7 @@ socket.on("connected", ({ id, name, email }) => { } users.push({ name, id, email, color: colors[0] }); - addusertolist({ name, id, email, color: colors[0] }); + addUserToList({ name, id, email, color: colors[0] }); colors = colors.splice(1); scrollSmoothToBottom("main"); @@ -151,38 +112,35 @@ socket.on("connected", ({ id, name, email }) => { // Received from server when someone gets disconnected socket.on("disconnected", (id) => { - let current_user = users.filter((user) => user.id === id); - colors.push(current_user[0].color); + let currentUser = users.filter((user) => user.id === id); + colors.push(currentUser[0].color); users = users.filter((user) => user.id != id); let item = document.createElement("li"); item.style.color = "black"; item.className = "connection p-2"; item.style.backgroundColor = "LightGray"; - item.textContent = current_user[0].name + " has disconnected"; + item.textContent = currentUser[0].name + " has disconnected"; messages.appendChild(item); scrollSmoothToBottom("main"); - removeuserfromlist(id); + removeUserFromList(id); feedback.innerHTML = ""; }); // Recieved from a server when a chat message is received socket.on("chat message", (user, msg, time, toUser) => { - console.log(user, msg, time, toUser); let item = document.createElement("li"); item.className = user.id + " clearfix position-relative"; - let current_user = users.filter((_user_) => _user_.id === user.id); + let currentUser = users.filter((_user_) => _user_.id === user.id); if (selfId === user.id) { item.innerHTML = `
${ user.name }
${md.render( msg )}
${time} `; - // item.classList.add('self') } else { - // item.style.color = current_user[0].color item.innerHTML = `
${ user.name }
${md.render( @@ -190,35 +148,29 @@ socket.on("chat message", (user, msg, time, toUser) => { )}
${time} `; } - // if (toUser !== "null") item.innerHTML = `${user.name} toUser: ${toUser.name}  ${time} ` + `
${md.render(msg)}
`; - // else item.innerHTML = `${user.name}  ${time} ` + `
${md.render(msg)}
`; - // item.innerHTML = `${ user.name }: ` + `
${msg}
`; - // item.classList.add('messages') messages.appendChild(item); scrollSmoothToBottom("main"); if (user.id !== selfId) feedback.innerHTML = ""; - // check if someone has set their name - users.forEach((saved_user) => { - if (saved_user.id === user.id) { - saved_user.name = user.name; + // Check if someone has set their name + users.forEach((savedUser) => { + if (savedUser.id === user.id) { + savedUser.name = user.name; let item = document.getElementById(user.id); item.innerHTML = `
${user.name}
`; } }); }); + +// Fetch messages after logging in socket.on("output", ({ result, useremail }) => { - console.log(result); if (result.length) { - for (var x = 0; x < result.length; x++) { + for (let x = 0; x < result.length; x++) { let item = document.createElement("li"); item.className = "clearfix position-relative"; - // item.innerHTML = `${result[x].name}  ${result[x].time} ` + `
${md.render(result[x].message)}
`; - if (result[x].email == useremail) { - // item.classList.add("useridentified"); item.innerHTML = `
${ result[x].name }
${md.render( @@ -227,7 +179,6 @@ socket.on("output", ({ result, useremail }) => { result[x].time } `; } else { - // item.classList.add('messages'); item.innerHTML = `
${ result[x].name }
${md.render( @@ -241,9 +192,11 @@ socket.on("output", ({ result, useremail }) => { } scroll("main"); }); + +// Scroll to bottom function scroll(id) { - var div = document.getElementById(id); - var scrollHeight = div.scrollHeight; + let div = document.getElementById(id); + let scrollHeight = div.scrollHeight; div.scroll({ top: scrollHeight + 10, }); @@ -255,67 +208,64 @@ input.addEventListener("keypress", () => { }); //Received from server when someone else is typing -let fbTimer; socket.on("typing", (user) => { + let fbTimer; clearTimeout(fbTimer); feedback.innerHTML = user + " is typing..."; fbTimer = setTimeout(() => { feedback.innerHTML = ""; }, 2000); }); -// Recieved from a server when an image file is received + +// Recieved from server when an image file is received socket.on("base64_file", (data, time) => { - var listitem = document.createElement("li"); - listitem.className = "clearfix position-relative"; - var curr_user_img = users.filter((_user_) => _user_.id === data.id); + let listItem = document.createElement("li"); + listItem.className = "clearfix position-relative"; + let currUserImg = users.filter((_user_) => _user_.id === data.id); if (selfId === data.id) { - listitem.innerHTML = `
${data.username} 
${time} `; - input_file.value = ""; + listItem.innerHTML = `
${data.username} 
${time} `; + inputFile.value = ""; } else { - listitem.innerHTML = `
${data.username} 
${time} `; + listItem.innerHTML = `
${data.username} 
${time} `; } - //listitem.classList.add('messages') - messages.appendChild(listitem); + messages.appendChild(listItem); if (data.id !== selfId) feedback.innerHTML = ""; scrollSmoothToBottom("main"); }); -// Remove use from collapsible -let removeuserfromlist = (userid) => { - let item = document.getElementById(userid); +// Remove user from collapsible +let removeUserFromList = (userId) => { + let item = document.getElementById(userId); if (item != null) item.remove(); }; -// Auto scroll to bottom when messages come +// Smooth scroll to bottom function scrollSmoothToBottom(id) { - var div = document.getElementById(id); - var scrollHeight = div.scrollHeight; + let div = document.getElementById(id); + let scrollHeight = div.scrollHeight; div.scroll({ top: scrollHeight + 10, behavior: "smooth", }); } +// Mention user function handleOnlineClick(id) { - let current_user = users.filter((user) => user.id === id); - input.value = `@${current_user[0].name}`; + let currentUser = users.filter((user) => user.id === id); + input.value = `@${currentUser[0].name}`; } -// search box JS -const searchBar = forms["search-messages"].querySelector("input"); - -document - .getElementById("search-messages") - .addEventListener("submit", function (event) { +// Search for a phrase in messages +searchBar.addEventListener("submit", function (event) { event.preventDefault(); }); -searchBar.addEventListener("keyup", (e) => { +searchBarInput.addEventListener("keyup", (e) => { e.preventDefault(); const term = e.target.value.toLowerCase(); - const messageList = list.getElementsByClassName("ls-msg"); + const messageList = messages.getElementsByClassName("ls-msg"); Array.from(messageList).forEach((msgList) => { const title = msgList.textContent; if (title.toLowerCase().indexOf(e.target.value) !== -1) { @@ -325,14 +275,17 @@ searchBar.addEventListener("keyup", (e) => { } }); }); + +// Animate send button when clicking sendBtn.addEventListener("mousedown", () => { - if (input.value || input_file.value) { + if (input.value || inputFile.value) { sendBtn.innerHTML = 'Sent  '; sendBtn.style.backgroundColor = "#38b000"; } }); +// Animate send button after clicking sendBtn.addEventListener("mouseup", () => { setTimeout(() => { sendBtn.innerHTML = 'Send '; @@ -340,6 +293,7 @@ sendBtn.addEventListener("mouseup", () => { }, 400); }); +// Animate send button after pressing enter key input.addEventListener("keyup", function (event) { if (event.key === "Enter") { sendBtn.click(); @@ -350,11 +304,12 @@ input.addEventListener("keyup", function (event) { } }); -function readThensend() { +// Sent to server when an image file is uploaded +function readThenSend() { const data = document.querySelector("input[type=file]").files[0]; const reader = new FileReader(); reader.onload = function (evt) { - var msg = {}; + let msg = {}; msg.username = socket.name; msg.file = evt.target.result; msg.fileName = data.fileName; @@ -362,31 +317,35 @@ function readThensend() { }; reader.readAsDataURL(data); } -function sendposition(position) { - var centerCoordinates = new google.maps.LatLng(37.6, -95.665); - var defaultOptions = { center: centerCoordinates, zoom: 4 }; - var mapLayer = document.createElement("div"); - var map = new google.maps.Map(mapLayer, defaultOptions); - var currentLatitude = position.coords.latitude; - var currentLongitude = position.coords.longitude; +// Sent to server current location +function sendPosition(position) { + let centerCoordinates = new google.maps.LatLng(37.6, -95.665); + let defaultOptions = { center: centerCoordinates, zoom: 4 }; + let mapLayer = document.createElement("div"); + + let map = new google.maps.Map(mapLayer, defaultOptions); + let currentLatitude = position.coords.latitude; + let currentLongitude = position.coords.longitude; - var infoWindowHTML = + let infoWindowHTML = "Latitude: " + currentLatitude + "
Longitude: " + currentLongitude; - var infoWindow = new google.maps.InfoWindow({ + let infoWindow = new google.maps.InfoWindow({ map: map, content: infoWindowHTML, }); - var currentLocation = { lat: currentLatitude, lng: currentLongitude }; + let currentLocation = { lat: currentLatitude, lng: currentLongitude }; infoWindow.setPosition(currentLocation); socket.emit("location_Send", infoWindow); } -function send_location() { + +function sendLocation() { if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition(sendposition); + navigator.geolocation.getCurrentPosition(sendPosition); } } +// Get current time function getTime() { let date = new Date(); let hours = date.getHours(); @@ -397,4 +356,4 @@ function getTime() { minutes = minutes < 10 ? "0" + minutes : minutes; let strTime = hours + ":" + minutes + " " + meridian; return strTime; -} +} \ No newline at end of file diff --git a/views/fpassword.html b/views/fpassword.html index 961615f..6a50153 100644 --- a/views/fpassword.html +++ b/views/fpassword.html @@ -2,18 +2,18 @@ - - - - - - + + + + + + Reset Password
- +

CHATAPP

@@ -26,68 +26,66 @@

Forgot Your Password?

+ >
+ >
+ >
+ >
-
+
- + \ No newline at end of file diff --git a/views/index.html b/views/index.html index c09465d..5dd2eac 100644 --- a/views/index.html +++ b/views/index.html @@ -5,75 +5,67 @@ ChatApp - + - + - -
-
-
-
-
-
-
-
+
+
+
+
+
+
- chatapp-logo -

CHAT APP

-
-

,

+
+
+ chatapp-logo +

CHAT APP

+
+

,

+
+
+
+ +
+ +
+
+
+
Online
+
    +
    -
    -
    - -
    - -
    -
    -
    -
    Online
    -
      -
    -
    -
    - LOG OUT -
    -
    -
    -
      -
    -
    -
    -
    -
    - -
    + LOG OUT +
    +
    +
    +
      +
      +
      +
      + + +
      - +
      - -
      -
      -
      -
      -
      -
      + +
      +
      +
      +
      +
      - - +
      + + diff --git a/views/login.html b/views/login.html index c09229c..62d5db5 100644 --- a/views/login.html +++ b/views/login.html @@ -2,18 +2,18 @@ - - - - - - + + + + + + Login
      - +

      CHATAPP

      @@ -28,11 +28,11 @@

      Login

      type="email" class="form-control" id="exampleInputEmail1" - aria-describedby="emailHelp" + aria-describedby="exampleInputEmail1" name="email" placeholder="Enter your Email" required - /> + >
      @@ -44,7 +44,7 @@

      Login

      name="password" placeholder="Enter your password" required - /> + >
      @@ -54,7 +54,6 @@

      Login

      Do not have an account? -
      @@ -67,14 +66,14 @@

      Login

      crossorigin="anonymous" > - + \ No newline at end of file diff --git a/views/signup.html b/views/signup.html index a479244..193498b 100644 --- a/views/signup.html +++ b/views/signup.html @@ -2,18 +2,18 @@ - - - - - - + + + + + + Signup
      - +

      CHATAPP

      @@ -26,53 +26,52 @@

      Register

      + >
      + >
      + >
      -
      +
      @@ -83,31 +82,35 @@

      Register

      - + \ No newline at end of file