patch chat list
This commit is contained in:
parent
21e8bb0ad0
commit
f178eb24ba
@ -1,7 +1,9 @@
|
|||||||
from PySide6.QtWidgets import QWidget, QListWidget, QVBoxLayout, QLabel, QListWidgetItem
|
from PySide6.QtWidgets import QWidget, QListWidget, QVBoxLayout, QListWidgetItem
|
||||||
from PySide6.QtCore import Qt
|
from PySide6.QtCore import Qt, QSize
|
||||||
from typing import List
|
from typing import List
|
||||||
from app.core.models.chat_models import PrivateChatListItem
|
from app.core.models.chat_models import PrivateChatListItem
|
||||||
|
from app.ui.widgets.chat_list_item_widget import ChatListItemWidget
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
class ChatListView(QWidget):
|
class ChatListView(QWidget):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -11,10 +13,45 @@ class ChatListView(QWidget):
|
|||||||
def init_ui(self):
|
def init_ui(self):
|
||||||
"""Инициализирует пользовательский интерфейс."""
|
"""Инициализирует пользовательский интерфейс."""
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
layout.setContentsMargins(0, 0, 0, 0)
|
layout.setContentsMargins(10, 10, 10, 10)
|
||||||
|
layout.setSpacing(0)
|
||||||
|
|
||||||
self.chat_list = QListWidget()
|
self.chat_list = QListWidget()
|
||||||
self.chat_list.setStyleSheet("QListWidget { border: none; }")
|
self.chat_list.setStyleSheet("""
|
||||||
|
QListWidget {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: none;
|
||||||
|
padding: 5px;
|
||||||
|
spacing: 8px;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
QListWidget::item {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
QListWidget::item:hover {
|
||||||
|
background-color: #e9e9e9;
|
||||||
|
}
|
||||||
|
QListWidget::item:selected {
|
||||||
|
background-color: #dcdcdc;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
QScrollBar:vertical {
|
||||||
|
border: none;
|
||||||
|
background: #f5f5f5;
|
||||||
|
width: 8px;
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
QScrollBar::handle:vertical {
|
||||||
|
background: #cccccc;
|
||||||
|
min-height: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
layout.addWidget(self.chat_list)
|
layout.addWidget(self.chat_list)
|
||||||
|
|
||||||
# Изначальное состояние
|
# Изначальное состояние
|
||||||
@ -25,6 +62,7 @@ class ChatListView(QWidget):
|
|||||||
self.chat_list.clear()
|
self.chat_list.clear()
|
||||||
item = QListWidgetItem(text)
|
item = QListWidgetItem(text)
|
||||||
item.setTextAlignment(Qt.AlignCenter)
|
item.setTextAlignment(Qt.AlignCenter)
|
||||||
|
item.setBackground(Qt.transparent)
|
||||||
self.chat_list.addItem(item)
|
self.chat_list.addItem(item)
|
||||||
|
|
||||||
def populate_chats(self, chat_items: List[PrivateChatListItem]):
|
def populate_chats(self, chat_items: List[PrivateChatListItem]):
|
||||||
@ -46,14 +84,21 @@ class ChatListView(QWidget):
|
|||||||
else:
|
else:
|
||||||
companion_name = "Неизвестный"
|
companion_name = "Неизвестный"
|
||||||
|
|
||||||
# Получаем текст последнего сообщения
|
# Получаем текст и время последнего сообщения
|
||||||
if chat.last_message and chat.last_message.content:
|
if chat.last_message and chat.last_message.content:
|
||||||
last_msg = chat.last_message.content
|
last_msg = chat.last_message.content
|
||||||
|
|
||||||
|
# Преобразуем время
|
||||||
|
timestamp = chat.last_message.created_at.strftime('%H:%M')
|
||||||
else:
|
else:
|
||||||
last_msg = "Нет сообщений"
|
last_msg = "Нет сообщений"
|
||||||
|
timestamp = ""
|
||||||
|
|
||||||
# Создаем кастомный виджет для элемента списка (можно будет улучшить)
|
# Создаем кастомный виджет
|
||||||
# Пока просто текстом
|
item_widget = ChatListItemWidget(companion_name, last_msg, timestamp)
|
||||||
item_text = f"{companion_name}\n{last_msg}"
|
|
||||||
list_item = QListWidgetItem(item_text)
|
# Создаем элемент списка и устанавливаем для него наш виджет
|
||||||
|
list_item = QListWidgetItem(self.chat_list)
|
||||||
|
list_item.setSizeHint(item_widget.sizeHint())
|
||||||
self.chat_list.addItem(list_item)
|
self.chat_list.addItem(list_item)
|
||||||
|
self.chat_list.setItemWidget(list_item, item_widget)
|
||||||
|
|||||||
69
app/ui/widgets/chat_list_item_widget.py
Normal file
69
app/ui/widgets/chat_list_item_widget.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel
|
||||||
|
from PySide6.QtGui import QPixmap, QPainter, QColor, QBrush
|
||||||
|
from PySide6.QtCore import Qt
|
||||||
|
|
||||||
|
class ChatListItemWidget(QWidget):
|
||||||
|
def __init__(self, companion_name, last_message, timestamp, avatar_path=None):
|
||||||
|
super().__init__()
|
||||||
|
self.init_ui(companion_name, last_message, timestamp, avatar_path)
|
||||||
|
|
||||||
|
def init_ui(self, companion_name, last_message, timestamp, avatar_path):
|
||||||
|
"""Инициализирует пользовательский интерфейс виджета."""
|
||||||
|
main_layout = QHBoxLayout(self)
|
||||||
|
main_layout.setContentsMargins(10, 10, 10, 10)
|
||||||
|
main_layout.setSpacing(10)
|
||||||
|
|
||||||
|
# Аватар
|
||||||
|
self.avatar_label = QLabel()
|
||||||
|
self.set_avatar(avatar_path)
|
||||||
|
main_layout.addWidget(self.avatar_label)
|
||||||
|
|
||||||
|
# Информация о чате
|
||||||
|
info_layout = QVBoxLayout()
|
||||||
|
info_layout.setSpacing(0)
|
||||||
|
|
||||||
|
# Верхняя строка: имя и время
|
||||||
|
top_line_layout = QHBoxLayout()
|
||||||
|
|
||||||
|
self.name_label = QLabel(companion_name)
|
||||||
|
self.name_label.setStyleSheet("font-weight: bold;")
|
||||||
|
|
||||||
|
self.timestamp_label = QLabel(timestamp)
|
||||||
|
self.timestamp_label.setStyleSheet("color: grey; font-size: 9px;")
|
||||||
|
|
||||||
|
top_line_layout.addWidget(self.name_label)
|
||||||
|
top_line_layout.addStretch()
|
||||||
|
top_line_layout.addWidget(self.timestamp_label)
|
||||||
|
|
||||||
|
self.last_message_label = QLabel(last_message)
|
||||||
|
self.last_message_label.setStyleSheet("color: grey;")
|
||||||
|
|
||||||
|
info_layout.addLayout(top_line_layout)
|
||||||
|
info_layout.addWidget(self.last_message_label)
|
||||||
|
|
||||||
|
main_layout.addLayout(info_layout)
|
||||||
|
main_layout.addStretch()
|
||||||
|
|
||||||
|
def set_avatar(self, image_path):
|
||||||
|
"""Устанавливает аватар. Если путь не указан, создает заглушку."""
|
||||||
|
if image_path:
|
||||||
|
pixmap = QPixmap(image_path)
|
||||||
|
else:
|
||||||
|
# Создаем круглую заглушку
|
||||||
|
pixmap = QPixmap(40, 40)
|
||||||
|
pixmap.fill(Qt.transparent)
|
||||||
|
painter = QPainter(pixmap)
|
||||||
|
painter.setRenderHint(QPainter.Antialiasing)
|
||||||
|
painter.setBrush(QBrush(QColor("#e0e0e0")))
|
||||||
|
painter.setPen(Qt.NoPen)
|
||||||
|
painter.drawEllipse(0, 0, 40, 40)
|
||||||
|
painter.end()
|
||||||
|
|
||||||
|
self.avatar_label.setPixmap(pixmap)
|
||||||
|
self.avatar_label.setFixedSize(40, 40)
|
||||||
|
self.avatar_label.setScaledContents(True)
|
||||||
|
|
||||||
|
def paintEvent(self, event):
|
||||||
|
"""Переопределяем для скругления углов аватара, если это изображение."""
|
||||||
|
# Этот метод можно будет доработать для создания круглых аватаров из картинок
|
||||||
|
super().paintEvent(event)
|
||||||
Reference in New Issue
Block a user