139 lines
5.5 KiB
Python
139 lines
5.5 KiB
Python
from PySide6.QtWidgets import (
|
||
QDialog, QVBoxLayout, QLineEdit,
|
||
QPushButton, QLabel, QMessageBox
|
||
)
|
||
from PySide6.QtCore import Qt, Signal, QObject
|
||
from src.api.auth_api import AuthAPI, AuthResult
|
||
import asyncio
|
||
from asyncio import TimeoutError
|
||
|
||
class LoginSignals(QObject):
|
||
success = Signal(AuthResult)
|
||
error = Signal(str)
|
||
|
||
class LoginDialog(QDialog):
|
||
def __init__(self, parent=None):
|
||
super().__init__(parent)
|
||
self.auth_api = AuthAPI()
|
||
self.auth_result = None
|
||
self.signals = LoginSignals()
|
||
self.login_timeout = 5 # Таймаут в секундах
|
||
# Кэшируем состояние UI
|
||
self._is_logging_in = False
|
||
self.setObjectName("login-dialog")
|
||
self.setup_ui()
|
||
|
||
# Подключаем сигналы
|
||
self.signals.success.connect(self.on_login_success)
|
||
self.signals.error.connect(self.on_login_error)
|
||
|
||
def setup_ui(self):
|
||
"""Настройка интерфейса"""
|
||
self.setWindowTitle("Авторизация")
|
||
self.setFixedSize(350, 320)
|
||
|
||
layout = QVBoxLayout(self)
|
||
layout.setSpacing(15)
|
||
layout.setContentsMargins(30, 30, 30, 30)
|
||
|
||
# Заголовок
|
||
title = QLabel("Вход в аккаунт")
|
||
title.setAlignment(Qt.AlignCenter)
|
||
title.setProperty("class", "login-title")
|
||
layout.addSpacing(5)
|
||
layout.addWidget(title)
|
||
layout.addSpacing(20)
|
||
|
||
# Поля ввода
|
||
self.username = QLineEdit()
|
||
self.username.setPlaceholderText("Имя аккаунта")
|
||
self.username.setProperty("class", "login-input")
|
||
self.username.setFixedHeight(40)
|
||
layout.addWidget(self.username)
|
||
layout.addSpacing(15)
|
||
|
||
self.password = QLineEdit()
|
||
self.password.setPlaceholderText("Пароль")
|
||
self.password.setEchoMode(QLineEdit.Password)
|
||
self.password.setProperty("class", "login-input")
|
||
self.password.setFixedHeight(40)
|
||
layout.addWidget(self.password)
|
||
layout.addSpacing(20)
|
||
|
||
# Кнопка входа
|
||
self.login_button = QPushButton("Войти")
|
||
self.login_button.setProperty("class", "login-button")
|
||
self.login_button.setFixedHeight(40)
|
||
self.login_button.clicked.connect(self.handle_login)
|
||
layout.addWidget(self.login_button)
|
||
layout.addSpacing(15)
|
||
|
||
# Дополнительные кнопки
|
||
self.register_button = QPushButton("Регистрация")
|
||
self.register_button.setProperty("class", "link-button")
|
||
layout.addWidget(self.register_button)
|
||
|
||
self.forgot_button = QPushButton("Забыли пароль?")
|
||
self.forgot_button.setProperty("class", "link-button")
|
||
layout.addWidget(self.forgot_button)
|
||
|
||
def handle_login(self):
|
||
"""Обработчик нажатия кнопки входа"""
|
||
if self._is_logging_in:
|
||
return
|
||
|
||
username = self.username.text().strip()
|
||
password = self.password.text().strip()
|
||
|
||
if not username or not password:
|
||
QMessageBox.warning(
|
||
self,
|
||
"Ошибка",
|
||
"Введите имя аккаунта и пароль"
|
||
)
|
||
return
|
||
|
||
self._is_logging_in = True
|
||
self.login_button.setEnabled(False)
|
||
self.login_button.setText("Вход...")
|
||
|
||
# Запускаем асинхронную авторизацию
|
||
loop = asyncio.get_event_loop()
|
||
loop.create_task(self.try_login(username, password))
|
||
|
||
async def try_login(self, username: str, password: str):
|
||
"""Асинхронная попытка авторизации"""
|
||
try:
|
||
# Добавляем таймаут для операции авторизации
|
||
result = await asyncio.wait_for(
|
||
self.auth_api.login(username, password),
|
||
timeout=self.login_timeout
|
||
)
|
||
if result.success:
|
||
self.signals.success.emit(result)
|
||
else:
|
||
self.signals.error.emit(result.message)
|
||
except TimeoutError:
|
||
self.signals.error.emit("Превышено время ожидания. Проверьте подключение к серверу.")
|
||
except ConnectionRefusedError:
|
||
self.signals.error.emit("Не удалось подключиться к серверу. Сервер недоступен.")
|
||
except Exception as e:
|
||
self.signals.error.emit("Ошибка подключения к серверу. Проверьте сетевое подключение.")
|
||
print(f"Login error: {str(e)}") # Для отладки
|
||
finally:
|
||
# Возвращаем кнопку в исходное состояние
|
||
self.login_button.setEnabled(True)
|
||
self.login_button.setText("Войти")
|
||
|
||
def on_login_success(self, result: AuthResult):
|
||
"""Обработчик успешной авторизации"""
|
||
self.auth_result = result
|
||
self.accept()
|
||
|
||
def on_login_error(self, message: str):
|
||
"""Обработчик ошибки авторизации"""
|
||
QMessageBox.warning(
|
||
self,
|
||
"Ошибка авторизации",
|
||
message
|
||
) |