mirror of
https://github.com/onionshare/onionshare.git
synced 2025-05-07 17:05:16 -04:00
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of background thread to generate a list of connected users - Send this user list anytime any change is made to the list. It can be: join, update username, disconnect - In js, render the entire user list everytime it is received. - Scroll to the bottom of the chat, everytime the current user sends a message - Else, if already at the bottom of the chat, scroll to the bottom after appending incoming status or chat message. But if the user is scrolled up in the chat window, then do not scroll to the bottom - When refreshed or close tab is clicked, default browser warning is shown. - On receiving disconnect, the browser removes user from room. - If refreshed, it is shown as if the user left and joined again.
This commit is contained in:
parent
440c0b0ab1
commit
89b112ea95
4 changed files with 158 additions and 85 deletions
|
@ -1,65 +1,123 @@
|
|||
$(function(){
|
||||
var socket;
|
||||
var last_username;
|
||||
var username_list = [];
|
||||
$(document).ready(function(){
|
||||
socket = io.connect('http://' + document.domain + ':' + location.port + '/chat');
|
||||
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) {
|
||||
$('#chat').append('<p><small><i>' + sanitizeHTML(data.msg) + '</i></small></p>');
|
||||
if (data.user && current_username !== data.user) {
|
||||
$('#user-list').append('<li>' + sanitizeHTML(data.user) + '</li>')
|
||||
username_list.push(data.user);
|
||||
}
|
||||
if (data.new_name && current_username !== data.new_name) {
|
||||
last_username = current_username;
|
||||
current_username = data.new_name;
|
||||
username_list[username_list.indexOf(last_username)] = current_username;
|
||||
$('#user-list li').each(function(key, value) {
|
||||
if ($(value).text() === data.old_name) {
|
||||
$(value).html(sanitizeHTML(current_username));
|
||||
}
|
||||
})
|
||||
}
|
||||
$('#chat').scrollTop($('#chat')[0].scrollHeight);
|
||||
});
|
||||
socket.on('update_list', function(data) {
|
||||
if (username_list.indexOf(data.name) === -1 &&
|
||||
current_username !== data.name &&
|
||||
last_username !== data.name
|
||||
) {
|
||||
username_list.push(data.name);
|
||||
$('#user-list').append('<li>' + sanitizeHTML(data.name) + '</li>')
|
||||
}
|
||||
$('#chat').scrollTop($('#chat')[0].scrollHeight);
|
||||
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) {
|
||||
$('#chat').append('<p>' + sanitizeHTML(data.msg) + '</p>');
|
||||
$('#chat').scrollTop($('#chat')[0].scrollHeight);
|
||||
addMessageToRoom(data, current_username, 'chat');
|
||||
});
|
||||
|
||||
// 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', emitMessage);
|
||||
$('#send-button').on('click', function(e) {
|
||||
emitMessage(socket);
|
||||
});
|
||||
|
||||
// Update username
|
||||
$('#update-username').on('click', function() {
|
||||
var username = $('#username').val();
|
||||
current_username = username;
|
||||
socket.emit('update_username', {username: username});
|
||||
});
|
||||
|
||||
// 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});
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/********* Util Functions ***********/
|
||||
/************************************/
|
||||
|
||||
var createUserListHTML = function(connected_users, current_user) {
|
||||
var userListHTML = '';
|
||||
connected_users.sort();
|
||||
connected_users.forEach(function(username) {
|
||||
if (username !== current_user) {
|
||||
userListHTML += `<li>${sanitizeHTML(username)}</li>`;
|
||||
}
|
||||
});
|
||||
return userListHTML;
|
||||
}
|
||||
|
||||
var getScrollDiffBefore = function() {
|
||||
return $('#chat').scrollTop() - ($('#chat')[0].scrollHeight - $('#chat')[0].offsetHeight);
|
||||
}
|
||||
|
||||
var scrollBottomMaybe = function(scrollDiff) {
|
||||
// Scrolls to bottom if the user is scrolled at bottom
|
||||
// if the user has scrolled upp, it wont scroll at bottom.
|
||||
// Note: when a user themselves send a message, it will still
|
||||
// scroll to the bottom even if they had scrolled up before.
|
||||
if (scrollDiff > 0) {
|
||||
$('#chat').scrollTop($('#chat')[0].scrollHeight);
|
||||
}
|
||||
}
|
||||
|
||||
var addStatusMessage = function(message) {
|
||||
$('#chat').append(
|
||||
`<p><small><i>${sanitizeHTML(message)}</i></small></p>`
|
||||
);
|
||||
}
|
||||
|
||||
var addChatMessage = function(message) {
|
||||
$('#chat').append(`<p>${sanitizeHTML(message)}</p>`);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue