Working Low Battery Indicator

This commit is contained in:
Hariharan Mudaliar 2025-12-08 15:50:51 +05:30
commit e6d9043c37
3 changed files with 27 additions and 0 deletions

View file

@ -586,6 +586,7 @@ struct SettingsView: View {
SettingsSearchEntry(tab: .battery, title: "Show battery percentage", keywords: ["battery percent"], highlightID: SettingsTab.battery.highlightID(for: "Show battery percentage")),
SettingsSearchEntry(tab: .battery, title: "Show power status notifications", keywords: ["notifications", "power"], highlightID: SettingsTab.battery.highlightID(for: "Show power status notifications")),
SettingsSearchEntry(tab: .battery, title: "Show power status icons", keywords: ["power icons", "charging icon"], highlightID: SettingsTab.battery.highlightID(for: "Show power status icons")),
SettingsSearchEntry(tab: .battery, title: "Play low battery alert sound", keywords: ["low battery", "alert", "sound"], highlightID: SettingsTab.battery.highlightID(for: "Play low battery alert sound")),
// HUDs
SettingsSearchEntry(tab: .hud, title: "Show Bluetooth device connections", keywords: ["bluetooth", "hud"], highlightID: SettingsTab.hud.highlightID(for: "Show Bluetooth device connections")),
@ -1050,6 +1051,8 @@ struct Charge: View {
.settingsHighlight(id: highlightID("Show battery indicator"))
Defaults.Toggle("Show power status notifications", key: .showPowerStatusNotifications)
.settingsHighlight(id: highlightID("Show power status notifications"))
Defaults.Toggle("Play low battery alert sound", key: .playLowBatteryAlertSound)
.settingsHighlight(id: highlightID("Play low battery alert sound"))
} header: {
Text("General")
}

View file

@ -11,6 +11,8 @@ class BatteryStatusViewModel: ObservableObject {
private var powerSourceChangedCallback: IOPowerSourceCallbackType?
private var runLoopSource: Unmanaged<CFRunLoopSource>?
var animations: DynamicIslandAnimations = DynamicIslandAnimations()
private let lowBatteryAlertSoundPlayer = AudioPlayer()
private let lowBatteryAlertThresholds: [Float] = [20, 15, 10, 5]
@ObservedObject var coordinator = DynamicIslandViewCoordinator.shared
@ -63,6 +65,8 @@ class BatteryStatusViewModel: ObservableObject {
case .batteryLevelChanged(let level):
print("🔋 Battery level: \(Int(level))%")
let previousLevel = self.levelBattery
self.handleLowBatteryAlertIfNeeded(previousLevel: previousLevel, newLevel: level)
withAnimation {
self.levelBattery = level
}
@ -128,6 +132,25 @@ class BatteryStatusViewModel: ObservableObject {
}
}
private func handleLowBatteryAlertIfNeeded(previousLevel: Float, newLevel: Float) {
guard Defaults[.playLowBatteryAlertSound] else { return }
guard !isPluggedIn, !isCharging else { return }
guard newLevel < previousLevel else { return }
for threshold in lowBatteryAlertThresholds {
if previousLevel >= threshold && newLevel < threshold {
self.statusText = "Low battery"
notifyImportanChangeStatus()
playLowBatteryAlertSound()
break
}
}
}
private func playLowBatteryAlertSound() {
lowBatteryAlertSoundPlayer.play(fileName: "lowbattery", fileExtension: "mp3")
}
deinit {
print("🔌 Cleaning up battery monitoring...")
if let managerBatteryId: Int = managerBatteryId {

View file

@ -482,6 +482,7 @@ extension Defaults.Keys {
static let showBatteryIndicator = Key<Bool>("showBatteryIndicator", default: true)
static let showBatteryPercentage = Key<Bool>("showBatteryPercentage", default: true)
static let showPowerStatusIcons = Key<Bool>("showPowerStatusIcons", default: true)
static let playLowBatteryAlertSound = Key<Bool>("playLowBatteryAlertSound", default: true)
// MARK: Downloads
static let enableDownloadListener = Key<Bool>("enableDownloadListener", default: true)