Socket.io stops emitting when any of the window is minimized - javascript

I'm trying to build a simple real time text editor that can be accessed and edited by a couple of collaborators at the very same time (not using any lock properties for now). It all works well, transmits live data - until I minimize any of the window (basically using two chrome windows to see the results) and socket stops emitting data.
Here are the server and client -
Server
const express = require("express");
const app = express();
const server = require("http").createServer(app);
const io = require("socket.io").listen(server);
users = [];
connections = [];
server.listen(4000);
console.log("server running");
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
io.sockets.on("connection", socket => {
//Connect
connections.push(socket);
console.log("connected: ", connections.length);
//Disconnect
socket.on("disconnect", data => {
connections.splice(connections.indexOf(socket), 1);
console.log("disconnected! left: ", connections.length);
});
//Send Message
socket.on('send message', data => {
console.log(data);
io.sockets.emit('new message', {msg: data});
});
});
Client
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Chat</title>
<link
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container">
<div class="msgArea" id="msgArea">
<div class="row">
<div class="col-md-4">
<div>
<h3>RealTime Editor</h3>
<ul class="list-groups" id="users"></ul>
</div>
</div>
<div class="col-md-8">
<div class="chat" id="chat"></div>
<form action="" id="msg-form">
<div class="form-group">
<label for="">Enter below</label>
<textarea name="" id="msg" rows="15" class="form-control"></textarea>
<br />
</div>
</form>
</div>
</div>
</div>
</div>
</body>
<script src="/socket.io/socket.io.js"></script>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"
></script>
<script>
$(document).ready(() => {
console.log("connect");
const socket = io.connect();
let $msg = $("#msg");
socket.on("new message", data => {
// $chat.append('<div class="well">' + data.msg + "</div>");
$('#msg').text(data.msg);
});
$("#msg").on("change keyup paste", function() {
socket.emit("send message", $msg.val());
});
});
</script>
</html>

Related

My contact form does not work when I deploy my website using firebase but it does when I use local host. My first website so don't know what to do

I followed a video tutorial that told me how to do this using nodemailer. It works perfectly fine when I use "npm run dev" to run it on localhost but after I deployed my website using firebase the alert that tells me in app.js that something went wrong shows up which means that the email has not been sent and I have also checked to see that it hasn't
code in app.js
const contactForm = document.querySelector('.contact-form');
let name = document.getElementById('name');
let email = document.getElementById('email');
let message = document.getElementById('message');
contactForm.addEventListener('submit', (e)=>{
e.preventDefault();
let formData = {
name: name.value,
email: email.value,
message: message.value
}
let xhr = new XMLHttpRequest();
xhr.open('POST', '/');
xhr.setRequestHeader('content-type', 'application/json');
xhr.onload = function(){
console.log(xhr.responseText);
if(xhr.responseText == 'success') {
alert('Email sent');
name.value = '';
email.value = '';
message.value = '';
}else{
alert('something went wrong');
}
}
xhr.send(JSON.stringify(formData));
})
code in server.js
const express = require('express');
const app = express();
const nodemailer = require("nodemailer");
const PORT = process.env.PORT || 2500;
//Middleware
app.use(express.static('webFiles'));
app.use(express.json())
app.get('/', (req, res)=>{
res.sendFile(__dirname + '/webFiles/Contact.html');
})
app.post('/', (req,res)=>{
console.log(req.body);
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'myEmail', -- had to hide these
pass: 'myEmailsPassword'
}
});
const mailOptions = {
from: req.body.email,
to: 'myEmail', -- sorry have to hide this again
subject: `Message from ${req.body.email}`,
text: req.body.message
};
transporter.sendMail(mailOptions, (error, info)=>{
if(error) {
console.log(error);
res.send('error');
}else{
console.log('Email sent: ' + info.response);
res.send('success');
}
});
})
app.listen(PORT, ()=>{
console.log(`Server running on port ${PORT}`);
})
Code in html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="referrer" content="origin">
<link href="https://fonts.googleapis.com/css2?family=Yanone+Kaffeesatz:wght#300&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/all.min.css">
<link rel="stylesheet" href="css/style.css">
<title>Contact Me</title>
</head>
<body>
<div class="loader_bg">
<div class="loader"></div>
</div>
<section class="wrapper">
<div id="stars"></div>
<div id="stars2"></div>
<div id="stars3"></div>
</section>
<div class="container">
<nav>
<h1 class="title">Ajaypartap ;<span> D</span></h1>
<ul>
<li>About Me</li>
<li>Projects</li>
<li>Skills</li>
<li>Contact Me</li>
</ul>
</nav>
</div>
<form id="contact-form" class="contact-form">
<div class="title">
<h2>CONTACT</h2>
</div>
<div class="half">
<div class="item">
<label for="name">NAME</label>
<input type="text" id="name" required="required">
</div>
<div class="item">
<label for="email">EMAIL</label>
<input type="email" id="email" required="required">
</div>
</div>
<div class="full">
<label for="message">MESSAGE</label>
<textarea id="message" required="required"></textarea>
</div>
<div class="action">
<input type="submit" class="submit" value="Send">
<input type="reset" value="Reset">
</div>
<div class="icons">
</div>
</form>
<script src="js/app.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
setTimeout(function(){
$('.loader_bg').fadeOut();
}, 2000);
</script>
</body>
</html>
code directory

