| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- import CoreData
- import SwiftUI
- struct PumpView: View {
- let reservoir: Decimal?
- let name: String
- let expiresAtDate: Date?
- let timerDate: Date
- let timeZone: TimeZone?
- let pumpStatusHighlightMessage: String?
- let battery: [OpenAPS_Battery]
- @Environment(\.colorScheme) var colorScheme
- private var batteryFormatter: NumberFormatter {
- let formatter = NumberFormatter()
- formatter.numberStyle = .percent
- return formatter
- }
- var body: some View {
- if let pumpStatusHighlightMessage = pumpStatusHighlightMessage { // display message instead pump info
- VStack(alignment: .center) {
- Text(pumpStatusHighlightMessage).font(.footnote).fontWeight(.bold)
- .multilineTextAlignment(.center).frame(maxWidth: /*@START_MENU_TOKEN@*/ .infinity/*@END_MENU_TOKEN@*/)
- }.frame(width: 100)
- } else {
- VStack(alignment: .leading, spacing: 20) {
- if reservoir == nil && battery.isEmpty {
- VStack(alignment: .center, spacing: 12) {
- HStack {
- Image(systemName: "keyboard.onehanded.left")
- .font(.body)
- .imageScale(.large)
- }
- HStack {
- Text("Add pump")
- .font(.caption)
- .bold()
- }
- }
- .frame(alignment: .top)
- }
- if let reservoir = reservoir {
- HStack {
- Image(systemName: "cross.vial.fill")
- .font(.callout)
- if reservoir == 0xDEAD_BEEF {
- Text("50+ " + NSLocalizedString("U", comment: "Insulin unit"))
- .font(.callout)
- .fontWeight(.bold)
- .fontDesign(.rounded)
- } else {
- Text(
- Formatter.integerFormatter
- .string(from: reservoir as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit")
- )
- .font(.callout)
- .fontWeight(.bold)
- .fontDesign(.rounded)
- }
- }
- .padding(.vertical, 5)
- .padding(.horizontal, 10)
- .foregroundStyle(reservoirColor)
- .overlay(
- Capsule()
- .stroke(reservoirColor.opacity(0.4), lineWidth: 2)
- )
- if let timeZone = timeZone, timeZone.secondsFromGMT() != TimeZone.current.secondsFromGMT() {
- HStack {
- Image(systemName: "clock.badge.exclamationmark.fill")
- .font(.callout)
- .symbolRenderingMode(.palette)
- .foregroundStyle(.red, Color(.warning))
- Text("Timezone")
- .font(.callout)
- .fontWeight(.bold)
- .fontDesign(.rounded)
- .foregroundStyle(.red)
- }
- .padding(.leading, 12)
- }
- }
- if (battery.first?.display) != nil, let shouldBatteryDisplay = battery.first?.display, shouldBatteryDisplay {
- HStack {
- Image(systemName: "battery.100")
- .font(.callout)
- .foregroundStyle(batteryColor)
- Text("\(Formatter.integerFormatter.string(for: battery.first?.percent ?? 100) ?? "100") %")
- .font(.callout).fontWeight(.bold).fontDesign(.rounded)
- }
- }
- if let date = expiresAtDate {
- HStack {
- Image(systemName: "stopwatch.fill")
- .font(.callout)
- .foregroundStyle(timerColor)
- Text(remainingTimeString(time: date.timeIntervalSince(timerDate)))
- .font(!(date.timeIntervalSince(timerDate) > 0) ? .subheadline : .callout)
- .fontWeight(.bold)
- .fontDesign(.rounded)
- }
- // aligns the stopwatch icon exactly with the first pixel of the reservoir icon
- .padding(.leading, 12)
- }
- }
- }
- }
- private func remainingTimeString(time: TimeInterval) -> String {
- guard time > 0 else {
- return NSLocalizedString("Replace pod", comment: "View/Header when pod expired")
- }
- var time = time
- let days = Int(time / 1.days.timeInterval)
- time -= days.days.timeInterval
- let hours = Int(time / 1.hours.timeInterval)
- time -= hours.hours.timeInterval
- let minutes = Int(time / 1.minutes.timeInterval)
- if days >= 1 {
- return "\(days)" + NSLocalizedString("d", comment: "abbreviation for days") + " \(hours)" +
- NSLocalizedString("h", comment: "abbreviation for hours")
- }
- if hours >= 1 {
- return "\(hours)" + NSLocalizedString("h", comment: "abbreviation for hours")
- }
- return "\(minutes)" + NSLocalizedString("m", comment: "abbreviation for minutes")
- }
- private var batteryColor: Color {
- guard let battery = battery.first else {
- return .gray
- }
- switch battery.percent {
- case ...10:
- return Color.loopRed
- case ...20:
- return Color.orange
- default:
- return Color.loopGreen
- }
- }
- private var reservoirColor: Color {
- guard let reservoir = reservoir else {
- return .gray
- }
- switch reservoir {
- case ...10:
- return Color.loopRed
- case ...30:
- return Color.orange
- default:
- return Color.insulin
- }
- }
- private var timerColor: Color {
- guard let expisesAt = expiresAtDate else {
- return .gray
- }
- let time = expisesAt.timeIntervalSince(timerDate)
- switch time {
- case ...8.hours.timeInterval:
- return Color.loopRed
- case ...1.days.timeInterval:
- return Color.orange
- default:
- return Color.loopGreen
- }
- }
- }
- // #Preview("message") {
- // PumpView(
- // reservoir: .constant(Decimal(10.0)),
- // battery: .constant(nil),
- // name: .constant("Pump test"),
- // expiresAtDate: .constant(Date().addingTimeInterval(24.hours)),
- // timerDate: .constant(Date()),
- // pumpStatusHighlightMessage: .constant("⚠️\n Insulin suspended")
- // )
- // }
- //
- // #Preview("pump reservoir") {
- // PumpView(
- // reservoir: .constant(Decimal(40.0)),
- // battery: .constant(Battery(percent: 50, voltage: 2.0, string: BatteryState.normal, display: true)),
- // name: .constant("Pump test"),
- // expiresAtDate: .constant(nil),
- // timerDate: .constant(Date().addingTimeInterval(-24.hours)),
- // pumpStatusHighlightMessage: .constant(nil)
- // )
- // }
- //
- // #Preview("pump expiration") {
- // PumpView(
- // reservoir: .constant(Decimal(10.0)),
- // battery: .constant(Battery(percent: 50, voltage: 2.0, string: BatteryState.normal, display: false)),
- // name: .constant("Pump test"),
- // expiresAtDate: .constant(Date().addingTimeInterval(2.hours)),
- // timerDate: .constant(Date().addingTimeInterval(2.hours)),
- // pumpStatusHighlightMessage: .constant(nil)
- // )
- // }
- //
- // #Preview("no pump") {
- // PumpView(
- // reservoir: .constant(nil),
- // name: .constant(nil),
- // expiresAtDate: .constant(""),
- // timerDate: .constant(nil),
- // timeZone: .constant(Date()),
- // pumpStatusHighlightMessage: .constant(nil)
- // )
- // }
|