burger menu
This commit is contained in:
parent
5d74af5597
commit
102826ac8a
@ -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")
|
||||
|
||||
@ -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")
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
{
|
||||
"sourceLanguage" : "en",
|
||||
"strings" : {
|
||||
"@%@" : {
|
||||
|
||||
},
|
||||
"@yourusername" : {
|
||||
|
||||
},
|
||||
|
||||
@ -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)")}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user