145 lines
5.3 KiB
Python
145 lines
5.3 KiB
Python
from PySide6.QtWidgets import QWidget, QVBoxLayout, QListWidget, QLineEdit, QPushButton, QHBoxLayout, QListWidgetItem
|
|
from PySide6.QtCore import Qt, Signal
|
|
from app.core.models.chat_models import MessageItem
|
|
from app.ui.widgets.message_bubble_widget import MessageBubbleWidget
|
|
from app.core.theme import theme_manager
|
|
from uuid import UUID
|
|
|
|
|
|
class ChatView(QWidget):
|
|
# Сигнал, который отдаём контроллеру при отправке
|
|
send_message_requested = Signal(str)
|
|
|
|
def __init__(self, chat_id: UUID, current_user_id: UUID):
|
|
super().__init__()
|
|
self.chat_id = chat_id
|
|
self.current_user_id = current_user_id
|
|
self.init_ui()
|
|
self.update_theme()
|
|
theme_manager.theme_changed.connect(self.update_theme)
|
|
|
|
def init_ui(self):
|
|
"""Базовая раскладка: список сообщений + поле ввода."""
|
|
main_layout = QVBoxLayout(self)
|
|
main_layout.setSpacing(0)
|
|
main_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
self.message_list = QListWidget()
|
|
self.message_list.setSpacing(10)
|
|
self.message_list.setWordWrap(True)
|
|
|
|
input_layout = QHBoxLayout()
|
|
input_layout.setSpacing(10)
|
|
input_layout.setContentsMargins(10, 10, 10, 10)
|
|
|
|
self.message_input = QLineEdit()
|
|
self.message_input.setPlaceholderText("Напишите сообщение…")
|
|
|
|
self.send_button = QPushButton("Отправить")
|
|
|
|
input_layout.addWidget(self.message_input)
|
|
input_layout.addWidget(self.send_button)
|
|
|
|
main_layout.addWidget(self.message_list)
|
|
main_layout.addLayout(input_layout)
|
|
|
|
# wire events
|
|
self.send_button.clicked.connect(self._on_send)
|
|
self.message_input.returnPressed.connect(self._on_send)
|
|
|
|
def _on_send(self):
|
|
"""Забрать текст и пробросить через сигнал контроллеру."""
|
|
message_text = self.message_input.text().strip()
|
|
if message_text:
|
|
self.send_message_requested.emit(message_text)
|
|
|
|
def clear_input(self):
|
|
"""Очистить поле ввода после отправки."""
|
|
self.message_input.clear()
|
|
|
|
def update_theme(self):
|
|
"""Применить палитру темы к виджетам."""
|
|
palette = theme_manager.get_current_palette()
|
|
self.setStyleSheet(f"background-color: {palette['primary']};")
|
|
self.message_list.setStyleSheet(f"""
|
|
QListWidget {{
|
|
background-color: {palette['primary']};
|
|
border: none;
|
|
padding: 10px;
|
|
}}
|
|
""")
|
|
self.message_input.setStyleSheet(f"""
|
|
QLineEdit {{
|
|
background-color: {palette['secondary']};
|
|
color: {palette['text']};
|
|
border: 1px solid {palette['border']};
|
|
border-radius: 15px;
|
|
padding: 5px 15px;
|
|
font-size: 10pt;
|
|
}}
|
|
""")
|
|
self.send_button.setStyleSheet(f"""
|
|
QPushButton {{
|
|
background-color: {palette['accent']};
|
|
color: #ffffff;
|
|
border: none;
|
|
border-radius: 15px;
|
|
padding: 5px 15px;
|
|
font-size: 10pt;
|
|
font-weight: bold;
|
|
}}
|
|
QPushButton:hover {{
|
|
background-color: #4a8ac0;
|
|
}}
|
|
""")
|
|
|
|
def add_message(self, message: MessageItem):
|
|
"""Добавить одно сообщение в список."""
|
|
is_own = message.sender_id == self.current_user_id
|
|
|
|
print("debug message", message)
|
|
# Имя отправителя для входящих (best-effort)
|
|
sender_name = None
|
|
if not is_own and getattr(message, 'sender_data', None):
|
|
sd = message.sender_data
|
|
try:
|
|
if isinstance(sd, dict):
|
|
sender_name = sd.get('display_name') or sd.get('full_name') or sd.get('name') or sd.get('username')
|
|
else:
|
|
sender_name = (
|
|
getattr(sd, 'display_name', None)
|
|
or getattr(sd, 'full_name', None)
|
|
or getattr(sd, 'name', None)
|
|
or getattr(sd, 'username', None)
|
|
)
|
|
except Exception:
|
|
sender_name = None
|
|
|
|
bubble = MessageBubbleWidget(
|
|
text=message.content,
|
|
timestamp=message.created_at.strftime('%H:%M'),
|
|
is_own=is_own,
|
|
sender_name=sender_name
|
|
)
|
|
|
|
item = QListWidgetItem(self.message_list)
|
|
item.setSizeHint(bubble.sizeHint())
|
|
|
|
# Выравнивание айтема по стороне
|
|
if is_own:
|
|
item.setTextAlignment(Qt.AlignRight)
|
|
else:
|
|
item.setTextAlignment(Qt.AlignLeft)
|
|
|
|
self.message_list.addItem(item)
|
|
self.message_list.setItemWidget(item, bubble)
|
|
self.message_list.scrollToBottom()
|
|
|
|
def populate_history(self, messages: list[MessageItem]):
|
|
"""Отрисовать историю сообщений (по возрастанию времени)."""
|
|
self.message_list.clear()
|
|
messages.sort(key=lambda m: m.created_at)
|
|
for message in messages:
|
|
self.add_message(message)
|
|
|