from PySide6.QtWidgets import ( QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QMessageBox, QHBoxLayout, QSpacerItem, QSizePolicy, QComboBox ) from PySide6.QtCore import Qt from ..widgets.validation_input import ValidationInput from common_lib.utils.validators import ( validate_username as common_validate_username, validate_password as common_validate_password ) from app.core.localizer import localizer def validate_username(username, is_login=False): if is_login: if len(username) < 3 or len(username) > 32: msg = "Неверный логин или пароль (валидатор)" return False, msg return True, username return common_validate_username(username, need_back=True) def validate_invite_code(invite_code): # Login must be between 3 and 32 characters long # Login must not contain whitespace characters # Login must not start with an underscore # Login must not contain consecutive underscores # Login must contain only English letters, digits, and underscores # Invite must be between 3 and 32 characters long # Invite must not contain whitespace characters # Invite must not start with an underscore # Invite must not contain consecutive underscores # Invite must contain only English letters, digits, and underscores return common_validate_username(invite_code, field_name="invite", need_back=True) def validate_password(password, is_login=False): if is_login: if len(password) < 8 or len(password) > 128: msg = "Неверный логин или пароль (валидатор)" return False, msg return True, password return common_validate_password(password, need_back=True) def validate_name(name): # Optional field if not name: return True, "" if len(name) >= 32: return False, "Имя не должно превышать 32 символов" return True, "" class LoginView(QWidget): def __init__(self, on_login): super().__init__() self.on_login = on_login self.setWindowTitle("yobble messenger") self.setFixedSize(400, 550) self.is_dark_theme = True self.lang_combo = None self.is_registration = False self.init_ui() self.apply_dark_theme() def init_ui(self): # Переключатель темы и языка theme_layout = QHBoxLayout() theme_layout.setAlignment(Qt.AlignRight) self.theme_button = QPushButton("🌞") self.theme_button.setFixedWidth(50) self.theme_button.clicked.connect(self.toggle_theme) self.lang_combo = QComboBox() self.lang_combo.setFixedWidth(100) self.lang_map = {} # display_name: lang_code for lang_code, lang_name in localizer.get_available_languages(): self.lang_map[lang_name] = lang_code self.lang_combo.addItem(lang_name) # ✅ Устанавливаем текущий язык по индексу for i in range(self.lang_combo.count()): item_text = self.lang_combo.itemText(i) if self.lang_map.get(item_text) == localizer.lang: self.lang_combo.setCurrentIndex(i) break print("localizer.lang", localizer.lang) self.lang_combo.currentTextChanged.connect(self.change_language) theme_layout.addSpacerItem(QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) theme_layout.addWidget(self.lang_combo) theme_layout.addWidget(self.theme_button) # Основная часть self.main_layout = QVBoxLayout() self.main_layout.setAlignment(Qt.AlignCenter) self.main_layout.setContentsMargins(40, 40, 40, 40) self.title = QLabel(localizer.translate("Авторизация")) self.title.setAlignment(Qt.AlignCenter) self.title.setStyleSheet("font-size: 20px; font-weight: bold;") self.main_layout.addWidget(self.title) self.main_layout.addSpacing(20) self.init_login_form() self.init_register_form() self.show_login_form() # Компоновка full_layout = QVBoxLayout(self) full_layout.addLayout(theme_layout) full_layout.addStretch() full_layout.addLayout(self.main_layout) full_layout.addStretch() self.setLayout(full_layout) def init_login_form(self): self.login_input = QLineEdit() self.login_input.setPlaceholderText(localizer.translate("Логин")) self.login_input.setFixedHeight(40) self.password_input = QLineEdit() self.password_input.setPlaceholderText(localizer.translate("Пароль")) self.password_input.setEchoMode(QLineEdit.Password) self.password_input.setFixedHeight(40) self.login_button = QPushButton(localizer.translate("Войти")) self.login_button.setFixedHeight(40) self.login_button.clicked.connect(self.handle_login) self.register_switch = QPushButton(localizer.translate("Нет аккаунта? Регистрация")) self.register_switch.setFlat(True) self.register_switch.clicked.connect(self.show_register_form) def init_register_form(self): # self.name_input = ValidationInput("Имя") # self.name_input.set_validator(validate_name, is_required=False) self.reg_login_input = ValidationInput(localizer.translate("Логин")) self.reg_login_input.set_validator(validate_username) self.reg_password_input = ValidationInput(localizer.translate("Пароль"), is_password=True) self.reg_password_input.set_validator(validate_password) self.confirm_password_input = ValidationInput(localizer.translate("Повторите пароль"), is_password=True) self.confirm_password_input.set_validator(self.validate_confirm_password) self.invite_code_input = ValidationInput(localizer.translate("Инвайт-код")) self.invite_code_input.set_validator(validate_invite_code, is_required=False) self.register_button = QPushButton(localizer.translate("Зарегистрироваться")) self.register_button.setFixedHeight(40) self.register_button.clicked.connect(self.handle_register) self.login_switch = QPushButton(localizer.translate("Уже есть аккаунт? Войти")) self.login_switch.setFlat(True) self.login_switch.clicked.connect(self.show_login_form) self.reg_password_input.textChanged.connect(self.confirm_password_input.on_text_changed) def show_login_form(self): self.is_registration = False self.title.setText(localizer.translate("Авторизация")) self.clear_form() # Очистка layout self.clear_main_layout() self.main_layout.addWidget(self.login_input) self.main_layout.addWidget(self.password_input) self.main_layout.addWidget(self.login_button) self.main_layout.addSpacing(10) self.main_layout.addWidget(self.register_switch) def show_register_form(self): self.is_registration = True self.title.setText(localizer.translate("Регистрация")) self.clear_form() self.clear_main_layout() # self.main_layout.addWidget(self.name_input) self.main_layout.addWidget(self.reg_login_input) self.main_layout.addWidget(self.reg_password_input) self.main_layout.addWidget(self.confirm_password_input) self.main_layout.addWidget(self.invite_code_input) self.main_layout.addWidget(self.register_button) self.main_layout.addSpacing(10) self.main_layout.addWidget(self.login_switch) def clear_form(self): self.login_input.clear() self.password_input.clear() # self.name_input.clear() self.reg_login_input.clear() self.reg_password_input.clear() self.confirm_password_input.clear() self.invite_code_input.clear() def clear_main_layout(self): while self.main_layout.count() > 2: # сохраняем title и spacing child = self.main_layout.takeAt(2) if child.widget(): child.widget().setParent(None) def handle_login(self): login = self.login_input.text() password = self.password_input.text() is_login_valid, login_msg = validate_username(login, is_login=True) is_password_valid, password_msg = validate_password(password, is_login=True) if not is_login_valid or not is_password_valid: # Показываем первую попавшуюся ошибку, они должны быть общими error_msg = login_msg if not is_login_valid else password_msg QMessageBox.warning(self, localizer.translate("Ошибка"), error_msg) return if login == "root" and password == "123": self.on_login(login) else: QMessageBox.warning(self, localizer.translate("Ошибка"), localizer.translate("Неверный логин или пароль")) def validate_confirm_password(self, text): if text != self.reg_password_input.text(): return False, localizer.translate("Пароли не совпадают") return True, "" def handle_register(self): # Trigger validation for all fields # self.name_input.on_text_changed(self.name_input.text()) self.reg_login_input.on_text_changed(self.reg_login_input.text()) self.reg_password_input.on_text_changed(self.reg_password_input.text()) self.confirm_password_input.on_text_changed(self.confirm_password_input.text()) self.invite_code_input.on_text_changed(self.invite_code_input.text()) if not all([ # self.name_input.is_valid, self.reg_login_input.is_valid, self.reg_password_input.is_valid, self.confirm_password_input.is_valid, self.invite_code_input.is_valid ]): QMessageBox.warning(self, localizer.translate("Ошибка"), localizer.translate("Пожалуйста, исправьте ошибки в форме")) return # name = self.name_input.text() login = self.reg_login_input.text() # password = self.reg_password_input.text() # invite = self.invite_code_input.text() QMessageBox.information(self, "Успех", f"{localizer.translate("Регистрация прошла успешно для")} {login}") self.show_login_form() def change_language(self, display_name): lang_code = self.lang_map.get(display_name) if lang_code: localizer.switch_language(lang_code) self.update_ui_language() def toggle_theme(self): self.is_dark_theme = not self.is_dark_theme if self.is_dark_theme: self.apply_dark_theme() else: self.apply_light_theme() def apply_dark_theme(self): self.setStyleSheet(""" QWidget { background-color: #2e2e2e; color: white; } QLineEdit { background-color: #444; color: white; border: 1px solid #666; border-radius: 5px; padding: 5px; } QPushButton { background-color: #555; color: white; border: none; border-radius: 5px; } QPushButton:hover { background-color: #777; } QPushButton:flat { background-color: transparent; color: #aaa; text-decoration: underline; } """) self.theme_button.setText("🌙") def apply_light_theme(self): self.setStyleSheet(""" QWidget { background-color: #f0f0f0; color: #222; } QLineEdit { background-color: white; color: black; border: 1px solid #ccc; border-radius: 5px; padding: 5px; } QPushButton { background-color: #e0e0e0; color: black; border: none; border-radius: 5px; } QPushButton:hover { background-color: #d0d0d0; } QPushButton:flat { background-color: transparent; color: #666; text-decoration: underline; } """) self.theme_button.setText("🌞") def update_ui_language(self): self.theme_button.setText("🌞" if not self.is_dark_theme else "🌙") if self.is_registration: self.title.setText(localizer.translate("Регистрация")) self.register_button.setText(localizer.translate("Зарегистрироваться")) self.login_switch.setText(localizer.translate("Уже есть аккаунт? Войти")) self.reg_login_input.set_label(localizer.translate("Логин")) self.reg_password_input.set_label(localizer.translate("Пароль")) self.confirm_password_input.set_label(localizer.translate("Повторите пароль")) self.invite_code_input.set_label(localizer.translate("Инвайт-код")) else: self.title.setText(localizer.translate("Авторизация")) self.login_button.setText(localizer.translate("Войти")) self.register_switch.setText(localizer.translate("Нет аккаунта? Регистрация")) self.login_input.setPlaceholderText(localizer.translate("Логин")) self.password_input.setPlaceholderText(localizer.translate("Пароль"))