Quellcode durchsuchen

Replace color with environment value

polscm32 vor 1 Jahr
Ursprung
Commit
b8e9eec10e
61 geänderte Dateien mit 1325 neuen und 963 gelöschten Zeilen
  1. 15 0
      FreeAPS/Sources/Application/AppState.swift
  2. 5 20
      FreeAPS/Sources/Modules/Adjustments/View/AdjustmentsRootView.swift
  3. 3 18
      FreeAPS/Sources/Modules/Adjustments/View/Overrides/AddOverrideForm.swift
  4. 3 17
      FreeAPS/Sources/Modules/Adjustments/View/Overrides/EditOverrideForm.swift
  5. 3 18
      FreeAPS/Sources/Modules/Adjustments/View/TempTargets/AddTempTargetForm.swift
  6. 3 17
      FreeAPS/Sources/Modules/Adjustments/View/TempTargets/EditTempTargetForm.swift
  7. 3 18
      FreeAPS/Sources/Modules/AlgorithmAdvancedSettings/View/AlgorithmAdvancedSettingsRootView.swift
  8. 2 18
      FreeAPS/Sources/Modules/AutosensSettings/View/AutosensSettingsRootView.swift
  9. 2 17
      FreeAPS/Sources/Modules/AutotuneConfig/View/AutotuneConfigRootView.swift
  10. 3 18
      FreeAPS/Sources/Modules/BasalProfileEditor/View/BasalProfileEditorRootView.swift
  11. 2 17
      FreeAPS/Sources/Modules/BolusCalculatorConfig/View/BolusCalculatorConfigRootView.swift
  12. 2 17
      FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift
  13. 2 18
      FreeAPS/Sources/Modules/CalendarEventSettings/View/CalendarEventSettingsRootView.swift
  14. 2 17
      FreeAPS/Sources/Modules/Calibrations/View/CalibrationsRootView.swift
  15. 3 18
      FreeAPS/Sources/Modules/CarbRatioEditor/View/CarbRatioEditorRootView.swift
  16. 2 17
      FreeAPS/Sources/Modules/ConfigEditor/View/ConfigEditorRootView.swift
  17. 4 20
      FreeAPS/Sources/Modules/DataTable/View/DataTableRootView.swift
  18. 2 17
      FreeAPS/Sources/Modules/DynamicSettings/View/DynamicSettingsRootView.swift
  19. 2 18
      FreeAPS/Sources/Modules/GeneralSettings/View/UnitsLimitsSettingsRootView.swift
  20. 2 18
      FreeAPS/Sources/Modules/GlucoseNotificationSettings/View/GlucoseNotificationSettingsRootView.swift
  21. 2 17
      FreeAPS/Sources/Modules/HealthKit/View/AppleHealthKitRootView.swift
  22. 1 18
      FreeAPS/Sources/Modules/Home/View/HomeRootView.swift
  23. 3 18
      FreeAPS/Sources/Modules/ISFEditor/View/ISFEditorRootView.swift
  24. 2 17
      FreeAPS/Sources/Modules/IconConfig/View/IconConfigRootWiew.swift
  25. 2 18
      FreeAPS/Sources/Modules/LiveActivitySettings/View/LiveActivitySettingsRootView.swift
  26. 3 1
      FreeAPS/Sources/Modules/LiveActivitySettings/View/LiveActivityWidgetConfiguration.swift
  27. 2 17
      FreeAPS/Sources/Modules/Main/View/MainRootView.swift
  28. 2 17
      FreeAPS/Sources/Modules/ManualTempBasal/View/ManualTempBasalRootView.swift
  29. 2 17
      FreeAPS/Sources/Modules/MealSettings/View/MealSettingsRootView.swift
  30. 2 17
      FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift
  31. 3 17
      FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConnectView.swift
  32. 3 17
      FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutFetchView.swift
  33. 3 17
      FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutUploadView.swift
  34. 3 17
      FreeAPS/Sources/Modules/NightscoutConfig/View/ProfileImport/NightscoutImportResultView.swift
  35. 3 17
      FreeAPS/Sources/Modules/NightscoutConfig/View/ProfileImport/ReviewInsulinActionView.swift
  36. 272 0
      FreeAPS/Sources/Modules/OverrideConfig/View/AddOverrideForm.swift
  37. 376 0
      FreeAPS/Sources/Modules/OverrideConfig/View/EditOverrideForm.swift
  38. 516 0
      FreeAPS/Sources/Modules/OverrideConfig/View/OverrideRootView.swift
  39. 2 17
      FreeAPS/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift
  40. 2 18
      FreeAPS/Sources/Modules/RemoteControlConfig/View/RemoteControlConfig.swift
  41. 2 18
      FreeAPS/Sources/Modules/SMBSettings/View/SMBSettingsRootView.swift
  42. 2 18
      FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift
  43. 3 17
      FreeAPS/Sources/Modules/Settings/View/Subviews/AlgorithmSettings.swift
  44. 3 17
      FreeAPS/Sources/Modules/Settings/View/Subviews/DevicesView.swift
  45. 3 17
      FreeAPS/Sources/Modules/Settings/View/Subviews/FeatureSettingsView.swift
  46. 3 17
      FreeAPS/Sources/Modules/Settings/View/Subviews/NotificationsView.swift
  47. 3 17
      FreeAPS/Sources/Modules/Settings/View/Subviews/ServicesView.swift
  48. 3 17
      FreeAPS/Sources/Modules/Settings/View/Subviews/TherapySettingsView.swift
  49. 2 17
      FreeAPS/Sources/Modules/Settings/View/TidepoolStartView.swift
  50. 2 18
      FreeAPS/Sources/Modules/ShortcutsConfig/View/ShortcutsConfigView.swift
  51. 2 17
      FreeAPS/Sources/Modules/Snooze/View/SnoozeRootView.swift
  52. 2 18
      FreeAPS/Sources/Modules/Stat/View/StatRootView.swift
  53. 2 18
      FreeAPS/Sources/Modules/TargetBehavoir/View/TargetBehavoirRootView.swift
  54. 3 18
      FreeAPS/Sources/Modules/TargetsEditor/View/TargetsEditorRootView.swift
  55. 3 17
      FreeAPS/Sources/Modules/Treatments/View/MealPreset/AddMealPresetView.swift
  56. 4 1
      FreeAPS/Sources/Modules/Treatments/View/MealPreset/MealPresetView.swift
  57. 2 18
      FreeAPS/Sources/Modules/Treatments/View/TreatmentsRootView.swift
  58. 4 17
      FreeAPS/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift
  59. 3 17
      FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigAppleWatchView.swift
  60. 3 17
      FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigGarminView.swift
  61. 2 17
      FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigRootView.swift

+ 15 - 0
FreeAPS/Sources/Application/AppState.swift

@@ -1,8 +1,23 @@
 import Foundation
 import Observation
+import SwiftUICore
 import UIKit
 
 @Observable class AppState {
+    func trioBackgroundColor(for colorScheme: ColorScheme) -> LinearGradient {
+        colorScheme == .dark
+            ? LinearGradient(
+                gradient: Gradient(colors: [Color.bgDarkBlue, Color.bgDarkerDarkBlue]),
+                startPoint: .top,
+                endPoint: .bottom
+            )
+            : LinearGradient(
+                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
+                startPoint: .top,
+                endPoint: .bottom
+            )
+    }
+
     func configureTabBarAppearance() {
         let appearance = UITabBarAppearance()
         appearance.configureWithDefaultBackground()

+ 5 - 20
FreeAPS/Sources/Modules/Adjustments/View/AdjustmentsRootView.swift

@@ -22,23 +22,7 @@ extension Adjustments {
         @State private var isEditingTT = false
 
         @Environment(\.colorScheme) var colorScheme
-
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var formatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -85,11 +69,12 @@ extension Adjustments {
                         case .tempTargets: tempTargets() }
                     }
                     .scrollContentBackground(.hidden)
-                    .background(color)
+                    .background(appState.trioBackgroundColor(for: colorScheme))
                 }
                 .listSectionSpacing(10)
                 .safeAreaInset(edge: .bottom, spacing: 30) { stickyStopButton }
-                .scrollContentBackground(.hidden).background(color)
+                .scrollContentBackground(.hidden)
+                .background(appState.trioBackgroundColor(for: colorScheme))
                 .onAppear(perform: configureView)
                 .navigationBarTitle("Adjustments")
                 .navigationBarTitleDisplayMode(.large)
@@ -155,7 +140,7 @@ extension Adjustments {
                         EditTempTargetForm(tempTargetToEdit: tempTarget, state: state)
                     }
                 }
