@@ -30,9 +30,9 @@ class TimedSheetManager: ObservableObject {
3030 static let shared = TimedSheetManager ( )
3131
3232 private let checkDelay : TimeInterval = 2.0 // 2 seconds delay
33- private var homeScreenTimer : Timer ?
33+ private var settleTimer : Timer ?
3434 private var queuedSheets : [ any TimedSheetItem ] = [ ]
35- private var isOnHomeScreen = false
35+ private var isOnPrimaryScreen = false
3636 private var currentlyShowingSheet : ( any TimedSheetItem ) ?
3737
3838 private weak var sheetViewModel : SheetViewModel ?
@@ -95,41 +95,47 @@ class TimedSheetManager: ObservableObject {
9595 Logger . debug ( " Removed timed sheet: \( id. rawValue) " )
9696 }
9797
98- /// Call this when user enters the home screen
99- func onHomeScreenEntered( ) {
100- guard !isOnHomeScreen else { return }
98+ /// Call this when a primary screen appears.
99+ ///
100+ /// A primary screen is a top-level screen where timed sheets are allowed to surface:
101+ /// the home screen (wallet flow) or the onboarding root (no wallet yet). The app-update
102+ /// prompt is the only registered sheet whose `shouldShow()` can pass without a wallet, so
103+ /// onboarding only ever surfaces that one (see issue #460).
104+ func onPrimaryScreenEntered( ) {
105+ guard !isOnPrimaryScreen else { return }
101106
102- isOnHomeScreen = true
103- Logger . debug ( " User entered home screen, starting timer" )
107+ isOnPrimaryScreen = true
108+ Logger . debug ( " Entered primary screen, starting timer" )
104109
105- // Cancel any existing timer
106- homeScreenTimer ? . invalidate ( )
110+ scheduleSettleCheck ( )
111+ }
107112
108- // Start timer to check for sheets after delay
109- homeScreenTimer = Timer . scheduledTimer ( withTimeInterval: checkDelay, repeats: false ) { [ weak self] _ in
110- Task { @MainActor in
111- await self ? . checkAndShowNextSheet ( )
112- }
113- }
113+ /// Re-check the timed-sheet queue after async state changes that may have made a sheet newly
114+ /// eligible (for example, the app-update info arriving after the initial settle check). No-ops
115+ /// unless on a primary screen with no sheet already open.
116+ func reevaluate( ) {
117+ guard isOnPrimaryScreen, !( sheetViewModel? . isAnySheetOpen ?? false ) else { return }
118+ Logger . debug ( " Re-evaluating timed sheets after external state change " )
119+ scheduleSettleCheck ( )
114120 }
115121
116- /// Call this when user leaves the home screen
117- func onHomeScreenExited ( ) {
118- guard isOnHomeScreen else { return }
122+ /// Call this when the primary screen disappears.
123+ func onPrimaryScreenExited ( ) {
124+ guard isOnPrimaryScreen else { return }
119125
120- isOnHomeScreen = false
121- Logger . debug ( " User exited home screen, cancelling timer" )
126+ isOnPrimaryScreen = false
127+ Logger . debug ( " Exited primary screen, cancelling timer" )
122128
123129 // Cancel timer
124- homeScreenTimer ? . invalidate ( )
125- homeScreenTimer = nil
130+ settleTimer ? . invalidate ( )
131+ settleTimer = nil
126132 }
127133
128134 /// Call this when any sheet is shown (to prevent showing timed sheets)
129135 func onSheetShown( ) {
130136 // If a sheet is shown, cancel any pending timed sheet checks
131- homeScreenTimer ? . invalidate ( )
132- homeScreenTimer = nil
137+ settleTimer ? . invalidate ( )
138+ settleTimer = nil
133139 }
134140
135141 /// Call this when a sheet is dismissed
@@ -141,6 +147,19 @@ class TimedSheetManager: ObservableObject {
141147 }
142148 }
143149
150+ /// (Re)start the settle timer that runs the queue check after a short delay.
151+ private func scheduleSettleCheck( ) {
152+ // Cancel any existing timer
153+ settleTimer? . invalidate ( )
154+
155+ // Start timer to check for sheets after delay
156+ settleTimer = Timer . scheduledTimer ( withTimeInterval: checkDelay, repeats: false ) { [ weak self] _ in
157+ Task { @MainActor in
158+ await self ? . checkAndShowNextSheet ( )
159+ }
160+ }
161+ }
162+
144163 /// Check the queue and show the highest priority sheet that should be shown
145164 private func checkAndShowNextSheet( ) async {
146165 guard let sheetViewModel else {
@@ -154,9 +173,9 @@ class TimedSheetManager: ObservableObject {
154173 return
155174 }
156175
157- // Don't show if not on home screen anymore
158- guard isOnHomeScreen else {
159- Logger . debug ( " No longer on home screen, skipping timed sheet check " )
176+ // Don't show if no longer on a primary screen
177+ guard isOnPrimaryScreen else {
178+ Logger . debug ( " No longer on a primary screen, skipping timed sheet check " )
160179 return
161180 }
162181
0 commit comments