2020-08-27 19:13:08 -04:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
OnionShare | https://onionshare.org/
|
|
|
|
|
2021-02-22 16:35:14 -05:00
|
|
|
Copyright (C) 2014-2021 Micah Lee, et al. <micah@micahflee.com>
|
2020-08-27 19:13:08 -04:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
|
|
|
2021-04-12 17:55:16 -04:00
|
|
|
from flask import request, render_template, make_response, jsonify, session
|
2020-03-08 05:21:43 -04:00
|
|
|
from flask_socketio import emit, join_room, leave_room
|
|
|
|
|
|
|
|
|
|
|
|
class ChatModeWeb:
|
|
|
|
"""
|
|
|
|
All of the web logic for chat mode
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, common, web):
|
|
|
|
self.common = common
|
|
|
|
self.common.log("ChatModeWeb", "__init__")
|
|
|
|
|
|
|
|
self.web = web
|
|
|
|
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
# This tracks users in the room
|
|
|
|
self.connected_users = []
|
2020-03-08 05:21:43 -04:00
|
|
|
|
|
|
|
# This tracks the history id
|
|
|
|
self.cur_history_id = 0
|
|
|
|
|
|
|
|
self.define_routes()
|
|
|
|
|
|
|
|
def define_routes(self):
|
|
|
|
"""
|
|
|
|
The web app routes for chatting
|
|
|
|
"""
|
|
|
|
|
|
|
|
@self.web.app.route("/")
|
|
|
|
def index():
|
|
|
|
history_id = self.cur_history_id
|
|
|
|
self.cur_history_id += 1
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
session["name"] = (
|
|
|
|
session.get("name")
|
|
|
|
if session.get("name")
|
|
|
|
else self.common.build_username()
|
|
|
|
)
|
2020-03-12 05:24:48 -04:00
|
|
|
session["room"] = self.web.settings.default_settings["chat"]["room"]
|
2020-03-08 05:21:43 -04:00
|
|
|
self.web.add_request(
|
2020-11-10 09:31:11 -05:00
|
|
|
request.path,
|
|
|
|
{"id": history_id, "status_code": 200},
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
|
|
|
r = make_response(
|
|
|
|
render_template(
|
2020-03-12 05:24:48 -04:00
|
|
|
"chat.html",
|
|
|
|
static_url_path=self.web.static_url_path,
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
username=session.get("name"),
|
2021-04-12 17:55:16 -04:00
|
|
|
title=self.web.settings.get("general", "title"),
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
|
|
|
)
|
|
|
|
return self.web.add_security_headers(r)
|
|
|
|
|
2020-05-11 03:21:46 -04:00
|
|
|
@self.web.app.route("/update-session-username", methods=["POST"])
|
|
|
|
def update_session_username():
|
|
|
|
history_id = self.cur_history_id
|
|
|
|
data = request.get_json()
|
2020-11-10 09:31:11 -05:00
|
|
|
if (
|
|
|
|
data.get("username", "")
|
|
|
|
and data.get("username", "") not in self.connected_users
|
|
|
|
):
|
2020-08-21 08:16:21 -04:00
|
|
|
session["name"] = data.get("username", session.get("name"))
|
2020-05-11 03:21:46 -04:00
|
|
|
self.web.add_request(
|
2020-11-10 09:31:11 -05:00
|
|
|
request.path,
|
|
|
|
{"id": history_id, "status_code": 200},
|
2020-05-11 03:21:46 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
2020-11-10 09:31:11 -05:00
|
|
|
r = make_response(
|
|
|
|
jsonify(
|
|
|
|
username=session.get("name"),
|
|
|
|
success=True,
|
|
|
|
)
|
|
|
|
)
|
2020-05-11 03:21:46 -04:00
|
|
|
return self.web.add_security_headers(r)
|
|
|
|
|
2020-03-08 05:21:43 -04:00
|
|
|
@self.web.socketio.on("joined", namespace="/chat")
|
|
|
|
def joined(message):
|
|
|
|
"""Sent by clients when they enter a room.
|
|
|
|
A status message is broadcast to all people in the room."""
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
self.connected_users.append(session.get("name"))
|
2020-03-08 05:21:43 -04:00
|
|
|
join_room(session.get("room"))
|
|
|
|
emit(
|
|
|
|
"status",
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
{
|
2020-08-19 19:40:00 -04:00
|
|
|
"username": session.get("name"),
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
"msg": "{} has joined.".format(session.get("name")),
|
|
|
|
"connected_users": self.connected_users,
|
|
|
|
"user": session.get("name"),
|
|
|
|
},
|
|
|
|
room=session.get("room"),
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
@self.web.socketio.on("text", namespace="/chat")
|
|
|
|
def text(message):
|
|
|
|
"""Sent by a client when the user entered a new message.
|
|
|
|
The message is sent to all people in the room."""
|
|
|
|
emit(
|
|
|
|
"message",
|
2020-08-19 19:40:00 -04:00
|
|
|
{"username": session.get("name"), "msg": message["msg"]},
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
room=session.get("room"),
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
2020-03-12 05:24:48 -04:00
|
|
|
|
|
|
|
@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")
|
2020-11-10 09:31:11 -05:00
|
|
|
if message.get("username", ""):
|
2020-08-21 08:16:21 -04:00
|
|
|
session["name"] = message["username"]
|
|
|
|
self.connected_users[
|
|
|
|
self.connected_users.index(current_name)
|
|
|
|
] = session.get("name")
|
2020-03-12 05:24:48 -04:00
|
|
|
emit(
|
|
|
|
"status",
|
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.
2020-05-03 18:17:13 -04:00
|
|
|
{
|
|
|
|
"msg": "{} has updated their username to: {}".format(
|
|
|
|
current_name, session.get("name")
|
|
|
|
),
|
|
|
|
"connected_users": self.connected_users,
|
|
|
|
"old_name": current_name,
|
|
|
|
"new_name": session.get("name"),
|
2020-03-12 05:24:48 -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.
2020-05-03 18:17:13 -04:00
|
|
|
room=session.get("room"),
|
2020-03-12 05:24:48 -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.
2020-05-03 18:17:13 -04:00
|
|
|
@self.web.socketio.on("disconnect", namespace="/chat")
|
|
|
|
def disconnect():
|
|
|
|
"""Sent by clients when they disconnect from a room.
|
|
|
|
A status message is broadcast to all people in the room."""
|
|
|
|
self.connected_users.remove(session.get("name"))
|
|
|
|
leave_room(session.get("room"))
|
|
|
|
emit(
|
|
|
|
"status",
|
|
|
|
{
|
|
|
|
"msg": "{} has left the room.".format(session.get("name")),
|
|
|
|
"connected_users": self.connected_users,
|
|
|
|
},
|
|
|
|
room=session.get("room"),
|
|
|
|
)
|