149 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			5.5 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;
 | 
						|
                outline: none;
 | 
						|
            }}
 | 
						|
            QLineEdit:focus {{
 | 
						|
                outline: none;
 | 
						|
                border: 1px solid {palette['border']};
 | 
						|
            }}
 | 
						|
        """)
 | 
						|
        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)
 |