Compare commits
	
		
			No commits in common. "3c394446d2c7bb984f0cc5983685cbf56ade692c" and "b466864350345257a9b719e2cd8770f29ef59aa1" have entirely different histories.
		
	
	
		
			3c394446d2
			...
			b466864350
		
	
		
@ -239,9 +239,6 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "Безопасность аккаунта" : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Блокировка контакта \"%1$@\" появится позже." : {
 | 
			
		||||
      "comment" : "Contacts block placeholder message"
 | 
			
		||||
@ -458,9 +455,6 @@
 | 
			
		||||
    },
 | 
			
		||||
    "Десктоп" : {
 | 
			
		||||
      "comment" : "Тип сессии — десктоп"
 | 
			
		||||
    },
 | 
			
		||||
    "Для начала, мы рекомендуем настроить параметры безопасности вашего аккаунта." : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Добавить друзей" : {
 | 
			
		||||
      "comment" : "Add friends",
 | 
			
		||||
@ -481,9 +475,6 @@
 | 
			
		||||
    },
 | 
			
		||||
    "Добавьте новый аккаунт в приложении аутентификации и введите следующий ключ:" : {
 | 
			
		||||
      "comment" : "Инструкция по добавлению ключа 2FA"
 | 
			
		||||
    },
 | 
			
		||||
    "Добро пожаловать в Yobble!" : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Другие устройства (%d)" : {
 | 
			
		||||
      "comment" : "Заголовок секции других устройств с количеством"
 | 
			
		||||
@ -1072,9 +1063,6 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "Начальная настройка" : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Не удалось выполнить поиск." : {
 | 
			
		||||
      "comment" : "Search error fallback\nSearch service decoding error"
 | 
			
		||||
@ -2022,9 +2010,6 @@
 | 
			
		||||
    },
 | 
			
		||||
    "Проверьте цифры и попробуйте снова." : {
 | 
			
		||||
      "comment" : "Описание ошибки неверного кода 2FA"
 | 
			
		||||
    },
 | 
			
		||||
    "Продолжить" : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Произошла неизвестная ошибка." : {
 | 
			
		||||
      "comment" : "Search unknown error"
 | 
			
		||||
