import SwiftUI import OnyxDesign import OnyxHelperProtocol /// Das Ladelimit. /// /// Ein Akku, der dauerhaft bei 100 % am Netz hängt, altert schneller. Deshalb /// gibt es die Einstellung — und deshalb ist sie so schmal: 80 bis 100 % ist /// der Bereich, den macOS selbst anbietet und in dem gemessen wurde, wie der /// zuständige SMC-Key aussieht. Darunter wäre geraten. struct ChargeLimitView: View { let control: FanControl /// In der Kachel ist es eng, im Einstellungsfenster nicht. let roomy: Bool @State private var pending: Double? private var current: Double { pending ?? Double(control.chargeLimit ?? ChargeSafety.noLimit) } var body: some View { VStack(alignment: .leading, spacing: 6) { HStack(spacing: 6) { Image(systemName: "battery.75percent") .font(.system(size: 11)) .foregroundStyle(Onyx.Color.textTertiary) Text("charge.limit") .font(Onyx.Font.caption) .foregroundStyle(Onyx.Color.textSecondary) Spacer(minLength: 4) // Hundert Prozent ist kein Limit — und soll auch nicht so // heißen, sonst sucht man den Ausschalter. Group { if current >= Double(ChargeSafety.noLimit) { Text("charge.limit.off") } else { Text(verbatim: "\(Int(current)) %") } } .font(Onyx.Font.metricSmall).monospacedDigit() .foregroundStyle(Onyx.Color.textPrimary) } Slider(value: Binding(get: { current }, set: { pending = $0.rounded() }), in: Double(ChargeSafety.minimumPercent)...Double(ChargeSafety.maximumPercent), step: 5, onEditingChanged: { editing in // Erst beim Loslassen schreiben. Bei jedem Zwischenwert // in den Ladepfad zu schreiben wäre ein Dutzend // Schreibvorgänge für eine einzige Entscheidung. guard !editing, let pending else { return } control.setChargeLimit(Int(pending)) self.pending = nil }) .controlSize(.mini) .disabled(control.installState != .installed) if roomy { Text("charge.limit.hint") .font(Onyx.Font.caption) .foregroundStyle(Onyx.Color.textTertiary) .fixedSize(horizontal: false, vertical: true) } } .onAppear { control.refreshChargeLimit() } } }