Sfoglia il codice sorgente

Add new Live Activity setting; refactor alarms, misc.

Deniz Cengiz 1 anno fa
parent
commit
4fc7dde4a7
17 ha cambiato i file con 456 aggiunte e 186 eliminazioni
  1. 51 19
      FreeAPS.xcodeproj/project.pbxproj
  2. 5 0
      FreeAPS/Sources/Modules/GlucoseNotificationSettings/GlucoseNotificationSettingsDataFlow.swift
  3. 3 0
      FreeAPS/Sources/Modules/GlucoseNotificationSettings/GlucoseNotificationSettingsProvider.swift
  4. 2 11
      FreeAPS/Sources/Modules/NotificationsConfig/NotificationsConfigStateModel.swift
  5. 181 0
      FreeAPS/Sources/Modules/GlucoseNotificationSettings/View/GlucoseNotificationSettingsRootView.swift
  6. 5 0
      FreeAPS/Sources/Modules/LiveActivitySettings/LiveActivitySettingsDataFlow.swift
  7. 3 0
      FreeAPS/Sources/Modules/LiveActivitySettings/LiveActivitySettingsProvider.swift
  8. 17 0
      FreeAPS/Sources/Modules/LiveActivitySettings/LiveActivitySettingsStateModel.swift
  9. 139 0
      FreeAPS/Sources/Modules/LiveActivitySettings/View/LiveActivitySettingsRootView.swift
  10. 0 5
      FreeAPS/Sources/Modules/NotificationsConfig/NotificationsConfigDataFlow.swift
  11. 0 3
      FreeAPS/Sources/Modules/NotificationsConfig/NotificationsConfigProvider.swift
  12. 0 143
      FreeAPS/Sources/Modules/NotificationsConfig/View/NotificationsConfigRootView.swift
  13. 6 2
      FreeAPS/Sources/Modules/Settings/View/Subviews/NotificationsView.swift
  14. 6 0
      FreeAPS/Sources/Modules/UserInterfaceSettings/UserInterfaceSettingsStateModel.swift
  15. 13 0
      FreeAPS/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift
  16. 6 3
      FreeAPS/Sources/Router/Screen.swift
  17. 19 0
      FreeAPS/Sources/Views/SettingInputHintView.swift

+ 51 - 19
FreeAPS.xcodeproj/project.pbxproj

@@ -10,7 +10,7 @@
 		041D1E995A6AE92E9289DC49 /* BolusDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D1A7CA8C10C4403D4BBFA7 /* BolusDataFlow.swift */; };
 		0437CE46C12535A56504EC19 /* SnoozeRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5822B15939E719628E9FF7C /* SnoozeRootView.swift */; };
 		0D9A5E34A899219C5C4CDFAF /* DataTableStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9455FA2D92E77A6C4AFED8A3 /* DataTableStateModel.swift */; };
-		0F7A65FBD2CD8D6477ED4539 /* NotificationsConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E625985B47742D498CB1681A /* NotificationsConfigProvider.swift */; };
+		0F7A65FBD2CD8D6477ED4539 /* GlucoseNotificationSettingsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E625985B47742D498CB1681A /* GlucoseNotificationSettingsProvider.swift */; };
 		110AEDE32C5193D200615CC9 /* BolusIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110AEDE02C5193D100615CC9 /* BolusIntent.swift */; };
 		110AEDE42C5193D200615CC9 /* BolusIntentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110AEDE12C5193D100615CC9 /* BolusIntentRequest.swift */; };
 		110AEDEB2C51A0AE00615CC9 /* ShortcutsConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110AEDE52C51A0AE00615CC9 /* ShortcutsConfigView.swift */; };
@@ -62,7 +62,7 @@
 		23888883D4EA091C88480FF2 /* BolusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C19984D62EFC0035A9E9644D /* BolusProvider.swift */; };
 		2BE9A6FA20875F6F4F9CD461 /* PumpSettingsEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D97F14812C1AFED3621165A5 /* PumpSettingsEditorProvider.swift */; };
 		3083261C4B268E353F36CD0B /* AutotuneConfigDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DCCCCE633F5E98E41B0CD3C /* AutotuneConfigDataFlow.swift */; };
-		3171D2818C7C72CD1584BB5E /* NotificationsConfigStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2C6489D29ECCCAD78E0721 /* NotificationsConfigStateModel.swift */; };
+		3171D2818C7C72CD1584BB5E /* GlucoseNotificationSettingsStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2C6489D29ECCCAD78E0721 /* GlucoseNotificationSettingsStateModel.swift */; };
 		320D030F724170A637F06D50 /* (null) in Sources */ = {isa = PBXBuildFile; };
 		3811DE0B25C9D32F00A708ED /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3811DE0725C9D32E00A708ED /* BaseView.swift */; };
 		3811DE0C25C9D32F00A708ED /* BaseProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3811DE0825C9D32F00A708ED /* BaseProvider.swift */; };
@@ -324,7 +324,7 @@
 		CA370FC152BC98B3D1832968 /* BasalProfileEditorRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8BCB0C37DEB5EC377B9612 /* BasalProfileEditorRootView.swift */; };
 		CC6C406E2ACDD69E009B8058 /* RawFetchedProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC6C406D2ACDD69E009B8058 /* RawFetchedProfile.swift */; };
 		CC76E9512BD4812E008BEB61 /* Forecast+helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC76E9502BD4812E008BEB61 /* Forecast+helper.swift */; };
