120 lines
5.0 KiB
Python
120 lines
5.0 KiB
Python
from PySide6.QtWidgets import QWidget, QListWidget, QVBoxLayout, QListWidgetItem
|
||
from PySide6.QtCore import Qt, QSize
|
||
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
|
||
|
||
class ChatListView(QWidget):
|
||
def __init__(self):
|
||
super().__init__()
|
||
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)
|
||
layout.addWidget(self.chat_list)
|
||
|
||
# Изначальное состояние
|
||
self.show_placeholder_message("Загрузка чатов...")
|
||
|
||
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']};
|
||
}}
|
||
QListWidget::item:selected {{
|
||
background-color: {palette['selected']};
|
||
}}
|
||
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()
|
||
|
||
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:
|
||
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)
|