From 79cb04d00e9eb1847a74b8faf31bcf86e7bed6e3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Oct 2025 02:33:03 +0300 Subject: [PATCH] search patch --- app/ui/views/search_results_view.py | 98 +++++++++++++++++++++++++++++ app/ui/views/yobble_home_view.py | 18 +++++- 2 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 app/ui/views/search_results_view.py diff --git a/app/ui/views/search_results_view.py b/app/ui/views/search_results_view.py new file mode 100644 index 0000000..40679af --- /dev/null +++ b/app/ui/views/search_results_view.py @@ -0,0 +1,98 @@ +from PySide6.QtCore import Qt, Signal +from PySide6.QtWidgets import QWidget, QVBoxLayout, QListWidget, QListWidgetItem, QLabel +from app.ui.widgets.chat_list_item_widget import ChatListItemWidget + + +class SearchResultsView(QWidget): + result_selected = Signal(dict) + def __init__(self, parent=None): + super().__init__(parent) + layout = QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + + self.list = QListWidget() + self.list.setUniformItemSizes(False) + self.list.setSpacing(2) + self.list.itemClicked.connect(self._on_item_clicked) + layout.addWidget(self.list) + + def clear(self): + self.list.clear() + + def populate(self, data): + """data: SearchData (users, groups, channels, messages).""" + self.clear() + + # Users + users = getattr(data, 'users', []) or [] + if users: + self._add_section_header("Пользователи") + for u in users: + title = u.login + subtitle = u.full_name or u.custom_name or "Пользователь" + self._add_chat_like_item(title, subtitle, timestamp="", payload={"type": "user", "user_id": str(u.user_id)}) + + # Groups + groups = getattr(data, 'groups', []) or [] + if groups: + self._add_section_header("Беседы") + for g in groups: + title = g.get("title") if isinstance(g, dict) else getattr(g, "title", "") + self._add_chat_like_item(title or "Группа", "Беседа", timestamp="", payload={"type": "group", "chat_id": str((g.get("chat_id") if isinstance(g, dict) else getattr(g, "chat_id", "")))}) + + # Channels + channels = getattr(data, 'channels', []) or [] + if channels: + self._add_section_header("Паблики") + for ch in channels: + title = ch.get("title") if isinstance(ch, dict) else getattr(ch, "title", "") + self._add_chat_like_item(title or "Паблик", "Паблик", timestamp="", payload={"type": "channel", "channel_id": str((ch.get("channel_id") if isinstance(ch, dict) else getattr(ch, "channel_id", "")))}) + + # Messages + messages = getattr(data, 'messages', []) or [] + if messages: + self._add_section_header("Сообщения") + for m in messages: + content = m.get("content") if isinstance(m, dict) else getattr(m, "content", "") + self._add_chat_like_item((content or "(пусто)"), "Сообщение", timestamp="", payload={"type": "message", "message_id": str((m.get("message_id") if isinstance(m, dict) else getattr(m, "message_id", "")))}) + + def _add_section_header(self, text: str): + item = QListWidgetItem() + item.setFlags(Qt.ItemIsEnabled) + label = QLabel(text) + label.setStyleSheet("padding: 8px 12px; color: #8e8e93; font-weight: 600;") + self.list.addItem(item) + self.list.setItemWidget(item, label) + + def _add_two_line_item(self, title: str, subtitle: str = "", payload=None): + w = QWidget() + v = QVBoxLayout(w) + v.setContentsMargins(12, 8, 12, 8) + v.setSpacing(2) + l1 = QLabel(title) + l1.setObjectName("ResultTitle") + l2 = QLabel(subtitle) + l2.setObjectName("ResultSubtitle") + l2.setStyleSheet("color: #8e8e93;") + v.addWidget(l1) + if subtitle: + v.addWidget(l2) + + item = QListWidgetItem() + item.setData(Qt.UserRole, payload) + self.list.addItem(item) + self.list.setItemWidget(item, w) + + def _add_chat_like_item(self, title: str, last_line: str, timestamp: str = "", payload=None): + widget = ChatListItemWidget(companion_name=title, last_message=last_line, timestamp=timestamp, avatar_path=None, unread_count=0) + item = QListWidgetItem() + item.setSizeHint(widget.sizeHint()) + item.setData(Qt.UserRole, payload) + self.list.addItem(item) + self.list.setItemWidget(item, widget) + + def _on_item_clicked(self, item: QListWidgetItem): + data = item.data(Qt.UserRole) + if data is not None: + self.result_selected.emit(data) diff --git a/app/ui/views/yobble_home_view.py b/app/ui/views/yobble_home_view.py index c8bb9f8..3e7d2b6 100644 --- a/app/ui/views/yobble_home_view.py +++ b/app/ui/views/yobble_home_view.py @@ -13,6 +13,7 @@ from app.core.theme import theme_manager from app.core.dialogs import show_themed_messagebox from app.ui.views.side_menu_view import SideMenuView from app.ui.views.chat_list_view import ChatListView +from app.ui.views.search_results_view import SearchResultsView from app.core.services.auth_service import get_user_role from app.core.database import get_current_access_token from app.core.localizer import localizer @@ -408,6 +409,10 @@ class YobbleHomeView(QWidget): self.chat_view_container = QWidget() self.content_stack.addWidget(self.chat_view_container) + # Страница результатов поиска + self.search_results_view = SearchResultsView() + self.content_stack.addWidget(self.search_results_view) + def update_chat_list(self, chat_data): """ Слот для обновления списка чатов. @@ -695,9 +700,16 @@ class YobbleHomeView(QWidget): groups_cnt = len(getattr(data, 'groups', []) or []) channels_cnt = len(getattr(data, 'channels', []) or []) messages_cnt = len(getattr(data, 'messages', []) or []) - self.show_notification( - localizer.translate(f"Найдено: пользователи {users_cnt}, беседы {groups_cnt}, паблики {channels_cnt}, сообщения {messages_cnt}") - ) + self.show_notification(localizer.translate( + f"Найдено: пользователи {users_cnt}, беседы {groups_cnt}, паблики {channels_cnt}, сообщения {messages_cnt}" + )) + + # Показать результаты на отдельной странице + try: + self.search_results_view.populate(data) + self.content_stack.setCurrentWidget(self.search_results_view) + except Exception: + pass def handle_notification_click(self): """Пустышка для кнопки уведомлений."""