110 lines
4.3 KiB
Python
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 |