First Commit

This commit is contained in:
yuvraj0028
2024-01-04 20:11:35 +05:30
commit 7a876d2d84
13 changed files with 3054 additions and 0 deletions

68
public/chat.html Normal file
View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat App</title>
<link rel="icon" href="./img/favicon.png">
<link rel="stylesheet" href="./css/styles.css">
</head>
<body>
<div class="chat">
<div id="sidebar" class="chat__sidebar">
</div>
<div class="chat__main">
<div id="messages" class="chat__messages"></div>
<div class="compose">
<!-- <button id="increment">+1</button> -->
<form id="message-form">
<input type="text" name="message" placeholder="Enter message" autocomplete="off">
<button type="submit">Send</button>
</form>
<button id="send-location">Send Location</button>
</div>
</div>
</div>
<script id="message-template" type="text/html">
<div class="message">
<p>
<span class="message__name">{{username}}</span>
<span class="message__meta">{{createdAt}}</span>
</p>
<p>{{message}}</p>
</div>
</script>
<script id="locmessage-template" type="text/html">
<div class="message">
<p>
<span class="message__name">{{username}}</span>
<span class="message__meta">{{createdAt}}</span>
</p>
<p><a href="{{url}}" target="_blank" style="color: #7C5CBF;">My Current Location</a></p>
</div>
</script>
<script id="sidebar-template" type="text/html">
<h2 class="room-title" >Room: {{room}}</h2>
<h3 class="list-title" >Users</h3>
<ul class="users" >
{{#users}}
<li> {{username}} </li>
{{/users}}
</ul>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.6.0/qs.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="./js/chat.js"></script>
</body>
</html>

BIN
public/css/.DS_Store vendored Normal file

Binary file not shown.

183
public/css/styles.css Normal file
View File

@@ -0,0 +1,183 @@
/* General Styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
}
input {
font-size: 14px;
}
body {
line-height: 1.4;
color: #333333;
font-family: Helvetica, Arial, sans-serif;
}
h1 {
margin-bottom: 16px;
}
label {
display: block;
font-size: 14px;
margin-bottom: 8px;
color: #777;
}
input {
border: 1px solid #eeeeee;
padding: 12px;
outline: none;
}
button {
cursor: pointer;
padding: 12px;
background: #7C5CBF;
border: none;
color: white;
font-size: 16px;
transition: background .3s ease;
}
button:hover {
background: #6b47b8;
}
button:disabled {
cursor: default;
background: #7c5cbf94;
}
/* Join Page Styles */
.centered-form {
background: #333744;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.centered-form__box {
box-shadow: 0px 0px 17px 1px #1D1F26;
background: #F7F7FA;
padding: 24px;
width: 250px;
}
.centered-form button {
width: 100%;
}
.centered-form input {
margin-bottom: 16px;
width: 100%;
}
/* Chat Page Layout */
.chat {
display: flex;
}
.chat__sidebar {
height: 100vh;
color: white;
background: #333744;
width: 225px;
overflow-y: scroll
}
/* Chat styles */
.chat__main {
flex-grow: 1;
display: flex;
flex-direction: column;
max-height: 100vh;
}
.chat__messages {
flex-grow: 1;
padding: 24px 24px 0 24px;
overflow-y: scroll;
}
/* Message Styles */
.message {
margin-bottom: 16px;
}
.message__name {
font-weight: 600;
font-size: 14px;
margin-right: 8px;
}
.message__meta {
color: #777;
font-size: 14px;
}
.message a {
color: #0070CC;
}
/* Message Composition Styles */
.compose {
display: flex;
flex-shrink: 0;
margin-top: 16px;
padding: 24px;
}
.compose form {
display: flex;
flex-grow: 1;
margin-right: 16px;
}
.compose input {
border: 1px solid #eeeeee;
width: 100%;
padding: 12px;
margin: 0 16px 0 0;
flex-grow: 1;
}
.compose button {
font-size: 14px;
}
/* Chat Sidebar Styles */
.room-title {
font-weight: 400;
font-size: 22px;
background: #2c2f3a;
padding: 24px;
}
.list-title {
font-weight: 500;
font-size: 18px;
margin-bottom: 4px;
padding: 12px 24px 0 24px;
}
.users {
list-style-type: none;
font-weight: 300;
padding: 12px 24px 0 24px;
}

169
public/css/styles.min.css vendored Normal file
View File

@@ -0,0 +1,169 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box
}
html {
font-size: 16px
}
input {
font-size: 14px
}
body {
line-height: 1.4;
color: #333;
font-family: Helvetica, Arial, sans-serif
}
h1 {
margin-bottom: 16px
}
label {
display: block;
font-size: 14px;
margin-bottom: 8px;
color: #777
}
input {
border: 1px solid #eee;
padding: 12px;
outline: none
}
button {
cursor: pointer;
padding: 12px;
background: #7C5CBF;
border: none;
color: #fff;
font-size: 16px;
transition: background .3s ease
}
button:hover {
background: #6b47b8
}
button:disabled {
cursor: default;
background: #7c5cbf94
}
.centered-form {
background: #333744;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center
}
.centered-form__box {
box-shadow: 0 0 17px 1px #1D1F26;
background: #F7F7FA;
padding: 24px;
width: 250px
}
.centered-form button {
width: 100%
}
.centered-form input {
margin-bottom: 16px;
width: 100%
}
.chat {
display: flex
}
.chat__sidebar {
height: 100vh;
color: #fff;
background: #333744;
width: 225px;
overflow-y: scroll
}
.chat__main {
flex-grow: 1;
display: flex;
flex-direction: column;
max-height: 100vh
}
.chat__messages {
flex-grow: 1;
padding: 24px 24px 0;
overflow-y: scroll
}
.message {
margin-bottom: 16px
}
.message__name {
font-weight: 600;
font-size: 14px;
margin-right: 8px
}
.message__meta {
color: #777;
font-size: 14px
}
.message a {
color: #0070CC
}
.compose {
display: flex;
flex-shrink: 0;
margin-top: 16px;
padding: 24px
}
.compose form {
display: flex;
flex-grow: 1;
margin-right: 16px
}
.compose input {
border: 1px solid #eee;
width: 100%;
padding: 12px;
margin: 0 16px 0 0;
flex-grow: 1
}
.compose button {
font-size: 14px
}
.room-title {
font-weight: 400;
font-size: 22px;
background: #2c2f3a;
padding: 24px
}
.list-title {
font-weight: 500;
font-size: 18px;
margin-bottom: 4px;
padding: 12px 24px 0
}
.users {
list-style-type: none;
font-weight: 300;
padding: 12px 24px 0
}

BIN
public/img/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

28
public/index.html Normal file
View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat App</title>
<link rel="icon" href="./img/favicon.png">
<link rel="stylesheet" href="./css/styles.css">
</head>
<body>
<div class="centered-form">
<div class="centered-form__box">
<h1>Join</h1>
<form action="./chat.html">
<label>Display Name</label>
<input type="text" name="username" required>
<label>Room</label>
<input type="text" name="room" required>
<button>Join</button>
</form>
</div>
</div>
</body>
</html>

149
public/js/chat.js Normal file
View File

@@ -0,0 +1,149 @@
const socket = io();
// Elements
const $messageForm = document.querySelector("#message-form");
const $messageFormInput = $messageForm.querySelector("input");
const $messageFormButton = $messageForm.querySelector("button");
const $sendLocationButton = document.querySelector("#send-location");
const $messages = document.querySelector("#messages");
// Templates
const messageTemplate = document.querySelector("#message-template").innerHTML;
const locationTemplate = document.querySelector(
"#locmessage-template"
).innerHTML;
const sidebarTemplate = document.querySelector("#sidebar-template").innerHTML;
// Options
const { username, room } = Qs.parse(location.search, {
ignoreQueryPrefix: true,
});
const autoScroll = () => {
// New message element
const $newMessage = $messages.lastElementChild;
// hight of the new message
const newMessageStyle = getComputedStyle($newMessage);
const newMessageMargin = parseInt(newMessageStyle.marginBottom);
const newMessageHeight = $newMessage.offsetHeight + newMessageMargin;
// visible height
const visibleHeight = $messages.offsetHeight;
// height of messages container
const containerHeight = $messages.scrollHeight;
// how far have I scrolled?
const scrollOffset = $messages.scrollTop + visibleHeight;
if (containerHeight - newMessageHeight <= scrollOffset) {
$messages.scrollTop = $messages.scrollHeight;
}
};
// server (emit) -> client (receive) - countUpdated
// client (emit) -> server (receive) - increment
socket.on("message", (message) => {
// console.log(message);
const html = Mustache.render(messageTemplate, {
username: message.username,
message: message.text,
createdAt: moment(message.createdAt).format("h:mm a"),
});
$messages.insertAdjacentHTML("beforeend", html);
autoScroll();
});
socket.on("locationMessage", (url) => {
// console.log(url.username);
const html = Mustache.render(locationTemplate, {
username: url.username,
url: url.url,
createdAt: moment(url.createdAt).format("h:mm a"),
});
$messages.insertAdjacentHTML("beforeend", html);
autoScroll();
});
socket.on("roomData", ({ room, users }) => {
const html = Mustache.render(sidebarTemplate, {
room: room,
users: users,
});
document.querySelector("#sidebar").innerHTML = html;
});
$messageForm.addEventListener("submit", (e) => {
e.preventDefault();
// disable form after submit
$messageFormButton.setAttribute("disabled", "disabled");
//disable
const message = $messageFormInput.value;
if (message === "") {
// enable form after submit
$messageFormButton.removeAttribute("disabled");
return;
}
socket.emit("sendMessage", message, (error) => {
// enable form after submit
$messageFormButton.removeAttribute("disabled");
// clear input
$messageFormInput.value = "";
// focus input
$messageFormInput.focus();
if (error) {
return console.log(error);
}
// console.log("Message Delivered");
});
});
document.querySelector("#send-location").addEventListener("click", (e) => {
e.preventDefault();
if (!navigator.geolocation) {
return alert("Geolocation is not supported by your browser");
}
navigator.permissions.query({ name: "geolocation" }).then((res) => {
// console.log(res);
if (res.state === "denied") {
return alert("Please allow permission to send location!");
}
});
navigator.geolocation.getCurrentPosition((position) => {
// console.log(position);
$sendLocationButton.setAttribute("disabled", "disabled");
socket.emit(
"sendLocation",
{
Latitude: position.coords.latitude,
Longitude: position.coords.longitude,
},
() => {
$sendLocationButton.removeAttribute("disabled");
// console.log("Location Shared");
}
);
});
});
socket.emit("join", { username, room }, (error) => {
if (error) {
alert(error);
location.href = "/";
}
});
// document.querySelector("#increment").addEventListener("click", (e) => {
// console.log("clicked");
// socket.emit("increment");
// });