diff --git a/yobble/Components/TopBarView.swift b/yobble/Components/TopBarView.swift index 0a9b9b2..2175323 100644 --- a/yobble/Components/TopBarView.swift +++ b/yobble/Components/TopBarView.swift @@ -7,7 +7,8 @@ struct TopBarView: View { @Binding var selectedAccount: String // @Binding var sheetType: ProfileTab.SheetType? var accounts: [String] - var viewModel: LoginViewModel +// var viewModel: LoginViewModel + @ObservedObject var viewModel: LoginViewModel // Привязка для управления боковым меню @Binding var isSideMenuPresented: Bool @@ -45,7 +46,7 @@ struct TopBarView: View { Spacer() Button(action: { }) { HStack(spacing: 4) { - Text(selectedAccount) + Text("@\(viewModel.username)") .font(.headline) .foregroundColor(.primary) Image(systemName: "chevron.down") diff --git a/yobble/Network/AuthService.swift b/yobble/Network/AuthService.swift index e53d302..12783f3 100644 --- a/yobble/Network/AuthService.swift +++ b/yobble/Network/AuthService.swift @@ -104,7 +104,6 @@ class AuthService { // Сохраняем токены в Keychain KeychainService.shared.save(loginResponse.access_token, forKey: "access_token", service: username) KeychainService.shared.save(loginResponse.refresh_token, forKey: "refresh_token", service: username) - print("loginResponse.user_id \(loginResponse.user_id)") KeychainService.shared.save(loginResponse.user_id, forKey: "userId", service: username) UserDefaults.standard.set(username, forKey: "currentUser") diff --git a/yobble/Resources/Localizable.xcstrings b/yobble/Resources/Localizable.xcstrings index ce871e8..e634ec1 100644 --- a/yobble/Resources/Localizable.xcstrings +++ b/yobble/Resources/Localizable.xcstrings @@ -1,6 +1,9 @@ { "sourceLanguage" : "en", "strings" : { + "@%@" : { + + }, "@yourusername" : { }, diff --git a/yobble/ViewModels/LoginViewModel.swift b/yobble/ViewModels/LoginViewModel.swift index 3eca5ca..8b07628 100644 --- a/yobble/ViewModels/LoginViewModel.swift +++ b/yobble/ViewModels/LoginViewModel.swift @@ -25,7 +25,7 @@ class LoginViewModel: ObservableObject { } init() { - loadStoredUser() +// loadStoredUser() // Запускаем автологин autoLogin() @@ -113,6 +113,6 @@ class LoginViewModel: ObservableObject { username = defaults.string(forKey: DefaultsKeys.currentUser) ?? "" userId = KeychainService.shared.get(forKey: DefaultsKeys.userId, service: username) ?? "" - print("username: \(username) | userId: \(userId)") + if AppConfig.DEBUG{ print("username: \(username) | userId: \(userId)")} } } diff --git a/yobble/Views/Login/LoginView.swift b/yobble/Views/Login/LoginView.swift index 00b34cc..616fb8d 100644 --- a/yobble/Views/Login/LoginView.swift +++ b/yobble/Views/Login/LoginView.swift @@ -13,6 +13,12 @@ struct LoginView: View { @Environment(\.colorScheme) private var colorScheme @State private var isShowingRegistration = false + @FocusState private var focusedField: Field? + + private enum Field: Hashable { + case username + case password + } private var isUsernameValid: Bool { let pattern = "^[A-Za-z0-9_]{3,32}$" @@ -29,7 +35,7 @@ struct LoginView: View { Color.clear // чтобы поймать тап .contentShape(Rectangle()) .onTapGesture { - hideKeyboard() + focusedField = nil } VStack { @@ -46,8 +52,8 @@ struct LoginView: View { } } .onTapGesture { - hideKeyboard() - } + focusedField = nil + } Spacer() @@ -57,6 +63,7 @@ struct LoginView: View { .cornerRadius(8) .autocapitalization(.none) .disableAutocorrection(true) + .focused($focusedField, equals: .username) .onChange(of: viewModel.username) { newValue in if newValue.count > 32 { viewModel.username = String(newValue.prefix(32)) @@ -76,6 +83,7 @@ struct LoginView: View { .background(Color(.secondarySystemBackground)) .cornerRadius(8) .autocapitalization(.none) + .focused($focusedField, equals: .password) .onChange(of: viewModel.password) { newValue in if newValue.count > 32 { viewModel.password = String(newValue.prefix(32)) @@ -140,8 +148,8 @@ struct LoginView: View { ) } .onTapGesture { - hideKeyboard() - } + focusedField = nil + } } } @@ -169,10 +177,6 @@ struct LoginView: View { UIApplication.shared.open(url) } - private func hideKeyboard() { - UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) - } - } struct LoginView_Previews: PreviewProvider { diff --git a/yobble/Views/Login/RegistrationView.swift b/yobble/Views/Login/RegistrationView.swift index 7ab000b..c3393cc 100644 --- a/yobble/Views/Login/RegistrationView.swift +++ b/yobble/Views/Login/RegistrationView.swift @@ -22,6 +22,15 @@ struct RegistrationView: View { @State private var showError: Bool = false @State private var errorMessage: String = "" + @FocusState private var focusedField: Field? + + private enum Field: Hashable { + case username + case password + case confirmPassword + case invite + } + private var isUsernameValid: Bool { let pattern = "^[A-Za-z0-9_]{3,32}$" return username.range(of: pattern, options: .regularExpression) != nil @@ -45,7 +54,7 @@ struct RegistrationView: View { ZStack(alignment: .top) { Color.clear .contentShape(Rectangle()) - .onTapGesture { hideKeyboard() } + .onTapGesture { focusedField = nil } VStack(alignment: .leading, spacing: 16) { Group { @@ -53,6 +62,7 @@ struct RegistrationView: View { TextField(NSLocalizedString("Логин", comment: "Логин"), text: $username) .autocapitalization(.none) .disableAutocorrection(true) + .focused($focusedField, equals: .username) Spacer() if !username.isEmpty { Image(systemName: isUsernameValid ? "checkmark.circle" : "xmark.circle") @@ -79,6 +89,7 @@ struct RegistrationView: View { HStack { SecureField(NSLocalizedString("Пароль", comment: "Пароль"), text: $password) .autocapitalization(.none) + .focused($focusedField, equals: .password) Spacer() if !password.isEmpty { Image(systemName: isPasswordValid ? "checkmark.circle" : "xmark.circle") @@ -104,6 +115,7 @@ struct RegistrationView: View { HStack { SecureField(NSLocalizedString("Подтверждение пароля", comment: "Подтверждение пароля"), text: $confirmPassword) .autocapitalization(.none) + .focused($focusedField, equals: .confirmPassword) Spacer() if !confirmPassword.isEmpty { Image(systemName: isConfirmPasswordValid ? "checkmark.circle" : "xmark.circle") @@ -132,6 +144,7 @@ struct RegistrationView: View { .cornerRadius(8) .autocapitalization(.none) .disableAutocorrection(true) + .focused($focusedField, equals: .invite) } Button(action: registerUser) { @@ -189,14 +202,10 @@ struct RegistrationView: View { } private func dismissSheet() { - hideKeyboard() + focusedField = nil isPresented = false presentationMode.wrappedValue.dismiss() } - - private func hideKeyboard() { - UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) - } } diff --git a/yobble/Views/Tab/MainView.swift b/yobble/Views/Tab/MainView.swift index 8acfbde..84ad797 100644 --- a/yobble/Views/Tab/MainView.swift +++ b/yobble/Views/Tab/MainView.swift @@ -79,7 +79,7 @@ struct MainView: View { .allowsHitTesting(menuOffset > 0) // Боковое меню - SideMenuView(isPresented: $isSideMenuPresented) + SideMenuView(viewModel: viewModel, isPresented: $isSideMenuPresented) .frame(width: menuWidth) .offset(x: -menuWidth + menuOffset) // Новая логика смещения .ignoresSafeArea(edges: .vertical) diff --git a/yobble/Views/Tab/SideMenuView.swift b/yobble/Views/Tab/SideMenuView.swift index a2df504..b550d7f 100644 --- a/yobble/Views/Tab/SideMenuView.swift +++ b/yobble/Views/Tab/SideMenuView.swift @@ -62,6 +62,7 @@ struct SideMenuFooterButton: View { // --- MAIN VIEW --- struct SideMenuView: View { + @ObservedObject var viewModel: LoginViewModel @EnvironmentObject var themeManager: ThemeManager @Environment(\.colorScheme) var colorScheme @Binding var isPresented: Bool @@ -132,10 +133,10 @@ struct SideMenuView: View { }) { HStack { VStack(alignment: .leading) { - Text("Your Name") + Text("@\(viewModel.username)") .font(.title3).bold() - Text("@yourusername") - .font(.footnote) +// Text("@yourusername") +// .font(.footnote) } .foregroundColor(.primary) @@ -172,8 +173,9 @@ struct SideMenuView: View { } VStack(alignment: .leading) { - Text(account.name).font(.footnote).bold() // Smaller text - Text(account.username).font(.caption2) // Smaller text + Text(account.username).font(.footnote).bold() // Smaller text +// Text(account.name).font(.footnote).bold() // Smaller text +// Text(account.username).font(.caption2) // Smaller text } .foregroundColor(.primary) } @@ -253,7 +255,8 @@ struct SideMenuView: View { struct SideMenuView_Previews: PreviewProvider { static var previews: some View { - SideMenuView(isPresented: .constant(true)) + let mockViewModel = LoginViewModel() + SideMenuView(viewModel: mockViewModel, isPresented: .constant(true)) .environmentObject(ThemeManager()) } }