-            }).background(color)
+            }).background(appState.trioBackgroundColor(for: colorScheme))
         }
 
         @ViewBuilder func overrides() -> some View {

+ 3 - 18
FreeAPS/Sources/Modules/Adjustments/View/Overrides/AddOverrideForm.swift

@@ -5,6 +5,7 @@ struct AddOverrideForm: View {
     @Environment(\.presentationMode) var presentationMode
     @Environment(\.colorScheme) var colorScheme
     @Environment(\.dismiss) var dismiss
+    @Environment(AppState.self) var appState
     @Bindable var state: Adjustments.StateModel
     @State private var selectedIsfCrOption: IsfAndOrCrOptions = .isfAndCr
     @State private var selectedDisableSmbOption: DisableSmbOptions = .dontDisable
@@ -20,23 +21,6 @@ struct AddOverrideForm: View {
     @State private var overrideTarget = false
     @State private var didPressSave = false
 
-    var color: LinearGradient {
-        colorScheme == .dark
-            ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-            : LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
-
     var body: some View {
         NavigationView {
             List {
@@ -46,7 +30,8 @@ struct AddOverrideForm: View {
             .listSectionSpacing(10)
             .padding(.top, 30)
             .ignoresSafeArea(edges: .top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Add Override")
             .navigationBarTitleDisplayMode(.inline)
             .toolbar {

+ 3 - 17
FreeAPS/Sources/Modules/Adjustments/View/Overrides/EditOverrideForm.swift

@@ -5,6 +5,7 @@ struct EditOverrideForm: View {
     var override: OverrideStored
     @Environment(\.presentationMode) var presentationMode
     @Environment(\.colorScheme) var colorScheme
+    @Environment(AppState.self) var appState
     @Bindable var state: Adjustments.StateModel
 
     @State private var name: String
@@ -64,22 +65,6 @@ struct EditOverrideForm: View {
         _uamMinutes = State(initialValue: overrideToEdit.uamMinutes?.decimalValue)
     }
 
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        ) :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
-
     private var percentageSelection: Binding<Double> {
         Binding<Double>(
             get: {
@@ -102,7 +87,8 @@ struct EditOverrideForm: View {
             .listSectionSpacing(10)
             .padding(.top, 30)
             .ignoresSafeArea(edges: .top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Edit Override")
             .navigationBarTitleDisplayMode(.inline)
             .toolbar {

+ 3 - 18
FreeAPS/Sources/Modules/Adjustments/View/TempTargets/AddTempTargetForm.swift

@@ -5,6 +5,7 @@ struct AddTempTargetForm: View {
     @StateObject var state: Adjustments.StateModel
     @Environment(\.presentationMode) var presentationMode
     @Environment(\.colorScheme) var colorScheme
+    @Environment(AppState.self) var appState
     @Environment(\.dismiss) var dismiss
     @State private var displayPickerDuration: Bool = false
     @State private var displayPickerTarget: Bool = false
@@ -26,23 +27,6 @@ struct AddTempTargetForm: View {
     @State var hintLabel: String?
     var isCustomizedAdjustSens: Bool = false
 
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
-
     private var formatter: NumberFormatter {
         let formatter = NumberFormatter()
         formatter.numberStyle = .decimal
@@ -70,7 +54,8 @@ struct AddTempTargetForm: View {
             .listSectionSpacing(10)
             .padding(.top, 30)
             .ignoresSafeArea(edges: .top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Add Temp Target")
             .navigationBarTitleDisplayMode(.inline)
             .toolbar {

+ 3 - 17
FreeAPS/Sources/Modules/Adjustments/View/TempTargets/EditTempTargetForm.swift

@@ -5,6 +5,7 @@ struct EditTempTargetForm: View {
     @ObservedObject var tempTarget: TempTargetStored
     @Environment(\.presentationMode) var presentationMode
     @Environment(\.colorScheme) var colorScheme
+    @Environment(AppState.self) var appState
     @StateObject var state: Adjustments.StateModel
     @State private var displayPickerDuration: Bool = false
     @State private var displayPickerTarget: Bool = false
@@ -47,22 +48,6 @@ struct EditTempTargetForm: View {
         _percentage = State(initialValue: calcPercentage)
     }
 
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        ) :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
-
     private var dateFormatter: DateFormatter {
         let f = DateFormatter()
         f.dateStyle = .short
@@ -79,7 +64,8 @@ struct EditTempTargetForm: View {
             .listSectionSpacing(10)
             .padding(.top, 30)
             .ignoresSafeArea(edges: .top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Edit Temp Target")
             .navigationBarTitleDisplayMode(.inline)
             .toolbar {

+ 3 - 18
FreeAPS/Sources/Modules/AlgorithmAdvancedSettings/View/AlgorithmAdvancedSettingsRootView.swift

@@ -14,23 +14,7 @@ extension AlgorithmAdvancedSettings {
 
         @Environment(\.colorScheme) var colorScheme
         @EnvironmentObject var appIcons: Icons
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             List {
@@ -313,7 +297,8 @@ extension AlgorithmAdvancedSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Additionals")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/AutosensSettings/View/AutosensSettingsRootView.swift

@@ -14,23 +14,7 @@ extension AutosensSettings {
 
         @Environment(\.colorScheme) var colorScheme
         @EnvironmentObject var appIcons: Icons
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             List {
@@ -107,7 +91,7 @@ extension AutosensSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Autosens")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 17
FreeAPS/Sources/Modules/AutotuneConfig/View/AutotuneConfigRootView.swift

@@ -16,22 +16,7 @@ extension AutotuneConfig {
         @State var replaceAlert = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var isfFormatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -192,7 +177,7 @@ extension AutotuneConfig {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Autotune")
             .navigationBarTitleDisplayMode(.automatic)

+ 3 - 18
FreeAPS/Sources/Modules/BasalProfileEditor/View/BasalProfileEditorRootView.swift

@@ -12,22 +12,7 @@ extension BasalProfileEditor {
             .date(from: DateComponents(year: 2001, month: 01, day: 01, hour: 0, minute: 0, second: 0))
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var dateFormatter: DateFormatter {
             let formatter = DateFormatter()
@@ -156,7 +141,7 @@ extension BasalProfileEditor {
                 state.calcTotal()
                 state.calculateChartData()
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Basal Profile")
             .navigationBarTitleDisplayMode(.automatic)
             .toolbar(content: {
@@ -207,7 +192,7 @@ extension BasalProfileEditor {
                 }.listRowBackground(Color.chart)
             }
             .padding(.top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Set Rate")
             .navigationBarTitleDisplayMode(.automatic)
         }

+ 2 - 17
FreeAPS/Sources/Modules/BolusCalculatorConfig/View/BolusCalculatorConfigRootView.swift

@@ -15,22 +15,7 @@ extension BolusCalculatorConfig {
         @State private var booleanPlaceholder: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var conversionFormatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -132,7 +117,7 @@ extension BolusCalculatorConfig {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationBarTitle("Bolus Calculator")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 17
FreeAPS/Sources/Modules/CGM/View/CGMRootView.swift

@@ -17,22 +17,7 @@ extension CGM {
         @State private var booleanPlaceholder: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             NavigationView {
@@ -210,7 +195,7 @@ extension CGM {
                         verboseHint: "Smooth Glucose Value… bla bla bla"
                     )
                 }
-                .scrollContentBackground(.hidden).background(color)
+                .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
                 .onAppear(perform: configureView)
                 .navigationTitle("CGM")
                 .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/CalendarEventSettings/View/CalendarEventSettingsRootView.swift

@@ -14,23 +14,7 @@ extension CalendarEventSettings {
 
         @Environment(\.colorScheme) var colorScheme
         @EnvironmentObject var appIcons: Icons
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             List {
@@ -123,7 +107,7 @@ extension CalendarEventSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Calendar Events")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 17
FreeAPS/Sources/Modules/Calibrations/View/CalibrationsRootView.swift

@@ -7,22 +7,7 @@ extension Calibrations {
         @State var state = StateModel()
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var formatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -107,7 +92,7 @@ extension Calibrations {
                     }
                 }
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .dynamicTypeSize(...DynamicTypeSize.xxLarge)
             .onAppear(perform: configureView)
             .navigationTitle("Calibrations")

+ 3 - 18
FreeAPS/Sources/Modules/CarbRatioEditor/View/CarbRatioEditorRootView.swift

@@ -9,22 +9,7 @@ extension CarbRatioEditor {
         @State private var editMode = EditMode.inactive
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var dateFormatter: DateFormatter {
             let formatter = DateFormatter()
@@ -99,7 +84,7 @@ extension CarbRatioEditor {
                 }.listRowBackground(Color.chart)
             }
             .safeAreaInset(edge: .bottom, spacing: 30) { saveButton }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Carb Ratios")
             .navigationBarTitleDisplayMode(.automatic)
@@ -148,7 +133,7 @@ extension CarbRatioEditor {
                 }.listRowBackground(Color.chart)
             }
             .padding(.top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Set Ratio")
             .navigationBarTitleDisplayMode(.automatic)
         }

+ 2 - 17
FreeAPS/Sources/Modules/ConfigEditor/View/ConfigEditorRootView.swift

@@ -9,22 +9,7 @@ extension ConfigEditor {
         @State private var showShareSheet = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             ZStack {
@@ -58,7 +43,7 @@ extension ConfigEditor {
                     .navigationBarTitleDisplayMode(.automatic)
                     .padding()
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
         }
     }
 }

+ 4 - 20
FreeAPS/Sources/Modules/DataTable/View/DataTableRootView.swift

@@ -21,6 +21,7 @@ extension DataTable {
 
         @Environment(\.colorScheme) var colorScheme
         @Environment(\.managedObjectContext) var context
+        @Environment(AppState.self) var appState
 
         @FetchRequest(
             entity: GlucoseStored.entity(),
@@ -103,23 +104,6 @@ extension DataTable {
             return formatter
         }
 
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
-
         var body: some View {
             ZStack(alignment: .center, content: {
                 VStack {
@@ -142,7 +126,7 @@ extension DataTable {
                         case .adjustments: adjustmentsList
                         }
                     }.scrollContentBackground(.hidden)
-                        .background(color)
+                        .background(appState.trioBackgroundColor(for: colorScheme))
                 }.blur(radius: state.waitForSuggestion ? 8 : 0)
 
                 // Show custom progress view
@@ -151,7 +135,7 @@ extension DataTable {
                     CustomProgressView(text: progressText.rawValue)
                 }
             })
-                .background(color)
+                .background(appState.trioBackgroundColor(for: colorScheme))
                 .onAppear(perform: configureView)
                 .onDisappear {
                     state.carbEntryDeleted = false
@@ -499,7 +483,7 @@ extension DataTable {
                                 .manualGlucose > limitHigh ? Color(.systemGray4) : Color(.systemBlue)
                         )
                         .tint(.white)
-                    }.scrollContentBackground(.hidden).background(color)
+                    }.scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
                 }
                 .onAppear(perform: configureView)
                 .navigationTitle("Add Glucose")

+ 2 - 17
FreeAPS/Sources/Modules/DynamicSettings/View/DynamicSettingsRootView.swift

@@ -21,22 +21,7 @@ extension DynamicSettings {
         }
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var formatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -214,7 +199,7 @@ extension DynamicSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationBarTitle("Dynamic Settings")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/GeneralSettings/View/UnitsLimitsSettingsRootView.swift

@@ -14,23 +14,7 @@ extension UnitsLimitsSettings {
 
         @Environment(\.colorScheme) var colorScheme
         @EnvironmentObject var appIcons: Icons
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             List {
@@ -131,7 +115,7 @@ extension UnitsLimitsSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("General")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/GlucoseNotificationSettings/View/GlucoseNotificationSettingsRootView.swift

@@ -36,23 +36,7 @@ extension GlucoseNotificationSettings {
         }
 
         @Environment(\.colorScheme) var colorScheme
-
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             Form {
@@ -210,7 +194,7 @@ extension GlucoseNotificationSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationBarTitle("Trio Notifications")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 17
FreeAPS/Sources/Modules/HealthKit/View/AppleHealthKitRootView.swift

@@ -14,22 +14,7 @@ extension AppleHealthKit {
         @State private var booleanPlaceholder: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             Form {
@@ -84,7 +69,7 @@ extension AppleHealthKit {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Apple Health")
             .navigationBarTitleDisplayMode(.automatic)

+ 1 - 18
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -107,23 +107,6 @@ extension Home {
             return dateFormatter
         }
 
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
-
         private var historySFSymbol: String {
             if #available(iOS 17.0, *) {
                 return "book.pages"
@@ -868,7 +851,7 @@ extension Home {
                     adjustmentView(geo: geo).padding(.bottom, UIDevice.adjustPadding(min: nil, max: 40))
                 }
             }
-            .background(color)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .onReceive(
                 resolver.resolve(AlertPermissionsChecker.self)!.$notificationsDisabled,
                 perform: {

+ 3 - 18
FreeAPS/Sources/Modules/ISFEditor/View/ISFEditorRootView.swift

@@ -9,22 +9,7 @@ extension ISFEditor {
         @State private var editMode = EditMode.inactive
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var dateFormatter: DateFormatter {
             let formatter = DateFormatter()
@@ -141,7 +126,7 @@ extension ISFEditor {
                 }.listRowBackground(Color.chart)
             }
             .safeAreaInset(edge: .bottom, spacing: 30) { saveButton }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Insulin Sensitivities")
             .navigationBarTitleDisplayMode(.automatic)
@@ -187,7 +172,7 @@ extension ISFEditor {
                 }.listRowBackground(Color.chart)
             }
             .padding(.top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Set Rate")
             .navigationBarTitleDisplayMode(.automatic)
         }

+ 2 - 17
FreeAPS/Sources/Modules/IconConfig/View/IconConfigRootWiew.swift

@@ -4,22 +4,7 @@ import Swinject
 extension IconConfig {
     struct RootView: BaseView {
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         let resolver: Resolver
         @StateObject var state = StateModel()
@@ -27,7 +12,7 @@ extension IconConfig {
         var body: some View {
             IconSelection()
                 .onAppear(perform: configureView)
-                .scrollContentBackground(.hidden).background(color)
+                .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
         }
     }
 }

+ 2 - 18
FreeAPS/Sources/Modules/LiveActivitySettings/View/LiveActivitySettingsRootView.swift

@@ -23,23 +23,7 @@ extension LiveActivitySettings {
         }()
 
         @Environment(\.colorScheme) var colorScheme
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             List {
@@ -143,7 +127,7 @@ extension LiveActivitySettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Live Activity")
             .navigationBarTitleDisplayMode(.automatic)

+ 3 - 1
FreeAPS/Sources/Modules/LiveActivitySettings/View/LiveActivityWidgetConfiguration.swift

@@ -18,6 +18,7 @@ struct LiveActivityWidgetConfiguration: BaseView {
 
     @Environment(\.colorScheme) var colorScheme
     @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
+    @Environment(AppState.self) var appState
 
     private var color: LinearGradient {
         colorScheme == .dark ? LinearGradient(
@@ -120,7 +121,8 @@ struct LiveActivityWidgetConfiguration: BaseView {
             Spacer()
         }
         .padding()
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Widget Configuration")
         .navigationBarTitleDisplayMode(.automatic)
         .onAppear {

+ 2 - 17
FreeAPS/Sources/Modules/Main/View/MainRootView.swift

@@ -7,22 +7,7 @@ extension Main {
         @StateObject var state = StateModel()
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             router.view(for: .home)
@@ -34,7 +19,7 @@ extension Main {
                     state.secondaryModalView ?? EmptyView().asAny()
                 }
                 .onAppear(perform: configureView)
-                .scrollContentBackground(.hidden).background(color)
+                .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
         }
     }
 }

+ 2 - 17
FreeAPS/Sources/Modules/ManualTempBasal/View/ManualTempBasalRootView.swift

@@ -7,22 +7,7 @@ extension ManualTempBasal {
         @State var state = StateModel()
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var formatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -65,7 +50,7 @@ extension ManualTempBasal {
                     label: { Text("Cancel Temp Basal") }
                 }
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Manual Temp Basal")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 17
FreeAPS/Sources/Modules/MealSettings/View/MealSettingsRootView.swift

@@ -18,22 +18,7 @@ extension MealSettings {
         @State private var displayPickerMaxProtein: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var conversionFormatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -289,7 +274,7 @@ extension MealSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationBarTitle("Meal Settings")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 17
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift

@@ -18,22 +18,7 @@ extension NightscoutConfig {
         @State private var booleanPlaceholder: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             ZStack {
@@ -187,7 +172,7 @@ extension NightscoutConfig {
             .alert(isPresented: $isImportAlertPresented) {
                 importAlert ?? Alert(title: Text("Unknown Error"))
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
         }
     }

+ 3 - 17
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConnectView.swift

@@ -5,22 +5,7 @@ struct NightscoutConnectView: View {
     @State private var portFormatter: NumberFormatter
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     init(state: NightscoutConfig.StateModel) {
         self.state = state
@@ -107,6 +92,7 @@ struct NightscoutConnectView: View {
         }
         .navigationTitle("Connect")
         .navigationBarTitleDisplayMode(.automatic)
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
     }
 }

+ 3 - 17
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutFetchView.swift

@@ -12,22 +12,7 @@ struct NightscoutFetchView: View {
     @State private var booleanPlaceholder: Bool = false
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -85,6 +70,7 @@ struct NightscoutFetchView: View {
         }
         .navigationTitle("Fetch & Remote")
         .navigationBarTitleDisplayMode(.automatic)
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
     }
 }

+ 3 - 17
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutUploadView.swift

@@ -11,22 +11,7 @@ struct NightscoutUploadView: View {
     @State private var booleanPlaceholder: Bool = false
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -81,6 +66,7 @@ struct NightscoutUploadView: View {
         }
         .navigationTitle("Upload")
         .navigationBarTitleDisplayMode(.automatic)
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
     }
 }

+ 3 - 17
FreeAPS/Sources/Modules/NightscoutConfig/View/ProfileImport/NightscoutImportResultView.swift

@@ -19,22 +19,7 @@ struct NightscoutImportResultView: BaseView {
     @State private var hasVisitedPumpSettingsEditor = false
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     private var allViewsVisited: Bool {
         hasVisitedBasalProfileEditor &&
@@ -134,7 +119,8 @@ struct NightscoutImportResultView: BaseView {
             }
             .navigationTitle("Review Import")
             .navigationBarTitleDisplayMode(.large)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .interactiveDismissDisabled(true)
             .screenNavigation(self)
         }

+ 3 - 17
FreeAPS/Sources/Modules/NightscoutConfig/View/ProfileImport/ReviewInsulinActionView.swift

@@ -16,22 +16,7 @@ struct ReviewInsulinActionView: BaseView {
     @State private var booleanPlaceholder: Bool = false
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         List {
@@ -63,7 +48,8 @@ struct ReviewInsulinActionView: BaseView {
                 sheetTitle: "Help"
             )
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .onAppear(perform: configureView)
         .navigationTitle("Duration of Insulin Action")
         .navigationBarTitleDisplayMode(.automatic)

+ 272 - 0
FreeAPS/Sources/Modules/OverrideConfig/View/AddOverrideForm.swift

@@ -0,0 +1,272 @@
+import Foundation
+import SwiftUI
+
+struct AddOverrideForm: View {
+    @Environment(\.presentationMode) var presentationMode
+    @Bindable var state: OverrideConfig.StateModel
+    @State private var isEditing = false
+    @State private var overrideTarget = false
+    @Environment(\.colorScheme) var colorScheme
+    @State private var showAlert = false
+    @State private var alertString = ""
+
+    @Environment(\.dismiss) var dismiss
+    @Environment(AppState.self) var appState
+
+    private var formatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        return formatter
+    }
+
+    private var glucoseFormatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        if state.units == .mmolL {
+            formatter.maximumFractionDigits = 1
+        }
+        formatter.roundingMode = .halfUp
+        return formatter
+    }
+
+    private var alertMessage: String {
+        let target: String = state.units == .mgdL ? "70-270 mg/dl" : "4-15 mmol/l"
+        return "Please enter a valid target between" + " \(target)."
+    }
+
+    var body: some View {
+        NavigationView {
+            Form {
+                addOverride()
+            }.scrollContentBackground(.hidden)
+                .background(appState.trioBackgroundColor(for: colorScheme))
+                .navigationTitle("Add Override")
+                .navigationBarItems(trailing: Button("Cancel") {
+                    presentationMode.wrappedValue.dismiss()
+                })
+        }
+    }
+
+    @ViewBuilder private func addOverride() -> some View {
+        Section {
+            VStack {
+                TextField("Name", text: $state.overrideName)
+            }
+        } header: {
+            Text("Name")
+        }.listRowBackground(Color.chart)
+
+        Section {
+            VStack {
+                Spacer()
+                Text("\(state.overrideSliderPercentage.formatted(.number)) %")
+                    .foregroundColor(
+                        state
+                            .overrideSliderPercentage >= 130 ? .red :
+                            (isEditing ? .orange : Color.tabBar)
+                    )
+                    .font(.largeTitle)
+                Slider(
+                    value: $state.overrideSliderPercentage,
+                    in: 10 ... 200,
+                    step: 1,
+                    onEditingChanged: { editing in
+                        isEditing = editing
+                    }
+                )
+                Spacer()
+                Toggle(isOn: $state.indefinite) {
+                    Text("Enable indefinitely")
+                }
+            }
+            if !state.indefinite {
+                HStack {
+                    Text("Duration")
+                    TextFieldWithToolBar(text: $state.overrideDuration, placeholder: "0", numberFormatter: formatter)
+                    Text("minutes").foregroundColor(.secondary)
+                }
+            }
+
+            HStack {
+                Toggle(isOn: $state.shouldOverrideTarget) {
+                    Text("Override Profile Target")
+                }
+            }
+            if state.shouldOverrideTarget {
+                HStack {
+                    Text("Target Glucose")
+                    TextFieldWithToolBar(text: $state.target, placeholder: "0", numberFormatter: glucoseFormatter)
+                    Text(state.units.rawValue).foregroundColor(.secondary)
+                }
+            }
+            HStack {
+                Toggle(isOn: $state.advancedSettings) {
+                    Text("More options")
+                }
+            }
+            if state.advancedSettings {
+                HStack {
+                    Toggle(isOn: $state.smbIsOff) {
+                        Text("Disable SMBs")
+                    }
+                }
+                HStack {
+                    Toggle(isOn: $state.smbIsAlwaysOff) {
+                        Text("Schedule when SMBs are Off")
+                    }.disabled(!state.smbIsOff)
+                }
+                if state.smbIsAlwaysOff {
+                    HStack {
+                        Text("First Hour SMBs are Off (24 hours)")
+                        TextFieldWithToolBar(text: $state.start, placeholder: "0", numberFormatter: formatter)
+                        Text("hour").foregroundColor(.secondary)
+                    }
+                    HStack {
+                        Text("Last Hour SMBs are Off (24 hours)")
+                        TextFieldWithToolBar(text: $state.end, placeholder: "0", numberFormatter: formatter)
+                        Text("hour").foregroundColor(.secondary)
+                    }
+                }
+                HStack {
+                    Toggle(isOn: $state.isfAndCr) {
+                        Text("Change ISF and CR")
+                    }
+                }
+                if !state.isfAndCr {
+                    HStack {
+                        Toggle(isOn: $state.isf) {
+                            Text("Change ISF")
+                        }
+                    }
+                    HStack {
+                        Toggle(isOn: $state.cr) {
+                            Text("Change CR")
+                        }
+                    }
+                }
+                HStack {
+                    Text("SMB Minutes")
+                    TextFieldWithToolBar(text: $state.smbMinutes, placeholder: "0", numberFormatter: formatter)
+                    Text("minutes").foregroundColor(.secondary)
+                }
+                HStack {
+                    Text("UAM SMB Minutes")
+                    TextFieldWithToolBar(text: $state.uamMinutes, placeholder: "0", numberFormatter: formatter)
+                    Text("minutes").foregroundColor(.secondary)
+                }
+            }
+
+            startAndSaveProfiles
+        }
+        header: { Text("Add custom Override") }
+        footer: {
+            Text(
+                "Your profile basal insulin will be adjusted with the override percentage and your profile ISF and CR will be inversly adjusted with the percentage."
+            )
+        }.listRowBackground(Color.chart)
+    }
+
+    private var startAndSaveProfiles: some View {
+        HStack {
+            Button("Start new Override") {
+                if !state.isInputInvalid(target: state.target) {
+                    showAlert.toggle()
+
+                    alertString = "\(state.overrideSliderPercentage.formatted(.number)) %, " +
+                        (
+                            state.overrideDuration > 0 || !state
+                                .indefinite ?
+                                (
+                                    state
+                                        .overrideDuration
+                                        .formatted(.number.grouping(.never).rounded().precision(.fractionLength(0))) +
+                                        " min."
+                                ) :
+                                NSLocalizedString(" infinite duration.", comment: "")
+                        ) +
+                        (
+                            (state.target == 0 || !state.shouldOverrideTarget) ? "" :
+                                (" Target: " + state.target.formatted() + " " + state.units.rawValue + ".")
+                        )
+                        +
+                        (
+                            state
+                                .smbIsOff ?
+                                NSLocalizedString(
+                                    " SMBs are disabled either by schedule or during the entire duration.",
+                                    comment: ""
+                                ) : ""
+                        )
+                        +
+                        "\n\n"
+                        +
+                        NSLocalizedString(
+                            "Starting this override will change your profiles and/or your Target Glucose used for looping during the entire selected duration. Tapping ”Start Override” will start your new Override or edit your current active Override.",
+                            comment: ""
+                        )
+                }
+            }
+            .disabled(unChanged())
+            .buttonStyle(BorderlessButtonStyle())
+            .font(.callout)
+            .controlSize(.mini)
+            .alert(
+                "Start Override",
+                isPresented: $showAlert,
+                actions: {
+                    Button("Cancel", role: .cancel) { state.isEnabled = false }
+                    Button("Start Override", role: .destructive) {
+                        Task {
+                            if state.indefinite { state.overrideDuration = 0 }
+                            state.isEnabled.toggle()
+                            await state.saveCustomOverride()
+                            await state.resetStateVariables()
+                            dismiss()
+                        }
+                    }
+                },
+                message: {
+                    Text(alertString)
+                }
+            )
+            .alert(isPresented: $state.showInvalidTargetAlert) {
+                Alert(
+                    title: Text("Invalid Input"),
+                    message: Text("\(state.alertMessage)"),
+                    dismissButton: .default(Text("OK")) { state.showInvalidTargetAlert = false }
+                )
+            }
+            Button {
+                Task {
+                    if !state.isInputInvalid(target: state.target) {
+                        await state.saveOverridePreset()
+                        dismiss()
+                    }
+                }
+            }
+            label: { Text("Save as Preset") }
+                .tint(.orange)
+                .frame(maxWidth: .infinity, alignment: .trailing)
+                .buttonStyle(BorderlessButtonStyle())
+                .controlSize(.mini)
+                .disabled(unChanged())
+        }
+    }
+
+    private func unChanged() -> Bool {
+        let isChanged = (
+            state.overrideSliderPercentage == 100 && !state.shouldOverrideTarget && !state.smbIsOff && !state
+                .advancedSettings
+        ) ||
+            (!state.indefinite && state.overrideDuration == 0) || (state.shouldOverrideTarget && state.target == 0) ||
+            (
+                state.overrideSliderPercentage == 100 && !state.shouldOverrideTarget && !state.smbIsOff && state.isf && state
+                    .cr && state
+                    .smbMinutes == state.defaultSmbMinutes && state.uamMinutes == state.defaultUamMinutes
+            )
+
+        return isChanged
+    }
+}

+ 376 - 0
FreeAPS/Sources/Modules/OverrideConfig/View/EditOverrideForm.swift

@@ -0,0 +1,376 @@
+import Foundation
+import SwiftUI
+
+struct EditOverrideForm: View {
+    var override: OverrideStored
+    @Environment(\.presentationMode) var presentationMode
+    @Environment(\.colorScheme) var colorScheme
+    @Environment(AppState.self) var appState
+    @Bindable var state: OverrideConfig.StateModel
+
+    @State private var name: String
+    @State private var percentage: Double
+    @State private var indefinite: Bool
+    @State private var duration: Decimal
+    @State private var target: Decimal?
+    @State private var advancedSettings: Bool
+    @State private var smbIsOff: Bool
+    @State private var smbIsAlwaysOff: Bool
+    @State private var start: Decimal?
+    @State private var end: Decimal?
+    @State private var isfAndCr: Bool
+    @State private var isf: Bool
+    @State private var cr: Bool
+    @State private var smbMinutes: Decimal?
+    @State private var uamMinutes: Decimal?
+
+    @State private var hasChanges = false
+    @State private var isEditing = false
+    @State private var target_override = false
+    @State private var showAlert = false
+
+    init(overrideToEdit: OverrideStored, state: OverrideConfig.StateModel) {
+        override = overrideToEdit
+        _state = Bindable(wrappedValue: state)
+        _name = State(initialValue: overrideToEdit.name ?? "")
+        _percentage = State(initialValue: overrideToEdit.percentage)
+        _indefinite = State(initialValue: overrideToEdit.indefinite)
+        _duration = State(initialValue: overrideToEdit.duration?.decimalValue ?? 0)
+        _target = State(
+            initialValue: state.units == .mgdL ? overrideToEdit.target?.decimalValue : overrideToEdit.target?
+                .decimalValue.asMmolL
+        )
+        _target_override = State(initialValue: overrideToEdit.target?.decimalValue != 0)
+        _advancedSettings = State(initialValue: overrideToEdit.advancedSettings)
+        _smbIsOff = State(initialValue: overrideToEdit.smbIsOff)
+        _smbIsAlwaysOff = State(initialValue: overrideToEdit.smbIsAlwaysOff)
+        _start = State(initialValue: overrideToEdit.start?.decimalValue)
+        _end = State(initialValue: overrideToEdit.end?.decimalValue)
+        _isfAndCr = State(initialValue: overrideToEdit.isfAndCr)
+        _isf = State(initialValue: overrideToEdit.isf)
+        _cr = State(initialValue: overrideToEdit.cr)
+        _smbMinutes = State(initialValue: overrideToEdit.smbMinutes?.decimalValue)
+        _uamMinutes = State(initialValue: overrideToEdit.uamMinutes?.decimalValue)
+    }
+
+    var color: LinearGradient {
+        colorScheme == .dark ? LinearGradient(
+            gradient: Gradient(colors: [
+                Color.bgDarkBlue,
+                Color.bgDarkerDarkBlue
+            ]),
+            startPoint: .top,
+            endPoint: .bottom
+        ) :
+            LinearGradient(
+                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
+                startPoint: .top,
+                endPoint: .bottom
+            )
+    }
+
+    private var formatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        return formatter
+    }
+
+    private var glucoseFormatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        if state.units == .mmolL {
+            formatter.maximumFractionDigits = 1
+        }
+        formatter.roundingMode = .halfUp
+        return formatter
+    }
+
+    var body: some View {
+        NavigationView {
+            Form {
+                editOverride()
+
+                saveButton
+
+            }.scrollContentBackground(.hidden)
+                .background(appState.trioBackgroundColor(for: colorScheme))
+                .navigationTitle("Edit Override")
+                .navigationBarTitleDisplayMode(.inline)
+                .navigationBarItems(leading: Button("Close") {
+                    presentationMode.wrappedValue.dismiss()
+                })
+                .onDisappear {
+                    if !hasChanges {
+                        // Reset UI changes
+                        resetValues()
+                    }
+                }
+                .alert(isPresented: $state.showInvalidTargetAlert) {
+                    Alert(
+                        title: Text("Invalid Input"),
+                        message: Text("\(state.alertMessage)"),
+                        dismissButton: .default(Text("OK")) { state.showInvalidTargetAlert = false }
+                    )
+                }
+        }
+    }
+
+    @ViewBuilder private func editOverride() -> some View {
+        if override.name != nil {
+            Section {
+                VStack {
+                    TextField("Name", text: $name)
+                        .onChange(of: name) { _ in hasChanges = true }
+                }
+            } header: {
+                Text("Name")
+            }.listRowBackground(Color.chart)
+        }
+        Section {
+            VStack {
+                Spacer()
+                Text("\(percentage.formatted(.number)) %")
+                    .foregroundColor(
+                        state
+                            .overrideSliderPercentage >= 130 ? .red :
+                            (isEditing ? .orange : Color.tabBar)
+                    )
+                    .font(.largeTitle)
+                Slider(
+                    value: $percentage,
+                    in: 10 ... 200,
+                    step: 1
+                ).onChange(of: percentage) { _ in hasChanges = true }
+                Spacer()
+                Toggle(isOn: $indefinite) {
+                    Text("Enable indefinitely")
+                }.onChange(of: indefinite) { _ in hasChanges = true }
+            }
+            if !indefinite {
+                HStack {
+                    Text("Duration")
+                    TextFieldWithToolBar(
+                        text: Binding(
+                            get: { duration },
+                            set: {
+                                duration = $0
+                                hasChanges = true
+                            }
+                        ),
+                        placeholder: "0",
+                        numberFormatter: formatter
+                    )
+                    Text("minutes").foregroundColor(.secondary)
+                }
+            }
+
+            HStack {
+                Toggle(isOn: $target_override) {
+                    Text("Override Override Target")
+                }.onChange(of: target_override) { _ in
+                    hasChanges = true
+                }
+            }
+            if target_override {
+                HStack {
+                    Text("Target Glucose")
+                    TextFieldWithToolBar(text: Binding(
+                        get: {
+                            target ?? 0
+                        },
+                        set: {
+                            target = $0
+                            hasChanges = true
+                        }
+                    ), placeholder: "0", numberFormatter: glucoseFormatter)
+                    Text(state.units.rawValue).foregroundColor(.secondary)
+                }
+            }
+
+            Toggle(isOn: $advancedSettings) {
+                Text("More options")
+            }.onChange(of: advancedSettings) { _ in hasChanges = true }
+
+            if advancedSettings {
+                Toggle(isOn: $smbIsOff) {
+                    Text("Disable SMBs")
+                }.onChange(of: smbIsOff) { _ in hasChanges = true }
+
+                Toggle(isOn: $smbIsAlwaysOff) {
+                    Text("Schedule when SMBs are Off")
+                }.onChange(of: smbIsAlwaysOff) { _ in hasChanges = true }
+
+                if smbIsAlwaysOff {
+                    HStack {
+                        Text("First Hour SMBs are Off (24 hours)")
+                        TextFieldWithToolBar(
+                            text: Binding(
+                                get: { start ?? 0 },
+                                set: {
+                                    start = $0
+                                    hasChanges = true
+                                }
+                            ),
+                            placeholder: "0",
+                            numberFormatter: formatter
+                        )
+                        Text("hour").foregroundColor(.secondary)
+                    }
+
+                    HStack {
+                        Text("Last Hour SMBs are Off (24 hours)")
+                        TextFieldWithToolBar(
+                            text: Binding(
+                                get: { end ?? 23 },
+                                set: {
+                                    end = $0
+                                    hasChanges = true
+                                }
+                            ),
+                            placeholder: "0",
+                            numberFormatter: formatter
+                        )
+                        Text("hour").foregroundColor(.secondary)
+                    }
+                }
+
+                Toggle(isOn: $isfAndCr) {
+                    Text("Change ISF and CR")
+                }.onChange(of: isfAndCr) { _ in hasChanges = true }
+
+                if !isfAndCr {
+                    Toggle(isOn: $isf) {
+                        Text("Change ISF")
+                    }.onChange(of: isf) { _ in hasChanges = true }
+
+                    Toggle(isOn: $cr) {
+                        Text("Change CR")
+                    }.onChange(of: cr) { _ in hasChanges = true }
+                }
+
+                HStack {
+                    Text("SMB Minutes")
+                    TextFieldWithToolBar(
+                        text: Binding(
+                            get: { smbMinutes ?? state.defaultSmbMinutes },
+                            set: {
+                                smbMinutes = $0
+                                hasChanges = true
+                            }
+                        ),
+                        placeholder: "0",
+                        numberFormatter: formatter
+                    )
+                    Text("minutes").foregroundColor(.secondary)
+                }
+
+                HStack {
+                    Text("UAM SMB Minutes")
+                    TextFieldWithToolBar(
+                        text: Binding(
+                            get: { uamMinutes ?? state.defaultUamMinutes },
+                            set: {
+                                uamMinutes = $0
+                                hasChanges = true
+                            }
+                        ),
+                        placeholder: "0",
+                        numberFormatter: formatter
+                    )
+                    Text("minutes").foregroundColor(.secondary)
+                }
+            }
+        }.listRowBackground(Color.chart)
+    }
+
+    private var saveButton: some View {
+        HStack {
+            Spacer()
+            Button(action: {
+                if !state.isInputInvalid(target: target ?? 0) {
+                    saveChanges()
+
+                    do {
+                        guard let moc = override.managedObjectContext else { return }
+                        guard moc.hasChanges else { return }
+                        try moc.save()
+                        Task {
+                            await state.nightscoutManager.uploadProfiles()
+                        }
+                        if let currentActiveOverride = state.currentActiveOverride {
+                            Task {
+                                await state.disableAllActiveOverrides(
+                                    except: currentActiveOverride.objectID,
+                                    createOverrideRunEntry: false
+                                )
+                            }
+                        }
+
+                        // Update View
+                        state.updateLatestOverrideConfiguration()
+                        hasChanges = false
+                        presentationMode.wrappedValue.dismiss()
+                    } catch {
+                        debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to edit Override")
+                    }
+                }
+            }, label: {
+                Text("Save")
+            })
+                .disabled(!hasChanges)
+                .frame(maxWidth: .infinity, alignment: .center)
+                .tint(.white)
+
+            Spacer()
+        }.listRowBackground(hasChanges ? Color(.systemBlue) : Color(.systemGray4))
+    }
+
+    private func saveChanges() {
+        if !override.isPreset, hasChanges, name == (override.name ?? "") {
+            override.name = "Custom Override"
+        } else {
+            override.name = name
+        }
+        override.percentage = percentage
+        override.indefinite = indefinite
+        override.duration = NSDecimalNumber(decimal: duration)
+        if target_override {
+            override.target = target.map {
+                state.units == .mmolL ? NSDecimalNumber(decimal: $0.asMgdL) : NSDecimalNumber(decimal: $0)
+            }
+        } else {
+            override.target = 0
+        }
+        override.advancedSettings = advancedSettings
+        override.smbIsOff = smbIsOff
+        override.smbIsAlwaysOff = smbIsAlwaysOff
+        override.start = start.map { NSDecimalNumber(decimal: $0) }
+        override.end = end.map { NSDecimalNumber(decimal: $0) }
+        override.isfAndCr = isfAndCr
+        override.isf = isf
+        override.cr = cr
+        override.smbMinutes = smbMinutes.map { NSDecimalNumber(decimal: $0) }
+        override.uamMinutes = uamMinutes.map { NSDecimalNumber(decimal: $0) }
+        override.isUploadedToNS = false
+    }
+
+    private func resetValues() {
+        name = override.name ?? ""
+        percentage = override.percentage
+        indefinite = override.indefinite
+        duration = override.duration?.decimalValue ?? 0
+        target = override.target?.decimalValue
+        advancedSettings = override.advancedSettings
+        smbIsOff = override.smbIsOff
+        smbIsAlwaysOff = override.smbIsAlwaysOff
+        start = override.start?.decimalValue
+        end = override.end?.decimalValue
+        isfAndCr = override.isfAndCr
+        isf = override.isf
+        cr = override.cr
+        smbMinutes = override.smbMinutes?.decimalValue ?? state.defaultSmbMinutes
+        uamMinutes = override.uamMinutes?.decimalValue ?? state.defaultUamMinutes
+    }
+}

+ 516 - 0
FreeAPS/Sources/Modules/OverrideConfig/View/OverrideRootView.swift

@@ -0,0 +1,516 @@
+import CoreData
+import SwiftUI
+import Swinject
+
+extension OverrideConfig {
+    struct RootView: BaseView {
+        let resolver: Resolver
+
+        @State var state = StateModel()
+
+        @State private var isEditing = false
+        @State private var showOverrideCreationSheet = false
+        @State private var showingDetail = false
+        @State private var showCheckmark: Bool = false
+        @State private var selectedPresetID: String?
+        @State private var selectedOverride: OverrideStored?
+        // temp targets
+        @State private var isPromptPresented = false
+        @State private var isRemoveAlertPresented = false
+        @State private var removeAlert: Alert?
+        @State private var isEditingTT = false
+
+        @Environment(\.managedObjectContext) var moc
+        @Environment(\.colorScheme) var colorScheme
+        @Environment(AppState.self) var appState
+
+        @FetchRequest(
+            entity: TempTargetsSlider.entity(),
+            sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]
+        ) var isEnabledArray: FetchedResults<TempTargetsSlider>
+
+        private var formatter: NumberFormatter {
+            let formatter = NumberFormatter()
+            formatter.numberStyle = .decimal
+            formatter.maximumFractionDigits = 0
+            return formatter
+        }
+
+        private var glucoseFormatter: NumberFormatter {
+            let formatter = NumberFormatter()
+            formatter.numberStyle = .decimal
+            formatter.maximumFractionDigits = 0
+            if state.units == .mmolL {
+                formatter.maximumFractionDigits = 1
+            }
+            formatter.roundingMode = .halfUp
+            return formatter
+        }
+
+        var body: some View {
+            VStack {
+                Picker("Tab", selection: $state.selectedTab) {
+                    ForEach(Tab.allCases) { tab in
+                        Text(NSLocalizedString(tab.name, comment: "")).tag(tab)
+                    }
+                }
+                .pickerStyle(.segmented).padding(.horizontal, 10)
+
+                Form {
+                    switch state.selectedTab {
+                    case .overrides: overrides()
+                    case .tempTargets: tempTargets() }
+                }.scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
+                    .onAppear(perform: configureView)
+                    .navigationBarTitle("Adjustments")
+                    .navigationBarTitleDisplayMode(.large)
+                    .toolbar {
+                        ToolbarItem(placement: .topBarTrailing) {
+                            switch state.selectedTab {
+                            case .overrides:
+                                Button(action: {
+                                    showOverrideCreationSheet = true
+                                }, label: {
+                                    HStack {
+                                        Text("Add Override")
+                                        Image(systemName: "plus")
+                                    }
+                                })
+                            default:
+                                EmptyView()
+                            }
+                        }
+                    }
+                    .sheet(isPresented: $state.showOverrideEditSheet, onDismiss: {
+                        Task {
+                            await state.resetStateVariables()
+                            state.showOverrideEditSheet = false
+                        }
+
+                    }) {
+                        if let override = selectedOverride {
+                            EditOverrideForm(overrideToEdit: override, state: state)
+                        }
+                    }
+                    .sheet(isPresented: $showOverrideCreationSheet, onDismiss: {
+                        Task {
+                            await state.resetStateVariables()
+                            showOverrideCreationSheet = false
+                        }
+                    }) {
+                        AddOverrideForm(state: state)
+                    }
+            }.background(appState.trioBackgroundColor(for: colorScheme))
+        }
+
+        @ViewBuilder func overrides() -> some View {
+            if state.overridePresets.isNotEmpty {
+                overridePresets
+            } else {
+                defaultText
+            }
+
+            if state.isEnabled, state.activeOverrideName.isNotEmpty {
+                currentActiveOverride
+            }
+
+            if state.overridePresets.isNotEmpty || state.currentActiveOverride != nil {
+                cancelOverrideButton
+            }
+        }
+
+        private var defaultText: some View {
+            Section {} header: {
+                Text("Add Preset or Override by tapping 'Add Override +' in the top right-hand corner of the screen.")
+                    .textCase(nil)
+                    .foregroundStyle(.secondary)
+            }
+        }
+
+        private var overridePresets: some View {
+            Section {
+                ForEach(state.overridePresets) { preset in
+                    overridesView(for: preset)
+                        .swipeActions(edge: .trailing, allowsFullSwipe: true) {
+                            Button(role: .none) {
+                                Task {
+                                    await state.invokeOverridePresetDeletion(preset.objectID)
+                                }
+                            } label: {
+                                Label("Delete", systemImage: "trash")
+                                    .tint(.red)
+                            }
+                            Button(action: {
+                                // Set the selected Override to the chosen Preset and pass it to the Edit Sheet
+                                selectedOverride = preset
+                                state.showOverrideEditSheet = true
+                            }, label: {
+                                Label("Edit", systemImage: "pencil")
+                                    .tint(.blue)
+                            })
+                        }
+                }
+                .onMove(perform: state.reorderOverride)
+                .listRowBackground(Color.chart)
+            } header: {
+                Text("Presets")
+            } footer: {
+                HStack {
+                    Image(systemName: "hand.draw.fill")
+                    Text("Swipe left to edit or delete an override preset. Hold, drag and drop to reorder a preset.")
+                }
+            }
+        }
+
+        private var currentActiveOverride: some View {
+            Section {
+                HStack {
+                    Text("\(state.activeOverrideName) is running")
+
+                    Spacer()
+                    Image(systemName: "square.and.pencil")
+                        .foregroundStyle(Color.blue)
+                }
+                .contentShape(Rectangle())
+                .onTapGesture {
+                    Task {
+                        /// To avoid editing the Preset when a Preset-Override is running we first duplicate the Preset-Override as a non-Preset Override
+                        /// The currentActiveOverride variable in the State will update automatically via MOC notification
+                        await state.duplicateOverridePresetAndCancelPreviousOverride()
+
+                        /// selectedOverride is used for passing the chosen Override to the EditSheet so we have to set the updated currentActiveOverride to be the selectedOverride
+                        selectedOverride = state.currentActiveOverride
+
+                        /// Now we can show the Edit sheet
+                        state.showOverrideEditSheet = true
+                    }
+                }
+            }
+            .listRowBackground(Color.blue.opacity(0.2))
+        }
+
+        private var cancelOverrideButton: some View {
+            Button(action: {
+                Task {
+                    // Save cancelled Override in OverrideRunStored Entity
+                    // Cancel ALL active Override
+                    await state.disableAllActiveOverrides(createOverrideRunEntry: true)
+                }
+            }, label: {
+                Text("Cancel Override")
+
+            })
+                .frame(maxWidth: .infinity, alignment: .center)
+                .disabled(!state.isEnabled)
+                .listRowBackground(!state.isEnabled ? Color(.systemGray4) : Color(.systemRed))
+                .tint(.white)
+        }
+
+        @ViewBuilder func tempTargets() -> some View {
+            if !state.presetsTT.isEmpty {
+                Section(header: Text("Presets")) {
+                    ForEach(state.presetsTT) { preset in
+                        presetView(for: preset)
+                    }
+                }.listRowBackground(Color.chart)
+            }
+
+            HStack {
+                Text("Experimental")
+                Toggle(isOn: $state.viewPercantage) {}.controlSize(.mini)
+                Image(systemName: "figure.highintensity.intervaltraining")
+                Image(systemName: "fork.knife")
+            }.listRowBackground(Color.chart)
+
+            if state.viewPercantage {
+                Section {
+                    VStack {
+                        Text("\(state.percentageTT.formatted(.number)) % Insulin")
+                            .foregroundColor(isEditingTT ? .orange : .blue)
+                            .font(.largeTitle)
+                            .padding(.vertical)
+                        Slider(
+                            value: $state.percentageTT,
+                            in: 15 ...
+                                min(Double(state.maxValue * 100), 200),
+                            step: 1,
+                            onEditingChanged: { editing in
+                                isEditingTT = editing
+                            }
+                        )
+                        // Only display target slider when not 100 %
+                        if state.percentageTT != 100 {
+                            Spacer()
+                            Divider()
+                            Text(
+                                (
+                                    state
+                                        .units == .mmolL ?
+                                        "\(state.computeTarget().asMmolL.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))) mmol/L" :
+                                        "\(state.computeTarget().formatted(.number.grouping(.never).rounded().precision(.fractionLength(0)))) mg/dl"
+                                )
+                                    + NSLocalizedString(" Target Glucose", comment: "")
+                            )
+                            .foregroundColor(.green)
+                            .padding(.vertical)
+
+                            Slider(
+                                value: $state.hbt,
+                                in: 101 ... 295,
+                                step: 1
+                            ).accentColor(.green)
+                        }
+                    }
+                }.listRowBackground(Color.chart)
+            } else {
+                Section(header: Text("Custom")) {
+                    HStack {
+                        Text("Target")
+                        Spacer()
+                        TextFieldWithToolBar(text: $state.low, placeholder: "0", numberFormatter: glucoseFormatter)
+                        Text(state.units.rawValue).foregroundColor(.secondary)
+                    }
+                    HStack {
+                        Text("Duration")
+                        Spacer()
+                        TextFieldWithToolBar(text: $state.durationTT, placeholder: "0", numberFormatter: formatter)
+                        Text("minutes").foregroundColor(.secondary)
+                    }
+                    DatePicker("Date", selection: $state.date)
+                    HStack {
+                        Button { state.enact() }
+                        label: { Text("Enact") }
+                            .disabled(state.durationTT == 0)
+                            .buttonStyle(BorderlessButtonStyle())
+                            .font(.callout)
+                            .controlSize(.mini)
+
+                        Button { isPromptPresented = true }
+                        label: { Text("Save as preset") }
+                            .disabled(state.durationTT == 0)
+                            .tint(.orange)
+                            .frame(maxWidth: .infinity, alignment: .trailing)
+                            .buttonStyle(BorderlessButtonStyle())
+                            .controlSize(.mini)
+                    }
+                }.listRowBackground(Color.chart)
+            }
+            if state.viewPercantage {
+                Section {
+                    HStack {
+                        Text("Duration")
+                        Spacer()
+                        TextFieldWithToolBar(text: $state.durationTT, placeholder: "0", numberFormatter: formatter)
+                        Text("minutes").foregroundColor(.secondary)
+                    }
+                    DatePicker("Date", selection: $state.date)
+                    HStack {
+                        Button { state.enact() }
+                        label: { Text("Enact") }
+                            .disabled(state.durationTT == 0)
+                            .buttonStyle(BorderlessButtonStyle())
+                            .font(.callout)
+                            .controlSize(.mini)
+
+                        Button { isPromptPresented = true }
+                        label: { Text("Save as preset") }
+                            .disabled(state.durationTT == 0)
+                            .tint(.orange)
+                            .frame(maxWidth: .infinity, alignment: .trailing)
+                            .buttonStyle(BorderlessButtonStyle())
+                            .controlSize(.mini)
+                    }
+                }.listRowBackground(Color.chart)
+            }
+
+            Section {
+                Button { state.cancel() }
+                label: {
+                    HStack {
+                        Spacer()
+                        Text("Cancel Temp Target")
+                        Spacer()
+                        Image(systemName: "xmark.app")
+                            .font(.title)
+                    }
+                }
+                .frame(maxWidth: .infinity, alignment: .center)
+                .disabled(state.storage.current() == nil)
+                .listRowBackground(state.storage.current() == nil ? Color(.systemGray4) : Color(.systemRed))
+                .tint(.white)
+            }.popover(isPresented: $isPromptPresented) {
+                Form {
+                    Section(header: Text("Enter preset name")) {
+                        TextField("Name", text: $state.newPresetName)
+                        Button {
+                            state.save()
+                            isPromptPresented = false
+                        }
+                        label: { Text("Save") }
+                        Button { isPromptPresented = false }
+                        label: { Text("Cancel") }
+                    }
+                }
+            }
+            .onAppear {
+                configureView()
+                state.hbt = isEnabledArray.first?.hbt ?? 160
+            }
+        }
+
+        private func presetView(for preset: TempTarget) -> some View {
+            var low = preset.targetBottom
+            var high = preset.targetTop
+            if state.units == .mmolL {
+                low = low?.asMmolL
+                high = high?.asMmolL
+            }
+            let isSelected = preset.id == selectedPresetID
+
+            return ZStack(alignment: .trailing, content: {
+                HStack {
+                    VStack {
+                        HStack {
+                            Text(preset.displayName)
+                            Spacer()
+                        }
+                        HStack(spacing: 2) {
+                            Text(
+                                "\(formatter.string(from: (low ?? 0) as NSNumber)!) - \(formatter.string(from: (high ?? 0) as NSNumber)!)"
+                            )
+                            .foregroundColor(.secondary)
+                            .font(.caption)
+
+                            Text(state.units.rawValue)
+                                .foregroundColor(.secondary)
+                                .font(.caption)
+                            Text("for")
+                                .foregroundColor(.secondary)
+                                .font(.caption)
+                            Text("\(formatter.string(from: preset.duration as NSNumber)!)")
+                                .foregroundColor(.secondary)
+                                .font(.caption)
+                            Text("min")
+                                .foregroundColor(.secondary)
+                                .font(.caption)
+
+                            Spacer()
+                        }.padding(.top, 2)
+                    }
+                    .contentShape(Rectangle())
+                    .onTapGesture {
+                        state.enactPreset(id: preset.id)
+                        selectedPresetID = preset.id
+                        showCheckmark.toggle()
+
+                        // deactivate showCheckmark after 3 seconds
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
+                            showCheckmark = false
+                        }
+                    }
+
+                    Image(systemName: "xmark.circle").foregroundColor(showCheckmark && isSelected ? Color.clear : Color.secondary)
+                        .contentShape(Rectangle())
+                        .padding(.vertical)
+                        .onTapGesture {
+                            removeAlert = Alert(
+                                title: Text("Are you sure?"),
+                                message: Text("Delete preset \"\(preset.displayName)\""),
+                                primaryButton: .destructive(Text("Delete"), action: { state.removePreset(id: preset.id) }),
+                                secondaryButton: .cancel()
+                            )
+                            isRemoveAlertPresented = true
+                        }
+                        .alert(isPresented: $isRemoveAlertPresented) {
+                            removeAlert!
+                        }
+                }
+                if showCheckmark && isSelected {
+                    // show checkmark to indicate if the preset was actually pressed
+                    Image(systemName: "checkmark.circle.fill")
+                        .imageScale(.large)
+                        .fontWeight(.bold)
+                        .foregroundStyle(Color.green)
+                }
+            })
+        }
+
+        @ViewBuilder private func overridesView(for preset: OverrideStored) -> some View {
+            let target = (state.units == .mgdL ? preset.target : preset.target?.decimalValue.asMmolL as NSDecimalNumber?) ?? 0
+
+            let duration = (preset.duration ?? 0) as Decimal
+            let name = ((preset.name ?? "") == "") || (preset.name?.isEmpty ?? true) ? "" : preset.name!
+            let percent = preset.percentage / 100
+            let perpetual = preset.indefinite
+            let durationString = perpetual ? "" : "\(formatter.string(from: duration as NSNumber)!)"
+            let scheduledSMBstring = (preset.smbIsOff && preset.smbIsAlwaysOff) ? "Scheduled SMBs" : ""
+            let smbString = (preset.smbIsOff && scheduledSMBstring == "") ? "SMBs are off" : ""
+            let targetString = target != 0 ? target.description : ""
+            let maxMinutesSMB = (preset.smbMinutes as Decimal?) != nil ? (preset.smbMinutes ?? 0) as Decimal : 0
+            let maxMinutesUAM = (preset.uamMinutes as Decimal?) != nil ? (preset.uamMinutes ?? 0) as Decimal : 0
+            let isfString = preset.isf ? "ISF" : ""
+            let crString = preset.cr ? "CR" : ""
+            let dash = crString != "" ? "/" : ""
+            let isfAndCRstring = isfString + dash + crString
+            let isSelected = preset.id == selectedPresetID
+
+            if name != "" {
+                ZStack(alignment: .trailing, content: {
+                    HStack {
+                        VStack {
+                            HStack {
+                                Text(name)
+                                Spacer()
+                            }
+                            HStack(spacing: 5) {
+                                Text(percent.formatted(.percent.grouping(.never).rounded().precision(.fractionLength(0))))
+                                if targetString != "" {
+                                    Text(targetString)
+                                    Text(targetString != "" ? state.units.rawValue : "")
+                                }
+                                if durationString != "" { Text(durationString + (perpetual ? "" : "min")) }
+                                if smbString != "" { Text(smbString).foregroundColor(.secondary).font(.caption) }
+                                if scheduledSMBstring != "" { Text(scheduledSMBstring) }
+                                if preset.advancedSettings {
+                                    Text(maxMinutesSMB == 0 ? "" : maxMinutesSMB.formatted() + " SMB")
+                                    Text(maxMinutesUAM == 0 ? "" : maxMinutesUAM.formatted() + " UAM")
+                                    Text(isfAndCRstring)
+                                }
+                                Spacer()
+                            }
+                            .padding(.top, 2)
+                            .foregroundColor(.secondary)
+                            .font(.caption)
+                        }
+                        .contentShape(Rectangle())
+                        .onTapGesture {
+                            Task {
+                                let objectID = preset.objectID
+                                await state.enactOverridePreset(withID: objectID)
+                                state.hideModal()
+                                showCheckmark.toggle()
+                                selectedPresetID = preset.id
+
+                                // deactivate showCheckmark after 3 seconds
+                                DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
+                                    showCheckmark = false
+                                }
+                            }
+                        }
+                    }
+                    // show checkmark to indicate if the preset was actually pressed
+                    if showCheckmark && isSelected {
+                        Image(systemName: "checkmark.circle.fill")
+                            .imageScale(.large)
+                            .fontWeight(.bold)
+                            .foregroundStyle(Color.green)
+                    } else {
+                        Image(systemName: "line.3.horizontal")
+                            .imageScale(.medium)
+                            .foregroundStyle(.secondary)
+                    }
+                })
+            }
+        }
+    }
+}

+ 2 - 17
FreeAPS/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift

@@ -16,22 +16,7 @@ extension PumpConfig {
         @State var showPumpSelection: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             NavigationView {
@@ -91,7 +76,7 @@ extension PumpConfig {
                     .padding(.top)
                     .listRowBackground(Color.chart)
                 }
-                .scrollContentBackground(.hidden).background(color)
+                .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
                 .onAppear(perform: configureView)
                 .navigationTitle("Insulin Pump")
                 .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/RemoteControlConfig/View/RemoteControlConfig.swift

@@ -17,23 +17,7 @@ extension RemoteControlConfig {
         @State private var isCopied: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             Form {
@@ -104,7 +88,7 @@ extension RemoteControlConfig {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Remote Control")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/SMBSettings/View/SMBSettingsRootView.swift

@@ -14,23 +14,7 @@ extension SMBSettings {
 
         @Environment(\.colorScheme) var colorScheme
         @EnvironmentObject var appIcons: Icons
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             List {
@@ -305,7 +289,7 @@ extension SMBSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("SMB Settings")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -21,23 +21,7 @@ extension Settings {
 
         @Environment(\.colorScheme) var colorScheme
         @EnvironmentObject var appIcons: Icons
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var filteredItems: [FilteredSettingItem] {
             SettingItems.filteredItems(searchText: searchText)
@@ -298,7 +282,7 @@ extension Settings {
 //                    }
 //                }.listRowBackground(Color.chart)
 
-            }.scrollContentBackground(.hidden).background(color)
+            }.scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
                 .sheet(isPresented: $shouldDisplayHint) {
                     SettingInputHintView(
                         hintDetent: $hintDetent,

+ 3 - 17
FreeAPS/Sources/Modules/Settings/View/Subviews/AlgorithmSettings.swift

@@ -14,22 +14,7 @@ struct AlgorithmSettings: BaseView {
     @ObservedObject var state: Settings.StateModel
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -44,7 +29,8 @@ struct AlgorithmSettings: BaseView {
                 }
             ).listRowBackground(Color.chart)
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Algorithm Settings")
         .navigationBarTitleDisplayMode(.automatic)
     }

+ 3 - 17
FreeAPS/Sources/Modules/Settings/View/Subviews/DevicesView.swift

@@ -14,22 +14,7 @@ struct DevicesView: BaseView {
     @ObservedObject var state: Settings.StateModel
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -43,7 +28,8 @@ struct DevicesView: BaseView {
             )
             .listRowBackground(Color.chart)
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Devices")
         .navigationBarTitleDisplayMode(.automatic)
     }

+ 3 - 17
FreeAPS/Sources/Modules/Settings/View/Subviews/FeatureSettingsView.swift

@@ -14,22 +14,7 @@ struct FeatureSettingsView: BaseView {
     @ObservedObject var state: Settings.StateModel
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -61,7 +46,8 @@ struct FeatureSettingsView: BaseView {
             )
             .listRowBackground(Color.chart)
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Feature Settings")
         .navigationBarTitleDisplayMode(.automatic)
     }

+ 3 - 17
FreeAPS/Sources/Modules/Settings/View/Subviews/NotificationsView.swift

@@ -22,22 +22,7 @@ struct NotificationsView: BaseView {
     @State var hintLabel: String? = "Manage iOS Preferences"
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -113,7 +98,8 @@ struct NotificationsView: BaseView {
                 sheetTitle: "Help"
             )
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Notifications")
         .navigationBarTitleDisplayMode(.automatic)
     }

+ 3 - 17
FreeAPS/Sources/Modules/Settings/View/Subviews/ServicesView.swift

@@ -15,22 +15,7 @@ struct ServicesView: BaseView {
     @ObservedObject var state: Settings.StateModel
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -46,7 +31,8 @@ struct ServicesView: BaseView {
             )
             .listRowBackground(Color.chart)
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Services")
         .navigationBarTitleDisplayMode(.automatic)
     }

+ 3 - 17
FreeAPS/Sources/Modules/Settings/View/Subviews/TherapySettingsView.swift

@@ -14,22 +14,7 @@ struct TherapySettingsView: BaseView {
     @ObservedObject var state: Settings.StateModel
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -52,7 +37,8 @@ struct TherapySettingsView: BaseView {
             )
             .listRowBackground(Color.chart)
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Therapy Settings")
         .navigationBarTitleDisplayMode(.automatic)
     }

+ 2 - 17
FreeAPS/Sources/Modules/Settings/View/TidepoolStartView.swift

@@ -12,22 +12,7 @@ struct TidepoolStartView: BaseView {
     @State private var booleanPlaceholder: Bool = false
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     var body: some View {
         Form {
@@ -117,7 +102,7 @@ struct TidepoolStartView: BaseView {
                 sheetTitle: "Help"
             )
         }
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
         .navigationTitle("Tidepool")
         .navigationBarTitleDisplayMode(.automatic)
         .onAppear(perform: configureView)

+ 2 - 18
FreeAPS/Sources/Modules/ShortcutsConfig/View/ShortcutsConfigView.swift

@@ -17,23 +17,7 @@ extension ShortcutsConfig {
         @State private var booleanPlaceholder: Bool = false
 
         @Environment(\.colorScheme) var colorScheme
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             Form {
@@ -83,7 +67,7 @@ extension ShortcutsConfig {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Shortcuts")
             .navigationBarTitleDisplayMode(.automatic)

+ 2 - 17
FreeAPS/Sources/Modules/Snooze/View/SnoozeRootView.swift

@@ -8,22 +8,7 @@ extension Snooze {
         @State var state = StateModel()
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         @State private var selectedInterval = 0
         @State private var snoozeDescription = "nothing to see here"
@@ -133,7 +118,7 @@ extension Snooze {
                     snoozeButton
                 }
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .navigationBarTitle("Snooze Alerts")
             .navigationBarTitleDisplayMode(.automatic)
             .navigationBarItems(trailing: Button("Close", action: state.hideModal))

+ 2 - 18
FreeAPS/Sources/Modules/Stat/View/StatRootView.swift

@@ -10,6 +10,7 @@ extension Stat {
         @State var state = StateModel()
 
         @Environment(\.colorScheme) var colorScheme
+        @Environment(AppState.self) var appState
 
         @State var paddingAmount: CGFloat? = 10
         @State var headline: Color = .secondary
@@ -17,23 +18,6 @@ extension Stat {
         @State var pointSize: CGFloat = 3
         @State var conversionFactor = 0.0555
 
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
-
         @ViewBuilder func stats() -> some View {
             ZStack {
                 Color.gray.opacity(0.05).ignoresSafeArea(.all)
@@ -145,7 +129,7 @@ extension Stat {
                 }
                 .pickerStyle(.segmented).background(.cyan.opacity(0.2))
                 stats()
-            }.background(color)
+            }.background(appState.trioBackgroundColor(for: colorScheme))
                 .onAppear(perform: configureView)
                 .navigationBarTitle("Statistics")
                 .navigationBarTitleDisplayMode(.automatic)

+ 2 - 18
FreeAPS/Sources/Modules/TargetBehavoir/View/TargetBehavoirRootView.swift

@@ -14,23 +14,7 @@ extension TargetBehavoir {
 
         @Environment(\.colorScheme) var colorScheme
         @EnvironmentObject var appIcons: Icons
-
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             List {
@@ -161,7 +145,7 @@ extension TargetBehavoir {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Target Behavior")
             .navigationBarTitleDisplayMode(.automatic)

+ 3 - 18
FreeAPS/Sources/Modules/TargetsEditor/View/TargetsEditorRootView.swift

@@ -9,22 +9,7 @@ extension TargetsEditor {
         @State private var editMode = EditMode.inactive
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var dateFormatter: DateFormatter {
             let formatter = DateFormatter()
@@ -82,7 +67,7 @@ extension TargetsEditor {
                 }.listRowBackground(Color.chart)
             }
             .safeAreaInset(edge: .bottom, spacing: 30) { saveButton }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Target Glucose")
             .navigationBarTitleDisplayMode(.automatic)
@@ -129,7 +114,7 @@ extension TargetsEditor {
                 }.listRowBackground(Color.chart)
             }
             .padding(.top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Set Target")
             .navigationBarTitleDisplayMode(.automatic)
         }

+ 3 - 17
FreeAPS/Sources/Modules/Treatments/View/MealPreset/AddMealPresetView.swift

@@ -13,22 +13,7 @@ struct AddMealPresetView: View {
     var onCancel: () -> Void
 
     @Environment(\.colorScheme) private var colorScheme
-    private var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     private var mealFormatter: NumberFormatter {
         let formatter = NumberFormatter()
@@ -57,7 +42,8 @@ struct AddMealPresetView: View {
 
                 savePresetButton
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Add Meal Preset")
             .navigationBarTitleDisplayMode(.inline)
             .toolbar(content: {

+ 4 - 1
FreeAPS/Sources/Modules/Treatments/View/MealPreset/MealPresetView.swift

@@ -4,9 +4,11 @@ import SwiftUI
 
 struct MealPresetView: View {
     @Bindable var state: Treatments.StateModel
+
     @Environment(\.colorScheme) var colorScheme
     @Environment(\.dismiss) var dismiss
     @Environment(\.managedObjectContext) var moc
+    @Environment(AppState.self) var appState
 
     @State private var showAlert = false
     @State private var dish: String = ""
@@ -56,7 +58,8 @@ struct MealPresetView: View {
                 dishInfos()
                 addPresetToTreatmentsButton
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .navigationTitle("Meal Presets")
             .navigationBarTitleDisplayMode(.automatic)
             .toolbar(content: {

+ 2 - 18
FreeAPS/Sources/Modules/Treatments/View/TreatmentsRootView.swift

@@ -31,6 +31,7 @@ extension Treatments {
         }
 
         @Environment(\.colorScheme) var colorScheme
+        @Environment(AppState.self) var appState
 
         private var formatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -61,23 +62,6 @@ extension Treatments {
             } else { return 0 }
         }
 
-        private var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
-
         /// Handles macro input (carb, fat, protein) in a debounced fashion.
         func handleDebouncedInput() {
             debounce?.cancel()
@@ -319,7 +303,7 @@ extension Treatments {
             }
             .padding(.top)
             .ignoresSafeArea(edges: .top)
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .blur(radius: state.showInfo ? 3 : 0)
             .navigationTitle("Treatments")
             .navigationBarTitleDisplayMode(.inline)

+ 4 - 17
FreeAPS/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift

@@ -4,6 +4,7 @@ import Swinject
 extension UserInterfaceSettings {
     struct RootView: BaseView {
         let resolver: Resolver
+
         @StateObject var state = StateModel()
 
         @State private var shouldDisplayHint: Bool = false
@@ -18,22 +19,7 @@ extension UserInterfaceSettings {
         @AppStorage("colorSchemePreference") private var colorSchemePreference: ColorSchemeOption = .systemDefault
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         private var glucoseFormatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -433,7 +419,8 @@ extension UserInterfaceSettings {
                     sheetTitle: "Help"
                 )
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden)
+            .background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationBarTitle("User Interface")
             .navigationBarTitleDisplayMode(.automatic)

+ 3 - 17
FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigAppleWatchView.swift

@@ -11,22 +11,7 @@ struct WatchConfigAppleWatchView: View {
     @State private var booleanPlaceholder: Bool = false
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     private func onDelete(offsets: IndexSet) {
         state.devices.remove(atOffsets: offsets)
@@ -120,6 +105,7 @@ struct WatchConfigAppleWatchView: View {
         }
         .navigationTitle("Apple Watch")
         .navigationBarTitleDisplayMode(.automatic)
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
     }
 }

+ 3 - 17
FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigGarminView.swift

@@ -11,22 +11,7 @@ struct WatchConfigGarminView: View {
     @State private var booleanPlaceholder: Bool = false
 
     @Environment(\.colorScheme) var colorScheme
-    var color: LinearGradient {
-        colorScheme == .dark ? LinearGradient(
-            gradient: Gradient(colors: [
-                Color.bgDarkBlue,
-                Color.bgDarkerDarkBlue
-            ]),
-            startPoint: .top,
-            endPoint: .bottom
-        )
-            :
-            LinearGradient(
-                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-    }
+    @Environment(AppState.self) var appState
 
     private func onDelete(offsets: IndexSet) {
         state.devices.remove(atOffsets: offsets)
@@ -95,6 +80,7 @@ struct WatchConfigGarminView: View {
         }
         .navigationTitle("Garmin")
         .navigationBarTitleDisplayMode(.automatic)
-        .scrollContentBackground(.hidden).background(color)
+        .scrollContentBackground(.hidden)
+        .background(appState.trioBackgroundColor(for: colorScheme))
     }
 }

+ 2 - 17
FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigRootView.swift

@@ -7,22 +7,7 @@ extension WatchConfig {
         @StateObject var state = StateModel()
 
         @Environment(\.colorScheme) var colorScheme
-        var color: LinearGradient {
-            colorScheme == .dark ? LinearGradient(
-                gradient: Gradient(colors: [
-                    Color.bgDarkBlue,
-                    Color.bgDarkerDarkBlue
-                ]),
-                startPoint: .top,
-                endPoint: .bottom
-            )
-                :
-                LinearGradient(
-                    gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
-                    startPoint: .top,
-                    endPoint: .bottom
-                )
-        }
+        @Environment(AppState.self) var appState
 
         var body: some View {
             Form {
@@ -34,7 +19,7 @@ extension WatchConfig {
                     }
                 ).listRowBackground(Color.chart)
             }
-            .scrollContentBackground(.hidden).background(color)
+            .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
             .onAppear(perform: configureView)
             .navigationTitle("Watch")
             .navigationBarTitleDisplayMode(.automatic)