Skip to content

Commit ff9639f

Browse files
author
–thanhbinh0710
committed
Update code
1 parent b41435d commit ff9639f

File tree

8 files changed

+285
-207
lines changed

8 files changed

+285
-207
lines changed

GUI.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import tkinter as tk
2+
from tkinter import ttk
3+
from datetime import datetime
4+
from p2p import P2PNetwork
5+
import socket
6+
7+
class ChatUI:
8+
def __init__(self, root):
9+
self.root = root
10+
self.root.title("P2P Segment Chat")
11+
self.root.geometry("800x500")
12+
13+
self.channel_messages = {}
14+
self.current_channel = "General"
15+
16+
self.create_channel_list()
17+
self.create_message_display()
18+
self.create_message_input()
19+
self.create_status_bar()
20+
21+
self.load_channel(self.current_channel)
22+
23+
self.p2p = P2PNetwork(server_port=5557,on_message_callback=self.receive_message)
24+
self.p2p.start_network()
25+
self.p2p.get_peer_list_from_tracker()
26+
pass
27+
28+
def create_channel_list(self):
29+
channel_frame = ttk.Frame(self.root, width=200)
30+
channel_frame.pack(side=tk.LEFT, fill=tk.Y)
31+
32+
ttk.Label(channel_frame, text="Danh sách kênh", font=('Arial', 12, 'bold')).pack(pady=5)
33+
self.channel_list = tk.Listbox(channel_frame)
34+
self.channel_list.pack(fill=tk.BOTH, expand=True, padx=5)
35+
36+
channels = ["General", "Random", "Project"]
37+
for ch in channels:
38+
self.channel_list.insert(tk.END, ch)
39+
self.channel_messages[ch] = []
40+
41+
self.channel_list.bind("<<ListboxSelect>>", self.on_channel_select)
42+
43+
def create_message_display(self):
44+
msg_frame = ttk.Frame(self.root)
45+
msg_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
46+
47+
self.message_display = tk.Text(msg_frame, state=tk.DISABLED, wrap=tk.WORD)
48+
self.message_display.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
49+
50+
def create_message_input(self):
51+
input_frame = ttk.Frame(self.root)
52+
input_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=5)
53+
54+
self.message_entry = ttk.Entry(input_frame)
55+
self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(10, 5))
56+
ttk.Button(input_frame, text="Send", command=self.send_message).pack(side=tk.RIGHT, padx=(5, 10))
57+
58+
def create_status_bar(self):
59+
self.status_var = tk.StringVar()
60+
self.status_var.set("Trạng thái: Online")
61+
62+
status_bar = ttk.Label(self.root, textvariable=self.status_var, anchor="w", relief=tk.SUNKEN)
63+
status_bar.pack(side=tk.BOTTOM, fill=tk.X)
64+
65+
def send_message(self):
66+
msg = self.message_entry.get()
67+
if msg:
68+
timestamp = datetime.now().strftime("%H:%M:%S")
69+
full_msg = f"[{timestamp}] You: {msg}"
70+
self.channel_messages[self.current_channel].append(full_msg)
71+
self.update_display()
72+
self.message_entry.delete(0, tk.END)
73+
for ip, port in self.p2p.connected_peers:
74+
try:
75+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
76+
sock.connect((ip, port))
77+
data_to_send = f"{self.current_channel}||{msg}"
78+
self.p2p.send(data_to_send, sock)
79+
sock.close()
80+
except Exception as e:
81+
print(f"[ERROR] Could not send to {(ip, port)}: {e}")
82+
83+
def receive_message(self, msg):
84+
try:
85+
channel, real_msg = msg.split("||", 1)
86+
except ValueError:
87+
channel, real_msg = "General", msg # fallback nếu định dạng cũ
88+
89+
timestamp = datetime.now().strftime("%H:%M:%S")
90+
full_msg = f"[{timestamp}] Peer: {real_msg}"
91+
92+
# Lưu tin nhắn theo kênh
93+
if channel not in self.channel_messages:
94+
self.channel_messages[channel] = []
95+
96+
self.channel_messages[channel].append(full_msg)
97+
98+
# Nếu đang ở đúng kênh thì hiển thị ngay
99+
if channel == self.current_channel:
100+
self.root.after(0, self.update_display)
101+
102+
103+
def _append_message(self, msg):
104+
self.channel_messages[self.current_channel].append(msg)
105+
self.update_display()
106+
107+
def update_display(self):
108+
self.message_display.config(state=tk.NORMAL)
109+
self.message_display.delete("1.0", tk.END)
110+
111+
for msg in self.channel_messages[self.current_channel]:
112+
self.message_display.insert(tk.END, msg + "\n")
113+
114+
self.message_display.config(state=tk.DISABLED)
115+
self.message_display.see(tk.END)
116+
117+
def display_message(self, msg):
118+
self.message_display.config(state=tk.NORMAL)
119+
self.message_display.insert(tk.END, msg + "\n")
120+
self.message_display.config(state=tk.DISABLED)
121+
self.message_display.see(tk.END)
122+
123+
def on_channel_select(self, event):
124+
selection = self.channel_list.curselection()
125+
if selection:
126+
selected_channel = self.channel_list.get(selection[0])
127+
if selected_channel != self.current_channel:
128+
self.load_channel(selected_channel)
129+
130+
def load_channel(self, channel):
131+
self.current_channel = channel
132+
self.status_var.set(f"Currently at channel: {channel}")
133+
self.update_display()
134+
135+
136+
if __name__ == "__main__":
137+
root = tk.Tk()
138+
app = ChatUI(root)
139+
root.mainloop()

__pycache__/login.cpython-313.pyc

1.54 KB
Binary file not shown.

__pycache__/p2p.cpython-313.pyc

8.15 KB
Binary file not shown.

client.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

images/icon.png

76.7 KB
Loading

0 commit comments

Comments
 (0)