-		CD78BB94E43B249D60CC1A1B /* NotificationsConfigRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22963BD06A9C83959D4914E4 /* NotificationsConfigRootView.swift */; };
+		CD78BB94E43B249D60CC1A1B /* GlucoseNotificationSettingsRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22963BD06A9C83959D4914E4 /* GlucoseNotificationSettingsRootView.swift */; };
 		CE1856F52ADC4858007E39C7 /* AddCarbPresetIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1856F42ADC4858007E39C7 /* AddCarbPresetIntent.swift */; };
 		CE1856F72ADC4869007E39C7 /* CarbPresetIntentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1856F62ADC4869007E39C7 /* CarbPresetIntentRequest.swift */; };
 		CE1F6DD92BADF4620064EB8D /* PluginManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F6DD82BADF4620064EB8D /* PluginManagerTests.swift */; };
@@ -462,6 +462,10 @@
 		DDD1631A2C4C695E00CD525A /* EditOverrideForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD163192C4C695E00CD525A /* EditOverrideForm.swift */; };
 		DDD1631C2C4C697400CD525A /* AddOverrideForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD1631B2C4C697400CD525A /* AddOverrideForm.swift */; };
 		DDD1631F2C4C6F6900CD525A /* TrioCoreDataPersistentContainer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DDD1631D2C4C6F6900CD525A /* TrioCoreDataPersistentContainer.xcdatamodeld */; };
+		DDF847DD2C5C28720049BB3B /* LiveActivitySettingsDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF847DC2C5C28720049BB3B /* LiveActivitySettingsDataFlow.swift */; };
+		DDF847DF2C5C28780049BB3B /* LiveActivitySettingsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF847DE2C5C28780049BB3B /* LiveActivitySettingsProvider.swift */; };
+		DDF847E12C5C287F0049BB3B /* LiveActivitySettingsStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF847E02C5C287F0049BB3B /* LiveActivitySettingsStateModel.swift */; };
+		DDF847E42C5C288F0049BB3B /* LiveActivitySettingsRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF847E32C5C288F0049BB3B /* LiveActivitySettingsRootView.swift */; };
 		E00EEC0327368630002FF094 /* ServiceAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = E00EEBFD27368630002FF094 /* ServiceAssembly.swift */; };
 		E00EEC0427368630002FF094 /* SecurityAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = E00EEBFE27368630002FF094 /* SecurityAssembly.swift */; };
 		E00EEC0527368630002FF094 /* StorageAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = E00EEBFF27368630002FF094 /* StorageAssembly.swift */; };
@@ -474,7 +478,7 @@
 		E0D4F80527513ECF00BDF1FE /* HealthKitSample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0D4F80427513ECF00BDF1FE /* HealthKitSample.swift */; };
 		E13B7DAB2A435F57066AF02E /* TargetsEditorStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36F58DDD71F0E795464FA3F0 /* TargetsEditorStateModel.swift */; };
 		E39E418C56A5A46B61D960EE /* ConfigEditorStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D5B4F8B4194BB7E260EF251 /* ConfigEditorStateModel.swift */; };
-		E3A08AAE59538BC8A8ABE477 /* NotificationsConfigDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3260468377DA9DB4DEE9AF6D /* NotificationsConfigDataFlow.swift */; };
+		E3A08AAE59538BC8A8ABE477 /* GlucoseNotificationSettingsDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3260468377DA9DB4DEE9AF6D /* GlucoseNotificationSettingsDataFlow.swift */; };
 		E4984C5262A90469788754BB /* PreferencesEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8BA8533F56BC55748CA877 /* PreferencesEditorProvider.swift */; };
 		E974172296125A5AE99E634C /* PumpConfigRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD22C985B79A2F0D2EA3D9D /* PumpConfigRootView.swift */; };
 		F5CA3DB1F9DC8B05792BBFAA /* CGMDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9B5C0607505A38F256BF99A /* CGMDataFlow.swift */; };