redirect to another page not working (Node.js)

I'm building a register form in nodejs. Once I save the user to a database and i try to redirect to another html page I get an error "SyntaxError: Unexpected token < in JSON at position 0". Could anyone help me out with it.If i console.log the user it appears, but if i try to redirect it doesn't work I make use of a express router to to route my requests.
Here is my code
const express = require("express");
const app = express();
const router = express.Router();
const path = require("path");
const bcrypt = require("bcryptjs");
const { registerValidation } = require("../models/validation");
const User = require("../models/user");
var appDir = path.dirname(require.main.filename);
app.use(express.static(path.join(__dirname, "public")));
router.get("/", (req, res) => {
res.sendFile(appDir + "/public/index.html");
});
router.get("/homepage", (req, res) => {
res.sendFile(appDir + "/public/homepage.html");
});
router.get("/register", (req, res) => {
res.sendFile(appDir + "/public/register.html");
});
router.post("/register", async (req, res) => {
const { error } = await registerValidation.validate(req.body);
if (error) return res.status(400).send(error);
let emailExist = await User.findOne({ email: req.body.email });
if (emailExist) {
return res.status(400).send({ message: "Email already exists" });
}
let salt = await bcrypt.genSalt(10);
let hashedPassword = await bcrypt.hash(req.body.password, salt);
let newUser = new User({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: hashedPassword,
});
try {
let savedUser = await newUser.save();
res.redirect("/homepage");
} catch (err) {
return res.status(400).send(err);
}
});
module.exports = router;
Home page Router
router.get("/homepage", (req, res) => {
res.sendFile(appDir + "/public/homepage.html");
});
homepage.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<p>This is homepage</p>
</body>
</html>
Register Page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Roboto&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="./css/register.css" />
<title>Register</title>
</head>
<body>
<section>
<div class="register-container">
<header class="header-text">
Register today to become a movie nerd!!
<hr />
</header>
<form method="POST" name="register-form" id="register-form">
<div class="register-form">
<div class="name-field">
<div class="name-input-container">
<input
type="text"
name="firstName"
class="form-input"
id="firstName"
value="Kevin"
required
placeholder="First Name "
/>
</div>
<div class="name-input-container">
<input
type="text"
name="lastName"
class="form-input"
id="lastName"
placeholder="Last Name "
required
value="Rodrigues"
/>
</div>
</div>
<div class="email-input-container">
<input
type="email"
name="email"
class="form-input"
id="email"
placeholder="Email "
value="kevinrodrigues43#gmail.com"
required
/>
</div>
<div class="password-field">
<div class="password-input-container">
<input
type="password"
name="password"
class="form-input"
id="password"
value="Kevinr78"
required
placeholder="Passsword "
/>
</div>
<div class="name-input-container">
<input
type="password"
name="confirmPassword"
class="form-input"
id="C_password"
placeholder="Confirm Password "
value="Kevinr78"
required
/>
</div>
</div>
<div class="error">
<p id="error"></p>
</div>
<div class="register-button">
<button type="button" id="register-button">Register</button>
</div>
</div>
</form>
</div>
</section>
<script>
document
.getElementById("register-button")
.addEventListener("click", async (e) => {
let formData = validation(e);
let response = await fetch("http://localhost:3000/register", {
method: "POST",
body: JSON.stringify(formData),
headers: {
"Content-type": "application/json;charset=UTF-8",
},
})
.then((data) => {
return data.json();
})
.then((data) => {
console.log(data);
const { message } = data;
document.getElementById("error").innerHTML = message;
})
.catch((err) => {
document.getElementById("error").innerHTML = err;
});
});
function validation(e) {
let email = document.getElementById("email").value;
let lastName = document.getElementById("lastName").value;
let firstName = document.getElementById("firstName").value;
let password = document.getElementById("password").value;
let confirmPassword = document.getElementById("C_password").value;
let emailRegex = "^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+$";
let error = "";
if (
firstName == "" ||
lastName == "" ||
password == "" ||
confirmPassword == "" ||
email == ""
) {
error += "<p>PLease fill all the fields</p>";
}
if (firstName.length < 2 || lastName.length < 2) {
error += "<p>Length of name field is minimum 2 characters</p>";
}
/* if (password != confirmPassword) {
error += "<p>Password Don't match</p>";
} */
if (!email.match(emailRegex)) {
error += "<p>Invalid Email</p>";
}
if (error == "") {
return { lastName, password, firstName, email, confirmPassword };
} else {
document.getElementById("error").innerHTML = error;
}
}
</script>
</body>
</html>
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
crossorigin="anonymous"
/>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Roboto&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="./css/index.css" />
<title>Movies Bay</title>
</head>
<body>
<section>
<nav class="nav-container">
<div class="brand-name">
<h3 href="#">Movies Bay</h3>
</div>
<div class="nav-items">
<div class="nav-item">
Login
</div>
<div class="nav-item">
Register
</div>
</div>
</nav>
<div class="main-content">
<h2 id="intro-text"></h2>
<br />
<h4>Your one stop destination for movies</h4>
</div>
<footer>
<p class="text-1">Made By Kevin Rodrigues</p>
<p class="text-2">© 2020-2021</p>
</footer>
</section>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4"
crossorigin="anonymous"
></script>
<script>
function printLetterByLetter(destination, message, speed) {
let element = document.getElementById(destination);
element.style.fontSize = "4.5em";
var i = 0;
var interval = setInterval(function () {
element.innerHTML += message.charAt(i);
i++;
if (i > message.length) {
clearInterval(interval);
}
}, speed);
}
printLetterByLetter("intro-text", "Welcome to Movies bay", 100);
</script>
</body>
</html>

