diff --git a/app/controllers/main_controller.py b/app/controllers/main_controller.py index 232bfaa..0492b25 100644 --- a/app/controllers/main_controller.py +++ b/app/controllers/main_controller.py @@ -1,8 +1,6 @@ from PySide6.QtWidgets import QStackedWidget from app.ui.views.login_view import LoginView -from app.ui.views.chat_list_view import ChatListView -from app.core.models.chat_models import PrivateChatListItem -from app.core.models.mock_data import get_mock_chats # ← заглушка +from app.ui.views.yobble_home_view import YobbleHomeView # <--- Изменено from typing import Optional from threading import Thread import time # эмуляция задержки от сервера @@ -12,7 +10,7 @@ class MainController(QStackedWidget): def __init__(self): super().__init__() self.login_view: Optional[LoginView] = None - self.chat_list_view: Optional[ChatListView] = None + self.yobble_home_view: Optional[YobbleHomeView] = None # <--- Изменено self.init_app() @@ -22,11 +20,9 @@ class MainController(QStackedWidget): if last_login: session = get_session(last_login) if session: - # Если сессия найдена, сразу переходим к списку чатов self.handle_login_success(last_login) return - # Если сессия не найдена, показываем экран входа self.show_login() def show_login(self): @@ -37,7 +33,6 @@ class MainController(QStackedWidget): def handle_login_success(self, username: str): """Обрабатывает успешный вход в систему.""" - # Сохраняем пользователя как последнего вошедшего set_last_login(username) if self.login_view: @@ -45,27 +40,17 @@ class MainController(QStackedWidget): self.removeWidget(self.login_view) self.login_view = None - # 🔹 1. Загружаем чаты локально - chat_items: list[PrivateChatListItem] = self.load_local_chats() + # Отображаем новый главный экран + self.yobble_home_view = YobbleHomeView(username=username) + self.addWidget(self.yobble_home_view) + self.setCurrentWidget(self.yobble_home_view) + self.yobble_home_view.show() - # 🔹 2. Отображаем список - self.chat_list_view = ChatListView(username=username, chat_items=chat_items) - self.addWidget(self.chat_list_view) - self.setCurrentWidget(self.chat_list_view) - self.chat_list_view.show() + # 🔹 Оставляем фоновое обновление на будущее + Thread(target=self.update_data_from_server, args=(username,), daemon=True).start() - # 🔹 3. Обновляем в фоне с сервера - Thread(target=self.update_chats_from_server, args=(username,), daemon=True).start() - - def load_local_chats(self) -> list[PrivateChatListItem]: - # Позже можешь заменить это чтением из JSON или SQLite - return get_mock_chats() - - def update_chats_from_server(self, username: str): + def update_data_from_server(self, username: str): # Эмуляция запроса - time.sleep(2) # ⏳ как будто идёт запрос - print(f"[Sync] Обновляем чаты пользователя: {username}") - - # Здесь должен быть запрос к серверу и обновление UI: - # new_chats = api.get_chats(username) - # self.chat_list_view.update_chat_items(new_chats) + time.sleep(2) + print(f"[Sync] Обновляем данные для пользователя: {username}") + # Здесь будет логика обновления данных для YobbleHome diff --git a/app/ui/views/yobble_home_view.py b/app/ui/views/yobble_home_view.py new file mode 100644 index 0000000..3899b8d --- /dev/null +++ b/app/ui/views/yobble_home_view.py @@ -0,0 +1,194 @@ +from PySide6.QtWidgets import ( + QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFrame, + QStackedWidget, QSpacerItem, QSizePolicy +) +from PySide6.QtCore import Qt, QSize +from PySide6.QtGui import QIcon + +class YobbleHomeView(QWidget): + def __init__(self, username: str): + super().__init__() + self.username = username + self.setWindowTitle(f"Yobble Home - {username}") + + # --- Основной макет --- + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(0, 0, 0, 0) + main_layout.setSpacing(0) + + # 1. Верхняя панель + top_bar = self.create_top_bar() + main_layout.addWidget(top_bar) + + # 2. Центральная область контента + self.content_stack = QStackedWidget() + self.setup_content_pages() + main_layout.addWidget(self.content_stack) + + # 3. Нижняя панель навигации + bottom_bar = self.create_bottom_bar() + main_layout.addWidget(bottom_bar) + + self.setStyleSheet(self.get_stylesheet()) + + def create_top_bar(self): + """Создает верхнюю панель с меню и заголовком.""" + top_bar_widget = QWidget() + top_bar_layout = QHBoxLayout(top_bar_widget) + top_bar_layout.setContentsMargins(10, 5, 10, 5) + + # Кнопка "Бургер" + self.burger_menu_button = QPushButton("☰") + self.burger_menu_button.setObjectName("BurgerMenuButton") + top_bar_layout.addWidget(self.burger_menu_button) + + # Заголовок + self.title_label = QLabel("Чаты") # Начальный заголовок + self.title_label.setObjectName("TitleLabel") + top_bar_layout.addWidget(self.title_label) + top_bar_layout.addStretch() + + return top_bar_widget + + def create_bottom_bar(self): + """Создает нижнюю панель навигации.""" + bottom_bar_widget = QWidget() + bottom_bar_widget.setObjectName("BottomBar") + # Устанавливаем высоту и убираем лишние отступы, чтобы текст не обрезался + bottom_bar_layout = QHBoxLayout(bottom_bar_widget) + bottom_bar_layout.setContentsMargins(10, 0, 10, 5) # Уменьшаем верхний и нижний отступы + bottom_bar_layout.setSpacing(10) + + # Создаем кнопки + btn_feed = self.create_tab_button("📄", "Лента", 0) + btn_search = self.create_tab_button("🔍", "Поиск", 1) + btn_chats = self.create_tab_button("💬", "Чаты", 2) + btn_profile = self.create_tab_button("👤", "Лицо", 3) + + # Центральная кнопка "Создать" + btn_create = QPushButton("+") + btn_create.setObjectName("CreateButton") + btn_create.setFixedSize(50, 50) + + # Добавляем кнопки в макет + bottom_bar_layout.addWidget(btn_feed) + bottom_bar_layout.addWidget(btn_search) + bottom_bar_layout.addWidget(btn_create) + bottom_bar_layout.addWidget(btn_chats) + bottom_bar_layout.addWidget(btn_profile) + + # Устанавливаем начальную активную вкладку + self.update_tab_selection(2) # Чаты по умолчанию + return bottom_bar_widget + + def create_tab_button(self, icon_text, text, index): + """Фабричный метод для создания кнопок вкладок.""" + button = QPushButton() + button.setObjectName("TabButton") + + layout = QVBoxLayout(button) + layout.setContentsMargins(0, 5, 0, 5) + layout.setSpacing(2) + + icon_label = QLabel(icon_text) + icon_label.setAlignment(Qt.AlignCenter) + icon_label.setObjectName("TabIcon") + + text_label = QLabel(text) + text_label.setAlignment(Qt.AlignCenter) + text_label.setObjectName("TabText") + + layout.addWidget(icon_label) + layout.addWidget(text_label) + + button.setProperty("tab_index", index) + button.clicked.connect(lambda: self.on_tab_button_clicked(index)) + return button + + def setup_content_pages(self): + """Создает страницы-заглушки для QStackedWidget.""" + self.content_stack.addWidget(QLabel("Контент Ленты")) + self.content_stack.addWidget(QLabel("Контент Поиска")) + self.content_stack.addWidget(QLabel("Контент Чатов")) + self.content_stack.addWidget(QLabel("Контент Профиля")) + + def on_tab_button_clicked(self, index): + """Обрабатывает нажатие на кнопку вкладки.""" + self.content_stack.setCurrentIndex(index) + self.update_tab_selection(index) + + # Обновляем заголовок + titles = ["Лента", "Поиск", "Чаты", "Лицо"] + self.title_label.setText(titles[index]) + + def update_tab_selection(self, selected_index): + """Обновляет визуальное состояние кнопок вкладок.""" + bottom_bar = self.findChild(QWidget, "BottomBar") + if not bottom_bar: return + + for button in bottom_bar.findChildren(QPushButton): + if button.property("tab_index") == selected_index: + button.setProperty("selected", True) + else: + button.setProperty("selected", False) + + # Обновляем стиль, чтобы изменения применились + button.style().unpolish(button) + button.style().polish(button) + + def get_stylesheet(self): + """Возвращает QSS стили для компонента.""" + return """ + YobbleHomeView { + background-color: white; /* Фон для основного виджета */ + } + /* Верхняя панель */ + #TopBar { + background-color: #f5f5f5; + border-bottom: 1px solid #e0e0e0; + } + #BurgerMenuButton { + font-size: 24px; + border: none; + padding: 5px; + } + #TitleLabel { + font-size: 18px; + font-weight: bold; + } + + /* Нижняя панель */ + #BottomBar { + background-color: #f5f5f5; + border-top: 1px solid #e0e0e0; + } + + /* Кнопки вкладок */ + #TabButton { + background-color: transparent; + border: none; + padding: 5px; + color: #888; + } + #TabButton[selected="true"] #TabText { + color: #007AFF; /* Яркий синий для активной вкладки */ + } + #TabButton[selected="true"] #TabIcon { + color: #007AFF; + } + #TabIcon { font-size: 22px; } + #TabText { font-size: 12px; } + + /* Центральная кнопка "Создать" */ + #CreateButton { + background-color: #007AFF; + color: white; + font-size: 24px; + font-weight: bold; + border: none; + border-radius: 25px; /* Делает ее круглой */ + } + #CreateButton:hover { + background-color: #0056b3; + } + """