inactive uesrs now collected.

modified:   app.py
	new file:   migrations/versions/5d93cdf18549_room_inactive_users_column.py
	modified:   templates/base.html
	modified:   templates/chat.html
This commit is contained in:
Russell Ballestrini 2024-11-24 14:16:25 -05:00
parent 96c10fc6d6
commit b01311a825
4 changed files with 116 additions and 34 deletions

71
app.py
View file

@ -170,22 +170,42 @@ class Room(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128), nullable=False, unique=True)
title = db.Column(db.String(128), nullable=True)
# Store as a comma-separated string
active_users = db.Column(db.Text, default="")
active_users = db.Column(db.Text, default="") # Store as a comma-separated string
inactive_users = db.Column(db.Text, default="") # Store as a comma-separated string
def add_user(self, username):
users = set(self.active_users.split(",")) if self.active_users else set()
users.add(username)
self.active_users = ",".join(sorted(users))
active_users = set(self.active_users.split(",")) if self.active_users else set()
inactive_users = (
set(self.inactive_users.split(",")) if self.inactive_users else set()
)
# Move from inactive to active if necessary
if username in inactive_users:
inactive_users.discard(username)
active_users.add(username)
self.active_users = ",".join(sorted(active_users))
self.inactive_users = ",".join(sorted(inactive_users))
def remove_user(self, username):
users = set(self.active_users.split(",")) if self.active_users else set()
users.discard(username)
self.active_users = ",".join(sorted(users))
active_users = set(self.active_users.split(",")) if self.active_users else set()
inactive_users = (
set(self.inactive_users.split(",")) if self.inactive_users else set()
)
if username in active_users:
active_users.discard(username)
inactive_users.add(username) # Move to inactive users
self.active_users = ",".join(sorted(active_users))
self.inactive_users = ",".join(sorted(inactive_users))
def get_active_users(self):
return self.active_users.split(",") if self.active_users else []
def get_inactive_users(self):
return self.inactive_users.split(",") if self.inactive_users else []
class UserSession(db.Model):
id = db.Column(db.Integer, primary_key=True)
@ -457,6 +477,7 @@ def on_join(data):
username = data["username"]
room = get_room(room_name)
# Add the user to the active users list
room.add_user(username)
# Store session data in the database
@ -464,18 +485,30 @@ def on_join(data):
session_id=request.sid, username=username, room_name=room_name, room_id=room.id
)
db.session.add(user_session)
db.session.commit()
# Emit the active users list to the new joiner
emit("active_users", {"users": room.get_active_users()}, room=request.sid)
# Emit the active users list to everyone in the room
# Emit the active and inactive users list to the new joiner
emit(
"active_users",
{"users": room.get_active_users()},
{
"active_users": room.get_active_users(),
"inactive_users": room.get_inactive_users(),
},
room=request.sid,
)
# Emit the active and inactive users list to everyone in the room
emit(
"active_users",
{
"active_users": room.get_active_users(),
"inactive_users": room.get_inactive_users(),
},
room=room_name,
include_self=False,
)
# this makes the client start listening for new events for this room.
# This makes the client start listening for new events for this room.
join_room(room_name)
# update the title bar with the proper room title, if it exists for just this new client.
@ -543,11 +576,21 @@ def on_disconnect():
room.remove_user(username)
leave_room(room_name)
# Broadcast to all clients in the room that a user has left the room.
emit("active_users", {"users": room.get_active_users()}, room=room_name)
# Emit the active and inactive users list to everyone in the room
emit(
"active_users",
{
"active_users": room.get_active_users(),
"inactive_users": room.get_inactive_users(),
},
room=room.name,
include_self=False,
)
emit(
"chat_message",
{"id": None, "content": f"{username} has left the room."},
room=room.name,
include_self=False,
)
# Remove session data from the database
db.session.delete(user_session)

View file

@ -0,0 +1,25 @@
"""room inactive_users column
Revision ID: 5d93cdf18549
Revises: 1ac5a8e0f577
Create Date: 2024-11-24 14:04:30.488155
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import sqlite
# revision identifiers, used by Alembic.
revision = '5d93cdf18549'
down_revision = '1ac5a8e0f577'
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table('room', schema=None) as batch_op:
batch_op.add_column(sa.Column('inactive_users', sa.Text(), nullable=True))
def downgrade():
with op.batch_alter_table('room', schema=None) as batch_op:
batch_op.drop_column('inactive_users')

View file

@ -262,7 +262,7 @@
</style>
</head>
<body>
<a href="https://github.com/russellballestrini/flask-socketio-llm-completions#interacting-with-language-models" target="_blank">🚀 docs for interacting with language models & other commands or try /help</a>
<a href="https://github.com/russellballestrini/opencompletion#interacting-with-language-models" target="_blank">🚀 docs for language models & other commands, also try /help</a>
<!-- Search form -->
<div id="search-form" style="width: 90%;">
<form action="/search" method="get">
@ -284,7 +284,7 @@
</div>
</div>
<!-- Chatroom list -->
<!-- Chatroom list -->
<div class="main-container">
<div id="rooms-list">
<ul id="rooms-list-ul">

View file

@ -50,12 +50,21 @@
<option value="shimmer">Shimmer</option>
</select>
</div>
<div>
<h3>Active Users</h3>
<ul id="active-users">
<!-- Active users will be dynamically populated here -->
</ul>
</div>
<div id="user-lists">
<div id="active-users-list">
<h3>Active Users</h3>
<ul id="active-users">
<!-- Active users will be dynamically populated here -->
</ul>
</div>
<div id="inactive-users-list">
<h3>Inactive Users</h3>
<ul id="inactive-users">
<!-- Inactive users will be dynamically populated here -->
</ul>
</div>
</div>
</div>
<script>
@ -128,29 +137,34 @@ function updateQueryString() {
window.history.replaceState({}, '', newUrl);
}
// Object to keep track of active users
let activeUsers = {};
// Function to update the active and inactive user lists in the DOM
function updateUserLists(activeUsers, inactiveUsers) {
const activeUserListElement = document.getElementById("active-users");
const inactiveUserListElement = document.getElementById("inactive-users");
// Function to update the active user list in the DOM
function updateActiveUserList(users) {
const userListElement = document.getElementById("active-users");
userListElement.innerHTML = ''; // Clear the current list
activeUserListElement.innerHTML = ''; // Clear the current list
inactiveUserListElement.innerHTML = ''; // Clear the current list
// Populate the list with active users
users.forEach(username => {
activeUsers.forEach(username => {
const userItem = document.createElement("li");
userItem.textContent = username;
userListElement.appendChild(userItem);
activeUserListElement.appendChild(userItem);
});
// Populate the list with inactive users
inactiveUsers.forEach(username => {
const userItem = document.createElement("li");
userItem.textContent = username;
inactiveUserListElement.appendChild(userItem);
});
}
// Update active users list whenever the event is received
// Update user lists whenever the event is received
socket.on("active_users", (data) => {
updateActiveUserList(data.users);
updateUserLists(data.active_users, data.inactive_users);
});
// Function to handle sending the message
function sendMessage() {
const message = document.getElementById("message").value;