desktop_app/app/ui/views/chat_list_view.py
2025-10-04 00:20:21 +03:00

167 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
# Ensure no default row backgrounds
self.chat_list.setAlternatingRowColors(False)
self.chat_list.setAutoFillBackground(False)
# 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;
}}
""")
# Force transparent backgrounds behind text/items
existing_styles = self.chat_list.styleSheet()
self.chat_list.setStyleSheet(existing_styles + f"""
QListWidget::item {{
background-color: transparent;
}}
QListWidget::item:hover {{
background-color: transparent;
}}
QListWidget::item:selected {{
background-color: transparent;
}}
QListView::item {{
background-color: transparent;
}}
QListView::item:hover {{
background-color: transparent;
}}
QListView::item:selected {{
background-color: transparent;
}}
QListWidget QLabel {{
background-color: transparent;
}}
""")
# Обновляем существующие элементы
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