From 10becffb77de1792a5b8566669640680756dbeb5 Mon Sep 17 00:00:00 2001 From: dadachi Date: Thu, 2 Apr 2026 21:29:25 +0900 Subject: [PATCH] Fix accept privacy/terms views not displaying Replace sheet-based presentation with inline content views. Privacy and terms views now render as the main content when shouldUpdatePrivacy or shouldUpdateTerms is true. Set shouldUpdatePrivacy and shouldUpdateTerms to false after successful server update. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Sessions/SessionController.swift | 2 + NativeAppTemplate/UI/App Root/MainView.swift | 76 +++++++++---------- .../UI/App Root/MainViewModel.swift | 14 ---- .../UI/App Root/MainViewModelTest.swift | 70 ----------------- 4 files changed, 36 insertions(+), 126 deletions(-) diff --git a/NativeAppTemplate/Sessions/SessionController.swift b/NativeAppTemplate/Sessions/SessionController.swift index 8e7d509..7da5ade 100644 --- a/NativeAppTemplate/Sessions/SessionController.swift +++ b/NativeAppTemplate/Sessions/SessionController.swift @@ -199,6 +199,7 @@ import Observation func updateConfirmedPrivacyVersion() async throws { do { try await meService.updateConfirmedPrivacyVersion() + shouldUpdatePrivacy = false } catch { Failure .update(from: Self.self, reason: error.codedDescription) @@ -210,6 +211,7 @@ import Observation func updateConfirmedTermsVersion() async throws { do { try await meService.updateConfirmedTermsVersion() + shouldUpdateTerms = false } catch { Failure .update(from: Self.self, reason: error.codedDescription) diff --git a/NativeAppTemplate/UI/App Root/MainView.swift b/NativeAppTemplate/UI/App Root/MainView.swift index 172374e..e73fe86 100644 --- a/NativeAppTemplate/UI/App Root/MainView.swift +++ b/NativeAppTemplate/UI/App Root/MainView.swift @@ -24,12 +24,6 @@ struct MainView: View { viewModel.handleBackgroundTagReading(userActivity) } }) - .onChange(of: sessionController.shouldUpdatePrivacy) { _, _ in - viewModel?.handlePrivacyUpdate() - } - .onChange(of: sessionController.shouldUpdateTerms) { _, _ in - viewModel?.handleTermsUpdate() - } .alert( String.itemTagAlreadyCompleted, isPresented: Binding( @@ -66,6 +60,10 @@ private extension MainView { @ViewBuilder var contentView: some View { if !sessionController.isLoggedIn { OnboardingView(onboardingRepository: dataManager.onboardingRepository) + } else if sessionController.shouldUpdatePrivacy { + acceptPrivacySheet + } else if sessionController.shouldUpdateTerms { + acceptTermsSheet } else { switch sessionController.permissionState { case .loaded: @@ -81,6 +79,36 @@ private extension MainView { } } + var acceptPrivacySheet: some View { + NavigationStack { + AcceptPrivacyView( + arePrivacyAccepted: Binding( + get: { viewModel?.arePrivacyAccepted ?? false }, + set: { viewModel?.arePrivacyAccepted = $0 } + ), + viewModel: AcceptPrivacyViewModel( + sessionController: sessionController, + messageBus: messageBus + ) + ) + } + } + + var acceptTermsSheet: some View { + NavigationStack { + AcceptTermsView( + areTermsAccepted: Binding( + get: { viewModel?.areTermsAccepted ?? false }, + set: { viewModel?.areTermsAccepted = $0 } + ), + viewModel: AcceptTermsViewModel( + sessionController: sessionController, + messageBus: messageBus + ) + ) + } + } + @ViewBuilder var tabBarView: some View { switch sessionController.sessionState { case .online: @@ -106,42 +134,6 @@ private extension MainView { settingsView: settingsView ) .environment(tabViewModel) - .sheet(isPresented: Binding( - get: { viewModel?.isShowingAcceptPrivacySheet ?? false }, - set: { viewModel?.isShowingAcceptPrivacySheet = $0 } - )) { - NavigationStack { - AcceptPrivacyView( - arePrivacyAccepted: Binding( - get: { viewModel?.arePrivacyAccepted ?? false }, - set: { viewModel?.arePrivacyAccepted = $0 } - ), - viewModel: AcceptPrivacyViewModel( - sessionController: sessionController, - messageBus: messageBus - ) - ) - .interactiveDismissDisabled(!(viewModel?.arePrivacyAccepted ?? false)) - } - } - .sheet(isPresented: Binding( - get: { viewModel?.isShowingAcceptTermsSheet ?? false }, - set: { viewModel?.isShowingAcceptTermsSheet = $0 } - )) { - NavigationStack { - AcceptTermsView( - areTermsAccepted: Binding( - get: { viewModel?.areTermsAccepted ?? false }, - set: { viewModel?.areTermsAccepted = $0 } - ), - viewModel: AcceptTermsViewModel( - sessionController: sessionController, - messageBus: messageBus - ) - ) - .interactiveDismissDisabled(!(viewModel?.areTermsAccepted ?? false)) - } - } } } case .offline: diff --git a/NativeAppTemplate/UI/App Root/MainViewModel.swift b/NativeAppTemplate/UI/App Root/MainViewModel.swift index c7edd72..8b665df 100644 --- a/NativeAppTemplate/UI/App Root/MainViewModel.swift +++ b/NativeAppTemplate/UI/App Root/MainViewModel.swift @@ -14,9 +14,7 @@ final class MainViewModel { var itemTagId: String? var isResetting = false var isShowingResetConfirmationDialog = false - var isShowingAcceptPrivacySheet = false var arePrivacyAccepted = false - var isShowingAcceptTermsSheet = false var areTermsAccepted = false private let sessionController: SessionControllerProtocol @@ -36,18 +34,6 @@ final class MainViewModel { self.tabViewModel = tabViewModel } - func handlePrivacyUpdate() { - if sessionController.shouldUpdatePrivacy { - isShowingAcceptPrivacySheet = true - } - } - - func handleTermsUpdate() { - if sessionController.shouldUpdateTerms { - isShowingAcceptTermsSheet = true - } - } - func resetTag() { guard let itemTagId else { return } resetTag(itemTagId: itemTagId) diff --git a/NativeAppTemplateTests/UI/App Root/MainViewModelTest.swift b/NativeAppTemplateTests/UI/App Root/MainViewModelTest.swift index b442f7b..4874762 100644 --- a/NativeAppTemplateTests/UI/App Root/MainViewModelTest.swift +++ b/NativeAppTemplateTests/UI/App Root/MainViewModelTest.swift @@ -38,74 +38,10 @@ struct MainViewModelTest { #expect(viewModel.itemTagId == nil) #expect(viewModel.isResetting == false) #expect(viewModel.isShowingResetConfirmationDialog == false) - #expect(viewModel.isShowingAcceptPrivacySheet == false) #expect(viewModel.arePrivacyAccepted == false) - #expect(viewModel.isShowingAcceptTermsSheet == false) #expect(viewModel.areTermsAccepted == false) } - @Test - func handlePrivacyUpdate() { - let dataManager = createTestDataManager() - let tabViewModel = createTestTabViewModel() - - let viewModel = MainViewModel( - sessionController: sessionController, - dataManager: dataManager, - messageBus: messageBus, - tabViewModel: tabViewModel - ) - - // Initially should not show privacy sheet - #expect(viewModel.isShowingAcceptPrivacySheet == false) - - // Set shouldUpdatePrivacy to true - sessionController.shouldUpdatePrivacy = true - - viewModel.handlePrivacyUpdate() - - #expect(viewModel.isShowingAcceptPrivacySheet == true) - - // Set shouldUpdatePrivacy to false - sessionController.shouldUpdatePrivacy = false - - viewModel.handlePrivacyUpdate() - - // Should not change the sheet state when false - #expect(viewModel.isShowingAcceptPrivacySheet == true) - } - - @Test - func handleTermsUpdate() { - let dataManager = createTestDataManager() - let tabViewModel = createTestTabViewModel() - - let viewModel = MainViewModel( - sessionController: sessionController, - dataManager: dataManager, - messageBus: messageBus, - tabViewModel: tabViewModel - ) - - // Initially should not show terms sheet - #expect(viewModel.isShowingAcceptTermsSheet == false) - - // Set shouldUpdateTerms to true - sessionController.shouldUpdateTerms = true - - viewModel.handleTermsUpdate() - - #expect(viewModel.isShowingAcceptTermsSheet == true) - - // Set shouldUpdateTerms to false - sessionController.shouldUpdateTerms = false - - viewModel.handleTermsUpdate() - - // Should not change the sheet state when false - #expect(viewModel.isShowingAcceptTermsSheet == true) - } - @Test func logout() async { let dataManager = createTestDataManager() @@ -212,15 +148,9 @@ struct MainViewModelTest { viewModel.isShowingResetConfirmationDialog = true #expect(viewModel.isShowingResetConfirmationDialog == true) - viewModel.isShowingAcceptPrivacySheet = true - #expect(viewModel.isShowingAcceptPrivacySheet == true) - viewModel.arePrivacyAccepted = true #expect(viewModel.arePrivacyAccepted == true) - viewModel.isShowingAcceptTermsSheet = true - #expect(viewModel.isShowingAcceptTermsSheet == true) - viewModel.areTermsAccepted = true #expect(viewModel.areTermsAccepted == true)