Merge pull request #240 from Ebullioscopic/ui/fixes

Decouple battery settings lock screen
This commit is contained in:
Hariharan Mudaliar 2026-01-08 23:39:56 +05:30 • committed by GitHub
commit 9b12aafd11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 42 deletions

View file

@ -3992,6 +3992,9 @@
}
}
}
},
"Battery Widget" : {
},
"Behavior & Style" : {
@ -8251,6 +8254,9 @@
},
"Enable stats monitoring in Settings to view system performance data." : {
},
"Enable the battery capsule and configure its layout." : {
},
"Enable the timer feature in Settings to access this tab." : {
"comment" : "A message explaining that the timer feature must be enabled in settings to access this tab.",

View file

@ -3107,8 +3107,8 @@ struct LockScreenSettings: View {
@Default(.lockScreenWeatherWidgetStyle) private var lockScreenWeatherWidgetStyle
@Default(.lockScreenWeatherProviderSource) private var lockScreenWeatherProviderSource
@Default(.lockScreenWeatherTemperatureUnit) private var lockScreenWeatherTemperatureUnit
@Default(.lockScreenWeatherShowsCharging) private var lockScreenWeatherShowsCharging
@Default(.lockScreenWeatherShowsBatteryGauge) private var lockScreenWeatherShowsBatteryGauge
@Default(.lockScreenBatteryShowsCharging) private var lockScreenWeatherShowsCharging
@Default(.lockScreenBatteryShowsBatteryGauge) private var lockScreenWeatherShowsBatteryGauge
@Default(.lockScreenWeatherShowsAQI) private var lockScreenWeatherShowsAQI
@Default(.lockScreenWeatherShowsSunrise) private var lockScreenWeatherShowsSunrise
@Default(.lockScreenWeatherAQIScale) private var lockScreenWeatherAQIScale
@ -3218,29 +3218,10 @@ struct LockScreenSettings: View {
.disabled(lockScreenWeatherWidgetStyle == .circular)
.settingsHighlight(id: highlightID("Show location label"))
Defaults.Toggle("Show charging status", key: .lockScreenWeatherShowsCharging)
.settingsHighlight(id: highlightID("Show charging status"))
if lockScreenWeatherShowsCharging {
Defaults.Toggle("Show charging percentage", key: .lockScreenWeatherShowsChargingPercentage)
.settingsHighlight(id: highlightID("Show charging percentage"))
}
Defaults.Toggle("Show sunrise time", key: .lockScreenWeatherShowsSunrise)
.disabled(lockScreenWeatherWidgetStyle != .inline)
.settingsHighlight(id: highlightID("Show sunrise time"))
Defaults.Toggle("Show battery indicator", key: .lockScreenWeatherShowsBatteryGauge)
.settingsHighlight(id: highlightID("Show battery indicator"))
if lockScreenWeatherShowsBatteryGauge {
Defaults.Toggle("Use MacBook icon when on battery", key: .lockScreenWeatherBatteryUsesLaptopSymbol)
.settingsHighlight(id: highlightID("Use MacBook icon when on battery"))
}
Defaults.Toggle("Show Bluetooth battery", key: .lockScreenWeatherShowsBluetooth)
.settingsHighlight(id: highlightID("Show Bluetooth battery"))
Defaults.Toggle("Show AQI widget", key: .lockScreenWeatherShowsAQI)
.disabled(!lockScreenWeatherProviderSource.supportsAirQuality)
.settingsHighlight(id: highlightID("Show AQI widget"))
@ -3270,6 +3251,33 @@ struct LockScreenSettings: View {
Text("Enable the weather capsule and configure its layout, provider, units, and optional battery/AQI indicators.")
}
if BatteryActivityManager.shared.hasBattery() {
Section {
Defaults.Toggle("Show battery indicator", key: .lockScreenBatteryShowsBatteryGauge)
.settingsHighlight(id: highlightID("Show battery indicator"))
if lockScreenWeatherShowsBatteryGauge {
Defaults.Toggle("Use MacBook icon when on battery", key: .lockScreenBatteryUsesLaptopSymbol)
.settingsHighlight(id: highlightID("Use MacBook icon when on battery"))
Defaults.Toggle("Show charging status", key: .lockScreenBatteryShowsCharging)
.settingsHighlight(id: highlightID("Show charging status"))
if lockScreenWeatherShowsCharging {
Defaults.Toggle("Show charging percentage", key: .lockScreenBatteryShowsChargingPercentage)
.settingsHighlight(id: highlightID("Show charging percentage"))
}
Defaults.Toggle("Show Bluetooth battery", key: .lockScreenBatteryShowsBluetooth)
.settingsHighlight(id: highlightID("Show Bluetooth battery"))
}
} header: {
Text("Battery Widget")
} footer: {
Text("Enable the battery capsule and configure its layout.")
}
}
Section {
Defaults.Toggle("Show focus widget", key: .enableLockScreenFocusWidget)
.settingsHighlight(id: highlightID("Show focus widget"))

View file

@ -65,7 +65,7 @@ final class LockScreenWeatherManager: ObservableObject {
let remaining = interval - Date().timeIntervalSince(lastFetchDate)
NSLog("LockScreenWeatherManager: skipping refresh (%.0f s remaining until next fetch)", max(remaining, 0))
if let payload = latestWeatherPayload {
if Defaults[.lockScreenWeatherShowsBluetooth] {
if Defaults[.lockScreenBatteryShowsBluetooth] {
BluetoothAudioManager.shared.refreshConnectedDeviceBatteries()
}
let snapshot = makeSnapshot(from: payload)
@ -89,7 +89,7 @@ final class LockScreenWeatherManager: ObservableObject {
)
let payload = try await fetchWeatherPayload(location: location)
latestWeatherPayload = payload
if Defaults[.lockScreenWeatherShowsBluetooth] {
if Defaults[.lockScreenBatteryShowsBluetooth] {
BluetoothAudioManager.shared.refreshConnectedDeviceBatteries()
}
let snapshot = makeSnapshot(from: payload)
@ -102,9 +102,9 @@ final class LockScreenWeatherManager: ObservableObject {
NSLog("LockScreenWeatherManager: failed to fetch weather - \(error.localizedDescription)")
let providerSource = Defaults[.lockScreenWeatherProviderSource]
let showsCharging = Defaults[.lockScreenWeatherShowsCharging]
let showsCharging = Defaults[.lockScreenBatteryShowsCharging]
let chargingInfo = showsCharging ? makeChargingInfo() : nil
let showsBatteryGauge = Defaults[.lockScreenWeatherShowsBatteryGauge]
let showsBatteryGauge = Defaults[.lockScreenBatteryShowsBatteryGauge]
let widgetStyle = Defaults[.lockScreenWeatherWidgetStyle]
let batteryInfo = showsBatteryGauge ? makeBatteryGaugeInfo(isCharging: chargingInfo != nil, widgetStyle: widgetStyle) : nil
let showsSunriseSetting = Defaults[.lockScreenWeatherShowsSunrise]
@ -116,12 +116,12 @@ final class LockScreenWeatherManager: ObservableObject {
description: snapshot?.description ?? "",
locationName: snapshot?.locationName,
charging: chargingInfo,
bluetooth: Defaults[.lockScreenWeatherShowsBluetooth] ? makeBluetoothInfo() : nil,
bluetooth: Defaults[.lockScreenBatteryShowsBluetooth] ? makeBluetoothInfo() : nil,
battery: batteryInfo,
showsLocation: snapshot?.showsLocation ?? false,
airQuality: (providerSource.supportsAirQuality && Defaults[.lockScreenWeatherShowsAQI]) ? snapshot?.airQuality : nil,
widgetStyle: widgetStyle,
showsChargingPercentage: Defaults[.lockScreenWeatherShowsChargingPercentage],
showsChargingPercentage: Defaults[.lockScreenBatteryShowsChargingPercentage],
temperatureInfo: snapshot?.temperatureInfo,
usesGaugeTint: Defaults[.lockScreenWeatherUsesGaugeTint],
sunCycle: sunCycle,
@ -187,15 +187,15 @@ final class LockScreenWeatherManager: ObservableObject {
let defaultsPublishers: [AnyPublisher<Void, Never>] = [
Defaults.publisher(.lockScreenWeatherShowsLocation, options: [])
.map { _ in () }.eraseToAnyPublisher(),
Defaults.publisher(.lockScreenWeatherShowsCharging, options: [])
Defaults.publisher(.lockScreenBatteryShowsCharging, options: [])
.map { _ in () }.eraseToAnyPublisher(),
Defaults.publisher(.lockScreenWeatherShowsChargingPercentage, options: [])
Defaults.publisher(.lockScreenBatteryShowsChargingPercentage, options: [])
.map { _ in () }.eraseToAnyPublisher(),
Defaults.publisher(.lockScreenWeatherShowsBluetooth, options: [])
Defaults.publisher(.lockScreenBatteryShowsBluetooth, options: [])
.map { _ in () }.eraseToAnyPublisher(),
Defaults.publisher(.lockScreenWeatherShowsBatteryGauge, options: [])
Defaults.publisher(.lockScreenBatteryShowsBatteryGauge, options: [])
.map { _ in () }.eraseToAnyPublisher(),
Defaults.publisher(.lockScreenWeatherBatteryUsesLaptopSymbol, options: [])
Defaults.publisher(.lockScreenBatteryUsesLaptopSymbol, options: [])
.map { _ in () }.eraseToAnyPublisher(),
Defaults.publisher(.lockScreenWeatherShowsSunrise, options: [])
.map { _ in () }.eraseToAnyPublisher(),
@ -292,14 +292,14 @@ final class LockScreenWeatherManager: ObservableObject {
private func makeSnapshot(from payload: LockScreenWeatherSnapshot) -> LockScreenWeatherSnapshot {
let locationName = payload.locationName
let chargingInfo = Defaults[.lockScreenWeatherShowsCharging] ? makeChargingInfo() : nil
let bluetoothInfo = Defaults[.lockScreenWeatherShowsBluetooth] ? makeBluetoothInfo() : nil
let chargingInfo = Defaults[.lockScreenBatteryShowsCharging] ? makeChargingInfo() : nil
let bluetoothInfo = Defaults[.lockScreenBatteryShowsBluetooth] ? makeBluetoothInfo() : nil
let widgetStyle = Defaults[.lockScreenWeatherWidgetStyle]
let shouldShowLocation = widgetStyle == .inline && Defaults[.lockScreenWeatherShowsLocation] && !(locationName?.isEmpty ?? true)
let showsChargingPercentage = Defaults[.lockScreenWeatherShowsChargingPercentage]
let showsChargingPercentage = Defaults[.lockScreenBatteryShowsChargingPercentage]
let providerSource = Defaults[.lockScreenWeatherProviderSource]
let airQualityInfo = (Defaults[.lockScreenWeatherShowsAQI] && providerSource.supportsAirQuality) ? payload.airQuality : nil
let batteryInfo = Defaults[.lockScreenWeatherShowsBatteryGauge] ? makeBatteryGaugeInfo(isCharging: chargingInfo != nil, widgetStyle: widgetStyle) : nil
let batteryInfo = Defaults[.lockScreenBatteryShowsBatteryGauge] ? makeBatteryGaugeInfo(isCharging: chargingInfo != nil, widgetStyle: widgetStyle) : nil
let usesGaugeTint = Defaults[.lockScreenWeatherUsesGaugeTint]
let showsSunriseSetting = Defaults[.lockScreenWeatherShowsSunrise]
let shouldShowSunrise = showsSunriseSetting && widgetStyle == .inline && payload.sunCycle?.sunrise != nil
@ -357,7 +357,7 @@ final class LockScreenWeatherManager: ObservableObject {
guard clampedLevel >= 0 else { return nil }
let usesLaptopSymbol = Defaults[.lockScreenWeatherBatteryUsesLaptopSymbol]
let usesLaptopSymbol = Defaults[.lockScreenBatteryUsesLaptopSymbol]
return LockScreenWeatherSnapshot.BatteryInfo(
batteryLevel: clampedLevel,

View file

@ -578,11 +578,6 @@ extension Defaults.Keys {
static let enableLockScreenTimerWidget = Key<Bool>("enableLockScreenTimerWidget", default: true)
static let lockScreenWeatherRefreshInterval = Key<TimeInterval>("lockScreenWeatherRefreshInterval", default: 30 * 60)
static let lockScreenWeatherShowsLocation = Key<Bool>("lockScreenWeatherShowsLocation", default: true)
static let lockScreenWeatherShowsCharging = Key<Bool>("lockScreenWeatherShowsCharging", default: true)
static let lockScreenWeatherShowsChargingPercentage = Key<Bool>("lockScreenWeatherShowsChargingPercentage", default: true)
static let lockScreenWeatherShowsBluetooth = Key<Bool>("lockScreenWeatherShowsBluetooth", default: true)
static let lockScreenWeatherShowsBatteryGauge = Key<Bool>("lockScreenWeatherShowsBatteryGauge", default: true)
static let lockScreenWeatherBatteryUsesLaptopSymbol = Key<Bool>("lockScreenWeatherBatteryUsesLaptopSymbol", default: true)
static let lockScreenWeatherShowsSunrise = Key<Bool>("lockScreenWeatherShowsSunrise", default: true)
static let lockScreenWeatherWidgetStyle = Key<LockScreenWeatherWidgetStyle>("lockScreenWeatherWidgetStyle", default: .circular)
static let lockScreenWeatherTemperatureUnit = Key<LockScreenWeatherTemperatureUnit>("lockScreenWeatherTemperatureUnit", default: .celsius)
@ -608,6 +603,15 @@ extension Defaults.Keys {
static let showPowerStatusIcons = Key<Bool>("showPowerStatusIcons", default: true)
static let playLowBatteryAlertSound = Key<Bool>("playLowBatteryAlertSound", default: true)
static let lockScreenBatteryShowsBatteryGauge = Key<Bool>(
"lockScreenWeatherShowsBatteryGauge",
default: BatteryActivityManager.shared.hasBattery()
)
static let lockScreenBatteryUsesLaptopSymbol = Key<Bool>("lockScreenWeatherBatteryUsesLaptopSymbol", default: true)
static let lockScreenBatteryShowsCharging = Key<Bool>("lockScreenWeatherShowsCharging", default: true)
static let lockScreenBatteryShowsChargingPercentage = Key<Bool>("lockScreenWeatherShowsChargingPercentage", default: true)
static let lockScreenBatteryShowsBluetooth = Key<Bool>("lockScreenWeatherShowsBluetooth", default: true)
// MARK: Downloads
static let enableDownloadListener = Key<Bool>("enableDownloadListener", default: true)
static let enableSafariDownloads = Key<Bool>("enableSafariDownloads", default: true)