$(function(){ $(document).ready(function(){ var socket = io.connect('http://' + document.domain + ':' + location.port + '/chat'); // Store current username received from app context var current_username = $('#username').val(); // On browser connect, emit a socket event to be added to // room and assigned random username socket.on('connect', function() { socket.emit('joined', {}); }); // Triggered on any status change by any user, such as some // user joined, or changed username, or left, etc. socket.on('status', function(data) { addMessageToRoom(data, current_username, 'status'); }); // Triggered when message is received from a user. Even when sent // by self, it get triggered after the server sends back the emit. socket.on('message', function(data) { addMessageToRoom(data, current_username, 'chat'); }); // Triggered when disconnected either by server stop or timeout socket.on('disconnect', function(data) { addMessageToRoom({'msg': 'The chat server is disconnected.'}, current_username, 'status'); }) socket.on('connect_error', function(error) { console.log("error"); }) // Trigger new message on enter or click of send message button. $('#new-message').on('keypress', function(e) { var code = e.keyCode || e.which; if (code == 13) { emitMessage(socket); } }); $('#send-button').on('click', function(e) { emitMessage(socket); }); // Keep buttons disabled unless changed or not empty $('#username').on('keyup',function(event) { if ($('#username').val() !== '' && $('#username').val() !== current_username) { $('#update-username').removeAttr('disabled'); if (event.keyCode == 13) { current_username = updateUsername(socket); } } else { $('#update-username').attr('disabled', true); } }); // Update username $('#update-username').on('click', function() { current_username = updateUsername(socket); }); // Show warning of losing data $(window).on('beforeunload', function (e) { e.preventDefault(); e.returnValue = ''; return ''; }); }); }); var addMessageToRoom = function(data, current_username, messageType) { var scrollDiff = getScrollDiffBefore(); if (messageType === 'status') { addStatusMessage(data.msg); if (data.connected_users) { addUserList(data.connected_users, current_username); } } else if (messageType === 'chat') { addChatMessage(data.msg) } scrollBottomMaybe(scrollDiff); } var emitMessage = function(socket) { var text = $('#new-message').val(); $('#new-message').val(''); $('#chat').scrollTop($('#chat')[0].scrollHeight); socket.emit('text', {msg: text}); } var updateUsername = function(socket) { var username = $('#username').val(); socket.emit('update_username', {username: username}); $.ajax({ method: 'POST', url: `http://${document.domain}:${location.port}/update-session-username`, contentType: 'application/json', dataType: 'json', data: JSON.stringify({'username': username}) }).done(function(response) { console.log(response); }); $('#update-username').attr('disabled', true); return username; } /************************************/ /********* Util Functions ***********/ /************************************/ var createUserListHTML = function(connected_users, current_user) { var userListHTML = ''; connected_users.sort(); connected_users.forEach(function(username) { if (username !== current_user) { userListHTML += `
${sanitizeHTML(message)}
` ); } var addChatMessage = function(message) { $('#chat').append(`${sanitizeHTML(message)}
`); } var addUserList = function(connected_users, current_username) { $('#user-list').html( createUserListHTML( connected_users, current_username ) ); } var sanitizeHTML = function(str) { var temp = document.createElement('span'); temp.textContent = str; return temp.innerHTML; };