diff --git a/yobble/Views/Login/LoginView.swift b/yobble/Views/Login/LoginView.swift index 7f35d18..61cf95d 100644 --- a/yobble/Views/Login/LoginView.swift +++ b/yobble/Views/Login/LoginView.swift @@ -12,15 +12,21 @@ struct LoginView: View { @AppStorage("messengerModeEnabled") private var isMessengerModeEnabled: Bool = false @State private var isShowingMessengerPrompt: Bool = true @State private var pendingMessengerMode: Bool = UserDefaults.standard.bool(forKey: "messengerModeEnabled") + @State private var showLegacySupportNotice = false var body: some View { ZStack { content .animation(.easeInOut(duration: 0.25), value: viewModel.loginFlowStep) - .allowsHitTesting(!isShowingMessengerPrompt) - .blur(radius: isShowingMessengerPrompt ? 3 : 0) + .allowsHitTesting(!isAnyBlockingOverlayPresented) + .blur(radius: isAnyBlockingOverlayPresented ? 3 : 0) - if isShowingMessengerPrompt { + if showLegacySupportNotice { + LegacySupportNoticeView(isPresented: $showLegacySupportNotice) + .transition(.opacity) + } + + if isShowingMessengerPrompt && !showLegacySupportNotice { Color.black.opacity(0.35) .ignoresSafeArea() .transition(.opacity) @@ -36,6 +42,7 @@ struct LoginView: View { } .onAppear { showModePrompt() + showLegacySupportNoticeIfNeeded() } } @@ -73,10 +80,30 @@ struct LoginView: View { } } + private var isAnyBlockingOverlayPresented: Bool { + isShowingMessengerPrompt || showLegacySupportNotice + } + private var unifiedTransition: AnyTransition { .opacity.combined(with: .scale(scale: 0.98, anchor: .center)) } + private func showLegacySupportNoticeIfNeeded() { + guard shouldShowLegacySupportNotice else { return } + withAnimation { + showLegacySupportNotice = true + } + } + + private var shouldShowLegacySupportNotice: Bool { +#if os(iOS) + let requiredVersion = OperatingSystemVersion(majorVersion: 16, minorVersion: 0, patchVersion: 0) + return !ProcessInfo.processInfo.isOperatingSystemAtLeast(requiredVersion) +#else + return false +#endif + } + private func applyMessengerModeSelection() { isMessengerModeEnabled = pendingMessengerMode dismissMessengerPrompt() @@ -97,7 +124,6 @@ struct PasswordLoginView: View { private let themeOptions = ThemeOption.ordered @AppStorage("messengerModeEnabled") private var isMessengerModeEnabled: Bool = false - @State private var showLegacySupportNotice = false @State private var isShowingTerms = false @State private var hasResetTermsOnAppear = false @State private var isShowingForgotPassword = false @@ -239,9 +265,6 @@ struct PasswordLoginView: View { viewModel.hasAcceptedTerms = false hasResetTermsOnAppear = true } - if shouldShowLegacySupportNotice { - showLegacySupportNotice = true - } } .fullScreenCover(isPresented: $isShowingTerms) { TermsFullScreenView( @@ -260,12 +283,6 @@ struct PasswordLoginView: View { } } } - .overlay(alignment: .center) { - if showLegacySupportNotice { - LegacySupportNoticeView(isPresented: $showLegacySupportNotice) - .transition(.opacity) - } - } .sheet(isPresented: $isShowingForgotPassword) { ForgotPasswordInfoView { isShowingForgotPassword = false @@ -288,15 +305,6 @@ struct PasswordLoginView: View { } } - private var shouldShowLegacySupportNotice: Bool { -#if os(iOS) - let requiredVersion = OperatingSystemVersion(majorVersion: 16, minorVersion: 0, patchVersion: 0) - return !ProcessInfo.processInfo.isOperatingSystemAtLeast(requiredVersion) -#else - return false -#endif - } - private func hideKeyboardAndShowModePrompt() { focusedField = nil onShowModePrompt() @@ -307,54 +315,6 @@ struct PasswordLoginView: View { UIApplication.shared.open(url) } - private struct LegacySupportNoticeView: View { - @Binding var isPresented: Bool - - var body: some View { - ZStack { - Color.black.opacity(0.5) - .ignoresSafeArea() - .onTapGesture { - isPresented = false - } - - VStack(spacing: 16) { - Image(systemName: "exclamationmark.triangle.fill") - .font(.system(size: 40, weight: .bold)) - .foregroundColor(.yellow) - - Text("Экспериментальная поддержка iOS 15") - .font(.headline) - .multilineTextAlignment(.center) - - Text("Поддержка iOS 15 работает в экспериментальном режиме. Для лучшей совместимости требуется iOS 16+.") - .font(.subheadline) - .foregroundColor(.secondary) - .multilineTextAlignment(.center) - - Button { - isPresented = false - } label: { - Text("Понятно") - .bold() - .frame(maxWidth: .infinity) - .padding() - .background(Color.blue) - .foregroundColor(.white) - .cornerRadius(12) - } - } - .padding(24) - .background( - RoundedRectangle(cornerRadius: 20, style: .continuous) - .fill(Color(.systemBackground)) - ) - .frame(maxWidth: 320) - .shadow(radius: 10) - } - } - } - private var selectedThemeOption: ThemeOption { ThemeOption.option(for: themeManager.theme) } @@ -499,6 +459,54 @@ private struct PasswordlessRequestView: View { } } +private struct LegacySupportNoticeView: View { + @Binding var isPresented: Bool + + var body: some View { + ZStack { + Color.black.opacity(0.5) + .ignoresSafeArea() + .onTapGesture { + isPresented = false + } + + VStack(spacing: 16) { + Image(systemName: "exclamationmark.triangle.fill") + .font(.system(size: 40, weight: .bold)) + .foregroundColor(.yellow) + + Text("Экспериментальная поддержка iOS 15") + .font(.headline) + .multilineTextAlignment(.center) + + Text("Поддержка iOS 15 работает в экспериментальном режиме. Для лучшей совместимости требуется iOS 16+.") + .font(.subheadline) + .foregroundColor(.secondary) + .multilineTextAlignment(.center) + + Button { + isPresented = false + } label: { + Text("Понятно") + .bold() + .frame(maxWidth: .infinity) + .padding() + .background(Color.blue) + .foregroundColor(.white) + .cornerRadius(12) + } + } + .padding(24) + .background( + RoundedRectangle(cornerRadius: 20, style: .continuous) + .fill(Color(.systemBackground)) + ) + .frame(maxWidth: 320) + .shadow(radius: 10) + } + } +} + private struct PasswordlessVerifyView: View { @ObservedObject var viewModel: LoginViewModel let shouldAutofocus: Bool