@@ -670,10 +674,10 @@
 		19F95FF929F1102A00314DDC /* StatRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatRootView.swift; sourceTree = "<group>"; };
 		1CAE81192B118804DCD23034 /* SnoozeProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SnoozeProvider.swift; sourceTree = "<group>"; };
 		223EC0494F55A91E3EA69EF4 /* BolusStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BolusStateModel.swift; sourceTree = "<group>"; };
-		22963BD06A9C83959D4914E4 /* NotificationsConfigRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NotificationsConfigRootView.swift; sourceTree = "<group>"; };
+		22963BD06A9C83959D4914E4 /* GlucoseNotificationSettingsRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GlucoseNotificationSettingsRootView.swift; sourceTree = "<group>"; };
 		2AD22C985B79A2F0D2EA3D9D /* PumpConfigRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PumpConfigRootView.swift; sourceTree = "<group>"; };
 		2F2A13DF0EDEEEDC4106AA2A /* NightscoutConfigDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NightscoutConfigDataFlow.swift; sourceTree = "<group>"; };
-		3260468377DA9DB4DEE9AF6D /* NotificationsConfigDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NotificationsConfigDataFlow.swift; sourceTree = "<group>"; };
+		3260468377DA9DB4DEE9AF6D /* GlucoseNotificationSettingsDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GlucoseNotificationSettingsDataFlow.swift; sourceTree = "<group>"; };
 		36A708CDB546692C2230B385 /* SnoozeDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SnoozeDataFlow.swift; sourceTree = "<group>"; };
 		36F58DDD71F0E795464FA3F0 /* TargetsEditorStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorStateModel.swift; sourceTree = "<group>"; };
 		3811DE0725C9D32E00A708ED /* BaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseView.swift; sourceTree = "<group>"; };
@@ -1018,7 +1022,7 @@
 		D0BDC6993C1087310EDFC428 /* CREditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CREditorRootView.swift; sourceTree = "<group>"; };
 		D295A3F870E826BE371C0BB5 /* AutotuneConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AutotuneConfigStateModel.swift; sourceTree = "<group>"; };
 		D97F14812C1AFED3621165A5 /* PumpSettingsEditorProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PumpSettingsEditorProvider.swift; sourceTree = "<group>"; };
-		DC2C6489D29ECCCAD78E0721 /* NotificationsConfigStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NotificationsConfigStateModel.swift; sourceTree = "<group>"; };
+		DC2C6489D29ECCCAD78E0721 /* GlucoseNotificationSettingsStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GlucoseNotificationSettingsStateModel.swift; sourceTree = "<group>"; };
 		DD09D47A2C5986D1003FEA5D /* CalendarEventSettingsDataFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarEventSettingsDataFlow.swift; sourceTree = "<group>"; };
 		DD09D47C2C5986DA003FEA5D /* CalendarEventSettingsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarEventSettingsProvider.swift; sourceTree = "<group>"; };
 		DD09D47E2C5986E5003FEA5D /* CalendarEventSettingsStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarEventSettingsStateModel.swift; sourceTree = "<group>"; };
@@ -1095,6 +1099,10 @@
 		DDD163192C4C695E00CD525A /* EditOverrideForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditOverrideForm.swift; sourceTree = "<group>"; };
 		DDD1631B2C4C697400CD525A /* AddOverrideForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOverrideForm.swift; sourceTree = "<group>"; };
 		DDD1631E2C4C6F6900CD525A /* TrioCoreDataPersistentContainer.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TrioCoreDataPersistentContainer.xcdatamodel; sourceTree = "<group>"; };
+		DDF847DC2C5C28720049BB3B /* LiveActivitySettingsDataFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivitySettingsDataFlow.swift; sourceTree = "<group>"; };
+		DDF847DE2C5C28780049BB3B /* LiveActivitySettingsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivitySettingsProvider.swift; sourceTree = "<group>"; };
+		DDF847E02C5C287F0049BB3B /* LiveActivitySettingsStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivitySettingsStateModel.swift; sourceTree = "<group>"; };
+		DDF847E32C5C288F0049BB3B /* LiveActivitySettingsRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivitySettingsRootView.swift; sourceTree = "<group>"; };
 		E00EEBFD27368630002FF094 /* ServiceAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceAssembly.swift; sourceTree = "<group>"; };
 		E00EEBFE27368630002FF094 /* SecurityAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecurityAssembly.swift; sourceTree = "<group>"; };
 		E00EEBFF27368630002FF094 /* StorageAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageAssembly.swift; sourceTree = "<group>"; };
@@ -1106,7 +1114,7 @@
 		E0CC2C5B275B9DAE00A7BC71 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; };
 		E0D4F80427513ECF00BDF1FE /* HealthKitSample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthKitSample.swift; sourceTree = "<group>"; };
 		E26904AACA8D9C15D229D675 /* SnoozeStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SnoozeStateModel.swift; sourceTree = "<group>"; };
-		E625985B47742D498CB1681A /* NotificationsConfigProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NotificationsConfigProvider.swift; sourceTree = "<group>"; };
+		E625985B47742D498CB1681A /* GlucoseNotificationSettingsProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GlucoseNotificationSettingsProvider.swift; sourceTree = "<group>"; };
 		F816825D28DB441200054060 /* HeartBeatManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeartBeatManager.swift; sourceTree = "<group>"; };
 		F816825F28DB441800054060 /* BluetoothTransmitter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothTransmitter.swift; sourceTree = "<group>"; };
 		F90692A9274B7AAE0037068D /* HealthKitManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthKitManager.swift; sourceTree = "<group>"; };
@@ -1391,6 +1399,7 @@
 		3811DE0325C9D31700A708ED /* Modules */ = {
 			isa = PBXGroup;
 			children = (
+				DDF847DB2C5C28550049BB3B /* LiveActivitySettings */,
 				DD09D4792C5986BA003FEA5D /* CalendarEventSettings */,
 				DD17454C2C55CA0200211FAC /* GeneralSettings */,
 				DD1745422C55C5C400211FAC /* AutosensSettings */,
@@ -1416,7 +1425,7 @@
 				3811DE1A25C9D48300A708ED /* Main */,
 				5031FE61F63C2A8A8B7674DD /* ManualTempBasal */,
 				D533BF261CDC1C3F871E7BFD /* NightscoutConfig */,
-				F66B236E00924A05D6A9F9DF /* NotificationsConfig */,
+				F66B236E00924A05D6A9F9DF /* GlucoseNotificationSettings */,
 				DDD163032C4C67B400CD525A /* OverrideConfig */,
 				3E1C41D9301B7058AA7BF5EA /* PreferencesEditor */,
 				99C01B871ACAB3F32CE755C7 /* PumpConfig */,
@@ -2656,6 +2665,25 @@
 			path = View;
 			sourceTree = "<group>";
 		};
+		DDF847DB2C5C28550049BB3B /* LiveActivitySettings */ = {
+			isa = PBXGroup;
+			children = (
+				DDF847E22C5C28830049BB3B /* View */,
+				DDF847DC2C5C28720049BB3B /* LiveActivitySettingsDataFlow.swift */,
+				DDF847DE2C5C28780049BB3B /* LiveActivitySettingsProvider.swift */,
+				DDF847E02C5C287F0049BB3B /* LiveActivitySettingsStateModel.swift */,
+			);
+			path = LiveActivitySettings;
+			sourceTree = "<group>";
+		};
+		DDF847E22C5C28830049BB3B /* View */ = {
+			isa = PBXGroup;
+			children = (
+				DDF847E32C5C288F0049BB3B /* LiveActivitySettingsRootView.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 		E00EEBFC27368630002FF094 /* Assemblies */ = {
 			isa = PBXGroup;
 			children = (
@@ -2702,20 +2730,20 @@
 		F5DE2E6D7B2133BBD3353DC7 /* View */ = {
 			isa = PBXGroup;
 			children = (
-				22963BD06A9C83959D4914E4 /* NotificationsConfigRootView.swift */,
+				22963BD06A9C83959D4914E4 /* GlucoseNotificationSettingsRootView.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
 		};
-		F66B236E00924A05D6A9F9DF /* NotificationsConfig */ = {
+		F66B236E00924A05D6A9F9DF /* GlucoseNotificationSettings */ = {
 			isa = PBXGroup;
 			children = (
-				3260468377DA9DB4DEE9AF6D /* NotificationsConfigDataFlow.swift */,
-				E625985B47742D498CB1681A /* NotificationsConfigProvider.swift */,
-				DC2C6489D29ECCCAD78E0721 /* NotificationsConfigStateModel.swift */,
+				3260468377DA9DB4DEE9AF6D /* GlucoseNotificationSettingsDataFlow.swift */,
+				E625985B47742D498CB1681A /* GlucoseNotificationSettingsProvider.swift */,
+				DC2C6489D29ECCCAD78E0721 /* GlucoseNotificationSettingsStateModel.swift */,
 				F5DE2E6D7B2133BBD3353DC7 /* View */,
 			);
-			path = NotificationsConfig;
+			path = GlucoseNotificationSettings;
 			sourceTree = "<group>";
 		};
 		F75CB57ED6971B46F8756083 /* CGM */ = {
@@ -3274,6 +3302,7 @@
 				CE82E02528E867BA00473A9C /* AlertStorage.swift in Sources */,
 				DD1745372C55B74200211FAC /* AlgorithmSettings.swift in Sources */,
 				38BF021D25E7E3AF00579895 /* Reservoir.swift in Sources */,
+				DDF847E12C5C287F0049BB3B /* LiveActivitySettingsStateModel.swift in Sources */,
 				583684082BD195A700070A60 /* Determination.swift in Sources */,
 				DD17451D2C543C5F00211FAC /* ServicesView.swift in Sources */,
 				38BF021B25E7D06400579895 /* PumpSettingsView.swift in Sources */,
@@ -3377,6 +3406,7 @@
 				19012CDC291D2CB900FB8210 /* LoopStats.swift in Sources */,
 				6632A0DC746872439A858B44 /* ISFEditorDataFlow.swift in Sources */,
 				DD17454B2C55C62800211FAC /* AutosensSettingsRootView.swift in Sources */,
+				DDF847DF2C5C28780049BB3B /* LiveActivitySettingsProvider.swift in Sources */,
 				DBA5254DBB2586C98F61220C /* ISFEditorProvider.swift in Sources */,
 				BDF34EBE2C0A31D100D51995 /* CustomNotification.swift in Sources */,
 				BDC2EA472C3045AD00E5BBD0 /* Override.swift in Sources */,
@@ -3479,19 +3509,21 @@
 				BD7DA9A52AE06DFC00601B20 /* BolusCalculatorConfigDataFlow.swift in Sources */,
 				6EADD581738D64431902AC0A /* (null) in Sources */,
 				CE94598729E9E4110047C9C6 /* WatchConfigRootView.swift in Sources */,
+				DDF847E42C5C288F0049BB3B /* LiveActivitySettingsRootView.swift in Sources */,
 				DD88C8E22C50420800F2D558 /* DefinitionRow.swift in Sources */,
 				B7C465E9472624D8A2BE2A6A /* (null) in Sources */,
 				320D030F724170A637F06D50 /* (null) in Sources */,
 				CE94598729E9E4110047C9C6 /* WatchConfigRootView.swift in Sources */,
 				19E1F7E829D082D0005C8D20 /* IconConfigDataFlow.swift in Sources */,
 				5A2325522BFCBF55003518CA /* NightscoutUploadView.swift in Sources */,
-				E3A08AAE59538BC8A8ABE477 /* NotificationsConfigDataFlow.swift in Sources */,
-				0F7A65FBD2CD8D6477ED4539 /* NotificationsConfigProvider.swift in Sources */,
-				3171D2818C7C72CD1584BB5E /* NotificationsConfigStateModel.swift in Sources */,
-				CD78BB94E43B249D60CC1A1B /* NotificationsConfigRootView.swift in Sources */,
+				E3A08AAE59538BC8A8ABE477 /* GlucoseNotificationSettingsDataFlow.swift in Sources */,
+				0F7A65FBD2CD8D6477ED4539 /* GlucoseNotificationSettingsProvider.swift in Sources */,
+				3171D2818C7C72CD1584BB5E /* GlucoseNotificationSettingsStateModel.swift in Sources */,
+				CD78BB94E43B249D60CC1A1B /* GlucoseNotificationSettingsRootView.swift in Sources */,
 				CE7CA3502A064973004BE681 /* CancelTempPresetIntent.swift in Sources */,
 				6B1F539F9FF75646D1606066 /* SnoozeDataFlow.swift in Sources */,
 				6FFAE524D1D9C262F2407CAE /* SnoozeProvider.swift in Sources */,
+				DDF847DD2C5C28720049BB3B /* LiveActivitySettingsDataFlow.swift in Sources */,
 				8194B80890CDD6A3C13B0FEE /* SnoozeStateModel.swift in Sources */,
 				0437CE46C12535A56504EC19 /* SnoozeRootView.swift in Sources */,
 			);

+ 5 - 0
FreeAPS/Sources/Modules/GlucoseNotificationSettings/GlucoseNotificationSettingsDataFlow.swift

@@ -0,0 +1,5 @@
+enum GlucoseNotificationSettings {
+    enum Config {}
+}
+
+protocol GlucoseNotificationSettingsProvider {}

+ 3 - 0
FreeAPS/Sources/Modules/GlucoseNotificationSettings/GlucoseNotificationSettingsProvider.swift

@@ -0,0 +1,3 @@
+extension GlucoseNotificationSettings {
+    final class Provider: BaseProvider, GlucoseNotificationSettingsProvider {}
+}

+ 2 - 11
FreeAPS/Sources/Modules/NotificationsConfig/NotificationsConfigStateModel.swift

@@ -1,6 +1,6 @@
 import SwiftUI
 
-extension NotificationsConfig {
+extension GlucoseNotificationSettings {
     final class StateModel: BaseStateModel<Provider> {
         @Published var glucoseBadge = false
         @Published var glucoseNotificationsAlways = false
@@ -8,10 +8,8 @@ extension NotificationsConfig {
         @Published var addSourceInfoToGlucoseNotifications = false
         @Published var lowGlucose: Decimal = 0
         @Published var highGlucose: Decimal = 0
-        @Published var carbsRequiredThreshold: Decimal = 0
-        @Published var useLiveActivity = false
+
         var units: GlucoseUnits = .mgdL
-        @Published var lockScreenView: LockScreenView = .simple
 
         override func subscribe() {
             let units = settingsManager.settings.units
@@ -22,8 +20,6 @@ extension NotificationsConfig {
             subscribeSetting(\.useAlarmSound, on: $useAlarmSound) { useAlarmSound = $0 }
             subscribeSetting(\.addSourceInfoToGlucoseNotifications, on: $addSourceInfoToGlucoseNotifications) {
                 addSourceInfoToGlucoseNotifications = $0 }
-            subscribeSetting(\.useLiveActivity, on: $useLiveActivity) { useLiveActivity = $0 }
-            subscribeSetting(\.lockScreenView, on: $lockScreenView) { lockScreenView = $0 }
             subscribeSetting(\.lowGlucose, on: $lowGlucose, initial: {
                 let value = max(min($0, 400), 40)
                 lowGlucose = units == .mmolL ? value.asMmolL : value
@@ -39,11 +35,6 @@ extension NotificationsConfig {
                 guard units == .mmolL else { return $0 }
                 return $0.asMgdL
             })
-
-            subscribeSetting(
-                \.carbsRequiredThreshold,
-                on: $carbsRequiredThreshold
-            ) { carbsRequiredThreshold = $0 }
         }
     }
 }

+ 181 - 0
FreeAPS/Sources/Modules/GlucoseNotificationSettings/View/GlucoseNotificationSettingsRootView.swift

@@ -0,0 +1,181 @@
+import ActivityKit
+import Combine
+import SwiftUI
+import Swinject
+
+extension GlucoseNotificationSettings {
+    struct RootView: BaseView {
+        let resolver: Resolver
+        @StateObject var state = StateModel()
+
+        @State private var shouldDisplayHint: Bool = false
+        @State var hintDetent = PresentationDetent.large
+        @State var selectedVerboseHint: String?
+        @State var hintLabel: String?
+        @State private var decimalPlaceholder: Decimal = 0.0
+        @State private var booleanPlaceholder: Bool = false
+
+        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 carbsFormatter: NumberFormatter {
+            let formatter = NumberFormatter()
+            formatter.numberStyle = .decimal
+            formatter.maximumFractionDigits = 0
+            return formatter
+        }
+
+        @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
+                )
+        }
+
+        var body: some View {
+            Form {
+                SettingInputSection(
+                    decimalValue: $decimalPlaceholder,
+                    booleanValue: $state.glucoseBadge,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    selectedVerboseHint: Binding(
+                        get: { selectedVerboseHint },
+                        set: {
+                            selectedVerboseHint = $0
+                            hintLabel = "Show Glucose App Badge"
+                        }
+                    ),
+                    type: .boolean,
+                    label: "Show Glucose App Badge",
+                    miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
+                    verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
+                    headerText: "Various Glucose Notifications"
+                )
+
+                SettingInputSection(
+                    decimalValue: $decimalPlaceholder,
+                    booleanValue: $state.glucoseNotificationsAlways,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    selectedVerboseHint: Binding(
+                        get: { selectedVerboseHint },
+                        set: {
+                            selectedVerboseHint = $0
+                            hintLabel = "Always Notify Glucose"
+                        }
+                    ),
+                    type: .boolean,
+                    label: "Always Notify Glucose",
+                    miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
+                    verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
+                )
+
+                SettingInputSection(
+                    decimalValue: $decimalPlaceholder,
+                    booleanValue: $state.useAlarmSound,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    selectedVerboseHint: Binding(
+                        get: { selectedVerboseHint },
+                        set: {
+                            selectedVerboseHint = $0
+                            hintLabel = "Play Alarm Sound"
+                        }
+                    ),
+                    type: .boolean,
+                    label: "Play Alarm Sound",
+                    miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
+                    verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
+                )
+
+                SettingInputSection(
+                    decimalValue: $decimalPlaceholder,
+                    booleanValue: $state.addSourceInfoToGlucoseNotifications,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    selectedVerboseHint: Binding(
+                        get: { selectedVerboseHint },
+                        set: {
+                            selectedVerboseHint = $0
+                            hintLabel = "Add Glucose Source to Alarm"
+                        }
+                    ),
+                    type: .boolean,
+                    label: "Add Glucose Source to Alarm",
+                    miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
+                    verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
+                )
+
+                Section {
+                    HStack {
+                        Text("Low Glucose Alarm Limit")
+                        Spacer()
+                        TextFieldWithToolBar(text: $state.lowGlucose, placeholder: "0", numberFormatter: glucoseFormatter)
+                        Text(state.units.rawValue).foregroundColor(.secondary)
+                    }.padding(.top)
+
+                    HStack {
+                        Text("High Glucose Alarm Limit")
+                        Spacer()
+                        TextFieldWithToolBar(text: $state.highGlucose, placeholder: "0", numberFormatter: glucoseFormatter)
+                        Text(state.units.rawValue).foregroundColor(.secondary)
+                    }
+
+                    HStack(alignment: .top) {
+                        Text(
+                            "Set the lower and upper limit for glucose alarms. See hint for more details."
+                        )
+                        .font(.footnote)
+                        .foregroundColor(.secondary)
+                        .lineLimit(nil)
+                        Spacer()
+                        Button(
+                            action: {
+                                hintLabel = "Low and High Glucose Alarm Limits"
+                                selectedVerboseHint =
+                                    "These two settings limit the range outside of which you will be notified via push notifications. If your CGM readings are below 'Low' or above 'High', you will receive a glucose alarm."
+                                shouldDisplayHint.toggle()
+                            },
+                            label: {
+                                HStack {
+                                    Image(systemName: "questionmark.circle")
+                                }
+                            }
+                        ).buttonStyle(BorderlessButtonStyle())
+                    }.padding(.vertical)
+                }
+                .listRowBackground(Color.chart)
+            }
+            .sheet(isPresented: $shouldDisplayHint) {
+                SettingInputHintView(
+                    hintDetent: $hintDetent,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    hintLabel: hintLabel ?? "",
+                    hintText: selectedVerboseHint ?? "",
+                    sheetTitle: "Help"
+                )
+            }
+            .scrollContentBackground(.hidden).background(color)
+            .onAppear(perform: configureView)
+            .navigationBarTitle("Glucose Notifications")
+            .navigationBarTitleDisplayMode(.automatic)
+        }
+    }
+}

+ 5 - 0
FreeAPS/Sources/Modules/LiveActivitySettings/LiveActivitySettingsDataFlow.swift

@@ -0,0 +1,5 @@
+enum LiveActivitySettings {
+    enum Config {}
+}
+
+protocol LiveActivitySettingsProvider: Provider {}

+ 3 - 0
FreeAPS/Sources/Modules/LiveActivitySettings/LiveActivitySettingsProvider.swift

@@ -0,0 +1,3 @@
+extension LiveActivitySettings {
+    final class Provider: BaseProvider, LiveActivitySettingsProvider {}
+}

+ 17 - 0
FreeAPS/Sources/Modules/LiveActivitySettings/LiveActivitySettingsStateModel.swift

@@ -0,0 +1,17 @@
+import Combine
+import SwiftUI
+
+extension LiveActivitySettings {
+    final class StateModel: BaseStateModel<Provider> {
+        @Injected() var settings: SettingsManager!
+        @Injected() var storage: FileStorage!
+
+        @Published var useLiveActivity = false
+        @Published var lockScreenView: LockScreenView = .simple
+
+        override func subscribe() {
+            subscribeSetting(\.useLiveActivity, on: $useLiveActivity) { useLiveActivity = $0 }
+            subscribeSetting(\.lockScreenView, on: $lockScreenView) { lockScreenView = $0 }
+        }
+    }
+}

+ 139 - 0
FreeAPS/Sources/Modules/LiveActivitySettings/View/LiveActivitySettingsRootView.swift

@@ -0,0 +1,139 @@
+import ActivityKit
+import SwiftUI
+import Swinject
+
+extension LiveActivitySettings {
+    struct RootView: BaseView {
+        let resolver: Resolver
+        @StateObject var state = StateModel()
+
+        @State private var shouldDisplayHint: Bool = false
+        @State var hintDetent = PresentationDetent.large
+        @State var selectedVerboseHint: String?
+        @State var hintLabel: String?
+        @State private var decimalPlaceholder: Decimal = 0.0
+        @State private var booleanPlaceholder: Bool = false
+
+        @State private var systemLiveActivitySetting: Bool = {
+            if #available(iOS 16.2, *) {
+                ActivityAuthorizationInfo().areActivitiesEnabled
+            } else {
+                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
+                )
+        }
+
+        var body: some View {
+            List {
+                if !systemLiveActivitySetting {
+                    Section(
+                        header: Text("Display Live Data From Trio"),
+                        content: {
+                            Text("Live Activities must be enabled under iOS Settings to allow Trio to display live data.")
+                        }
+                    ).listRowBackground(Color.chart)
+
+                    Section {
+                        Button {
+                            UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
+                        }
+                        label: { Label("Open iOS Settings", systemImage: "gear.circle").font(.title3).padding() }
+                            .frame(maxWidth: .infinity, alignment: .center)
+                            .buttonStyle(.bordered)
+                    }
+                    .listRowBackground(Color.clear)
+                } else {
+                    SettingInputSection(
+                        decimalValue: $decimalPlaceholder,
+                        booleanValue: $state.useLiveActivity,
+                        shouldDisplayHint: $shouldDisplayHint,
+                        selectedVerboseHint: Binding(
+                            get: { selectedVerboseHint },
+                            set: {
+                                selectedVerboseHint = $0
+                                hintLabel = "Show Live Activity"
+                            }
+                        ),
+                        type: .boolean,
+                        label: "Enable Live Activity",
+                        miniHint: "Live Activities display Trio's glucose readings, and other current data on the iPhone Lock Screen and in the Dynamic Island",
+                        verboseHint: "With Live Activities, you can let Trio display most current data, e.g. glucose reading from CGM, insulin on board, carbohydrates on board, or even a glucose trend chart, on the iPhone Lock Screen and in the Dynamic Island. It allows you to refer to live information at a glance and perform quick actions in your diabetes management.",
+                        headerText: "Display Live Data From Trio"
+                    )
+
+                    if state.useLiveActivity {
+                        Section {
+                            VStack {
+                                Picker(
+                                    selection: $state.lockScreenView,
+                                    label: Text("Lock Screen Widget Style")
+                                ) {
+                                    ForEach(LockScreenView.allCases) { selection in
+                                        Text(selection.displayName).tag(selection)
+                                    }
+                                }
+
+                                HStack(alignment: .top) {
+                                    Text(
+                                        "Trio Live Activities can be simplistic or detailed in their information display. See hint for more details."
+                                    )
+                                    .font(.footnote)
+                                    .foregroundColor(.secondary)
+                                    .lineLimit(nil)
+                                    Spacer()
+                                    Button(
+                                        action: {
+                                            hintLabel = "Lock Screen Widget Style"
+                                            selectedVerboseHint =
+                                                "Trio's simple lock screen widget only display current glucose reading, trend arrow, delta and the timestamp of the current reading.\n\nThe detailed Lock Screen widget offers users a glucose chart, glucose trend arrow, glucose delta, current insulin and carbohydrates on board, and an icon as an indicator for running overrides."
+                                            shouldDisplayHint.toggle()
+                                        },
+                                        label: {
+                                            HStack {
+                                                Image(systemName: "questionmark.circle")
+                                            }
+                                        }
+                                    ).buttonStyle(BorderlessButtonStyle())
+                                }.padding(.top)
+                            }.padding(.bottom)
+                        }.listRowBackground(Color.chart)
+                    }
+                }
+            }
+            .onReceive(resolver.resolve(LiveActivityBridge.self)!.$systemEnabled, perform: {
+                self.systemLiveActivitySetting = $0
+            })
+            .sheet(isPresented: $shouldDisplayHint) {
+                SettingInputHintView(
+                    hintDetent: $hintDetent,
+                    shouldDisplayHint: $shouldDisplayHint,
+                    hintLabel: hintLabel ?? "",
+                    hintText: selectedVerboseHint ?? "",
+                    sheetTitle: "Help"
+                )
+            }
+            .scrollContentBackground(.hidden).background(color)
+            .onAppear(perform: configureView)
+            .navigationTitle("Live Activity")
+            .navigationBarTitleDisplayMode(.automatic)
+        }
+    }
+}

+ 0 - 5
FreeAPS/Sources/Modules/NotificationsConfig/NotificationsConfigDataFlow.swift

@@ -1,5 +0,0 @@
-enum NotificationsConfig {
-    enum Config {}
-}
-
-protocol NotificationsConfigProvider {}

+ 0 - 3
FreeAPS/Sources/Modules/NotificationsConfig/NotificationsConfigProvider.swift

@@ -1,3 +0,0 @@
-extension NotificationsConfig {
-    final class Provider: BaseProvider, NotificationsConfigProvider {}
-}

+ 0 - 143
FreeAPS/Sources/Modules/NotificationsConfig/View/NotificationsConfigRootView.swift

@@ -1,143 +0,0 @@
-import ActivityKit
-import Combine
-import SwiftUI
-import Swinject
-
-extension NotificationsConfig {
-    struct RootView: BaseView {
-        let resolver: Resolver
-        @StateObject var state = StateModel()
-
-        @State private var systemLiveActivitySetting: Bool = {
-            if #available(iOS 16.1, *) {
-                ActivityAuthorizationInfo().areActivitiesEnabled
-            } else {
-                false
-            }
-        }()
-
-        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 carbsFormatter: NumberFormatter {
-            let formatter = NumberFormatter()
-            formatter.numberStyle = .decimal
-            formatter.maximumFractionDigits = 0
-            return formatter
-        }
-
-        @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
-                )
-        }
-
-        @ViewBuilder private func liveActivitySection() -> some View {
-            if #available(iOS 16.2, *) {
-                Section(
-                    header: Text("Live Activity"),
-                    footer: Text(
-                        liveActivityFooterText()
-                    ),
-                    content: {
-                        if !systemLiveActivitySetting {
-                            Button("Open Settings App") {
-                                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
-                            }
-                        } else {
-                            Toggle("Show Live Activity", isOn: $state.useLiveActivity)
-                        }
-                        Picker(
-                            selection: $state.lockScreenView,
-                            label: Text("Lock screen widget")
-                        ) {
-                            ForEach(LockScreenView.allCases) { selection in
-                                Text(selection.displayName).tag(selection)
-                            }
-                        }
-                    }
-                )
-                .onReceive(resolver.resolve(LiveActivityBridge.self)!.$systemEnabled, perform: {
-                    self.systemLiveActivitySetting = $0
-                })
-            }
-        }
-
-        private func liveActivityFooterText() -> String {
-            var footer =
-                "Live activity displays blood glucose live on the lock screen and on the dynamic island (if available)"
-
-            if !systemLiveActivitySetting {
-                footer =
-                    "Live activities are turned OFF in system settings. To enable live activities, go to Settings app -> Trio -> Turn live Activities ON.\n\n" +
-                    footer
-            }
-
-            return footer
-        }
-
-        var body: some View {
-            Form {
-                Section(header: Text("Glucose")) {
-                    Toggle("Show glucose on the app badge", isOn: $state.glucoseBadge)
-                    Toggle("Always Notify Glucose", isOn: $state.glucoseNotificationsAlways)
-                    Toggle("Also play alert sound", isOn: $state.useAlarmSound)
-                    Toggle("Also add source info", isOn: $state.addSourceInfoToGlucoseNotifications)
-
-                    HStack {
-                        Text("Low")
-                        Spacer()
-                        TextFieldWithToolBar(text: $state.lowGlucose, placeholder: "0", numberFormatter: glucoseFormatter)
-                        Text(state.units.rawValue).foregroundColor(.secondary)
-                    }
-
-                    HStack {
-                        Text("High")
-                        Spacer()
-                        TextFieldWithToolBar(text: $state.highGlucose, placeholder: "0", numberFormatter: glucoseFormatter)
-                        Text(state.units.rawValue).foregroundColor(.secondary)
-                    }
-                }
-
-                Section(header: Text("Other")) {
-                    HStack {
-                        Text("Carbs Required Threshold")
-                        Spacer()
-                        TextFieldWithToolBar(
-                            text: $state.carbsRequiredThreshold,
-                            placeholder: "0",
-                            numberFormatter: carbsFormatter
-                        )
-                        Text("g").foregroundColor(.secondary)
-                    }
-                }
-
-                liveActivitySection()
-            }.scrollContentBackground(.hidden).background(color)
-                .onAppear(perform: configureView)
-                .navigationBarTitle("Notifications")
-                .navigationBarTitleDisplayMode(.automatic)
-        }
-    }
-}

+ 6 - 2
FreeAPS/Sources/Modules/Settings/View/Subviews/NotificationsView.swift

@@ -36,8 +36,12 @@ struct NotificationsView: BaseView {
             Section(
                 header: Text("Notification Center"),
                 content: {
-                    Text("Alerts").navigationLink(to: .notificationsConfig, from: self)
-                    Text("TODO: Live Activity Settings View")
+                    Text("Glucose Notifications").navigationLink(to: .glucoseNotificationSettings, from: self)
+
+                    if #available(iOS 16.2, *) {
+                        Text("Live Activity").navigationLink(to: .liveActivitySettings, from: self)
+                    }
+
                     Text("Calendar Events").navigationLink(to: .calendarEventSettings, from: self)
                 }
             )

+ 6 - 0
FreeAPS/Sources/Modules/UserInterfaceSettings/UserInterfaceSettingsStateModel.swift

@@ -12,6 +12,7 @@ extension UserInterfaceSettings {
         @Published var yGridLines: Bool = false
         @Published var oneDimensionalGraph = false
         @Published var rulerMarks: Bool = true
+        @Published var carbsRequiredThreshold: Decimal = 0
 
         var units: GlucoseUnits = .mgdL
 
@@ -42,6 +43,11 @@ extension UserInterfaceSettings {
                 guard units == .mmolL else { return $0 }
                 return $0.asMgdL
             })
+
+            subscribeSetting(
+                \.carbsRequiredThreshold,
+                on: $carbsRequiredThreshold
+            ) { carbsRequiredThreshold = $0 }
         }
     }
 }

+ 13 - 0
FreeAPS/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift

@@ -74,6 +74,19 @@ extension UserInterfaceSettings {
                     Toggle("Override HbA1c Unit", isOn: $state.overrideHbA1cUnit)
 
                 } header: { Text("Statistics settings ") }
+
+                Section(header: Text("Other")) {
+                    HStack {
+                        Text("Carbs Required Threshold")
+                        Spacer()
+                        TextFieldWithToolBar(
+                            text: $state.carbsRequiredThreshold,
+                            placeholder: "0",
+                            numberFormatter: carbsFormatter
+                        )
+                        Text("g").foregroundColor(.secondary)
+                    }
+                }
             }
             .scrollContentBackground(.hidden).background(color)
             .onAppear(perform: configureView)

+ 6 - 3
FreeAPS/Sources/Router/Screen.swift

@@ -23,7 +23,7 @@ enum Screen: Identifiable, Hashable {
     case cgm
     case cgmDirect
     case healthkit
-    case notificationsConfig
+    case glucoseNotificationSettings
     case mealSettings
     case iconConfig
     case overrideConfig
@@ -40,6 +40,7 @@ enum Screen: Identifiable, Hashable {
     case algorithmSettings
     case featureSettings
     case notificationSettings
+    case liveActivitySettings
     case calendarEventSettings
     case serviceSettings
     case autosensSettings
@@ -96,8 +97,8 @@ extension Screen {
             CGM.RootView(resolver: resolver, displayClose: true)
         case .healthkit:
             AppleHealthKit.RootView(resolver: resolver)
-        case .notificationsConfig:
-            NotificationsConfig.RootView(resolver: resolver)
+        case .glucoseNotificationSettings:
+            GlucoseNotificationSettings.RootView(resolver: resolver)
         case .mealSettings:
             MealSettings.RootView(resolver: resolver)
         case .iconConfig:
@@ -130,6 +131,8 @@ extension Screen {
             FeatureSettingsView(resolver: resolver, state: Settings.StateModel())
         case .notificationSettings:
             NotificationsView(resolver: resolver, state: Settings.StateModel())
+        case .liveActivitySettings:
+            LiveActivitySettings.RootView(resolver: resolver)
         case .calendarEventSettings:
             CalendarEventSettings.RootView(resolver: resolver)
         case .serviceSettings:

+ 19 - 0
FreeAPS/Sources/Views/SettingInputHintView.swift

@@ -6,6 +6,25 @@ struct SettingInputHintView: View {
     var hintLabel: String
     var hintText: String
     var sheetTitle: String
+
+    @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
+            )
+    }
+
     var body: some View {
         NavigationStack {
             List {