94 lines
2.6 KiB
Swift
94 lines
2.6 KiB
Swift
//
|
|
// BatteryOverlayView.swift
|
|
// TheNoiseClock
|
|
//
|
|
// Created by Matt Bruce on 9/7/25.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
/// Component for displaying battery level overlay
|
|
struct BatteryOverlayView: View {
|
|
|
|
// MARK: - Properties
|
|
let color: Color
|
|
let opacity: Double
|
|
let batteryLevel: Int
|
|
let isCharging: Bool
|
|
|
|
// MARK: - Body
|
|
var body: some View {
|
|
let clamped = ColorUtils.clampOpacity(opacity)
|
|
let batteryIcon = getBatteryIcon()
|
|
let batteryColor = getBatteryColor()
|
|
|
|
HStack(spacing: 4) {
|
|
Image(systemName: batteryIcon)
|
|
.foregroundStyle(batteryColor)
|
|
.symbolEffect(.pulse, options: .repeating, isActive: isCharging)
|
|
.contentTransition(.symbolEffect(.replace))
|
|
Text("\(batteryLevel)%")
|
|
.foregroundStyle(color)
|
|
.contentTransition(.numericText())
|
|
.animation(.snappy(duration: 0.3), value: batteryLevel)
|
|
}
|
|
.opacity(clamped)
|
|
.font(.callout.weight(.semibold))
|
|
}
|
|
|
|
// MARK: - Private Methods
|
|
private func getBatteryIcon() -> String {
|
|
// Show charging icon when charging
|
|
if isCharging {
|
|
return "bolt.circle.fill"
|
|
}
|
|
|
|
// Return battery icon based on level
|
|
switch batteryLevel {
|
|
case 75...100:
|
|
return "battery.100"
|
|
case 50..<75:
|
|
return "battery.75"
|
|
case 25..<50:
|
|
return "battery.50"
|
|
case 10..<25:
|
|
return "battery.25"
|
|
default:
|
|
return "battery.0"
|
|
}
|
|
}
|
|
|
|
private func getBatteryColor() -> Color {
|
|
// Green when charging
|
|
if isCharging {
|
|
return .green
|
|
}
|
|
|
|
// Color based on battery level
|
|
switch batteryLevel {
|
|
case 50...100:
|
|
return .green
|
|
case 20..<50:
|
|
return .yellow
|
|
case 10..<20:
|
|
return .orange
|
|
default:
|
|
return .red
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Previews
|
|
|
|
#Preview("Battery Overlay - All States") {
|
|
VStack(spacing: 20) {
|
|
BatteryOverlayView(color: .white, opacity: 1.0, batteryLevel: 100, isCharging: false)
|
|
BatteryOverlayView(color: .white, opacity: 1.0, batteryLevel: 50, isCharging: false)
|
|
BatteryOverlayView(color: .white, opacity: 1.0, batteryLevel: 15, isCharging: false)
|
|
BatteryOverlayView(color: .white, opacity: 1.0, batteryLevel: 5, isCharging: false)
|
|
BatteryOverlayView(color: .white, opacity: 1.0, batteryLevel: 75, isCharging: true)
|
|
}
|
|
.padding()
|
|
.background(Color.black)
|
|
}
|