Update onboarding

This commit is contained in:
Hariharan Mudaliar 2026-03-05 16:24:06 +05:30
commit 5accee5d02
No known key found for this signature in database
GPG key ID: 025583EB0BE5640E
6 changed files with 78 additions and 81 deletions

View file

@ -396,9 +396,10 @@ struct ContentView: View {
}
}
.onAppear(perform: {
if coordinator.firstLaunch {
// Single open during first launch; closeHello() handles the timed close.
runAfter(1) {
withAnimation(vm.animation) {
if coordinator.firstLaunch {
openNotch()
}
}
@ -1635,7 +1636,7 @@ struct ContentView: View {
}
private func shouldPreventAutoClose() -> Bool {
hasAnyActivePopovers() || vm.isAutoCloseSuppressed || SharingStateManager.shared.preventNotchClose
coordinator.firstLaunch || hasAnyActivePopovers() || vm.isAutoCloseSuppressed || SharingStateManager.shared.preventNotchClose
}
// Helper to prevent rapid haptic feedback

View file

@ -1607,10 +1607,6 @@
}
}
},
"±10 Seconds" : {
"comment" : "Display name for the \"±10 Seconds\" music skip behavior option.",
"isCommentAutoGenerated" : true
},
"0" : {
"comment" : "A label displayed in a circular gauge to indicate the minimum battery level.",
"isCommentAutoGenerated" : true,
@ -1927,10 +1923,6 @@
}
}
},
"Accent" : {
"comment" : "Display name for the \"Accent\" caps lock indicator tint mode.",
"isCommentAutoGenerated" : true
},
"Accent color" : {
"localizations" : {
"ar" : {
@ -2276,10 +2268,6 @@
}
}
},
"Adaptive gradient" : {
"comment" : "Name of the timer icon color mode option that uses an adaptive gradient.",
"isCommentAutoGenerated" : true
},
"Add" : {
"localizations" : {
"ar" : {
@ -3875,10 +3863,6 @@
}
}
},
"Apple Music" : {
"comment" : "Localized name for the \"Now Playing\" media controller type.",
"isCommentAutoGenerated" : true
},
"Applies the notch-style parallax effect to the lock screen media widget album art." : {
"localizations" : {
"pt-BR" : {
@ -4293,10 +4277,6 @@
}
}
},
"Bar" : {
"comment" : "Localized name for the 'Bar' timer progress style.",
"isCommentAutoGenerated" : true
},
"Battery" : {
"localizations" : {
"ar" : {
@ -8567,10 +8547,6 @@
}
}
},
"Digital" : {
"comment" : "The display name for the \"Digital\" reminder presentation style.",
"isCommentAutoGenerated" : true
},
"Dimensions" : {
"localizations" : {
"pt-BR" : {
@ -8862,6 +8838,9 @@
}
}
}
},
"Display Style" : {
},
"Displays a HUD notification when Bluetooth audio devices (headphones, AirPods, speakers) connect, showing device name and battery level." : {
"comment" : "A footer for the \"Bluetooth Audio Devices\" section in the HUD settings.",
@ -11966,10 +11945,6 @@
}
}
},
"Green" : {
"comment" : "Name of the \"Green\" Caps Lock Indicator Tint Mode.",
"isCommentAutoGenerated" : true
},
"Height:" : {
"extractionState" : "stale",
"localizations" : {
@ -14092,6 +14067,9 @@
}
}
}
},
"Main screen style" : {
},
"Manage indicator preferences from Settings → Privacy. No manual microphone toggle is required." : {
"comment" : "A description of how to manage the microphone privacy indicator preferences.",
@ -15647,6 +15625,7 @@
}
},
"Minutes" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
@ -17863,10 +17842,6 @@
}
}
},
"Now Playing" : {
"comment" : "Localized name for each media controller type.",
"isCommentAutoGenerated" : true
},
"Number of lines kept in the scrollback buffer. Higher values use more memory." : {
},
@ -18242,10 +18217,6 @@
}
}
},
"Panel" : {
"comment" : "Display name for the \"Panel\" clipboard display mode.",
"isCommentAutoGenerated" : true
},
"Panel mode shows clipboard in a floating window near the notch." : {
"comment" : "A description of the \"Panel\" clipboard display mode.",
"isCommentAutoGenerated" : true,
@ -19860,10 +19831,6 @@
}
}
},
"Ring" : {
"comment" : "Localized name for the \"Ring\" timer progress style.",
"isCommentAutoGenerated" : true
},
"Rotation:" : {
"extractionState" : "stale",
"localizations" : {
@ -20690,10 +20657,6 @@
}
}
},
"Separate Tab" : {
"comment" : "Name of the clipboard display mode option that opens the clipboard in a separate tab.",
"isCommentAutoGenerated" : true
},
"Separate Tab mode integrates Copied Items and Notes into a single view. If both are enabled, Notes appear on the right and Clipboard on the left." : {
"comment" : "A description of the \"Separate Tab\" clipboard display mode.",
"isCommentAutoGenerated" : true,
@ -21755,14 +21718,6 @@
}
}
},
"Shows screen assistant as a dropdown attached to the AI button" : {
"comment" : "Description of the \"Popover\" display mode for the screen assistant.",
"isCommentAutoGenerated" : true
},
"Shows screen assistant in a floating panel near the notch" : {
"comment" : "Description of the \"panel\" display mode for the screen assistant.",
"isCommentAutoGenerated" : true
},
"Shows the model's reasoning process before the final answer" : {
"localizations" : {
"fr" : {
@ -21825,10 +21780,6 @@
}
}
},
"Skip forward or backward by ten seconds" : {
"comment" : "Description of the \"Skip forward or backward by ten seconds\" music skip behavior.",
"isCommentAutoGenerated" : true
},
"Slider color" : {
"localizations" : {
"ar" : {
@ -22397,10 +22348,6 @@
}
}
},
"Spotify" : {
"comment" : "Add more media controller types here.",
"isCommentAutoGenerated" : true
},
"Square" : {
"localizations" : {
"ar" : {
@ -22513,10 +22460,6 @@
},
"Standard notch media controls are hidden. Re-enable the toggle above to restore them." : {
},
"Standard previous/next track controls" : {
"comment" : "Description of a music skip behavior option that uses standard previous/next track controls.",
"isCommentAutoGenerated" : true
},
"Start" : {
"localizations" : {
@ -23878,10 +23821,6 @@
},
"shouldTranslate" : false
},
"Track Skip" : {
"comment" : "Name of the music skip behavior option that skips to the next track.",
"isCommentAutoGenerated" : true
},
"Transform" : {
"extractionState" : "stale",
"localizations" : {
@ -25803,10 +25742,6 @@
"comment" : "A footer note explaining the app's funding.",
"isCommentAutoGenerated" : true
},
"Youtube Music" : {
"comment" : "Add more media player types here.",
"isCommentAutoGenerated" : true
},
"YouTube Music requires this third-party app to be installed: " : {
"localizations" : {
"ar" : {

View file

@ -209,6 +209,7 @@ func applyProfileSettings(_ profiles: Set<String>) {
if isDeveloper {
Defaults[.enableColorPickerFeature] = true
Defaults[.enableStatsFeature] = true
Defaults[.enableTerminalFeature] = true
Defaults[.enableTimerFeature] = true
Defaults[.enableScreenAssistant] = true
Defaults[.showMirror] = false
@ -262,9 +263,35 @@ func applyProfileSettings(_ profiles: Set<String>) {
Defaults[.menubarIcon] = true
Defaults[.enableHaptics] = true
// Lyrics disabled by default for all profiles
Defaults[.enableLyrics] = false
// Weather widget defaults to inline style
Defaults[.lockScreenWeatherWidgetStyle] = .inline
// Auto-detect notch: Dynamic Island for non-notch Macs, standard notch otherwise
if mainScreenHasNotch() {
Defaults[.externalDisplayStyle] = .notch
} else {
Defaults[.externalDisplayStyle] = .dynamicIsland
}
// Lock screen glass: custom liquid glass v11 on macOS 26+
if #available(macOS 26.0, *) {
Defaults[.lockScreenGlassStyle] = .liquid
Defaults[.lockScreenGlassCustomizationMode] = .customLiquid
Defaults[.lockScreenMusicLiquidGlassVariant] = .v11
}
print("✅ Applied profile settings for: \(profiles.joined(separator: ", "))")
}
/// Returns `true` when the main screen has a physical notch (safe area insets > 0).
private func mainScreenHasNotch() -> Bool {
guard let screen = NSScreen.main else { return false }
return screen.safeAreaInsets.top > 0
}
#Preview {
ProfileSelectionView(onContinue: { profiles in
print("Selected profiles: \(profiles)")

View file

@ -778,6 +778,7 @@ struct SettingsView: View {
SettingsSearchEntry(tab: .shelf, title: "Quick Share Service", keywords: ["shelf", "share", "airdrop"], highlightID: SettingsTab.shelf.highlightID(for: "Quick Share Service")),
// Appearance
SettingsSearchEntry(tab: .appearance, title: "Main screen style", keywords: ["dynamic island", "pill", "non-notch", "display style", "notch style"], highlightID: SettingsTab.appearance.highlightID(for: "Main screen style")),
SettingsSearchEntry(tab: .appearance, title: "Settings icon in notch", keywords: ["settings button", "toolbar"], highlightID: SettingsTab.appearance.highlightID(for: "Settings icon in notch")),
SettingsSearchEntry(tab: .appearance, title: "Enable window shadow", keywords: ["shadow", "appearance"], highlightID: SettingsTab.appearance.highlightID(for: "Enable window shadow")),
SettingsSearchEntry(tab: .appearance, title: "Corner radius scaling", keywords: ["corner radius", "shape"], highlightID: SettingsTab.appearance.highlightID(for: "Corner radius scaling")),
@ -3457,6 +3458,7 @@ struct Appearance: View {
@Default(.lockScreenTimerWidgetUsesBlur) private var timerGlassModeIsGlass
@Default(.enableLockScreenMediaWidget) private var enableLockScreenMediaWidget
@Default(.enableLockScreenTimerWidget) private var enableLockScreenTimerWidget
@Default(.externalDisplayStyle) private var externalDisplayStyle
@State private var selectedListVisualizer: CustomVisualizer? = nil
@State private var isIconImporterPresented = false
@ -3468,6 +3470,12 @@ struct Appearance: View {
@State private var url: String = ""
@State private var speed: CGFloat = 1.0
/// Whether the main screen has a physical notch.
private var mainScreenHasPhysicalNotch: Bool {
guard let screen = NSScreen.main else { return false }
return screen.safeAreaInsets.top > 0
}
private var notchWidthRange: ClosedRange<Double> {
let minW = Double(currentRecommendedMinimumNotchWidth())
let maxW = min(900, Double(maxAllowedNotchWidth()))
@ -3528,6 +3536,27 @@ struct Appearance: View {
Text("General")
}
// Show display style picker only on non-notch Macs (main screen has no physical notch)
if !mainScreenHasPhysicalNotch {
Section {
Picker("Main screen style", selection: $externalDisplayStyle) {
ForEach(ExternalDisplayStyle.allCases) { style in
Text(style.localizedName)
.tag(style)
}
}
.onChange(of: externalDisplayStyle) {
NotificationCenter.default.post(name: Notification.Name.notchHeightChanged, object: nil)
}
.settingsHighlight(id: highlightID("Main screen style"))
Text(externalDisplayStyle.description)
.font(.caption)
.foregroundStyle(.secondary)
} header: {
Text("Display Style")
}
}
notchWidthControls()
Section {

View file

@ -786,7 +786,7 @@ extension Defaults.Keys {
static let lockScreenWeatherRefreshInterval = Key<TimeInterval>("lockScreenWeatherRefreshInterval", default: 30 * 60)
static let lockScreenWeatherShowsLocation = Key<Bool>("lockScreenWeatherShowsLocation", default: true)
static let lockScreenWeatherShowsSunrise = Key<Bool>("lockScreenWeatherShowsSunrise", default: true)
static let lockScreenWeatherWidgetStyle = Key<LockScreenWeatherWidgetStyle>("lockScreenWeatherWidgetStyle", default: .circular)
static let lockScreenWeatherWidgetStyle = Key<LockScreenWeatherWidgetStyle>("lockScreenWeatherWidgetStyle", default: .inline)
static let lockScreenWeatherTemperatureUnit = Key<LockScreenWeatherTemperatureUnit>("lockScreenWeatherTemperatureUnit", default: .celsius)
static let lockScreenWeatherShowsAQI = Key<Bool>("lockScreenWeatherShowsAQI", default: true)
static let lockScreenWeatherAQIScale = Key<LockScreenWeatherAirQualityScale>("lockScreenWeatherAQIScale", default: .us)
@ -1078,7 +1078,7 @@ extension Defaults.Keys {
static let enableMinimalisticUI = Key<Bool>("enableMinimalisticUI", default: false)
// MARK: Lyrics Feature
static let enableLyrics = Key<Bool>("enableLyrics", default: true)
static let enableLyrics = Key<Bool>("enableLyrics", default: false)
// MARK: Notes Feature
static let enableNotes = Key<Bool>("enableNotes", default: false)

View file

@ -395,11 +395,16 @@ class DynamicIslandViewModel: NSObject, ObservableObject {
}
}
private var helloCloseScheduled = false
func closeHello() {
guard !helloCloseScheduled else { return }
helloCloseScheduled = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3.5) { [weak self] in
self?.coordinator.firstLaunch = false
withAnimation(self?.animationLibrary.animation) {
self?.close()
guard let self else { return }
self.coordinator.firstLaunch = false
withAnimation(self.animationLibrary.animation) {
self.close()
}
}
}