mirror of
https://github.com/onionshare/onionshare.git
synced 2025-02-14 05:31:25 -05:00
Adds list of active users in the chat and allows username change
- allows users to update their username and save the new username - runs a background thread for every user session which emits a broadcast with the username so every user can build their list of active users in the frontend via the socket information - on updating username, stop the old thread and start a new thread with the new username being emitted. The username is updated in everyone's list along with a status message for the same.
This commit is contained in:
parent
425beadce7
commit
0376a36822
@ -1,13 +1,7 @@
|
|||||||
import os
|
|
||||||
import tempfile
|
|
||||||
import json
|
|
||||||
from datetime import datetime
|
|
||||||
from flask import Request, request, render_template, make_response, flash, redirect, session
|
from flask import Request, request, render_template, make_response, flash, redirect, session
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
from flask_socketio import emit, join_room, leave_room
|
from flask_socketio import emit, join_room, leave_room
|
||||||
|
|
||||||
from .. import strings
|
|
||||||
|
|
||||||
|
|
||||||
class ChatModeWeb:
|
class ChatModeWeb:
|
||||||
"""
|
"""
|
||||||
@ -37,6 +31,8 @@ class ChatModeWeb:
|
|||||||
def index():
|
def index():
|
||||||
history_id = self.cur_history_id
|
history_id = self.cur_history_id
|
||||||
self.cur_history_id += 1
|
self.cur_history_id += 1
|
||||||
|
session["name"] = self.common.build_username()
|
||||||
|
session["room"] = self.web.settings.default_settings["chat"]["room"]
|
||||||
self.web.add_request(
|
self.web.add_request(
|
||||||
request.path,
|
request.path,
|
||||||
{"id": history_id, "status_code": 200},
|
{"id": history_id, "status_code": 200},
|
||||||
@ -45,7 +41,9 @@ class ChatModeWeb:
|
|||||||
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
||||||
r = make_response(
|
r = make_response(
|
||||||
render_template(
|
render_template(
|
||||||
"chat.html", static_url_path=self.web.static_url_path
|
"chat.html",
|
||||||
|
static_url_path=self.web.static_url_path,
|
||||||
|
username=session.get("name")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return self.web.add_security_headers(r)
|
return self.web.add_security_headers(r)
|
||||||
@ -54,12 +52,15 @@ class ChatModeWeb:
|
|||||||
def joined(message):
|
def joined(message):
|
||||||
"""Sent by clients when they enter a room.
|
"""Sent by clients when they enter a room.
|
||||||
A status message is broadcast to all people in the room."""
|
A status message is broadcast to all people in the room."""
|
||||||
session["name"] = self.common.build_username()
|
session["worker"] = UserListWorker(self.web.socketio)
|
||||||
session["room"] = self.web.settings.default_settings["chat"]["room"]
|
session["thread"] = self.web.socketio.start_background_task(
|
||||||
|
session["worker"].background_thread, session["name"]
|
||||||
|
)
|
||||||
join_room(session.get("room"))
|
join_room(session.get("room"))
|
||||||
emit(
|
emit(
|
||||||
"status",
|
"status",
|
||||||
{"msg": session.get("name") + " has entered the room."},
|
{"msg": session.get("name") + " has entered the room.",
|
||||||
|
"user": session.get("name")},
|
||||||
room=session.get("room")
|
room=session.get("room")
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -72,3 +73,47 @@ class ChatModeWeb:
|
|||||||
{"msg": session.get("name") + ": " + message["msg"]},
|
{"msg": session.get("name") + ": " + message["msg"]},
|
||||||
room=session.get("room")
|
room=session.get("room")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@self.web.socketio.on("update_username", namespace="/chat")
|
||||||
|
def update_username(message):
|
||||||
|
"""Sent by a client when the user updates their username.
|
||||||
|
The message is sent to all people in the room."""
|
||||||
|
current_name = session.get("name")
|
||||||
|
session["name"] = message["username"]
|
||||||
|
session["worker"].stop_thread()
|
||||||
|
session["worker"] = UserListWorker(self.web.socketio)
|
||||||
|
session['thread'] = self.web.socketio.start_background_task(
|
||||||
|
session["worker"].background_thread, session['name']
|
||||||
|
)
|
||||||
|
emit(
|
||||||
|
"status",
|
||||||
|
{"msg": current_name + " has updated their username to: " + session.get("name"),
|
||||||
|
"old_name": current_name,
|
||||||
|
"new_name": session.get("name")
|
||||||
|
},
|
||||||
|
room=session.get("room")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class UserListWorker(object):
|
||||||
|
|
||||||
|
def __init__(self, socketio):
|
||||||
|
"""
|
||||||
|
assign socketio object to emit
|
||||||
|
"""
|
||||||
|
self.socketio = socketio
|
||||||
|
self.switch = True
|
||||||
|
|
||||||
|
def background_thread(self, name):
|
||||||
|
count = 0
|
||||||
|
while self.switch:
|
||||||
|
self.socketio.sleep(5)
|
||||||
|
count += 1
|
||||||
|
self.socketio.emit('update_list',
|
||||||
|
{'name': name, 'count': count},
|
||||||
|
namespace="/chat",
|
||||||
|
broadcast=True)
|
||||||
|
|
||||||
|
def stop_thread(self):
|
||||||
|
self.switch = False
|
||||||
|
@ -130,9 +130,34 @@ table.file-list td:last-child {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-users {
|
||||||
|
width: 20%;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
border-radius: 2px;
|
||||||
|
overflow: auto;
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-users .editable-username {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-users input#username {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-users #user-list li {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.chat-wrapper {
|
.chat-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
margin: 0 1rem;
|
margin: 0 1rem;
|
||||||
height: calc(100vh - (45px + 2em));
|
height: calc(100vh - (45px + 2em));
|
||||||
}
|
}
|
||||||
@ -150,6 +175,10 @@ table.file-list td:last-child {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-wrapper input#new-message {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.upload-wrapper {
|
.upload-wrapper {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -1,12 +1,39 @@
|
|||||||
$(function(){
|
$(function(){
|
||||||
var socket;
|
var socket;
|
||||||
|
var last_username;
|
||||||
|
var username_list = [];
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
socket = io.connect('http://' + document.domain + ':' + location.port + '/chat');
|
socket = io.connect('http://' + document.domain + ':' + location.port + '/chat');
|
||||||
|
var current_username = $('#username').val();
|
||||||
socket.on('connect', function() {
|
socket.on('connect', function() {
|
||||||
socket.emit('joined', {});
|
socket.emit('joined', {});
|
||||||
});
|
});
|
||||||
socket.on('status', function(data) {
|
socket.on('status', function(data) {
|
||||||
$('#chat').append('<p><small><i>' + sanitizeHTML(data.msg) + '</i></small></p>');
|
$('#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);
|
$('#chat').scrollTop($('#chat')[0].scrollHeight);
|
||||||
});
|
});
|
||||||
socket.on('message', function(data) {
|
socket.on('message', function(data) {
|
||||||
@ -20,11 +47,15 @@ $(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#send-button').on('click', emitMessage);
|
$('#send-button').on('click', emitMessage);
|
||||||
|
$('#update-username').on('click', function() {
|
||||||
|
var username = $('#username').val();
|
||||||
|
socket.emit('update_username', {username: username});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var emitMessage = function(socket) {
|
var emitMessage = function(socket) {
|
||||||
text = $('#new-message').val();
|
var text = $('#new-message').val();
|
||||||
$('#new-message').val('');
|
$('#new-message').val('');
|
||||||
socket.emit('text', {msg: text});
|
socket.emit('text', {msg: text});
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,12 @@
|
|||||||
|
|
||||||
<div class="chat-container">
|
<div class="chat-container">
|
||||||
<div class="chat-users">
|
<div class="chat-users">
|
||||||
|
<ul id="user-list">
|
||||||
|
<li class="editable-username">
|
||||||
|
<input id="username" value="{{ username }}" />
|
||||||
|
<button id="update-username">Save</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="chat-wrapper">
|
<div class="chat-wrapper">
|
||||||
<p class="chat-header">Chat Messages</p>
|
<p class="chat-header">Chat Messages</p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user