@ -2041,9 +2026,6 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "Пропустить" : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Просмотр \"%1$@\" появится позже." : {
 | 
			
		||||
      "comment" : "Contacts placeholder message"
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@ class LoginViewModel: ObservableObject {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum OnboardingDestination: Equatable {
 | 
			
		||||
        case afterRegister
 | 
			
		||||
        case securitySettings
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private enum DefaultsKeys {
 | 
			
		||||
@ -132,7 +132,7 @@ class LoginViewModel: ObservableObject {
 | 
			
		||||
                    self?.isLoggedIn = true // 👈 переключаем на главный экран после автологина
 | 
			
		||||
                    self?.loadStoredUser()
 | 
			
		||||
                    self?.socketService.connectForCurrentUser()
 | 
			
		||||
                    self?.onboardingDestination = .afterRegister
 | 
			
		||||
                    self?.onboardingDestination = .securitySettings
 | 
			
		||||
                } else {
 | 
			
		||||
                    self?.socketService.disconnect()
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -1,72 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  AfterRegisterView.swift
 | 
			
		||||
//  yobble
 | 
			
		||||
//
 | 
			
		||||
//  Created by cheykrym on 24.10.2025.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import SwiftUI
 | 
			
		||||
 | 
			
		||||
struct AfterRegisterView: View {
 | 
			
		||||
    @Binding var isPresented: Bool
 | 
			
		||||
    @State private var isTwoFactorActive = false
 | 
			
		||||
    @State private var isEmailSettingsActive = false
 | 
			
		||||
    @State private var isAppLockActive = false
 | 
			
		||||
 | 
			
		||||
    var body: some View {
 | 
			
		||||
        NavigationView {
 | 
			
		||||
            Form {
 | 
			
		||||
                Section(header: Text(NSLocalizedString("Добро пожаловать в Yobble!", comment: ""))) {
 | 
			
		||||
                    Text(NSLocalizedString("Для начала, мы рекомендуем настроить параметры безопасности вашего аккаунта.", comment: ""))
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Section(header: Text(NSLocalizedString("Безопасность аккаунта", comment: ""))) {
 | 
			
		||||
                    NavigationLink(destination: TwoFactorAuthView()) {
 | 
			
		||||
                        Label(NSLocalizedString("Двухфакторная аутентификация", comment: ""), systemImage: "lock.shield")
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    NavigationLink(destination: EmailSecuritySettingsView()) {
 | 
			
		||||
                        Label(NSLocalizedString("Настройки email", comment: ""), systemImage: "envelope")
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Section(header: Text(NSLocalizedString("Приложение", comment: ""))) {
 | 
			
		||||
                    NavigationLink(destination: AppLockSettingsView()) {
 | 
			
		||||
                        Label(NSLocalizedString("Пароль на приложение", comment: ""), systemImage: "lock.square")
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Section(header: Text(NSLocalizedString("Профиль", comment: ""))) {
 | 
			
		||||
                    NavigationLink(destination: EditProfileView()) {
 | 
			
		||||
                        Label(NSLocalizedString("Редактировать профиль", comment: ""), systemImage: "person.crop.circle")
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    NavigationLink(destination: EditPrivacyView()) {
 | 
			
		||||
                        Label(NSLocalizedString("Конфиденциальность", comment: ""), systemImage: "lock.fill")
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                Section {
 | 
			
		||||
                    Button(action: { isPresented = false }) {
 | 
			
		||||
                        Text(NSLocalizedString("Продолжить", comment: ""))
 | 
			
		||||
                            .frame(maxWidth: .infinity, alignment: .center)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            .navigationTitle(NSLocalizedString("Начальная настройка", comment: ""))
 | 
			
		||||
            .toolbar {
 | 
			
		||||
                ToolbarItem(placement: .navigationBarTrailing) {
 | 
			
		||||
                    Button(NSLocalizedString("Пропустить", comment: "")) {
 | 
			
		||||
                        isPresented = false
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct AfterRegisterView_Previews: PreviewProvider {
 | 
			
		||||
    static var previews: some View {
 | 
			
		||||
        AfterRegisterView(isPresented: .constant(true))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -22,7 +22,6 @@ struct MainView: View {
 | 
			
		||||
    @State private var deepLinkChatItem: PrivateChatListItem?
 | 
			
		||||
    @State private var isDeepLinkChatActive = false
 | 
			
		||||
    @State private var hasTriggeredSecuritySettingsOnboarding = false
 | 
			
		||||
    @State private var isAfterRegisterPresented = false
 | 
			
		||||
 | 
			
		||||
    private var tabTitle: String {
 | 
			
		||||
        switch selectedTab {
 | 
			
		||||
@ -174,14 +173,14 @@ struct MainView: View {
 | 
			
		||||
        }
 | 
			
		||||
        .onAppear {
 | 
			
		||||
            enforceTabSelectionForMessengerMode()
 | 
			
		||||
            handleAfterRegisterOnboardingIfNeeded()
 | 
			
		||||
            handleTwoFactorOnboardingIfNeeded()
 | 
			
		||||
        }
 | 
			
		||||
        .onChange(of: isMessengerModeEnabled) { _ in
 | 
			
		||||
            enforceTabSelectionForMessengerMode()
 | 
			
		||||
            handleAfterRegisterOnboardingIfNeeded()
 | 
			
		||||
            handleTwoFactorOnboardingIfNeeded()
 | 
			
		||||
        }
 | 
			
		||||
        .onChange(of: viewModel.onboardingDestination) { _ in
 | 
			
		||||
            handleAfterRegisterOnboardingIfNeeded()
 | 
			
		||||
            handleTwoFactorOnboardingIfNeeded()
 | 
			
		||||
        }
 | 
			
		||||
        .onChange(of: messageCenter.pendingNavigation?.id) { _ in
 | 
			
		||||
            guard !AppConfig.PRESENT_CHAT_AS_SHEET,
 | 
			
		||||
@ -210,9 +209,6 @@ struct MainView: View {
 | 
			
		||||
                isSettingsPresented = false
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        .fullScreenCover(isPresented: $isAfterRegisterPresented) {
 | 
			
		||||
            AfterRegisterView(isPresented: $isAfterRegisterPresented)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -227,13 +223,27 @@ private extension MainView {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    func handleAfterRegisterOnboardingIfNeeded() {
 | 
			
		||||
        guard viewModel.onboardingDestination == .afterRegister else {
 | 
			
		||||
    func handleTwoFactorOnboardingIfNeeded() {
 | 
			
		||||
        guard viewModel.onboardingDestination == .securitySettings else {
 | 
			
		||||
            hasTriggeredSecuritySettingsOnboarding = false
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        isAfterRegisterPresented = true
 | 
			
		||||
        guard !hasTriggeredSecuritySettingsOnboarding else { return }
 | 
			
		||||
        hasTriggeredSecuritySettingsOnboarding = true
 | 
			
		||||
 | 
			
		||||
        if isMessengerModeEnabled {
 | 
			
		||||
            if selectedTab != 5 {
 | 
			
		||||
                selectedTab = 5
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if selectedTab != 3 {
 | 
			
		||||
                selectedTab = 3
 | 
			
		||||
            }
 | 
			
		||||
            DispatchQueue.main.async {
 | 
			
		||||
                isSettingsPresented = true
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var deepLinkNavigationLink: some View {
 | 
			
		||||
 | 
			
		||||
@ -132,6 +132,12 @@ struct SettingsView: View {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        .navigationTitle("Настройки")
 | 
			
		||||
        .onAppear {
 | 
			
		||||
            handleTwoFactorOnboardingIfNeeded()
 | 
			
		||||
        }
 | 
			
		||||
        .onChange(of: viewModel.onboardingDestination) { _ in
 | 
			
		||||
            handleTwoFactorOnboardingIfNeeded()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private func openLanguageSettings() {
 | 
			
		||||
@ -172,3 +178,13 @@ struct SettingsView: View {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private extension SettingsView {
 | 
			
		||||
    func handleTwoFactorOnboardingIfNeeded() {
 | 
			
		||||
        guard viewModel.onboardingDestination == .securitySettings else { return }
 | 
			
		||||
        guard !isSecurityActive else { return }
 | 
			
		||||
        DispatchQueue.main.async {
 | 
			
		||||
            isSecurityActive = true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user