How do I stop Socket.io spaming connections?

I am making a socket.io chat app. When I either start the server or make the first connection it spams the callback. The callback does not stop until the server is stopped. I think the error is coming from the html file, but I'm not exactly sure. Thank you for your time.
IO callback:
io.sockets.on('connection', (socket) =>{
connections.push('socket')
console.log('Connection made \n ' + connections.length + ' made')
socket.on('disconnect', function(data){
connections.splice(connections.indexOf(socket), 1)
console.log('Disconnected: %s sockets left', connections.length)
})
})
My HTML file:
<!DOCTYPE html>
<html>
<head>
<title>Chat App</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<style>
body{
margin: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="well">
<h3>Online Users</h3>
<ul class="list-group" id="users"></ul>
</div>
</div>
<div class="col-md-8">
<div class="chat" id="chat"></div>
<form id="messageForm">
<div class="form-group">
<label>Enter Message</label>
<textarea id="message" class="form-control"></textarea>
<br>
<input type="submit" class="btn btn-primary" value="Send">
</div>
</form>
</div>
</div>
</div>
<script>
var socket = io()
</script>
</body>
</html>
The problem is on line 2. You are pushing string i.e 'socket' to connections. 'socket' doesnot refer to the socket variable in the argument. You need to push socket not 'socket' because its just combinations of letters not variable
io.sockets.on('connection', (socket) =>{
connections.push(socket) // this line is changed
console.log('Connection made \n ' + connections.length + ' made')
socket.on('disconnect', function(data){
connections.splice(connections.indexOf(socket), 1)
console.log('Disconnected: %s sockets left', connections.length)
})
})

Button won't execute Javascript no matter what I do

The following code below is supposed to work as follows, the user is suppose to input a URL, Proxy IP & Proxy port once they click "test" it would grab the response code and replace the html h5 "awaiting test" with the new status code text. I made another version of this same exact script and it worked via client but when you run via electron app and click test button all you get is an error how do I get the button "test" to execute the script? Any help would be greatly appreciated.
Index HTML
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Simple Tester</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.3/semantic.min.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.3/semantic.min.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 id="header">Simple Tester v1.00</h1>
<div class="content">
<div class="proxytesturls">
<h3 id="url" style="color:#4a04de;" >Site URL:</h3>
<div class="ui large input">
<input type="text" placeholder="Google.com" id="siteurltext">
</div>
</div>
<div class="proxyip">
<h3 id="ip" style="color:#4a04de;">Proxy IP:</h3>
<div class="ui large input" id="proxyinput">
<input type="text" placeholder="1.1.1.1" id="proxyipinput">
</div>
</div>
<div class="proxyport">
<h3 id="port" style="color:#4a04de;">Proxy Port:</h3>
<div class="ui large input">
<input type="text" placeholder="8080" id="proxyportinput">
</div>
</div>
<input type="button" id="btnclick" value="test" onclick="pingProxy();">
<div class="ui raised segment" id="logger">
<h2 style="color:#4a04de;" id="logstext">Logger</h2>
<h5 id="awaitingtest">Awaiting test...</h5>
</div>
</div>
<script src="tester.js" type="text/javascript"></script>
</body>
</html>
tester.js
const request = require('request');
var pingProxy = require('ping-proxy');
var url = document.getElementById("siteurltext").value;
var proxyip = document.getElementById("proxyipinput").value;
var proxyport = document.getElementById("proxyportinput").value;
pingProxy({
proxyHost: proxyip,
proxyPort: proxyport,
proxyTestUrl: 'https://', url
},
function (err, options, statuscode) {
if (statuscode == 407) {
document.getElementById('awaitingtest').innerHTML = ('Status: Proxy Authentication Required');
}
if (statuscode == 200) {
document.getElementById('awaitingtest').innerHTML = ('Status: Valid Proxy!');
}
if (statuscode == 403) {
document.getElementById('awaitingtest').innerHTML = ('Status: Banned Proxy!');
}
if (statuscode == 401) {
document.getElementById('awaitingtest').innerHTML = ('Status: Unauthorized!');
}
}
);
Main.js
const electron = require('electron')
const {app, BrowserWindow} = require('electron')
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadFile('index.html')
}
app.on('ready', createWindow)
Errors:
Uncaught TypeError: callback is not a function
at pingProxyAsync (C:\Users***********\proxytester\node_modules\ping-proxy\ping-proxy.js:21)
at HTMLInputElement.onclick (index.html:37)
You may need to concatenate the proxyTestUrl. Replace the comma with a plus sign.
pingProxy({
proxyHost: proxyip,
proxyPort: proxyport,
proxyTestUrl: 'https://' + url
},

How to connect to a SignalR hub from PhoneGap app on iOS?

I am attempting to build a PhoneGap iOS client for a basic SignalR chat server I have running (ASP.NET MVC 4). Everything works great when accessing it from a page in a browser but I just can't seem to get it to connect from the PhoneGap app. Here's the relevant parts of my code:
Server global.asax
protected void Application_Start()
{
// Register the default hubs route: ~/signalr * This must be registered before any other routes
RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Server web.config
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"></modules>
</system.webServer>
</configuration>
Server hub
public class ChatHub : Hub
{
public void Send(string name, string message)
{
Clients.All.broadcastMessage(name, message);
}
}
PhoneGap client
<body>
<div data-role="page">
<div data-role="header">
<h1>Life As A Pixel</h1>
</div><!-- /header -->
<div data-role="content">
<label for="username">Name:</label>
<input type="text" name="username" id="username" value="" />
<label for="message">Message:</label>
<input type="text" name="message" id="message" value="" />
<br>
<input type="button" value="Send" id="sendmessage" />
</div><!-- /content -->
<div data-role="footer" data-position="fixed">
<h4></h4>
</div><!-- /footer -->
</div><!-- /page -->
<script type="text/javascript" src="cordova-2.7.0.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="js/jquery.mobile-1.3.1.js"></script>
<script type="text/javascript" src="js/jquery.signalR-1.0.0-rc1.min.js"></script>
<script type="text/javascript" src="http://www.mysite.com/signalr/hubs"></script>
<script type="text/javascript">
app.initialize();
</script>
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub
jQuery.support.cors = true;
$.connection.hub.url = 'http://www.mysite.com/signalr';
var chat = $.connection.chatHub;
alert(chat);
//alert(chat);
// Create a function that the hub can call to broadcast messages.
//chat.client.broadcastMessage = function (name, message) {
//$('#discussion').append('<li><strong>' + name
// + '</strong>: ' + message + '</li>');
//};
// Set initial focus to message input box.
//$('#message').focus();
// Start the connection.
$.connection.hub.start({ jsonp: true }).done(function () {
alert("connected");
$('#sendmessage').click(function () {
// Html encode display name and message.
var encodedName = $('<div />').text($('#username').val()).html();
var encodedMsg = $('<div />').text($('#message').val()).html();
// Call the Send method on the hub.
chat.send(encodedName, encodedMsg);
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
}).fail(function () {
alert("Failed to connect");
});
});
</script>
</body>
I've been through a ton of sites that talk about bits and pieces of it but can't get it figured out.
Thanks in advance,
Jason
I hope this helps. From here -> http://agilefromthegroundup.blogspot.com/2012/09/getting-signalr-and-phonegap-working.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Chat</title>
<link rel="stylesheet" href="jquery.mobile-1.0.1.css" />
<script type="text/javascript" src="jquery-1.7.1.js"></script>
<script type="text/javascript" src="jquery.mobile-1.0.1.js"></script>
<script type="text/javascript" src="http://jgough/SignalR/Scripts/jquery.signalR-0.5.3.js"></script>
<script type="text/javascript" src="http://jgough/SignalR/signalr/hubs"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.4.1.js"></script>
<style type="text/css">
.ui-title
{
font-weight: bold;
}
</style>
<script type="text/javascript">
$(function () {
$.connection.hub.url = "http://jgough/SignalR/signalr";
// Grab the hub by name, the same name as specified on the server
var chat = $.connection.chat;
chat.addMessage = function (message) {
$('#chatMessages').append('<li>' + message + '</li>');
};
$.connection.hub.start({ jsonp: true });
$("#sendChatMessage").click(function () {
var message = $("#chatMessage").val();
console.log("Message: " + message);
chat.send(message);
});
});
</script>
</head>
<body>
<div id="home" data-role="page">
<div data-role="header">
<h1>
Chat!</h1>
</div>
<div data-role="content">
<h2>
Chat your heart out...</h2>
<div>
<textarea id="chatMessage"></textarea>
<br />
<a id="sendChatMessage" data-role="button">Send Chat Message</a>
</div>
<ul id="chatMessages">
</ul>
</div>
<div data-role="footer" data-position="fixed">
Thank you for chatting
</div>
</div>
</body>
</html>

Categories