| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- import CoreData
- import SwiftUI
- extension Adjustments.RootView {
- @ViewBuilder func tempTargets() -> some View {
- if state.isTempTargetEnabled, state.activeTempTargetName.isNotEmpty {
- currentActiveAdjustment
- }
- if state.scheduledTempTargets.isNotEmpty {
- scheduledTempTargets
- }
- if state.tempTargetPresets.isNotEmpty {
- tempTargetPresets
- } else {
- defaultText
- }
- }
- private var scheduledTempTargets: some View {
- Section {
- ForEach(state.scheduledTempTargets) { tempTarget in
- tempTargetView(for: tempTarget)
- .swipeActions(edge: .trailing, allowsFullSwipe: true) {
- swipeActionsForTempTargets(for: tempTarget)
- }
- }
- .listRowBackground(Color.chart)
- } header: {
- Text("Scheduled Temp Targets")
- }
- }
- private var tempTargetPresets: some View {
- Section {
- ForEach(state.tempTargetPresets) { preset in
- tempTargetView(for: preset, showCheckmark: showTempTargetCheckmark) {
- enactTempTargetPreset(preset)
- }
- .swipeActions(edge: .trailing, allowsFullSwipe: true) {
- swipeActionsForTempTargets(for: preset)
- }
- }
- .onMove(perform: state.reorderTempTargets)
- .confirmationDialog(
- deleteConfirmationTitle,
- isPresented: $isConfirmDeletePresented,
- titleVisibility: .visible
- ) {
- deleteConfirmationButtons()
- } message: {
- deleteConfirmationMessage
- }
- .listRowBackground(Color.chart)
- } header: {
- Text("Temporary Target Presets")
- } footer: {
- HStack {
- Image(systemName: "hand.draw.fill").foregroundStyle(.primary)
- Text("Swipe left to edit or delete a temporary target preset. Hold, drag and drop to reorder a preset.")
- }
- }
- }
- private func enactTempTargetPreset(_ preset: TempTargetStored) {
- Task {
- let objectID = preset.objectID
- await state.enactTempTargetPreset(withID: objectID)
- selectedTempTargetPresetID = preset.id?.uuidString
- showTempTargetCheckmark = true
- DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
- showTempTargetCheckmark = false
- }
- }
- }
- private func swipeActionsForTempTargets(for tempTarget: TempTargetStored) -> some View {
- Group {
- Button {
- Task {
- selectedTempTarget = tempTarget
- isConfirmDeletePresented = true
- }
- } label: {
- Label("Delete", systemImage: "trash.fill")
- .tint(.red)
- }
- Button(action: {
- selectedTempTarget = tempTarget
- state.showTempTargetEditSheet = true
- }, label: {
- Label("Edit", systemImage: "pencil")
- .tint(.blue)
- })
- }
- }
- private var deleteConfirmationTitle: String {
- "Delete the Temp Target Preset \"\(selectedTempTarget?.name ?? "")\"?"
- }
- private func deleteConfirmationButtons() -> some View {
- Group {
- if let itemToDelete = selectedTempTarget {
- Button(
- state.currentActiveTempTarget == selectedTempTarget ? "Stop and Delete" : "Delete",
- role: .destructive
- ) {
- if state.currentActiveTempTarget == selectedTempTarget {
- Task {
- await state.disableAllActiveTempTargets(createTempTargetRunEntry: true)
- }
- }
- Task {
- await state.invokeTempTargetPresetDeletion(itemToDelete.objectID)
- }
- selectedTempTarget = nil
- }
- }
- Button("Cancel", role: .cancel) {
- selectedTempTarget = nil
- }
- }
- }
- private var deleteConfirmationMessage: Text? {
- if state.currentActiveTempTarget == selectedTempTarget {
- return Text("This Temp Target preset is currently running. Deleting will stop it.")
- }
- return nil
- }
- var stickyStopTempTargetButton: some View {
- ZStack {
- Rectangle()
- .frame(width: UIScreen.main.bounds.width, height: 65)
- .foregroundStyle(colorScheme == .dark ? Color.bgDarkerDarkBlue : Color.white)
- .background(.thinMaterial)
- .opacity(0.8)
- .clipShape(Rectangle())
- Button(action: {
- Task {
- // Save cancelled Temp Targets in TempTargetRunStored Entity
- // Cancel ALL active Temp Targets
- await state.disableAllActiveTempTargets(createTempTargetRunEntry: true)
- // Update View
- state.updateLatestTempTargetConfiguration()
- }
- }, label: {
- Text("Stop Temp Target")
- .frame(maxWidth: .infinity, maxHeight: .infinity)
- .padding(10)
- })
- .frame(width: UIScreen.main.bounds.width * 0.9, height: 40, alignment: .center)
- .disabled(!state.isTempTargetEnabled)
- .background(!state.isTempTargetEnabled ? Color(.systemGray4) : Color(.systemRed))
- .tint(.white)
- .clipShape(RoundedRectangle(cornerRadius: 8))
- .padding(5)
- }
- }
- private func tempTargetView(
- for tempTarget: TempTargetStored,
- showCheckmark: Bool = false,
- onTap: (() -> Void)? = nil
- ) -> some View {
- let target = tempTarget.target ?? 100
- let tempTargetValue = Decimal(target as! Double.RawValue)
- let isSelected = tempTarget.id?.uuidString == selectedTempTargetPresetID
- let tempTargetHalfBasal = Decimal(
- tempTarget.halfBasalTarget as? Double
- .RawValue ?? Double(state.settingHalfBasalTarget)
- )
- let percentage = Int(
- state.computeAdjustedPercentage(usingHBT: tempTargetHalfBasal, usingTarget: tempTargetValue)
- )
- let remainingTime = tempTarget.date?.timeIntervalSinceNow ?? 0
- return ZStack(alignment: .trailing) {
- HStack {
- VStack(alignment: .leading) {
- HStack {
- Text(tempTarget.name ?? "")
- Spacer()
- if remainingTime > 0 {
- Text("Starts in \(formattedTimeRemaining(remainingTime))")
- .foregroundColor(colorScheme == .dark ? .orange : .accentColor)
- }
- }
- HStack(spacing: 2) {
- Text(formattedGlucose(glucose: target as Decimal))
- .foregroundColor(.secondary)
- .font(.caption)
- Text("for")
- .foregroundColor(.secondary)
- .font(.caption)
- Text("\(Formatter.integerFormatter.string(from: (tempTarget.duration ?? 0) as NSNumber)!)")
- .foregroundColor(.secondary)
- .font(.caption)
- Text("min")
- .foregroundColor(.secondary)
- .font(.caption)
- if state.isAdjustSensEnabled(usingTarget: tempTargetValue) {
- Text(", \(percentage)%")
- .foregroundColor(.secondary)
- .font(.caption)
- }
- Spacer()
- }
- .padding(.top, 2)
- }
- .contentShape(Rectangle())
- .onTapGesture {
- onTap?()
- }
- }
- if showCheckmark && isSelected {
- Image(systemName: "checkmark.circle.fill")
- .imageScale(.large)
- .fontWeight(.bold)
- .foregroundStyle(Color.green)
- } else if onTap != nil {
- Image(systemName: "line.3.horizontal")
- .imageScale(.medium)
- .foregroundStyle(.secondary)
- }
- }
- }
- }
|