ProyectoFinalPython/app/widgets/ChatTab.py

110 lines
4.3 KiB
Python

import time
import tkinter as tk
from tkinter import ttk
from tkinter.ttk import Notebook
from tkinter import Tk
import requests
from app.widgets.abc import ThreadedTab
class ChatTab(ThreadedTab):
def __init__(self, root: Notebook | Tk, chat_server_url: str, sender_name: str, **kwargs):
self.chat_server_url = chat_server_url
self.sender_name = sender_name
self.conn = False
self.last_msg = 0
super().__init__(root, **kwargs)
def task(self):
try:
self.get_messages()
if not self.conn:
self.connected()
self.conn = True
except requests.ConnectionError:
self.disconnected()
def build(self):
# Create the main frame for the chat interface
self.chat_frame = tk.Frame(self)
self.chat_frame.pack(fill="both", expand=True)
# Create the status label
self.status_label = tk.Label(self.chat_frame, text="", font=("Helvetica", 16))
self.status_label.pack(fill="x")
# Create the history frame with a scrollbar
self.history_frame = tk.Frame(self.chat_frame)
self.history_frame.pack(fill="both", expand=True)
self.history_canvas = tk.Canvas(self.history_frame)
self.history_canvas.pack(side="left", fill="both", expand=True)
self.scrollbar = ttk.Scrollbar(self.history_frame, orient="vertical", command=self.history_canvas.yview)
self.scrollbar.pack(side="right", fill="y")
self.history_canvas.configure(yscrollcommand=self.scrollbar.set)
self.history_canvas.bind('<Configure>', lambda e: self.history_canvas.configure(scrollregion=self.history_canvas.bbox("all")))
self.history_container = tk.Frame(self.history_canvas)
self.history_container.bind("<Configure>", self.on_frame_configure)
self.history_canvas.create_window((0, 0), window=self.history_container, anchor="nw")
# Create the input frame at the bottom
self.input_frame = tk.Frame(self.chat_frame)
self.input_frame.pack(fill="x")
self.message_entry = tk.Entry(self.input_frame)
self.message_entry.pack(side="left", fill="x", expand=True, padx=5, pady=5)
self.message_entry.bind("<Return>", lambda event: self.send_message()) # Bind Enter key to send_message
self.send_button = tk.Button(self.input_frame, text="Send", command=self.send_message)
self.send_button.pack(side="right", padx=5, pady=5)
def on_frame_configure(self, event):
self.history_canvas.configure(scrollregion=self.history_canvas.bbox("all"))
def send_message(self):
message = self.message_entry.get()
if message and self.conn:
response = requests.post(f"{self.chat_server_url}/send_message", json={"content": message, "sender": self.sender_name})
self.last_msg = response.json().get("id")
self.display_message(self.sender_name, message)
self.message_entry.delete(0, tk.END)
def display_message(self, sender, message):
message_frame = tk.Frame(self.history_container, bg="lightgray", pady=5)
message_frame.pack(fill="x", padx=5, pady=5)
message_label = tk.Label(message_frame, text=f"{sender}: {message}", anchor="w", justify="left", wraplength=300)
message_label.pack(fill="x")
self.history_canvas.update_idletasks()
self.history_canvas.yview_moveto(1)
def get_messages(self):
response = requests.post(f"{self.chat_server_url}/get_messages", json={"last_id": self.last_msg})
messages = response.json().get("messages")
for message in messages:
self.display_message(message["sender"], message["content"])
self.last_msg = messages[-1]["id"] if messages else self.last_msg
def connected(self):
self.conn = True
self.status_label.config(text="Connected to chat", fg="green")
self.send_button.config(state="normal")
def disconnected(self):
self.conn = False
self.status_label.config(text="Disconnected from Chat", fg="red")
self.send_button.config(state="disabled")
def change_sender_name(self, new_name: str):
self.sender_name = new_name
def change_server_url(self, new_url: str):
self.chat_server_url = new_url