mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Update onboarding
This commit is contained in:
parent
5b489ee90d
commit
5accee5d02
6 changed files with 78 additions and 81 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" : {
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue