Skip to content

Instantly share code, notes, and snippets.

@ahmedtalaltwd7
Created July 1, 2022 22:58
Show Gist options
  • Save ahmedtalaltwd7/555a67b39b9c507e56a10a5eaa0164e1 to your computer and use it in GitHub Desktop.
Save ahmedtalaltwd7/555a67b39b9c507e56a10a5eaa0164e1 to your computer and use it in GitHub Desktop.
Chat Socket
<div class="background"></div>
<div id="messenger">
<div id="profile"></div>
<ul id="history"></ul>
<div id="users"></div>
<form id='emit'>
<div class="editor">
<textarea id="message"></textarea>
</div>
<button type='submit'>
<i class="fas fa-paper-plane"></i>
</button>
</form>
</div>
const socket = io('https://webclin-backend.herokuapp.com');
const language = navigator.language || navigator.userLanguage;
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const toggleFullScreen = () => {
var doc = window.document;
var docEl = doc.documentElement;
var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
if(!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
requestFullScreen.call(docEl);
}
else {
cancelFullScreen.call(doc);
}
}
document.getElementById("profile").addEventListener("click", () => toggleFullScreen());
const socketEmit = (data) => {
socket.emit('data', data);
};
const uuid = (() => {
let seed = Date.now();
if (window.performance && typeof window.performance.now === "function") {
seed += performance.now();
}
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (seed + Math.random() * 16) % 16 | 0;
seed = Math.floor(seed/16);
return (c === 'x' ? r : r & (0x3|0x8)).toString(16);
});
return uuid;
})();
let onlineUsers = [];
let myRandomName = {}
const createMyName = (() => {
let fakeNames = {};
const json = {
names: ["Alan Bedoura De Pinto","Alan Brado","Alan Bida do Rego","Alê Itada","Ana Konda","Armando Botelho Pinto","Armando Pinto","Aron Bado","Balan Sarrola","Beijamin Arrola","Botelho Kunavara","Botelho Pinto","Caio Pinto","Caio Rolando da Rocha","Crispin Tudo","Cuca Areka","Cuca Beludo","Dayde Costa","Davi Agra","Déssio Pinto","Diva Aginaberta","Dr. Castro Pinto","Elba Tiúma","Ema Conieira","Eva Dias","Eva Gabunda","H.Romeu Pinto","Henrique Cando","Isadora Bocchetti","Isadora Pinto","Jacinto Leite Aquino Rego","Jacinto Pinto","Jaem Rabei","Jalin Habey","Jamila Ambeiro Pinto","Julia Mello Pinto","Kelly Inguissa","Kemel Pinto","Kevin Mamar","Laís Correga Navara","Levi Adão","Licarco Ferro","Lucas Trado","Luma Madeira","Marco Zinho De Oliveira","Melbi Lau","Mia Regazza","Mila Ascaro","Mila Ambeiro","Mila Ambuza","Omar Telo","Oscar Aglio","Patricia De Paula Dentro","Paul Herguido","Paula Ambeno","Paula Ambido","Paula da Roça","Paula Dentro","Paula Nabussa","Paula Tejano","Patty Ingatar","Peri Kitho","Rolando Pinto","Sarah Pinto","Sávio Lado","Shana Berta","Sheila Meusako","Silas Cando","Simas Turbano","Sophie Zanall","Tais Condida","Tais Follando","Tasha Padona","Tati Komenno","Thais Melo Pinto","Thiago Zado","Tico Meria","Tim Habay","Tomas Turbano","Tommy Jado","Tommy Leite","Valemtim Terra","Vailin Rabar","Vanessa Fadinha","Vivara Grande","Yasmin Asbolla","Zeca Gado"]
};
fakeNames = json.names;
myRandomName = fakeNames[Math.floor(Math.random() * fakeNames.length)];
socketEmit({ id: uuid, event: 'enterInChat', name: myRandomName });
const profile = document.getElementById("profile");
const profileField = document.createElement("DIV");
profileField.setAttribute("id", uuid);
profileField.setAttribute("class", "name");
profileField.innerHTML = `<i class="far fa-user"></i> ${myRandomName}`;
profile.appendChild(profileField);
})();
let emoticonList = {};
const createEmoticonList = (() => {
emoticonList = {
"=)": "😀","=/": "😕","8)": "🙂","8(": "☹️","=p": "😜",";)": "😉","S2": "😍","8p": "🤪","=|": "😐","8|": "😲"
}
})();
const addPopover = (elementId, msg) => {
const el = document.getElementById(elementId);
const popover = document.createElement("DIV");
const popoverText = document.createElement("P");
const popoverArrow = document.createElement("DIV");
const popoverTextNode = document.createTextNode(msg);
popover.setAttribute("class", "popover");
popoverArrow.setAttribute("class", "arrow-left");
popoverText.appendChild(popoverTextNode);
popover.appendChild(popoverArrow);
popover.appendChild(popoverText);
el.appendChild(popover);
setTimeout(() => {
popover.remove();
}, 8000);
}
addPopover('messenger', 'Clique para deixar em tela cheia');
var converter = new showdown.Converter();
var simplemde = new SimpleMDE({
autofocus: true,
status: false,
autosave: {
enabled: true,
uniqueId: 'simplemde',
delay: 1000
},
placeholder: "Digite sua mensagem...",
hideIcons: ["fullscreen", "preview", "guide", "side-by-side"],
element: document.getElementById("message")
});
let whileWriting;
let sendBeginWriting = false;
simplemde.codemirror.on("change", () => {
if(!simplemde.value()) return;
if(!sendBeginWriting) {
socketEmit({ id: uuid, event: 'beginWriting', name: myRandomName });
sendBeginWriting = true;
}
if(whileWriting) {
clearTimeout(whileWriting);
whileWriting = null;
}
whileWriting = setTimeout(() => {
socketEmit({ id: uuid, event: 'endWriting', name: myRandomName });
sendBeginWriting = false;
}, 1000);
});
document.getElementById("emit").addEventListener("submit", (e) => {
e.preventDefault();
const message = document.getElementById("message").value;
if(!message) return;
socketEmit({ id: uuid, event: 'endWriting', name: myRandomName });
socketEmit({
id: uuid,
event: 'sendMessage',
name: myRandomName,
message: message,
timestamp: moment()
});
simplemde.value('');
});
socket.on('data', (data) => {
switch(data.event) {
case 'enterInChat':
enterInChat(data);
break;
case 'beginWriting':
beginWriting(data);
break;
case 'endWriting':
endWriting(data);
break;
case 'sendMessage':
sendMessage(data);
break;
case 'stillOnline':
stillOnline(data);
break;
}
});
const enterInChat = (data) => {
if(uuid === data.id) return;
const users = document.getElementById("users");
const userField = document.createElement("DIV");
userField.setAttribute("id", data.id);
userField.innerHTML = `<i class="far fa-user"></i> ${data.name}`;
users.appendChild(userField);
};
const beginWriting = (data) => {
if(uuid === data.id) return;
const history = document.getElementById("history");
const msg = document.createElement("LI");
const msgBox = document.createElement("DIV");
const msgUserInfo = document.createElement("DIV");
const msgTextUserInfo = document.createTextNode(`${data.name} está escrevendo...`);
msg.setAttribute("id", data.id);
msg.setAttribute("class", "writingMessage");
msgBox.setAttribute("class", "msgBox");
msgUserInfo.setAttribute("class", "msgUserInfo");
msgUserInfo.appendChild(msgTextUserInfo);
msgBox.appendChild(msgUserInfo);
msg.appendChild(msgBox);
history.appendChild(msg);
history.scrollTo(0,history.scrollHeight);
};
const endWriting = (data) => {
if(uuid === data.id) return;
const writingMessage = document.querySelectorAll(".writingMessage");
writingMessage.forEach((e, i) => {
if(data.id !== e.id) return;
e.parentNode.removeChild(e);
});
};
const sendMessage = (data) => {
const history = document.getElementById("history");
const msg = document.createElement("LI");
const msgBox = document.createElement("DIV");
const msgArrow = document.createElement("DIV");
const msgUserInfo = document.createElement("DIV");
const msgContent = document.createElement("DIV");
const msgDate = document.createElement("DIV");
const msgTextUserInfo = document.createTextNode(data.name);
const msgTextContent = document.createTextNode(data.message);
const msgTextDate = document.createTextNode(moment(data.timestamp).locale(language).tz(timezone).format('llll'));
msg.setAttribute("id", data.id);
uuid === data.id && msg.classList.add("myMsgBox");
uuid === data.id ? msgArrow.setAttribute("class", "arrow-right") : msgArrow.setAttribute("class", "arrow-left");
msgBox.setAttribute("class", "msgBox");
msgUserInfo.setAttribute("class", "msgUserInfo");
msgContent.setAttribute("class", "msgContent");
msgDate.setAttribute("class", "msgDate");
msgUserInfo.appendChild(msgTextUserInfo);
msgContent.appendChild(msgTextContent);
msgDate.appendChild(msgTextDate);
msgBox.appendChild(msgArrow);
msgBox.appendChild(msgUserInfo);
msgBox.appendChild(textToEmoticon(msgContent));
msgBox.appendChild(msgDate);
msg.appendChild(msgBox);
history.appendChild(msg);
history.scrollTo(0,history.scrollHeight);
};
const textToEmoticon = (msgText) => {
let msgTextContentWithEmoticons = msgText.innerHTML;
Object.entries(emoticonList).forEach(([key, value]) => {
msgTextContentWithEmoticons = msgTextContentWithEmoticons.split(String(key)).join(String(value));
});
msgText.innerHTML = converter.makeHtml(msgTextContentWithEmoticons);
return msgText;
}
const stillOnline = (data) => {
let checkUserInList = onlineUsers.filter((e) => e.id === data.id)
if(checkUserInList.length > 0) {
checkUserInList.map((e) => e.timestamp = data.timestamp);
} else {
onlineUsers.push(data);
}
};
setInterval(() => {
socketEmit({ id: uuid, name: myRandomName, event: 'stillOnline', timestamp: moment() });
let disconnectedUsers = onlineUsers.filter((e) => moment().diff(moment(e.timestamp), 'seconds') > 10);
disconnectedUsers.map((e) => {
const currentUsers = document.querySelectorAll('#users > div');
currentUsers.forEach((userField) => {
if(userField.id === e.id){
userField.remove();
}
});
onlineUsers.find((item, i) => {
if(item) {
if(item.id === e.id) {
socketEmit({ id: e.id, name: e.name, event: 'sendMessage', message: 'Acabou de sair...', timestamp: moment() });
}
onlineUsers.splice(i, 1);
}
});
});
onlineUsers.map((e) => {
const currentUsers = document.querySelectorAll('#users > div');
currentUsers.forEach((userField) => {
if(e.id !== uuid)
if(userField.id !== e.id) {
if(document.getElementById(e.id))
document.getElementById(e.id).setAttribute("class", "leavingState");
}
else {
document.getElementById(e.id).classList.remove("leavingState");
}
});
});
}, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.27/moment-timezone-with-data.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.1/showdown.min.js"></script>
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
* {
font-family: 'Roboto', sans-serif;
font-weight: normal;
}
::-webkit-scrollbar-track
{
background-color: transparent;
}
::-webkit-scrollbar
{
width: 5px;
height: 5px;
background-color: transparent;
}
::-webkit-scrollbar-thumb
{
background-color: #1d8dbf;
}
body {
background-color: #dedfe3;
overflow: hidden;
}
.popover {
position: absolute;
font-size: 11px;
width: auto;
max-width: 120px;
height: auto;
background: #FFF;
color: #444;
overflow-wrap: break-word;
right: 0;
line-height: 15px;
text-align: center;
padding: 10px 5px;
margin: 20px;
border-radius: 5px;
box-shadow: 0 5px 10px rgba(12, 53, 71,.2);
z-index: 999;
}
.popover p {
margin: 0;
padding: 0;
}
#messenger {
position: absolute;
width: 100%;
height: 100%;
background-color: #dedfe3;
overflow: auto;
z-index: 10;
}
#messenger > #profile {
position: absolute;
left: 0;
right: 0;
height: 80px;
text-align: center;
background: rgb(29,141,191);
background: linear-gradient(90deg, rgba(29,141,191,1) 0%, rgba(29,141,191,1) 35%, rgba(0,224,255,1) 100%);
cursor: pointer;
z-index: 1;
}
#messenger > #profile > .name {
position: relative;
display: inline-block;
height: 100%;
color: #FFF;
line-height: 60px;
padding: 0 20px;
}
#messenger > #profile > .name .far {
margin-right: 10px;
}
#messenger > ul {
position: absolute;
top: 60px;
left: 0;
right: 0;
background-color: #dedfe3;
bottom: 260px;
overflow-x: hidden;
overflow-y: auto;
padding: 20px;
margin: 0;
list-style: none;
box-sizing: border-box;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
z-index: 1;
}
#messenger > ul > li {
position: relative;
animation: slide-up 0.4s ease;
}
#messenger > ul > li > .msgBox {
position: relative;
display: inline-block;
background-color: #FFF;
border-radius: 20px;
padding: 18px;
margin-bottom: 20px;
box-shadow: 0 5px 10px rgba(12, 53, 71,.1);
}
#messenger > ul > li > .msgBox > .msgUserInfo {
font-size: 14px;
width: 100%;
text-align: left;
color: #AAA;
}
#messenger > ul > li > .msgBox > .msgContent {
width: 100%;
text-align: left;
min-width: 200px;
font-size: auto;
padding: 3px 0;
word-break: break-all !important;
}
#messenger > ul > li > .msgBox > .msgContent .fas {
font-size: 48px;
color: #c9ae00;
padding: 10px;
}
#messenger > ul > li > .msgBox > .msgContent img {
max-width: 100%;
}
#messenger > ul > li > .msgBox > .msgDate {
width: 100%;
font-size: 10px;
text-align: right;
color: #AAA;
}
#messenger > ul > .myMsgBox {
text-align: right;
}
.writingMessage > .msgBox > .msgUserInfo {
animation: writing 1s ease alternate infinite;
}
#messenger > #users {
position: absolute;
height: 60px;
bottom: 190px;
left: 10px;
right: 10px;
white-space: nowrap;
overflow-y: hidden;
overflow-x: scroll;
box-shadow: 0 -30px 30px rgba(222, 223, 227, 1);
z-index: 100;
}
#messenger > #users > div {
position: relative;
display: inline-block;
height: 45px;
padding: 0 15px;
margin: 0 2px;
line-height: 45px;
background: #FFF;
border-radius: 10px;
color: #666;
cursor: pointer;
transition: .2s;
animation: slide-up 0.4s ease;
box-shadow: 0 5px 10px rgba(12, 53, 71,.2);
}
#messenger > #users > div .far {
margin-right: 10px;
}
#messenger > #users > div:hover {
background-color: #1d8dbf;
color: #FFF;
}
form {
position: absolute;
background: #FFF;
height: auto;
left: 0;
right: 0;
bottom: 0;
padding: 10px;
margin: 10px;
border-radius: 4px;
box-shadow: 0 5px 10px rgba(12, 53, 71,.2);
}
form > input[type=text] {
font-size: 22px;
color: #444;
width: 80%;
height: 100%;
border: none;
padding: 0 20px;
margin: 0;
outline: none !important;
}
form > .editor {
display: inline-block;
width: 100%;
height: 100%;
border: none;
box-sizing: border-box;
}
.leavingState {
opacity: 0.5;
}
form > button {
position: absolute;
font-size: 20px;
background-color: #1d8dbf;
border: none;
padding: 19px;
right: 30px;
bottom: 35px;
color: #FFF;
outline: none !important;
border-radius: 50%;
box-shadow: 0 8px 15px rgba(12, 53, 71,.2);
cursor: pointer;
transition: .2s;
z-index: 9999;
}
form > button:hover {
background: #0a5d82;
}
form > button:active {
background: #0a5d82;
transform: scale(0.6);
}
@keyframes slide-up {
0% {
opacity: 0;
transform: translateY(20px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
@keyframes writing {
0% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
.arrow-right {
position: absolute;
width: 0;
height: 0;
right: -10px;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid white;
}
.arrow-left {
position: absolute;
width: 0;
height: 0;
left: -10px;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right:10px solid white;
}
.editor-toolbar {
border: none;
}
.CodeMirror, .CodeMirror-scroll {
min-height: 80px;
max-height: 80px;
}
@media (min-width: 1000px) {
#messenger {
position: absolute;
width: 1000px;
height: 90%;
top: 5%;
left: 50%;
margin-left: -500px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
box-shadow: 0 4px 5px rgba(0,0,0,0.5), 0 10px 55px rgba(0,0,0,0.5);
}
.background {
position: absolute;
top: -50px;
left: -50px;
right: -50px;
bottom: -50px;
background-image: url("https://images.unsplash.com/photo-1577578306649-09e937512e28?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2550&q=80");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
filter: blur(20px);
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto&amp;display=swap" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment