Compare commits

...

4 Commits

Author SHA1 Message Date
3c394446d2 add afterregister 2025-10-24 21:23:53 +03:00
9f2a938b1e add buttons 2025-10-24 21:19:49 +03:00
7a2fb798a3 delete old open settings 2025-10-24 21:15:21 +03:00
b46fc3ae16 add afterregister sheet 2025-10-24 21:05:11 +03:00
5 changed files with 103 additions and 39 deletions

View File

@ -239,6 +239,9 @@
} }
} }
} }
},
"Безопасность аккаунта" : {
}, },
"Блокировка контакта \"%1$@\" появится позже." : { "Блокировка контакта \"%1$@\" появится позже." : {
"comment" : "Contacts block placeholder message" "comment" : "Contacts block placeholder message"
@ -455,6 +458,9 @@
}, },
"Десктоп" : { "Десктоп" : {
"comment" : "Тип сессии — десктоп" "comment" : "Тип сессии — десктоп"
},
"Для начала, мы рекомендуем настроить параметры безопасности вашего аккаунта." : {
}, },
"Добавить друзей" : { "Добавить друзей" : {
"comment" : "Add friends", "comment" : "Add friends",
@ -475,6 +481,9 @@
}, },
"Добавьте новый аккаунт в приложении аутентификации и введите следующий ключ:" : { "Добавьте новый аккаунт в приложении аутентификации и введите следующий ключ:" : {
"comment" : "Инструкция по добавлению ключа 2FA" "comment" : "Инструкция по добавлению ключа 2FA"
},
"Добро пожаловать в Yobble!" : {
}, },
"Другие устройства (%d)" : { "Другие устройства (%d)" : {
"comment" : "Заголовок секции других устройств с количеством" "comment" : "Заголовок секции других устройств с количеством"
@ -1063,6 +1072,9 @@
} }
} }
} }
},
"Начальная настройка" : {
}, },
"Не удалось выполнить поиск." : { "Не удалось выполнить поиск." : {
"comment" : "Search error fallback\nSearch service decoding error" "comment" : "Search error fallback\nSearch service decoding error"
@ -2010,6 +2022,9 @@
}, },
"Проверьте цифры и попробуйте снова." : { "Проверьте цифры и попробуйте снова." : {
"comment" : "Описание ошибки неверного кода 2FA" "comment" : "Описание ошибки неверного кода 2FA"
},
"Продолжить" : {
}, },
"Произошла неизвестная ошибка." : { "Произошла неизвестная ошибка." : {
"comment" : "Search unknown error" "comment" : "Search unknown error"
@ -2026,6 +2041,9 @@
} }
} }
} }
},
"Пропустить" : {
}, },
"Просмотр \"%1$@\" появится позже." : { "Просмотр \"%1$@\" появится позже." : {
"comment" : "Contacts placeholder message" "comment" : "Contacts placeholder message"

View File

@ -34,7 +34,7 @@ class LoginViewModel: ObservableObject {
} }
enum OnboardingDestination: Equatable { enum OnboardingDestination: Equatable {
case securitySettings case afterRegister
} }
private enum DefaultsKeys { private enum DefaultsKeys {
@ -132,7 +132,7 @@ class LoginViewModel: ObservableObject {
self?.isLoggedIn = true // 👈 переключаем на главный экран после автологина self?.isLoggedIn = true // 👈 переключаем на главный экран после автологина
self?.loadStoredUser() self?.loadStoredUser()
self?.socketService.connectForCurrentUser() self?.socketService.connectForCurrentUser()
self?.onboardingDestination = .securitySettings self?.onboardingDestination = .afterRegister
} else { } else {
self?.socketService.disconnect() self?.socketService.disconnect()
} }

View File

@ -0,0 +1,72 @@
//
// 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))
}
}

View File

@ -22,6 +22,7 @@ struct MainView: View {
@State private var deepLinkChatItem: PrivateChatListItem? @State private var deepLinkChatItem: PrivateChatListItem?
@State private var isDeepLinkChatActive = false @State private var isDeepLinkChatActive = false
@State private var hasTriggeredSecuritySettingsOnboarding = false @State private var hasTriggeredSecuritySettingsOnboarding = false
@State private var isAfterRegisterPresented = false
private var tabTitle: String { private var tabTitle: String {
switch selectedTab { switch selectedTab {
@ -173,14 +174,14 @@ struct MainView: View {
} }
.onAppear { .onAppear {
enforceTabSelectionForMessengerMode() enforceTabSelectionForMessengerMode()
handleTwoFactorOnboardingIfNeeded() handleAfterRegisterOnboardingIfNeeded()
} }
.onChange(of: isMessengerModeEnabled) { _ in .onChange(of: isMessengerModeEnabled) { _ in
enforceTabSelectionForMessengerMode() enforceTabSelectionForMessengerMode()
handleTwoFactorOnboardingIfNeeded() handleAfterRegisterOnboardingIfNeeded()
} }
.onChange(of: viewModel.onboardingDestination) { _ in .onChange(of: viewModel.onboardingDestination) { _ in
handleTwoFactorOnboardingIfNeeded() handleAfterRegisterOnboardingIfNeeded()
} }
.onChange(of: messageCenter.pendingNavigation?.id) { _ in .onChange(of: messageCenter.pendingNavigation?.id) { _ in
guard !AppConfig.PRESENT_CHAT_AS_SHEET, guard !AppConfig.PRESENT_CHAT_AS_SHEET,
@ -209,6 +210,9 @@ struct MainView: View {
isSettingsPresented = false isSettingsPresented = false
} }
} }
.fullScreenCover(isPresented: $isAfterRegisterPresented) {
AfterRegisterView(isPresented: $isAfterRegisterPresented)
}
} }
} }
@ -223,27 +227,13 @@ private extension MainView {
} }
} }
func handleTwoFactorOnboardingIfNeeded() {
guard viewModel.onboardingDestination == .securitySettings else { func handleAfterRegisterOnboardingIfNeeded() {
hasTriggeredSecuritySettingsOnboarding = false guard viewModel.onboardingDestination == .afterRegister else {
return return
} }
guard !hasTriggeredSecuritySettingsOnboarding else { return } isAfterRegisterPresented = true
hasTriggeredSecuritySettingsOnboarding = true
if isMessengerModeEnabled {
if selectedTab != 5 {
selectedTab = 5
}
} else {
if selectedTab != 3 {
selectedTab = 3
}
DispatchQueue.main.async {
isSettingsPresented = true
}
}
} }
var deepLinkNavigationLink: some View { var deepLinkNavigationLink: some View {

View File

@ -132,12 +132,6 @@ struct SettingsView: View {
} }
} }
.navigationTitle("Настройки") .navigationTitle("Настройки")
.onAppear {
handleTwoFactorOnboardingIfNeeded()
}
.onChange(of: viewModel.onboardingDestination) { _ in
handleTwoFactorOnboardingIfNeeded()
}
} }
private func openLanguageSettings() { private func openLanguageSettings() {
@ -178,13 +172,3 @@ struct SettingsView: View {
} }
} }
private extension SettingsView {
func handleTwoFactorOnboardingIfNeeded() {
guard viewModel.onboardingDestination == .securitySettings else { return }
guard !isSecurityActive else { return }
DispatchQueue.main.async {
isSecurityActive = true
}
}
}