Chat w/ websockets
Chat w/ websockets
by Dumine Stefan Daniel
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class='header'>
</div>
<main id='stream-chat'>
<div class='overflow' style='height:100px;'>
<div id='messages'></div>
</div>
<div id='input-area'>
<input id="input" type="text" disabled class="form-control" name="msg" placeholder="UserName">
</div>
</main>
CSS
* { padding: 0; margin: 0; box-sizing: border-box; }
$background: white;
$header-color: #2B2B2B;
$odd-color: #111111;
$even-color: #171717;
$input-color: #090909;
$text-color: #919090;
$input-area-background: #1D1D1D;
body {
font-family: 'Lato', sans-serif;
min-height: 100vh;
min-width: 100vw;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
background: $background;
}
//
// NAME-INPUT
//
#name-input {
display: flex;
justify-content: center;
align-items: center;
}
//
// STREAM-CHAT
//
$header-text-color: #EEEEEE;
#stream-chat {
h1 {
background: $header-color;
color: $header-text-color;
text-align: center;
font-weight: 300;
padding: 1rem;
}
margin: 10px;
min-width: 500px;
max-width: 600px;
width: 80%;
min-height: 500px;
max-height: 600px;
height: 80%;
display: flex;
flex-direction: column;
align-items: stretch;
}
//
// INPUT-AREA
//
#input-area {
display: flex;
min-height: 175px;
flex-direction: column;
background: $input-area-background;
padding: 15px;
}
$button-background: #632F9F;
#send {
align-self: flex-end;
padding: 8px 15px;
margin: 3px;
background: $button-background;
border: none;
color: #F8EBEC;
font-weight: 900;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
box-shadow: 0 0 10px 0px darken($button-background, 10%);
}
$input-border-color: #282828;
#input {
flex-grow: 1;
border: 5px solid $input-border-color;
flex-grow: 1;
background: $input-color;
color: $text-color;
margin-bottom: .7em;
resize: none;
&:focus {
outline: none;
}
}
//
// MESSAGES
//
$time-stamp-color: #626A6F;
$message-text-color: #BBB7AB;
$messages-padding-left: 12px;
#messages {
min-height: 500px;
background: linear-gradient(to bottom, $header-color, $input-area-background);
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content:...
JavaScript
var connection = new WebSocket('wss://stream-chat-demo.herokuapp.com')
const input = document.querySelector('#input')
const messages = document.querySelector('#messages')
const overflow = document.querySelector('.overflow')
const nameInput = document.querySelector('#name-input')
const sendButton = document.querySelector('#send')
let userName, userColor
let oddMessage = true
let autoScroll = true
// Respond to new connection
connection.addEventListener('open', (e) => {
})
// Respond to WebSocket messages
connection.addEventListener('message', (message) => {
let resData
try {
resData = JSON.parse(message.data)
} catch(error) {
console.warn(error)
console.warn('invalid JSON')
}
// Once message is received allow user to send another message
input.removeAttribute('disabled')
input.focus()
if (resData.type === 'history') {
resData.data.forEach(message => addMessage(message))
}
else if (resData.type === 'color') {
userColor = resData.data
}
else if (resData.type === 'message') {
addMessage(resData.data)
}
if (autoScroll) {
overflow.scrollTop = overflow.scrollHeight - overflow.clientHeight;
}
})
// Respond to user input
function sendMessage(message) {
if (!message) return
input.setAttribute('disabled', true)
input.value = ''
connection.send(message)
// The first message will be the user's name
if (!userName) {
userName = message
sendMessage(' >>> ONLINE <<< ')
$('.overflow').css("filter", "none");
$('#input').attr('placeholder', 'Scrie un mesaj...');
}
}
input.addEventListener('keydown', (e) => {
if (e.keyCode === 13) {
sendMessage(e.target.value)
}
})
sendButton.addEventListener('click', (e) => {
sendMessage(input.value)
})
// Add a message to message to DOM
function addMessage(data) {
const newMsg = document.createElement('div')
const time = timeString(data.timestamp)
const messageParity = addMessage.odd ? 'odd' : 'even'
addMessage.odd =...