Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions GUI.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import tkinter as tk
from tkinter import ttk
from datetime import datetime
from p2p import P2PNetwork
import socket

class ChatUI:
def __init__(self, root):
self.root = root
self.root.title("P2P Segment Chat")
self.root.geometry("800x500")

self.channel_messages = {}
self.current_channel = "General"

self.create_channel_list()
self.create_message_display()
self.create_message_input()
self.create_status_bar()

self.load_channel(self.current_channel)

self.p2p = P2PNetwork(server_port=5557,on_message_callback=self.receive_message)
self.p2p.start_network()
self.p2p.get_peer_list_from_tracker()
pass

def create_channel_list(self):
channel_frame = ttk.Frame(self.root, width=200)
channel_frame.pack(side=tk.LEFT, fill=tk.Y)

ttk.Label(channel_frame, text="Danh sách kênh", font=('Arial', 12, 'bold')).pack(pady=5)
self.channel_list = tk.Listbox(channel_frame)
self.channel_list.pack(fill=tk.BOTH, expand=True, padx=5)

channels = ["General", "Random", "Project"]
for ch in channels:
self.channel_list.insert(tk.END, ch)
self.channel_messages[ch] = []

self.channel_list.bind("<<ListboxSelect>>", self.on_channel_select)

def create_message_display(self):
msg_frame = ttk.Frame(self.root)
msg_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

self.message_display = tk.Text(msg_frame, state=tk.DISABLED, wrap=tk.WORD)
self.message_display.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

def create_message_input(self):
input_frame = ttk.Frame(self.root)
input_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=5)

self.message_entry = ttk.Entry(input_frame)
self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(10, 5))
ttk.Button(input_frame, text="Send", command=self.send_message).pack(side=tk.RIGHT, padx=(5, 10))

def create_status_bar(self):
self.status_var = tk.StringVar()
self.status_var.set("Trạng thái: Online")

status_bar = ttk.Label(self.root, textvariable=self.status_var, anchor="w", relief=tk.SUNKEN)
status_bar.pack(side=tk.BOTTOM, fill=tk.X)

def send_message(self):
msg = self.message_entry.get()
if msg:
timestamp = datetime.now().strftime("%H:%M:%S")
full_msg = f"[{timestamp}] You: {msg}"
self.channel_messages[self.current_channel].append(full_msg)
self.update_display()
self.message_entry.delete(0, tk.END)
for ip, port in self.p2p.connected_peers:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
data_to_send = f"{self.current_channel}||{msg}"
self.p2p.send(data_to_send, sock)
sock.close()
except Exception as e:
print(f"[ERROR] Could not send to {(ip, port)}: {e}")

def receive_message(self, msg):
try:
channel, real_msg = msg.split("||", 1)
except ValueError:
channel, real_msg = "General", msg # fallback nếu định dạng cũ

timestamp = datetime.now().strftime("%H:%M:%S")
full_msg = f"[{timestamp}] Peer: {real_msg}"

# Lưu tin nhắn theo kênh
if channel not in self.channel_messages:
self.channel_messages[channel] = []

self.channel_messages[channel].append(full_msg)

# Nếu đang ở đúng kênh thì hiển thị ngay
if channel == self.current_channel:
self.root.after(0, self.update_display)


def _append_message(self, msg):
self.channel_messages[self.current_channel].append(msg)
self.update_display()

def update_display(self):
self.message_display.config(state=tk.NORMAL)
self.message_display.delete("1.0", tk.END)

for msg in self.channel_messages[self.current_channel]:
self.message_display.insert(tk.END, msg + "\n")

self.message_display.config(state=tk.DISABLED)
self.message_display.see(tk.END)

def display_message(self, msg):
self.message_display.config(state=tk.NORMAL)
self.message_display.insert(tk.END, msg + "\n")
self.message_display.config(state=tk.DISABLED)
self.message_display.see(tk.END)

def on_channel_select(self, event):
selection = self.channel_list.curselection()
if selection:
selected_channel = self.channel_list.get(selection[0])
if selected_channel != self.current_channel:
self.load_channel(selected_channel)

def load_channel(self, channel):
self.current_channel = channel
self.status_var.set(f"Currently at channel: {channel}")
self.update_display()


if __name__ == "__main__":
root = tk.Tk()
app = ChatUI(root)
root.mainloop()
Binary file added __pycache__/login.cpython-313.pyc
Binary file not shown.
Binary file added __pycache__/p2p.cpython-313.pyc
Binary file not shown.
29 changes: 0 additions & 29 deletions client.py

This file was deleted.

Binary file added images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading