139 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from PySide6.QtWidgets import QWidget, QListWidget, QVBoxLayout, QListWidgetItem, QAbstractItemView
 | 
						||
from PySide6.QtCore import Qt, QSize, Signal
 | 
						||
from typing import List
 | 
						||
from app.core.models.chat_models import PrivateChatListItem
 | 
						||
from app.ui.widgets.chat_list_item_widget import ChatListItemWidget
 | 
						||
from app.core.theme import theme_manager
 | 
						||
from datetime import datetime
 | 
						||
from uuid import UUID
 | 
						||
 | 
						||
class ChatListView(QWidget):
 | 
						||
    chat_selected = Signal(UUID)
 | 
						||
 | 
						||
    def __init__(self):
 | 
						||
        super().__init__()
 | 
						||
        self.chat_items_map = {}
 | 
						||
        self.init_ui()
 | 
						||
        self.update_theme()
 | 
						||
        theme_manager.theme_changed.connect(self.update_theme)
 | 
						||
 | 
						||
    def init_ui(self):
 | 
						||
        """Инициализирует пользовательский интерфейс."""
 | 
						||
        layout = QVBoxLayout(self)
 | 
						||
        layout.setContentsMargins(0, 0, 0, 0)
 | 
						||
        layout.setSpacing(0)
 | 
						||
 | 
						||
        self.chat_list = QListWidget()
 | 
						||
        self.chat_list.setSpacing(2)
 | 
						||
        # Disable selection to avoid persistent click highlight
 | 
						||
        self.chat_list.setSelectionMode(QAbstractItemView.NoSelection)
 | 
						||
        self.chat_list.itemClicked.connect(self.on_chat_item_clicked)
 | 
						||
        layout.addWidget(self.chat_list)
 | 
						||
 | 
						||
        # Изначальное состояние
 | 
						||
        self.show_placeholder_message("Загрузка чатов...")
 | 
						||
 | 
						||
    def on_chat_item_clicked(self, item: QListWidgetItem):
 | 
						||
        """Обработчик клика по элементу списка чатов."""
 | 
						||
        chat_id = self.chat_items_map.get(id(item))
 | 
						||
        if chat_id:
 | 
						||
            self.chat_selected.emit(chat_id)
 | 
						||
            # Remove focus to avoid blue outline after selection
 | 
						||
            self.chat_list.clearFocus()
 | 
						||
 | 
						||
    def update_theme(self):
 | 
						||
        """Обновляет стили в соответствии с темой."""
 | 
						||
        palette = theme_manager.get_current_palette()
 | 
						||
        self.chat_list.setStyleSheet(f"""
 | 
						||
            QListWidget {{
 | 
						||
                background-color: {palette['primary']};
 | 
						||
                border: none;
 | 
						||
                padding: 5px;
 | 
						||
                outline: 0;
 | 
						||
            }}
 | 
						||
            QListWidget::item {{
 | 
						||
                border-radius: 5px;
 | 
						||
            }}
 | 
						||
            QListWidget::item:hover {{
 | 
						||
                background-color: {palette['hover']};
 | 
						||
            }}
 | 
						||
            QScrollBar:vertical {{
 | 
						||
                border: none;
 | 
						||
                background: {palette['primary']};
 | 
						||
                width: 8px;
 | 
						||
                margin: 0px 0px 0px 0px;
 | 
						||
            }}
 | 
						||
            QScrollBar::handle:vertical {{
 | 
						||
                background: {palette['secondary']};
 | 
						||
                min-height: 20px;
 | 
						||
                border-radius: 4px;
 | 
						||
            }}
 | 
						||
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {{
 | 
						||
                height: 0px;
 | 
						||
            }}
 | 
						||
        """)
 | 
						||
        # Обновляем существующие элементы
 | 
						||
        for i in range(self.chat_list.count()):
 | 
						||
            item = self.chat_list.item(i)
 | 
						||
            widget = self.chat_list.itemWidget(item)
 | 
						||
            if isinstance(widget, ChatListItemWidget):
 | 
						||
                widget.update_theme()
 | 
						||
 | 
						||
    def show_placeholder_message(self, text):
 | 
						||
        """Очищает список и показывает одно сообщение (например, "Загрузка..." или "Чатов нет")."""
 | 
						||
        self.chat_list.clear()
 | 
						||
        item = QListWidgetItem(text)
 | 
						||
        item.setTextAlignment(Qt.AlignCenter)
 | 
						||
        # Убираем фон у элемента-заглушки
 | 
						||
        item.setBackground(Qt.transparent)
 | 
						||
        self.chat_list.addItem(item)
 | 
						||
 | 
						||
    def populate_chats(self, chat_items: List[PrivateChatListItem]):
 | 
						||
        """
 | 
						||
        Заполняет список чатов данными, полученными от сервера.
 | 
						||
        """
 | 
						||
        self.chat_list.clear()
 | 
						||
        self.chat_items_map.clear()
 | 
						||
 | 
						||
        if not chat_items:
 | 
						||
            self.show_placeholder_message("У вас пока нет чатов")
 | 
						||
            return
 | 
						||
        
 | 
						||
        # Сортируем чаты по времени последнего сообщения
 | 
						||
        chat_items.sort(key=lambda x: x.last_message.created_at if x.last_message else datetime.min, reverse=True)
 | 
						||
 | 
						||
        for chat in chat_items:
 | 
						||
            # Определяем имя собеседника
 | 
						||
            if chat.chat_type == "self":
 | 
						||
                companion_name = "Избранное"
 | 
						||
            elif chat.chat_data and 'login' in chat.chat_data:
 | 
						||
                if chat.chat_data['full_name']:
 | 
						||
                    companion_name = chat.chat_data['full_name']
 | 
						||
                else:
 | 
						||
                    companion_name = chat.chat_data['login']
 | 
						||
            else:
 | 
						||
                companion_name = "Неизвестный"
 | 
						||
 | 
						||
            # Получаем текст и время последнего сообщения
 | 
						||
            if chat.last_message and chat.last_message.content:
 | 
						||
                last_msg = chat.last_message.content
 | 
						||
                timestamp = chat.last_message.created_at.strftime('%H:%M')
 | 
						||
            else:
 | 
						||
                last_msg = "Нет сообщений"
 | 
						||
                timestamp = ""
 | 
						||
            
 | 
						||
            # TODO: Заменить на реальное количество непрочитанных сообщений
 | 
						||
            unread_count = 2 
 | 
						||
 | 
						||
            # Создаем кастомный виджет
 | 
						||
            item_widget = ChatListItemWidget(companion_name, last_msg, timestamp, unread_count=unread_count)
 | 
						||
            
 | 
						||
            # Создаем элемент списка и устанавливаем для него наш виджет
 | 
						||
            list_item = QListWidgetItem(self.chat_list)
 | 
						||
            list_item.setSizeHint(item_widget.sizeHint())
 | 
						||
            self.chat_list.addItem(list_item)
 | 
						||
            self.chat_list.setItemWidget(list_item, item_widget)
 | 
						||
            
 | 
						||
            # Сохраняем ID чата в словаре
 | 
						||
            self.chat_items_map[id(list_item)] = chat.chat_id
 |