TheNoiseClock/TheNoiseClock/Views/Clock/Components/BatteryOverlayView.swift

288 lines
6.3 KiB
Swift

//
// BatteryOverlayView.swift
// TheNoiseClock
//
// Created by Matt Bruce on 9/7/25.
//
import SwiftUI
import Combine
/// 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)
.foregroundColor(batteryColor)
Text("\(batteryLevel)%")
.foregroundColor(color)
}
.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 - Full Charge") {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 100,
isCharging: false
)
}
#Preview("Battery Overlay - High Charge") {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 75,
isCharging: false
)
}
#Preview("Battery Overlay - Medium Charge") {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 50,
isCharging: false
)
}
#Preview("Battery Overlay - Low Charge") {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 25,
isCharging: false
)
}
#Preview("Battery Overlay - Critical Charge") {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 10,
isCharging: false
)
}
#Preview("Battery Overlay - Charging") {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 85,
isCharging: true
)
}
#Preview("Battery Overlay - Charging States") {
VStack(spacing: 20) {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 75,
isCharging: false
)
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 75,
isCharging: true
)
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 25,
isCharging: false
)
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 25,
isCharging: true
)
}
.padding()
.background(Color.black)
}
#Preview("Battery Overlay - Different Colors") {
VStack(spacing: 20) {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 75,
isCharging: false
)
BatteryOverlayView(
color: .blue,
opacity: 1.0,
batteryLevel: 50,
isCharging: false
)
BatteryOverlayView(
color: .green,
opacity: 1.0,
batteryLevel: 25,
isCharging: false
)
BatteryOverlayView(
color: .red,
opacity: 1.0,
batteryLevel: 10,
isCharging: false
)
}
.padding()
.background(Color.black)
}
#Preview("Battery Overlay - Different Opacities") {
VStack(spacing: 20) {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 75,
isCharging: false
)
BatteryOverlayView(
color: .white,
opacity: 0.7,
batteryLevel: 50,
isCharging: false
)
BatteryOverlayView(
color: .white,
opacity: 0.5,
batteryLevel: 25,
isCharging: false
)
BatteryOverlayView(
color: .white,
opacity: 0.3,
batteryLevel: 10,
isCharging: false
)
}
.padding()
.background(Color.black)
}
#Preview("Battery Overlay - Dark Background") {
BatteryOverlayView(
color: .white,
opacity: 1.0,
batteryLevel: 75,
isCharging: false
)
.padding()
.background(Color.black)
}
#Preview("Battery Overlay - Light Background") {
BatteryOverlayView(
color: .black,
opacity: 1.0,
batteryLevel: 50,
isCharging: false
)
.padding()
.background(Color.white)
}
#Preview("Battery Overlay - Clock Context") {
ZStack {
// Simulate clock background
Color.black
.ignoresSafeArea()
VStack {
Spacer()
// Simulate clock display
Text("12:34")
.font(.system(size: 80, weight: .bold, design: .rounded))
.foregroundColor(.white)
Spacer()
// Battery overlay at bottom
HStack {
Spacer()
BatteryOverlayView(
color: .white,
opacity: 0.8,
batteryLevel: 75,
isCharging: false
)
Spacer()
}
.padding(.bottom, 50)
}
}
}