-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Fix desktop onboarding reset scoping #5604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2466,6 +2466,12 @@ class AppState: ObservableObject { | |
| nonisolated func resetOnboardingAndRestart() { | ||
| log("Resetting onboarding state for current app...") | ||
|
|
||
| // Update live @AppStorage state in the current app instance before touching | ||
| // raw UserDefaults so SwiftUI doesn't write stale onboarding values back. | ||
| DispatchQueue.main.async { | ||
| NotificationCenter.default.post(name: .resetOnboardingRequested, object: nil) | ||
| } | ||
|
|
||
| // Clear onboarding-related UserDefaults keys (thread-safe, do first) | ||
| let onboardingKeys = [ | ||
| "hasCompletedOnboarding", | ||
|
|
@@ -2503,6 +2509,7 @@ class AppState: ObservableObject { | |
|
|
||
| // Restart off the main thread to avoid blocking the menu action path. | ||
| DispatchQueue.global(qos: .utility).async { [self] in | ||
| Thread.sleep(forTimeInterval: 0.15) | ||
|
Comment on lines
2511
to
+2512
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { [self] in
self.restartApp()
}This also removes the need for |
||
| // Keep onboarding reset scoped to the current app instance. | ||
| // It must not mutate production defaults, shared local data, or TCC permissions. | ||
| self.restartApp() | ||
|
|
@@ -2773,6 +2780,8 @@ class AppState: ObservableObject { | |
| // MARK: - System Event Notification Names | ||
|
|
||
| extension Notification.Name { | ||
| /// Posted when the current app instance should fully clear its own onboarding state. | ||
| static let resetOnboardingRequested = Notification.Name("resetOnboardingRequested") | ||
| /// Posted when the system wakes from sleep | ||
| static let systemDidWake = Notification.Name("systemDidWake") | ||
| /// Posted when the screen is locked | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,8 @@ struct DesktopHomeView: View { | |
| }() | ||
| @State private var isSidebarCollapsed: Bool = false | ||
| @AppStorage("currentTierLevel") private var currentTierLevel = 0 | ||
| @AppStorage("onboardingStep") private var onboardingStep = 0 | ||
| @AppStorage("onboardingJustCompleted") private var onboardingJustCompleted = false | ||
|
|
||
| // Settings sidebar state | ||
| @State private var selectedSettingsSection: SettingsContentView.SettingsSection = .general | ||
|
|
@@ -201,6 +203,13 @@ struct DesktopHomeView: View { | |
| appState.hasCompletedOnboarding = false | ||
| appState.stopTranscription() | ||
| } | ||
| .onReceive(NotificationCenter.default.publisher(for: .resetOnboardingRequested)) { _ in | ||
| log("DesktopHomeView: resetOnboardingRequested — clearing live onboarding state for current app") | ||
| appState.hasCompletedOnboarding = false | ||
| onboardingStep = 0 | ||
| onboardingJustCompleted = false | ||
| appState.stopTranscription() | ||
| } | ||
|
Comment on lines
+206
to
+212
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The net result is functionally identical to having removed them — both paths produce the default value on next read. However, it is worth noting that after the notification fires the keys will be present in UserDefaults (value |
||
| // Handle transcription toggle from menu bar | ||
| .onReceive(NotificationCenter.default.publisher(for: .toggleTranscriptionRequested)) { notification in | ||
| if let enabled = notification.userInfo?["enabled"] as? Bool { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misleading comment — notification fires after UserDefaults clearing on the main thread
The inline comment says "before touching raw UserDefaults", but both call sites (
SettingsPage.swiftbutton action andOmiApp.swift's@MainActor resetOnboarding()) invoke this function on the main thread. BecauseDispatchQueue.main.asyncsimply enqueues a block for the next run-loop iteration, the synchronousUserDefaults.standard.removeObjectloop below runs first. The notification is therefore dispatched after the keys are already cleared, not before.This doesn't cause a functional bug in practice (clearing + writing
0/falseproduces the same final state), but the comment misrepresents the ordering and could mislead future readers about the intent of the guard.Consider either: