|
|
|
|
@ -293,11 +293,13 @@ class P2PChatGUI(QObject):
|
|
|
|
|
self._chat_widget.file_send_requested.connect(lambda peer_id: self._on_send_file())
|
|
|
|
|
self._chat_widget.image_send_requested.connect(lambda peer_id: self._on_send_image())
|
|
|
|
|
self._chat_widget.voice_call_requested.connect(lambda peer_id: self._on_voice_call())
|
|
|
|
|
self._chat_widget.voice_call_end_requested.connect(self._on_end_voice_call)
|
|
|
|
|
|
|
|
|
|
# 连接联系人列表信号
|
|
|
|
|
self._contact_list_widget.contact_selected.connect(self._on_contact_selected)
|
|
|
|
|
self._contact_list_widget.contact_double_clicked.connect(self._on_contact_double_clicked)
|
|
|
|
|
self._contact_list_widget.refresh_requested.connect(self._refresh_users)
|
|
|
|
|
self._contact_list_widget.lan_discovery_requested.connect(self._on_lan_discovery)
|
|
|
|
|
|
|
|
|
|
# 设置系统托盘
|
|
|
|
|
try:
|
|
|
|
|
@ -433,6 +435,9 @@ class P2PChatGUI(QObject):
|
|
|
|
|
logger.info(f"Voice call accepted by {sender}")
|
|
|
|
|
self.main_window._statusbar.showMessage(f"通话已接通 - {sender}", 5000)
|
|
|
|
|
self.main_window.show_notification("通话已接通", f"与 {sender} 的通话已建立")
|
|
|
|
|
# 更新UI状态为通话中
|
|
|
|
|
if hasattr(self, '_chat_widget') and self._chat_widget:
|
|
|
|
|
self._chat_widget.set_call_state(True, "通话中...")
|
|
|
|
|
|
|
|
|
|
elif message.msg_type == MessageType.VOICE_CALL_REJECT:
|
|
|
|
|
sender = message.sender_id
|
|
|
|
|
@ -440,12 +445,18 @@ class P2PChatGUI(QObject):
|
|
|
|
|
logger.info(f"Voice call rejected by {sender}: {reason}")
|
|
|
|
|
self.main_window._statusbar.showMessage(f"呼叫被拒绝: {reason}", 5000)
|
|
|
|
|
self.main_window.show_notification("呼叫被拒绝", f"{sender} 拒绝了你的通话请求")
|
|
|
|
|
# 恢复UI状态
|
|
|
|
|
if hasattr(self, '_chat_widget') and self._chat_widget:
|
|
|
|
|
self._chat_widget.set_call_state(False)
|
|
|
|
|
|
|
|
|
|
elif message.msg_type == MessageType.VOICE_CALL_END:
|
|
|
|
|
sender = message.sender_id
|
|
|
|
|
logger.info(f"Voice call ended by {sender}")
|
|
|
|
|
self.main_window._statusbar.showMessage("通话已结束", 3000)
|
|
|
|
|
self.main_window.show_notification("通话结束", f"与 {sender} 的通话已结束")
|
|
|
|
|
# 恢复UI状态
|
|
|
|
|
if hasattr(self, '_chat_widget') and self._chat_widget:
|
|
|
|
|
self._chat_widget.set_call_state(False)
|
|
|
|
|
|
|
|
|
|
def _on_user_list_updated(self, users: List[UserInfo]):
|
|
|
|
|
"""用户列表更新回调"""
|
|
|
|
|
@ -463,6 +474,9 @@ class P2PChatGUI(QObject):
|
|
|
|
|
]
|
|
|
|
|
self._contact_list_widget.set_contacts(other_users)
|
|
|
|
|
logger.info(f"Contact list updated: {len(other_users)} contacts")
|
|
|
|
|
|
|
|
|
|
# 更新连接模式显示
|
|
|
|
|
self._update_connection_modes()
|
|
|
|
|
|
|
|
|
|
def _on_state_changed(self, state: str, reason: str):
|
|
|
|
|
"""状态变化回调"""
|
|
|
|
|
@ -480,6 +494,48 @@ class P2PChatGUI(QObject):
|
|
|
|
|
if self.worker:
|
|
|
|
|
self.worker.refresh_users()
|
|
|
|
|
|
|
|
|
|
def _on_lan_discovery(self):
|
|
|
|
|
"""发现局域网用户"""
|
|
|
|
|
self.main_window._statusbar.showMessage("正在发现局域网用户...", 5000)
|
|
|
|
|
|
|
|
|
|
if self.worker and self.worker._loop and self.worker._running:
|
|
|
|
|
future = asyncio.run_coroutine_threadsafe(
|
|
|
|
|
self._discover_lan_peers_async(),
|
|
|
|
|
self.worker._loop
|
|
|
|
|
)
|
|
|
|
|
try:
|
|
|
|
|
peers = future.result(timeout=5.0)
|
|
|
|
|
if peers:
|
|
|
|
|
self.main_window._statusbar.showMessage(f"发现 {len(peers)} 个局域网用户", 3000)
|
|
|
|
|
self.main_window.show_notification("局域网发现", f"发现 {len(peers)} 个局域网用户")
|
|
|
|
|
# 更新联系人列表中的连接模式
|
|
|
|
|
self._update_connection_modes()
|
|
|
|
|
else:
|
|
|
|
|
self.main_window._statusbar.showMessage("未发现局域网用户", 3000)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"LAN discovery error: {e}")
|
|
|
|
|
self.main_window._statusbar.showMessage("局域网发现失败", 3000)
|
|
|
|
|
|
|
|
|
|
async def _discover_lan_peers_async(self):
|
|
|
|
|
"""异步发现局域网用户"""
|
|
|
|
|
if self.client:
|
|
|
|
|
return await self.client.discover_lan_peers()
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
def _update_connection_modes(self):
|
|
|
|
|
"""更新联系人列表中的连接模式显示"""
|
|
|
|
|
if not self.client or not hasattr(self, '_contact_list_widget'):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 获取所有连接模式
|
|
|
|
|
connection_manager = self.client.connection_manager
|
|
|
|
|
|
|
|
|
|
# 更新每个联系人的连接模式
|
|
|
|
|
for user_id in list(self._contact_list_widget._contacts.keys()):
|
|
|
|
|
mode = connection_manager.get_connection_mode(user_id)
|
|
|
|
|
mode_str = "p2p" if mode.value == "p2p" else "relay"
|
|
|
|
|
self._contact_list_widget.update_connection_mode(user_id, mode_str)
|
|
|
|
|
|
|
|
|
|
def _on_send_file(self):
|
|
|
|
|
"""发送文件"""
|
|
|
|
|
from PyQt6.QtWidgets import QFileDialog, QMessageBox
|
|
|
|
|
@ -564,6 +620,11 @@ class P2PChatGUI(QObject):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.main_window._statusbar.showMessage(f"正在呼叫 {self._current_chat_peer}...")
|
|
|
|
|
|
|
|
|
|
# 更新UI状态为呼叫中
|
|
|
|
|
if hasattr(self, '_chat_widget') and self._chat_widget:
|
|
|
|
|
self._chat_widget.set_call_state(True, "正在呼叫...")
|
|
|
|
|
|
|
|
|
|
if self.worker:
|
|
|
|
|
success = self.worker.start_voice_call(self._current_chat_peer)
|
|
|
|
|
if success:
|
|
|
|
|
@ -571,6 +632,20 @@ class P2PChatGUI(QObject):
|
|
|
|
|
else:
|
|
|
|
|
self.main_window._statusbar.showMessage("呼叫失败", 3000)
|
|
|
|
|
QMessageBox.warning(self.main_window, "呼叫失败", "无法发起语音通话,请检查网络连接")
|
|
|
|
|
# 恢复UI状态
|
|
|
|
|
if hasattr(self, '_chat_widget') and self._chat_widget:
|
|
|
|
|
self._chat_widget.set_call_state(False)
|
|
|
|
|
|
|
|
|
|
def _on_end_voice_call(self):
|
|
|
|
|
"""结束语音通话"""
|
|
|
|
|
logger.info("Ending voice call from GUI")
|
|
|
|
|
if self.worker:
|
|
|
|
|
self.worker.end_voice_call()
|
|
|
|
|
self.main_window._statusbar.showMessage("通话已结束", 3000)
|
|
|
|
|
|
|
|
|
|
# 更新UI状态
|
|
|
|
|
if hasattr(self, '_chat_widget') and self._chat_widget:
|
|
|
|
|
self._chat_widget.set_call_state(False)
|
|
|
|
|
|
|
|
|
|
def _show_incoming_call_dialog(self, caller_id: str):
|
|
|
|
|
"""显示来电对话框"""
|
|
|
|
|
@ -599,6 +674,9 @@ class P2PChatGUI(QObject):
|
|
|
|
|
if success:
|
|
|
|
|
self.main_window._statusbar.showMessage("通话已接通", 3000)
|
|
|
|
|
logger.info(f"Call accepted successfully with {caller_id}")
|
|
|
|
|
# 更新UI状态为通话中
|
|
|
|
|
if hasattr(self, '_chat_widget') and self._chat_widget:
|
|
|
|
|
self._chat_widget.set_call_state(True, "通话中...")
|
|
|
|
|
else:
|
|
|
|
|
self.main_window._statusbar.showMessage("接听失败", 3000)
|
|
|
|
|
logger.error(f"Failed to accept call from {caller_id}")
|
|
|
|
|
|