Преглед изворни кода

Merge branch 'core-data-sync-trio' into core-data-sync-autotune-removed

Deniz Cengiz пре 1 година
родитељ
комит
83532f8a32
50 измењених фајлова са 110 додато и 581 уклоњено
  1. 0 12
      FreeAPS.xcodeproj/project.pbxproj
  2. 0 1
      FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json
  3. 0 97
      FreeAPS/Sources/APS/APSManager.swift
  4. 0 52
      FreeAPS/Sources/APS/FetchAnnouncementsManager.swift
  5. 0 2
      FreeAPS/Sources/APS/OpenAPS/Constants.swift
  6. 0 80
      FreeAPS/Sources/APS/Storage/AnnouncementsStorage.swift
  7. 1 1
      FreeAPS/Sources/APS/Storage/OverrideStorage.swift
  8. 0 1
      FreeAPS/Sources/Application/FreeAPSApp.swift
  9. 0 1
      FreeAPS/Sources/Assemblies/APSAssembly.swift
  10. 0 1
      FreeAPS/Sources/Assemblies/StorageAssembly.swift
  11. 0 6
      FreeAPS/Sources/Localizations/Main/ar.lproj/Localizable.strings
  12. 0 6
      FreeAPS/Sources/Localizations/Main/ca.lproj/Localizable.strings
  13. 0 6
      FreeAPS/Sources/Localizations/Main/da.lproj/Localizable.strings
  14. 0 6
      FreeAPS/Sources/Localizations/Main/de.lproj/Localizable.strings
  15. 0 6
      FreeAPS/Sources/Localizations/Main/en.lproj/Localizable.strings
  16. 0 6
      FreeAPS/Sources/Localizations/Main/es.lproj/Localizable.strings
  17. 0 6
      FreeAPS/Sources/Localizations/Main/fi.lproj/Localizable.strings
  18. 0 6
      FreeAPS/Sources/Localizations/Main/fr.lproj/Localizable.strings
  19. 0 6
      FreeAPS/Sources/Localizations/Main/he.lproj/Localizable.strings
  20. 0 6
      FreeAPS/Sources/Localizations/Main/hu.lproj/Localizable.strings
  21. 0 6
      FreeAPS/Sources/Localizations/Main/it.lproj/Localizable.strings
  22. 0 6
      FreeAPS/Sources/Localizations/Main/nb.lproj/Localizable.strings
  23. 0 6
      FreeAPS/Sources/Localizations/Main/nl.lproj/Localizable.strings
  24. 0 6
      FreeAPS/Sources/Localizations/Main/pl.lproj/Localizable.strings
  25. 0 6
      FreeAPS/Sources/Localizations/Main/pt-BR.lproj/Localizable.strings
  26. 0 6
      FreeAPS/Sources/Localizations/Main/pt-PT.lproj/Localizable.strings
  27. 0 6
      FreeAPS/Sources/Localizations/Main/ru.lproj/Localizable.strings
  28. 0 6
      FreeAPS/Sources/Localizations/Main/sk.lproj/Localizable.strings
  29. 0 6
      FreeAPS/Sources/Localizations/Main/sv.lproj/Localizable.strings
  30. 0 6
      FreeAPS/Sources/Localizations/Main/tr.lproj/Localizable.strings
  31. 0 6
      FreeAPS/Sources/Localizations/Main/uk.lproj/Localizable.strings
  32. 0 6
      FreeAPS/Sources/Localizations/Main/vi.lproj/Localizable.strings
  33. 0 6
      FreeAPS/Sources/Localizations/Main/zh-Hans.lproj/Localizable.strings
  34. 0 57
      FreeAPS/Sources/Models/Announcement.swift
  35. 0 5
      FreeAPS/Sources/Models/FreeAPSSettings.swift
  36. 0 1
      FreeAPS/Sources/Modules/Home/HomeDataFlow.swift
  37. 0 7
      FreeAPS/Sources/Modules/Home/HomeProvider.swift
  38. 0 1
      FreeAPS/Sources/Modules/Home/HomeStateModel.swift
  39. 45 14
      FreeAPS/Sources/Modules/Home/View/Chart/ChartElements/BasalChart.swift
  40. 1 1
      FreeAPS/Sources/Modules/Home/View/Chart/ChartElements/OverrideView.swift
  41. 5 2
      FreeAPS/Sources/Modules/Home/View/HomeRootView.swift
  42. 0 2
      FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift
  43. 1 1
      FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift
  44. 2 35
      FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutFetchView.swift
  45. 0 4
      FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift
  46. 24 0
      FreeAPS/Sources/Modules/Treatments/TreatmentsStateModel.swift
  47. 31 13
      FreeAPS/Sources/Modules/Treatments/View/TreatmentsRootView.swift
  48. 0 35
      FreeAPS/Sources/Services/Network/Nightscout/NightscoutAPI.swift
  49. 0 16
      FreeAPS/Sources/Services/Network/Nightscout/NightscoutManager.swift
  50. 0 1
      LiveActivity/Views/WidgetItems/LiveActivityIOBLabelView.swift

+ 0 - 12
FreeAPS.xcodeproj/project.pbxproj

@@ -120,8 +120,6 @@
 		38569349270B5DFB0002C50D /* AppGroupSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38569346270B5DFB0002C50D /* AppGroupSource.swift */; };
 		38569349270B5DFB0002C50D /* AppGroupSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38569346270B5DFB0002C50D /* AppGroupSource.swift */; };
 		38569353270B5E350002C50D /* CGMRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38569352270B5E350002C50D /* CGMRootView.swift */; };
 		38569353270B5E350002C50D /* CGMRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38569352270B5E350002C50D /* CGMRootView.swift */; };
 		385CEA8225F23DFD002D6D5B /* NightscoutStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CEA8125F23DFD002D6D5B /* NightscoutStatus.swift */; };
 		385CEA8225F23DFD002D6D5B /* NightscoutStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CEA8125F23DFD002D6D5B /* NightscoutStatus.swift */; };
-		385CEAC125F2EA52002D6D5B /* Announcement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CEAC025F2EA52002D6D5B /* Announcement.swift */; };
-		385CEAC425F2F154002D6D5B /* AnnouncementsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CEAC325F2F154002D6D5B /* AnnouncementsStorage.swift */; };
 		3862CC2E2743F9F700BF832C /* CalendarManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3862CC2D2743F9F700BF832C /* CalendarManager.swift */; };
 		3862CC2E2743F9F700BF832C /* CalendarManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3862CC2D2743F9F700BF832C /* CalendarManager.swift */; };
 		3870FF4725EC187A0088248F /* BloodGlucose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3870FF4225EC13F40088248F /* BloodGlucose.swift */; };
 		3870FF4725EC187A0088248F /* BloodGlucose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3870FF4225EC13F40088248F /* BloodGlucose.swift */; };
 		3871F39C25ED892B0013ECB5 /* TempTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3871F39B25ED892B0013ECB5 /* TempTarget.swift */; };
 		3871F39C25ED892B0013ECB5 /* TempTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3871F39B25ED892B0013ECB5 /* TempTarget.swift */; };
@@ -146,7 +144,6 @@
 		38A0363B25ECF07E00FCBB52 /* GlucoseStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A0363A25ECF07E00FCBB52 /* GlucoseStorage.swift */; };
 		38A0363B25ECF07E00FCBB52 /* GlucoseStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A0363A25ECF07E00FCBB52 /* GlucoseStorage.swift */; };
 		38A0364225ED069400FCBB52 /* TempBasal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A0364125ED069400FCBB52 /* TempBasal.swift */; };
 		38A0364225ED069400FCBB52 /* TempBasal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A0364125ED069400FCBB52 /* TempBasal.swift */; };
 		38A13D3225E28B4B00EAA382 /* PumpHistoryEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A13D3125E28B4B00EAA382 /* PumpHistoryEvent.swift */; };
 		38A13D3225E28B4B00EAA382 /* PumpHistoryEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A13D3125E28B4B00EAA382 /* PumpHistoryEvent.swift */; };
-		38A43598262E0E4900E80935 /* FetchAnnouncementsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A43597262E0E4900E80935 /* FetchAnnouncementsManager.swift */; };
 		38A504A425DD9C4000C5B9E8 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A5049125DD9C4000C5B9E8 /* UserDefaultsExtensions.swift */; };
 		38A504A425DD9C4000C5B9E8 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A5049125DD9C4000C5B9E8 /* UserDefaultsExtensions.swift */; };
 		38A9260525F012D8009E3739 /* CarbRatios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A9260425F012D8009E3739 /* CarbRatios.swift */; };
 		38A9260525F012D8009E3739 /* CarbRatios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A9260425F012D8009E3739 /* CarbRatios.swift */; };
 		38AAF85525FFF846004AF583 /* CurrentGlucoseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38AAF85425FFF846004AF583 /* CurrentGlucoseView.swift */; };
 		38AAF85525FFF846004AF583 /* CurrentGlucoseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38AAF85425FFF846004AF583 /* CurrentGlucoseView.swift */; };
@@ -813,8 +810,6 @@
 		38569346270B5DFB0002C50D /* AppGroupSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppGroupSource.swift; sourceTree = "<group>"; };
 		38569346270B5DFB0002C50D /* AppGroupSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppGroupSource.swift; sourceTree = "<group>"; };
 		38569352270B5E350002C50D /* CGMRootView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGMRootView.swift; sourceTree = "<group>"; };
 		38569352270B5E350002C50D /* CGMRootView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGMRootView.swift; sourceTree = "<group>"; };
 		385CEA8125F23DFD002D6D5B /* NightscoutStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutStatus.swift; sourceTree = "<group>"; };
 		385CEA8125F23DFD002D6D5B /* NightscoutStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutStatus.swift; sourceTree = "<group>"; };
-		385CEAC025F2EA52002D6D5B /* Announcement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Announcement.swift; sourceTree = "<group>"; };
-		385CEAC325F2F154002D6D5B /* AnnouncementsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementsStorage.swift; sourceTree = "<group>"; };
 		3862CC2D2743F9F700BF832C /* CalendarManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarManager.swift; sourceTree = "<group>"; };
 		3862CC2D2743F9F700BF832C /* CalendarManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarManager.swift; sourceTree = "<group>"; };
 		3870FF4225EC13F40088248F /* BloodGlucose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BloodGlucose.swift; sourceTree = "<group>"; };
 		3870FF4225EC13F40088248F /* BloodGlucose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BloodGlucose.swift; sourceTree = "<group>"; };
 		3871F39B25ED892B0013ECB5 /* TempTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempTarget.swift; sourceTree = "<group>"; };
 		3871F39B25ED892B0013ECB5 /* TempTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempTarget.swift; sourceTree = "<group>"; };
@@ -841,7 +836,6 @@
 		38A0363A25ECF07E00FCBB52 /* GlucoseStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseStorage.swift; sourceTree = "<group>"; };
 		38A0363A25ECF07E00FCBB52 /* GlucoseStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseStorage.swift; sourceTree = "<group>"; };
 		38A0364125ED069400FCBB52 /* TempBasal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempBasal.swift; sourceTree = "<group>"; };
 		38A0364125ED069400FCBB52 /* TempBasal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempBasal.swift; sourceTree = "<group>"; };
 		38A13D3125E28B4B00EAA382 /* PumpHistoryEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpHistoryEvent.swift; sourceTree = "<group>"; };
 		38A13D3125E28B4B00EAA382 /* PumpHistoryEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpHistoryEvent.swift; sourceTree = "<group>"; };
-		38A43597262E0E4900E80935 /* FetchAnnouncementsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchAnnouncementsManager.swift; sourceTree = "<group>"; };
 		38A5049125DD9C4000C5B9E8 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = "<group>"; };
 		38A5049125DD9C4000C5B9E8 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = "<group>"; };
 		38A9260425F012D8009E3739 /* CarbRatios.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbRatios.swift; sourceTree = "<group>"; };
 		38A9260425F012D8009E3739 /* CarbRatios.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbRatios.swift; sourceTree = "<group>"; };
 		38AAF85425FFF846004AF583 /* CurrentGlucoseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentGlucoseView.swift; sourceTree = "<group>"; };
 		38AAF85425FFF846004AF583 /* CurrentGlucoseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentGlucoseView.swift; sourceTree = "<group>"; };
@@ -1813,7 +1807,6 @@
 				CE95BF562BA5F5FE00DC3DE3 /* PluginManager.swift */,
 				CE95BF562BA5F5FE00DC3DE3 /* PluginManager.swift */,
 				3811DF0F25CAAAE200A708ED /* APSManager.swift */,
 				3811DF0F25CAAAE200A708ED /* APSManager.swift */,
 				38BF021E25E7F0DE00579895 /* DeviceDataManager.swift */,
 				38BF021E25E7F0DE00579895 /* DeviceDataManager.swift */,
-				38A43597262E0E4900E80935 /* FetchAnnouncementsManager.swift */,
 				38DAB289260D349500F74C1A /* FetchGlucoseManager.swift */,
 				38DAB289260D349500F74C1A /* FetchGlucoseManager.swift */,
 				38192E06261BA9960094D973 /* FetchTreatmentsManager.swift */,
 				38192E06261BA9960094D973 /* FetchTreatmentsManager.swift */,
 				3856933F270B57A00002C50D /* CGM */,
 				3856933F270B57A00002C50D /* CGM */,
@@ -1991,7 +1984,6 @@
 				DD07CA132CE80B73002D45A9 /* TimeInRangeChartStyle.swift */,
 				DD07CA132CE80B73002D45A9 /* TimeInRangeChartStyle.swift */,
 				DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */,
 				DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */,
 				DD6D67E32C9C253500660C9B /* ColorSchemeOption.swift */,
 				DD6D67E32C9C253500660C9B /* ColorSchemeOption.swift */,
-				385CEAC025F2EA52002D6D5B /* Announcement.swift */,
 				388E5A5F25B6F2310019842D /* Autosens.swift */,
 				388E5A5F25B6F2310019842D /* Autosens.swift */,
 				388358C725EEF6D200E024B2 /* BasalProfileEntry.swift */,
 				388358C725EEF6D200E024B2 /* BasalProfileEntry.swift */,
 				38D0B3B525EBE24900CB6E88 /* Battery.swift */,
 				38D0B3B525EBE24900CB6E88 /* Battery.swift */,
@@ -2084,7 +2076,6 @@
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
 				CE82E02428E867BA00473A9C /* AlertStorage.swift */,
 				CE82E02428E867BA00473A9C /* AlertStorage.swift */,
-				385CEAC325F2F154002D6D5B /* AnnouncementsStorage.swift */,
 				38AEE75625F0F18E0013F05B /* CarbsStorage.swift */,
 				38AEE75625F0F18E0013F05B /* CarbsStorage.swift */,
 				DDB37CC42D05048F00D99BF4 /* ContactImageStorage.swift */,
 				DDB37CC42D05048F00D99BF4 /* ContactImageStorage.swift */,
 				5864E8582C42CFAE00294306 /* DeterminationStorage.swift */,
 				5864E8582C42CFAE00294306 /* DeterminationStorage.swift */,
@@ -3402,7 +3393,6 @@
 				5825A1BE2C97335C0046467E /* EditTempTargetForm.swift in Sources */,
 				5825A1BE2C97335C0046467E /* EditTempTargetForm.swift in Sources */,
 				19D466A329AA2B80004D5F33 /* MealSettingsDataFlow.swift in Sources */,
 				19D466A329AA2B80004D5F33 /* MealSettingsDataFlow.swift in Sources */,
 				3811DEB225C9D88300A708ED /* KeychainItemAccessibility.swift in Sources */,
 				3811DEB225C9D88300A708ED /* KeychainItemAccessibility.swift in Sources */,
-				385CEAC425F2F154002D6D5B /* AnnouncementsStorage.swift in Sources */,
 				38AEE73D25F0200C0013F05B /* FreeAPSSettings.swift in Sources */,
 				38AEE73D25F0200C0013F05B /* FreeAPSSettings.swift in Sources */,
 				38FCF3FD25E997A80078B0D1 /* PumpHistoryStorage.swift in Sources */,
 				38FCF3FD25E997A80078B0D1 /* PumpHistoryStorage.swift in Sources */,
 				58645BA72CA2D390008AFCE7 /* ChartAxisSetup.swift in Sources */,
 				58645BA72CA2D390008AFCE7 /* ChartAxisSetup.swift in Sources */,
@@ -3657,7 +3647,6 @@
 				BD2B464E0745FBE7B79913F4 /* NightscoutConfigProvider.swift in Sources */,
 				BD2B464E0745FBE7B79913F4 /* NightscoutConfigProvider.swift in Sources */,
 				9825E5E923F0B8FA80C8C7C7 /* NightscoutConfigStateModel.swift in Sources */,
 				9825E5E923F0B8FA80C8C7C7 /* NightscoutConfigStateModel.swift in Sources */,
 				58645B9D2CA2D275008AFCE7 /* DeterminationSetup.swift in Sources */,
 				58645B9D2CA2D275008AFCE7 /* DeterminationSetup.swift in Sources */,
-				38A43598262E0E4900E80935 /* FetchAnnouncementsManager.swift in Sources */,
 				DD1745442C55C60E00211FAC /* AutosensSettingsDataFlow.swift in Sources */,
 				DD1745442C55C60E00211FAC /* AutosensSettingsDataFlow.swift in Sources */,
 				BDCAF2382C639F35002DC907 /* SettingItems.swift in Sources */,
 				BDCAF2382C639F35002DC907 /* SettingItems.swift in Sources */,
 				58D08B342C8DF9A700AA37D3 /* CobIobChart.swift in Sources */,
 				58D08B342C8DF9A700AA37D3 /* CobIobChart.swift in Sources */,
@@ -3685,7 +3674,6 @@
 				DD1745242C55526000211FAC /* SMBSettingsStateModel.swift in Sources */,
 				DD1745242C55526000211FAC /* SMBSettingsStateModel.swift in Sources */,
 				F90692D1274B99B60037068D /* HealthKitProvider.swift in Sources */,
 				F90692D1274B99B60037068D /* HealthKitProvider.swift in Sources */,
 				19F95FF729F10FEE00314DDC /* StatStateModel.swift in Sources */,
 				19F95FF729F10FEE00314DDC /* StatStateModel.swift in Sources */,
-				385CEAC125F2EA52002D6D5B /* Announcement.swift in Sources */,
 				8B759CFCF47B392BB365C251 /* BasalProfileEditorDataFlow.swift in Sources */,
 				8B759CFCF47B392BB365C251 /* BasalProfileEditorDataFlow.swift in Sources */,
 				195D80B42AF6973A00D25097 /* DynamicSettingsRootView.swift in Sources */,
 				195D80B42AF6973A00D25097 /* DynamicSettingsRootView.swift in Sources */,
 				389442CB25F65F7100FA1F27 /* NightscoutTreatment.swift in Sources */,
 				389442CB25F65F7100FA1F27 /* NightscoutTreatment.swift in Sources */,

+ 0 - 1
FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json

@@ -1,7 +1,6 @@
 {
 {
   "units" : "mg/dL",
   "units" : "mg/dL",
   "closedLoop" : false,
   "closedLoop" : false,
-  "allowAnnouncements" : false,
   "isUploadEnabled" : false,
   "isUploadEnabled" : false,
   "isDownloadEnabled" : false,
   "isDownloadEnabled" : false,
   "useLocalGlucoseSource" : false,
   "useLocalGlucoseSource" : false,

+ 0 - 97
FreeAPS/Sources/APS/APSManager.swift

@@ -26,7 +26,6 @@ protocol APSManager {
     func roundBolus(amount: Decimal) -> Decimal
     func roundBolus(amount: Decimal) -> Decimal
     var lastError: CurrentValueSubject<Error?, Never> { get }
     var lastError: CurrentValueSubject<Error?, Never> { get }
     func cancelBolus() async
     func cancelBolus() async
-    func enactAnnouncement(_ announcement: Announcement)
 }
 }
 
 
 enum APSError: LocalizedError {
 enum APSError: LocalizedError {
@@ -62,7 +61,6 @@ final class BaseAPSManager: APSManager, Injectable {
     @Injected() private var alertHistoryStorage: AlertHistoryStorage!
     @Injected() private var alertHistoryStorage: AlertHistoryStorage!
     @Injected() private var tempTargetsStorage: TempTargetsStorage!
     @Injected() private var tempTargetsStorage: TempTargetsStorage!
     @Injected() private var carbsStorage: CarbsStorage!
     @Injected() private var carbsStorage: CarbsStorage!
-    @Injected() private var announcementsStorage: AnnouncementsStorage!
     @Injected() private var determinationStorage: DeterminationStorage!
     @Injected() private var determinationStorage: DeterminationStorage!
     @Injected() private var deviceDataManager: DeviceDataManager!
     @Injected() private var deviceDataManager: DeviceDataManager!
     @Injected() private var nightscout: NightscoutManager!
     @Injected() private var nightscout: NightscoutManager!
@@ -520,101 +518,6 @@ final class BaseAPSManager: APSManager, Injectable {
         }
         }
     }
     }
 
 
-    func enactAnnouncement(_ announcement: Announcement) {
-        guard let action = announcement.action else {
-            warning(.apsManager, "Invalid Announcement action")
-            return
-        }
-
-        guard let pump = pumpManager else {
-            warning(.apsManager, "Pump is not set")
-            return
-        }
-
-        debug(.apsManager, "Start enact announcement: \(action)")
-
-        switch action {
-        case let .bolus(amount):
-            if let error = verifyStatus() {
-                processError(error)
-                return
-            }
-            let roundedAmount = pump.roundToSupportedBolusVolume(units: Double(amount))
-            pump.enactBolus(units: roundedAmount, activationType: .manualRecommendationAccepted) { error in
-                if let error = error {
-                    // warning(.apsManager, "Announcement Bolus failed with error: \(error.localizedDescription)")
-                    switch error {
-                    case .uncertainDelivery:
-                        // Do not generate notification on uncertain delivery error
-                        break
-                    default:
-                        // Do not generate notifications for automatic boluses that fail.
-                        warning(.apsManager, "Announcement Bolus failed with error: \(error.localizedDescription)")
-                    }
-
-                } else {
-                    debug(.apsManager, "Announcement Bolus succeeded")
-                    self.announcementsStorage.storeAnnouncements([announcement], enacted: true)
-                    self.bolusProgress.send(0)
-                }
-            }
-        case let .pump(pumpAction):
-            switch pumpAction {
-            case .suspend:
-                if let error = verifyStatus() {
-                    processError(error)
-                    return
-                }
-                pump.suspendDelivery { error in
-                    if let error = error {
-                        debug(.apsManager, "Pump not suspended by Announcement: \(error.localizedDescription)")
-                    } else {
-                        debug(.apsManager, "Pump suspended by Announcement")
-                        self.announcementsStorage.storeAnnouncements([announcement], enacted: true)
-                    }
-                }
-            case .resume:
-                guard pump.status.pumpStatus.suspended else {
-                    return
-                }
-                pump.resumeDelivery { error in
-                    if let error = error {
-                        warning(.apsManager, "Pump not resumed by Announcement: \(error.localizedDescription)")
-                    } else {
-                        debug(.apsManager, "Pump resumed by Announcement")
-                        self.announcementsStorage.storeAnnouncements([announcement], enacted: true)
-                    }
-                }
-            }
-        case let .looping(closedLoop):
-            settings.closedLoop = closedLoop
-            debug(.apsManager, "Closed loop \(closedLoop) by Announcement")
-            announcementsStorage.storeAnnouncements([announcement], enacted: true)
-        case let .tempbasal(rate, duration):
-            if let error = verifyStatus() {
-                processError(error)
-                return
-            }
-            // unable to do temp basal during manual temp basal 😁
-            if isManualTempBasal {
-                processError(APSError.manualBasalTemp(message: "Loop not possible during the manual basal temp"))
-                return
-            }
-            guard !settings.closedLoop else {
-                return
-            }
-            let roundedRate = pump.roundToSupportedBasalRate(unitsPerHour: Double(rate))
-            pump.enactTempBasal(unitsPerHour: roundedRate, for: TimeInterval(duration) * 60) { error in
-                if let error = error {
-                    warning(.apsManager, "Announcement TempBasal failed with error: \(error.localizedDescription)")
-                } else {
-                    debug(.apsManager, "Announcement TempBasal succeeded")
-                    self.announcementsStorage.storeAnnouncements([announcement], enacted: true)
-                }
-            }
-        }
-    }
-
     private func fetchCurrentTempBasal(date: Date) async -> TempBasal {
     private func fetchCurrentTempBasal(date: Date) async -> TempBasal {
         let results = await CoreDataStack.shared.fetchEntitiesAsync(
         let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: PumpEventStored.self,
             ofType: PumpEventStored.self,

+ 0 - 52
FreeAPS/Sources/APS/FetchAnnouncementsManager.swift

@@ -1,52 +0,0 @@
-import Combine
-import Foundation
-import SwiftDate
-import Swinject
-
-protocol FetchAnnouncementsManager {}
-
-final class BaseFetchAnnouncementsManager: FetchAnnouncementsManager, Injectable {
-    private let processQueue = DispatchQueue(label: "BaseFetchAnnouncementsManager.processQueue")
-    @Injected() var announcementsStorage: AnnouncementsStorage!
-    @Injected() var nightscoutManager: NightscoutManager!
-    @Injected() var apsManager: APSManager!
-    @Injected() var settingsManager: SettingsManager!
-
-    private var lifetime = Lifetime()
-    private let timer = DispatchTimer(timeInterval: 5.minutes.timeInterval)
-
-    init(resolver: Resolver) {
-        injectServices(resolver)
-        subscribe()
-    }
-
-    private func subscribe() {
-        timer.publisher
-            .receive(on: processQueue)
-            .flatMap { _ -> AnyPublisher<[Announcement], Never> in
-                guard self.settingsManager.settings.allowAnnouncements else {
-                    return Just([]).eraseToAnyPublisher()
-                }
-                debug(.nightscout, "FetchAnnouncementsManager heartbeat")
-                debug(.nightscout, "Start fetching announcements")
-                return self.nightscoutManager.fetchAnnouncements()
-            }
-            .sink { announcements in
-                guard let last = announcements.filter({ $0.createdAt > self.announcementsStorage.syncDate() })
-                    .sorted(by: { $0.createdAt < $1.createdAt })
-                    .last
-                else { return }
-
-                self.announcementsStorage.storeAnnouncements([last], enacted: false)
-                if self.settingsManager.settings.allowAnnouncements, let recent = self.announcementsStorage.recent(),
-                   recent.action != nil
-                {
-                    debug(.nightscout, "New announcements found")
-                    self.apsManager.enactAnnouncement(recent)
-                }
-            }
-            .store(in: &lifetime)
-        timer.fire()
-        timer.resume()
-    }
-}

+ 0 - 2
FreeAPS/Sources/APS/OpenAPS/Constants.swift

@@ -92,8 +92,6 @@ extension OpenAPS {
 
 
     enum FreeAPS {
     enum FreeAPS {
         static let settings = "freeaps/freeaps_settings.json"
         static let settings = "freeaps/freeaps_settings.json"
-        static let announcements = "freeaps/announcements.json"
-        static let announcementsEnacted = "freeaps/announcements_enacted.json"
         static let tempTargetsPresets = "freeaps/temptargets_presets.json"
         static let tempTargetsPresets = "freeaps/temptargets_presets.json"
         static let calibrations = "freeaps/calibrations.json"
         static let calibrations = "freeaps/calibrations.json"
     }
     }

+ 0 - 80
FreeAPS/Sources/APS/Storage/AnnouncementsStorage.swift

@@ -1,80 +0,0 @@
-import Foundation
-import SwiftDate
-import Swinject
-
-protocol AnnouncementsStorage {
-    func storeAnnouncements(_ announcements: [Announcement], enacted: Bool)
-    func syncDate() -> Date
-    func recent() -> Announcement?
-    func validate() -> [Announcement]
-}
-
-final class BaseAnnouncementsStorage: AnnouncementsStorage, Injectable {
-    enum Config {
-        static let recentInterval = 10.minutes.timeInterval
-    }
-
-    private let processQueue = DispatchQueue(label: "BaseAnnouncementsStorage.processQueue")
-    @Injected() private var storage: FileStorage!
-
-    init(resolver: Resolver) {
-        injectServices(resolver)
-    }
-
-    func storeAnnouncements(_ announcements: [Announcement], enacted: Bool) {
-        processQueue.sync {
-            let file = enacted ? OpenAPS.FreeAPS.announcementsEnacted : OpenAPS.FreeAPS.announcements
-            self.storage.transaction { storage in
-                storage.append(announcements, to: file, uniqBy: \.createdAt)
-                let uniqEvents = storage.retrieve(file, as: [Announcement].self)?
-                    .filter { $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date() }
-                    .sorted { $0.createdAt > $1.createdAt } ?? []
-                storage.save(Array(uniqEvents), as: file)
-            }
-        }
-    }
-
-    func syncDate() -> Date {
-        guard let events = storage.retrieve(OpenAPS.FreeAPS.announcementsEnacted, as: [Announcement].self),
-              let recentEnacted = events.filter({ $0.enteredBy == Announcement.remote }).first
-        else {
-            return Date().addingTimeInterval(-Config.recentInterval)
-        }
-        return recentEnacted.createdAt.addingTimeInterval(Config.recentInterval)
-    }
-
-    func recent() -> Announcement? {
-        guard let events = storage.retrieve(OpenAPS.FreeAPS.announcements, as: [Announcement].self)
-        else {
-            return nil
-        }
-        guard let recent = events
-            .filter({
-                $0.enteredBy == Announcement.remote && $0.createdAt.addingTimeInterval(Config.recentInterval) > Date()
-            })
-            .first
-        else {
-            return nil
-        }
-        guard let enactedEvents = storage.retrieve(OpenAPS.FreeAPS.announcementsEnacted, as: [Announcement].self)
-        else {
-            return recent
-        }
-
-        guard enactedEvents.first(where: { $0.createdAt == recent.createdAt }) == nil
-        else {
-            return nil
-        }
-        return recent
-    }
-
-    func validate() -> [Announcement] {
-        guard let enactedEvents = storage.retrieve(OpenAPS.FreeAPS.announcementsEnacted, as: [Announcement].self)?.reversed()
-        else {
-            return []
-        }
-        let validate = enactedEvents
-            .filter({ $0.enteredBy == Announcement.remote })
-        return validate
-    }
-}

+ 1 - 1
FreeAPS/Sources/APS/Storage/OverrideStorage.swift

@@ -218,7 +218,7 @@ final class BaseOverrideStorage: @preconcurrency OverrideStorage, Injectable {
             guard let fetchedOverrides = results as? [OverrideStored] else { return [] }
             guard let fetchedOverrides = results as? [OverrideStored] else { return [] }
 
 
             return fetchedOverrides.map { override in
             return fetchedOverrides.map { override in
-                let duration = override.indefinite ? 1440 : override.duration ?? 0 // 1440 min = 1 day
+                let duration = override.indefinite ? 43200 : override.duration ?? 0 // 43200 min = 30 days
                 return NightscoutExercise(
                 return NightscoutExercise(
                     duration: Int(truncating: duration),
                     duration: Int(truncating: duration),
                     eventType: OverrideStored.EventType.nsExercise,
                     eventType: OverrideStored.EventType.nsExercise,

+ 0 - 1
FreeAPS/Sources/Application/FreeAPSApp.swift

@@ -46,7 +46,6 @@ import Swinject
         _ = resolver.resolve(APSManager.self)!
         _ = resolver.resolve(APSManager.self)!
         _ = resolver.resolve(FetchGlucoseManager.self)!
         _ = resolver.resolve(FetchGlucoseManager.self)!
         _ = resolver.resolve(FetchTreatmentsManager.self)!
         _ = resolver.resolve(FetchTreatmentsManager.self)!
-        _ = resolver.resolve(FetchAnnouncementsManager.self)!
         _ = resolver.resolve(CalendarManager.self)!
         _ = resolver.resolve(CalendarManager.self)!
         _ = resolver.resolve(UserNotificationsManager.self)!
         _ = resolver.resolve(UserNotificationsManager.self)!
         _ = resolver.resolve(WatchManager.self)!
         _ = resolver.resolve(WatchManager.self)!

+ 0 - 1
FreeAPS/Sources/Assemblies/APSAssembly.swift

@@ -7,7 +7,6 @@ final class APSAssembly: Assembly {
         container.register(APSManager.self) { r in BaseAPSManager(resolver: r) }
         container.register(APSManager.self) { r in BaseAPSManager(resolver: r) }
         container.register(FetchGlucoseManager.self) { r in BaseFetchGlucoseManager(resolver: r) }
         container.register(FetchGlucoseManager.self) { r in BaseFetchGlucoseManager(resolver: r) }
         container.register(FetchTreatmentsManager.self) { r in BaseFetchTreatmentsManager(resolver: r) }
         container.register(FetchTreatmentsManager.self) { r in BaseFetchTreatmentsManager(resolver: r) }
-        container.register(FetchAnnouncementsManager.self) { r in BaseFetchAnnouncementsManager(resolver: r) }
         container.register(BluetoothStateManager.self) { r in BaseBluetoothStateManager(resolver: r) }
         container.register(BluetoothStateManager.self) { r in BaseBluetoothStateManager(resolver: r) }
         container.register(PluginManager.self) { r in BasePluginManager(resolver: r) }
         container.register(PluginManager.self) { r in BasePluginManager(resolver: r) }
         container.register(CalibrationService.self) { r in BaseCalibrationService(resolver: r) }
         container.register(CalibrationService.self) { r in BaseCalibrationService(resolver: r) }

+ 0 - 1
FreeAPS/Sources/Assemblies/StorageAssembly.swift

@@ -14,7 +14,6 @@ final class StorageAssembly: Assembly {
         container.register(TempTargetsStorage.self) { r in BaseTempTargetsStorage(resolver: r) }
         container.register(TempTargetsStorage.self) { r in BaseTempTargetsStorage(resolver: r) }
         container.register(CarbsStorage.self) { r in BaseCarbsStorage(resolver: r) }
         container.register(CarbsStorage.self) { r in BaseCarbsStorage(resolver: r) }
         container.register(ContactImageStorage.self) { r in BaseContactImageStorage(resolver: r) }
         container.register(ContactImageStorage.self) { r in BaseContactImageStorage(resolver: r) }
-        container.register(AnnouncementsStorage.self) { r in BaseAnnouncementsStorage(resolver: r) }
         container.register(SettingsManager.self) { r in BaseSettingsManager(resolver: r) }
         container.register(SettingsManager.self) { r in BaseSettingsManager(resolver: r) }
         container.register(Keychain.self) { _ in BaseKeychain() }
         container.register(Keychain.self) { _ in BaseKeychain() }
         container.register(AlertHistoryStorage.self) { r in BaseAlertHistoryStorage(resolver: r) }
         container.register(AlertHistoryStorage.self) { r in BaseAlertHistoryStorage(resolver: r) }

+ 0 - 6
FreeAPS/Sources/Localizations/Main/ar.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/ca.lproj/Localizable.strings

@@ -1086,12 +1086,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/da.lproj/Localizable.strings

@@ -1196,12 +1196,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Udført";
 "Enacted" = "Udført";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/de.lproj/Localizable.strings

@@ -1241,12 +1241,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "letzte Berechnung";
 "Enacted" = "letzte Berechnung";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Notifikationen";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Erlassene Ankündigungen";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/en.lproj/Localizable.strings

@@ -1238,12 +1238,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/es.lproj/Localizable.strings

@@ -1234,12 +1234,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/fi.lproj/Localizable.strings

@@ -1241,12 +1241,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/fr.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Activé";
 "Enacted" = "Activé";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Annonces";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Annonces émises";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/he.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/hu.lproj/Localizable.strings

@@ -1193,12 +1193,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/it.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Debug Attivato";
 "Enacted" = "Debug Attivato";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Annunci";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Annunci attivati";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/nb.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Utført";
 "Enacted" = "Utført";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Kunngjøringer";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Utførte kunngjøringer";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/nl.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Vastgesteld";
 "Enacted" = "Vastgesteld";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Meldingen";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Ingevoerde meldingen";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/pl.lproj/Localizable.strings

@@ -1237,12 +1237,6 @@ Połączono z Nightscout!";
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/pt-BR.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/pt-PT.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/ru.lproj/Localizable.strings

@@ -1238,12 +1238,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Принято";
 "Enacted" = "Принято";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Оповещения";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Принятые оповещения";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Автотюн";
 "Autotune" = "Автотюн";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/sk.lproj/Localizable.strings

@@ -1193,12 +1193,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Prijaté";
 "Enacted" = "Prijaté";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Oznámenia";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Prijaté oznámenia";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/sv.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Utfört";
 "Enacted" = "Utfört";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Meddelanden (via NS)";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Överförda meddelanden";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/tr.lproj/Localizable.strings

@@ -1239,12 +1239,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Duyurular";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Otoayar";
 "Autotune" = "Otoayar";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/uk.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Введено в дію";
 "Enacted" = "Введено в дію";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Оголошення";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Введені в дію оголошення";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Автотюн";
 "Autotune" = "Автотюн";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/vi.lproj/Localizable.strings

@@ -1193,12 +1193,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Đã kích hoạt";
 "Enacted" = "Đã kích hoạt";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Các thông báo";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Thông báo đã kích hoạt";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "Autotune";
 "Autotune" = "Autotune";
 
 

+ 0 - 6
FreeAPS/Sources/Localizations/Main/zh-Hans.lproj/Localizable.strings

@@ -1235,12 +1235,6 @@ Enact a temp Basal or a temp target */
 /* Debug option view Enacted */
 /* Debug option view Enacted */
 "Enacted" = "Enacted";
 "Enacted" = "Enacted";
 
 
-/* Debug option view Announcements (from NS) */
-"Announcements" = "Announcements";
-
-/* Debug option view Enacted announcements announcements (from NS) */
-"Enacted announcements" = "Enacted announcements";
-
 /* Debug option view Autotune */
 /* Debug option view Autotune */
 "Autotune" = "自动调谐";
 "Autotune" = "自动调谐";
 
 

+ 0 - 57
FreeAPS/Sources/Models/Announcement.swift

@@ -1,57 +0,0 @@
-import Foundation
-
-struct Announcement: JSON, Equatable, Hashable {
-    let createdAt: Date
-    let enteredBy: String
-    let notes: String
-
-    static let remote = "remote"
-
-    var action: AnnouncementAction? {
-        let components = notes.replacingOccurrences(of: " ", with: "").split(separator: ":")
-        guard components.count == 2 else {
-            return nil
-        }
-        let command = String(components[0]).lowercased()
-        let arguments = String(components[1]).lowercased()
-        switch command {
-        case "bolus":
-            guard let amount = Decimal(from: arguments) else { return nil }
-            return .bolus(amount)
-        case "pump":
-            guard let action = PumpAction(rawValue: arguments) else { return nil }
-            return .pump(action)
-        case "looping":
-            guard let looping = Bool(from: arguments) else { return nil }
-            return .looping(looping)
-        case "tempbasal":
-            let basalComponents = arguments.split(separator: ",")
-            guard basalComponents.count == 2 else { return nil }
-            let rateArg = String(basalComponents[0])
-            let durationArg = String(basalComponents[1])
-            guard let rate = Decimal(from: rateArg), let duration = Decimal(from: durationArg) else { return nil }
-            return .tempbasal(rate: rate, duration: duration)
-        default: return nil
-        }
-    }
-}
-
-extension Announcement {
-    private enum CodingKeys: String, CodingKey {
-        case createdAt = "created_at"
-        case enteredBy
-        case notes
-    }
-}
-
-enum AnnouncementAction {
-    case bolus(Decimal)
-    case pump(PumpAction)
-    case looping(Bool)
-    case tempbasal(rate: Decimal, duration: Decimal)
-}
-
-enum PumpAction: String {
-    case suspend
-    case resume
-}

+ 0 - 5
FreeAPS/Sources/Models/FreeAPSSettings.swift

@@ -18,7 +18,6 @@ enum BolusShortcutLimit: String, JSON, CaseIterable, Identifiable {
 struct FreeAPSSettings: JSON, Equatable {
 struct FreeAPSSettings: JSON, Equatable {
     var units: GlucoseUnits = .mgdL
     var units: GlucoseUnits = .mgdL
     var closedLoop: Bool = false
     var closedLoop: Bool = false
-    var allowAnnouncements: Bool = false
     var isUploadEnabled: Bool = false
     var isUploadEnabled: Bool = false
     var isDownloadEnabled: Bool = false
     var isDownloadEnabled: Bool = false
     var useLocalGlucoseSource: Bool = false
     var useLocalGlucoseSource: Bool = false
@@ -92,10 +91,6 @@ extension FreeAPSSettings: Decodable {
             settings.closedLoop = closedLoop
             settings.closedLoop = closedLoop
         }
         }
 
 
-        if let allowAnnouncements = try? container.decode(Bool.self, forKey: .allowAnnouncements) {
-            settings.allowAnnouncements = allowAnnouncements
-        }
-
         if let isUploadEnabled = try? container.decode(Bool.self, forKey: .isUploadEnabled) {
         if let isUploadEnabled = try? container.decode(Bool.self, forKey: .isUploadEnabled) {
             settings.isUploadEnabled = isUploadEnabled
             settings.isUploadEnabled = isUploadEnabled
         }
         }

+ 0 - 1
FreeAPS/Sources/Modules/Home/HomeDataFlow.swift

@@ -12,6 +12,5 @@ protocol HomeProvider: Provider {
     func tempTargets(hours: Int) -> [TempTarget]
     func tempTargets(hours: Int) -> [TempTarget]
     func pumpReservoir() -> Decimal?
     func pumpReservoir() -> Decimal?
     func tempTarget() -> TempTarget?
     func tempTarget() -> TempTarget?
-    func announcement(_ hours: Int) -> [Announcement]
     func getBGTarget() async -> BGTargets
     func getBGTarget() async -> BGTargets
 }
 }

+ 0 - 7
FreeAPS/Sources/Modules/Home/HomeProvider.swift

@@ -7,7 +7,6 @@ extension Home {
         @Injected() var apsManager: APSManager!
         @Injected() var apsManager: APSManager!
         @Injected() var glucoseStorage: GlucoseStorage!
         @Injected() var glucoseStorage: GlucoseStorage!
         @Injected() var tempTargetsStorage: TempTargetsStorage!
         @Injected() var tempTargetsStorage: TempTargetsStorage!
-        @Injected() var announcementStorage: AnnouncementsStorage!
 
 
         func pumpTimeZone() -> TimeZone? {
         func pumpTimeZone() -> TimeZone? {
             apsManager.pumpManager?.status.timeZone
             apsManager.pumpManager?.status.timeZone
@@ -27,12 +26,6 @@ extension Home {
             tempTargetsStorage.current()
             tempTargetsStorage.current()
         }
         }
 
 
-        func announcement(_ hours: Int) -> [Announcement] {
-            announcementStorage.validate().filter {
-                $0.createdAt.addingTimeInterval(hours.hours.timeInterval) > Date()
-            }
-        }
-
         func pumpSettings() -> PumpSettings {
         func pumpSettings() -> PumpSettings {
             storage.retrieve(OpenAPS.Settings.settings, as: PumpSettings.self)
             storage.retrieve(OpenAPS.Settings.settings, as: PumpSettings.self)
                 ?? PumpSettings(from: OpenAPS.defaults(for: OpenAPS.Settings.settings))
                 ?? PumpSettings(from: OpenAPS.defaults(for: OpenAPS.Settings.settings))

+ 0 - 1
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -20,7 +20,6 @@ extension Home {
         private let timer = DispatchTimer(timeInterval: 5)
         private let timer = DispatchTimer(timeInterval: 5)
         private(set) var filteredHours = 24
         private(set) var filteredHours = 24
         var manualGlucose: [BloodGlucose] = []
         var manualGlucose: [BloodGlucose] = []
-        var announcement: [Announcement] = []
         var uploadStats = false
         var uploadStats = false
         var recentGlucose: BloodGlucose?
         var recentGlucose: BloodGlucose?
         var maxBasal: Decimal = 2
         var maxBasal: Decimal = 2

+ 45 - 14
FreeAPS/Sources/Modules/Home/View/Chart/ChartElements/BasalChart.swift

@@ -153,7 +153,7 @@ extension MainChartView {
         return tempBasals.compactMap { temp -> (start: Date, end: Date, rate: Double)? in
         return tempBasals.compactMap { temp -> (start: Date, end: Date, rate: Double)? in
             let duration = temp.tempBasal?.duration ?? 0
             let duration = temp.tempBasal?.duration ?? 0
             let timestamp = temp.timestamp ?? Date()
             let timestamp = temp.timestamp ?? Date()
-            let end = min(timestamp + duration.minutes, now)
+            let end = timestamp + duration.minutes
             let isInsulinSuspended = state.suspensions.contains { $0.timestamp ?? now >= timestamp && $0.timestamp ?? now <= end }
             let isInsulinSuspended = state.suspensions.contains { $0.timestamp ?? now >= timestamp && $0.timestamp ?? now <= end }
 
 
             let rate = Double(truncating: temp.tempBasal?.rate ?? Decimal.zero as NSDecimalNumber) * (isInsulinSuspended ? 0 : 1)
             let rate = Double(truncating: temp.tempBasal?.rate ?? Decimal.zero as NSDecimalNumber) * (isInsulinSuspended ? 0 : 1)
@@ -202,25 +202,56 @@ extension MainChartView {
         Task {
         Task {
             let dayAgoTime = Date().addingTimeInterval(-1.days.timeInterval).timeIntervalSince1970
             let dayAgoTime = Date().addingTimeInterval(-1.days.timeInterval).timeIntervalSince1970
 
 
-            // Get Regular Basal
-            let basalPoints = await findRegularBasalPoints(
+            async let getRegularBasalPoints = findRegularBasalPoints(
                 timeBegin: dayAgoTime,
                 timeBegin: dayAgoTime,
                 timeEnd: endMarker.timeIntervalSince1970
                 timeEnd: endMarker.timeIntervalSince1970
             )
             )
 
 
-            var totalBasal = basalPoints
-            totalBasal.sort {
-                $0.startDate.timeIntervalSince1970 < $1.startDate.timeIntervalSince1970
-            }
+            var regularPoints = await getRegularBasalPoints
+            regularPoints.sort { $0.startDate < $1.startDate }
 
 
             var basals: [BasalProfile] = []
             var basals: [BasalProfile] = []
-            totalBasal.indices.forEach { index in
-                basals.append(BasalProfile(
-                    amount: totalBasal[index].amount,
-                    isOverwritten: totalBasal[index].isOverwritten,
-                    startDate: totalBasal[index].startDate,
-                    endDate: totalBasal.count > index + 1 ? totalBasal[index + 1].startDate : endMarker
-                ))
+
+            // No basal data? Then there's nothing to draw
+            if regularPoints.isEmpty {
+                // basals stays empty; do nothing
+            }
+            // Exactly one data point?
+            else if regularPoints.count == 1 {
+                let single = regularPoints[0]
+                // Make one BasalProfile that stretches entire marker area
+                basals.append(
+                    BasalProfile(
+                        amount: single.amount,
+                        isOverwritten: single.isOverwritten,
+                        startDate: startMarker,
+                        endDate: endMarker
+                    )
+                )
+            }
+            // Multiple data points: chain them so each point ends where the next begins
+            else {
+                for i in 0 ..< (regularPoints.count - 1) {
+                    basals.append(
+                        BasalProfile(
+                            amount: regularPoints[i].amount,
+                            isOverwritten: regularPoints[i].isOverwritten,
+                            startDate: regularPoints[i].startDate,
+                            endDate: regularPoints[i + 1].startDate
+                        )
+                    )
+                }
+                // The last item goes from its start to endMarker
+                if let lastItem = regularPoints.last {
+                    basals.append(
+                        BasalProfile(
+                            amount: lastItem.amount,
+                            isOverwritten: lastItem.isOverwritten,
+                            startDate: lastItem.startDate,
+                            endDate: endMarker
+                        )
+                    )
+                }
             }
             }
 
 
             await MainActor.run {
             await MainActor.run {

+ 1 - 1
FreeAPS/Sources/Modules/Home/View/Chart/ChartElements/OverrideView.swift

@@ -24,7 +24,7 @@ struct OverrideView: ChartContent {
                 context: viewContext
                 context: viewContext
             ) ?? 0
             ) ?? 0
             let end: Date = duration != 0 ? start.addingTimeInterval(duration) : start
             let end: Date = duration != 0 ? start.addingTimeInterval(duration) : start
-                .addingTimeInterval(6 * 60 * 60) // handle infinite overrides
+                .addingTimeInterval(60 * 60 * 24 * 30) // handle infinite overrides -> 60s x 60m x 24h x 30d = 30 days duration
 
 
             let target = getOverrideTarget(override: override)
             let target = getOverrideTarget(override: override)
 
 

+ 5 - 2
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -732,7 +732,10 @@ extension Home {
 
 
                 }.padding(.horizontal, 10).padding(.bottom, UIDevice.adjustPadding(min: nil, max: 10))
                 }.padding(.horizontal, 10).padding(.bottom, UIDevice.adjustPadding(min: nil, max: 10))
                     .overlay(alignment: .bottom) {
                     .overlay(alignment: .bottom) {
-                        bolusProgressBar(progress).padding(.horizontal, 18).offset(y: 48)
+                        // Use a geo-based offset here to position progress bar independent of device size
+                        let offset = geo.size.height * 0.0725
+                        bolusProgressBar(progress).padding(.horizontal, 18)
+                            .offset(y: offset)
                     }.clipShape(RoundedRectangle(cornerRadius: 15))
                     }.clipShape(RoundedRectangle(cornerRadius: 15))
             }
             }
         }
         }
@@ -952,7 +955,7 @@ extension Home {
                             .font(.system(size: 40))
                             .font(.system(size: 40))
                             .foregroundStyle(Color.tabBar)
                             .foregroundStyle(Color.tabBar)
                             .padding(.bottom, 1)
                             .padding(.bottom, 1)
-                            .padding(.horizontal, 20)
+                            .padding(.horizontal, 22.5)
                     }
                     }
                 )
                 )
             }.ignoresSafeArea(.keyboard, edges: .bottom).blur(radius: state.waitForSuggestion ? 8 : 0)
             }.ignoresSafeArea(.keyboard, edges: .bottom).blur(radius: state.waitForSuggestion ? 8 : 0)

+ 0 - 2
FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift

@@ -32,7 +32,6 @@ extension NightscoutConfig {
         @Published var dia: Decimal = 6
         @Published var dia: Decimal = 6
         @Published var maxBasal: Decimal = 2
         @Published var maxBasal: Decimal = 2
         @Published var maxBolus: Decimal = 10
         @Published var maxBolus: Decimal = 10
-        @Published var allowAnnouncements: Bool = false
         @Published var isConnectedToNS: Bool = false
         @Published var isConnectedToNS: Bool = false
 
 
         @Published var isImportResultReviewPresented: Bool = false
         @Published var isImportResultReviewPresented: Bool = false
@@ -57,7 +56,6 @@ extension NightscoutConfig {
             maxBolus = settingsManager.pumpSettings.maxBolus
             maxBolus = settingsManager.pumpSettings.maxBolus
             changeUploadGlucose = (cgmManager.cgmGlucoseSourceType != CGMType.plugin)
             changeUploadGlucose = (cgmManager.cgmGlucoseSourceType != CGMType.plugin)
 
 
-            subscribeSetting(\.allowAnnouncements, on: $allowAnnouncements) { allowAnnouncements = $0 }
             subscribeSetting(\.isUploadEnabled, on: $isUploadEnabled) { isUploadEnabled = $0 }
             subscribeSetting(\.isUploadEnabled, on: $isUploadEnabled) { isUploadEnabled = $0 }
             subscribeSetting(\.isDownloadEnabled, on: $isDownloadEnabled) { isDownloadEnabled = $0 }
             subscribeSetting(\.isDownloadEnabled, on: $isDownloadEnabled) { isDownloadEnabled = $0 }
             subscribeSetting(\.useLocalGlucoseSource, on: $useLocalSource) { useLocalSource = $0 }
             subscribeSetting(\.useLocalGlucoseSource, on: $useLocalSource) { useLocalSource = $0 }

+ 1 - 1
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift

@@ -41,7 +41,7 @@ extension NightscoutConfig {
                                 }
                                 }
                             })
                             })
                             NavigationLink("Upload", destination: NightscoutUploadView(state: state))
                             NavigationLink("Upload", destination: NightscoutUploadView(state: state))
-                            NavigationLink("Fetch & Remote Control", destination: NightscoutFetchView(state: state))
+                            NavigationLink("Fetch", destination: NightscoutFetchView(state: state))
                         }
                         }
                     ).listRowBackground(Color.chart)
                     ).listRowBackground(Color.chart)
 
 

+ 2 - 35
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutFetchView.swift

@@ -37,41 +37,8 @@ struct NightscoutFetchView: View {
                         "The Fetch Treatments toggle enables fetching of carbs and temp targets entered in Careportal or by another uploading device than Trio from Nightscout."
                         "The Fetch Treatments toggle enables fetching of carbs and temp targets entered in Careportal or by another uploading device than Trio from Nightscout."
                     )
                     )
                 },
                 },
-                headerText: "Remote & Fetch Capabilities"
+                headerText: "Fetch NS Care Portal Data"
             )
             )
-
-            if state.isDownloadEnabled {
-                SettingInputSection(
-                    decimalValue: $decimalPlaceholder,
-                    booleanValue: $state.allowAnnouncements,
-                    shouldDisplayHint: $shouldDisplayHint,
-                    selectedVerboseHint: Binding(
-                        get: { selectedVerboseHint },
-                        set: {
-                            selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Allow Remote Control of Trio"
-                        }
-                    ),
-                    units: state.units,
-                    type: .boolean,
-                    label: "Allow Remote Control of Trio",
-                    miniHint: "Enables selected remote control capabilities via Nightscout.",
-                    verboseHint: VStack(alignment: .leading, spacing: 10) {
-                        Text("Default: OFF").bold()
-                        Text("When enabled you allow the following remote functions through announcements from Nightscout:")
-                        VStack(alignment: .leading) {
-                            Text("• Suspend/Resume Pump")
-                            Text("• Opening/Closing Loop")
-                            Text("• Set Temp Basal")
-                            Text("• Enact Bolus")
-                        }
-                    }
-                )
-            } else {
-                Section {
-                    Text("'Allow Fetching from Nightscout' must be enabled to allow for Trio Remote Control.")
-                }.listRowBackground(Color.tabBar)
-            }
         }
         }
         .listSectionSpacing(sectionSpacing)
         .listSectionSpacing(sectionSpacing)
         .sheet(isPresented: $shouldDisplayHint) {
         .sheet(isPresented: $shouldDisplayHint) {
@@ -83,7 +50,7 @@ struct NightscoutFetchView: View {
                 sheetTitle: "Help"
                 sheetTitle: "Help"
             )
             )
         }
         }
-        .navigationTitle("Fetch & Remote")
+        .navigationTitle("Fetch")
         .navigationBarTitleDisplayMode(.automatic)
         .navigationBarTitleDisplayMode(.automatic)
         .scrollContentBackground(.hidden)
         .scrollContentBackground(.hidden)
         .background(appState.trioBackgroundColor(for: colorScheme))
         .background(appState.trioBackgroundColor(for: colorScheme))

+ 0 - 4
FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -266,10 +266,6 @@ extension Settings {
 //                                .navigationLink(to: .configEditor(file: OpenAPS.Settings.profile), from: self)
 //                                .navigationLink(to: .configEditor(file: OpenAPS.Settings.profile), from: self)
 //                            //                            Text("Carbs")
 //                            //                            Text("Carbs")
 //                            //                                .navigationLink(to: .configEditor(file: OpenAPS.Monitor.carbHistory), from: self)
 //                            //                                .navigationLink(to: .configEditor(file: OpenAPS.Monitor.carbHistory), from: self)
-//                            //                            Text("Announcements")
-//                            //                                .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.announcements), from: self)
-//                            //                            Text("Enacted announcements")
-//                            //                                .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.announcementsEnacted), from: self)
 //                        }
 //                        }
 //
 //
 //                        Group {
 //                        Group {

+ 24 - 0
FreeAPS/Sources/Modules/Treatments/TreatmentsStateModel.swift

@@ -126,6 +126,9 @@ extension Treatments {
 
 
         typealias PumpEvent = PumpEventStored.EventType
         typealias PumpEvent = PumpEventStored.EventType
 
 
+        var isBolusInProgress: Bool = false
+        private var bolusProgressCancellable: AnyCancellable?
+
         func unsubscribe() {
         func unsubscribe() {
             subscriptions.forEach { $0.cancel() }
             subscriptions.forEach { $0.cancel() }
             subscriptions.removeAll()
             subscriptions.removeAll()
@@ -145,6 +148,7 @@ extension Treatments {
             registerHandlers()
             registerHandlers()
             registerSubscribers()
             registerSubscribers()
             setupBolusStateConcurrently()
             setupBolusStateConcurrently()
+            subscribeToBolusProgress()
         }
         }
 
 
         deinit {
         deinit {
@@ -155,6 +159,8 @@ extension Treatments {
             // Cancel Combine subscriptions
             // Cancel Combine subscriptions
             unsubscribe()
             unsubscribe()
 
 
+            bolusProgressCancellable?.cancel()
+
             debug(.bolusState, "Bolus.StateModel deinitialized")
             debug(.bolusState, "Bolus.StateModel deinitialized")
         }
         }
 
 
@@ -191,6 +197,24 @@ extension Treatments {
             }
             }
         }
         }
 
 
+        /// Observes changes to the `bolusProgress` published by the `apsManager` to update the `isBolusInProgress` property in real time.
+        ///
+        /// - Important:
+        ///   - `apsManager.bolusProgress` is a `CurrentValueSubject<Decimal?, Never>`.
+        ///   - When a bolus starts, this subject emits `0` (or a fraction like `0.1, 0.5, etc.`).
+        ///   - When the bolus finishes, the subject is typically set to `nil`.
+        ///   - This treats ANY non-nil value as “bolus in progress.”
+        ///
+        private func subscribeToBolusProgress() {
+            bolusProgressCancellable = apsManager.bolusProgress
+                .receive(on: DispatchQueue.main)
+                .sink { [weak self] progressValue in
+                    guard let self = self else { return }
+                    // If progressValue is non-nil, a bolus is in progress.
+                    self.isBolusInProgress = (progressValue != nil)
+                }
+        }
+
         // MARK: - Basal
         // MARK: - Basal
 
 
         private enum SettingType {
         private enum SettingType {

+ 31 - 13
FreeAPS/Sources/Modules/Treatments/View/TreatmentsRootView.swift

@@ -365,28 +365,38 @@ extension Treatments {
         }
         }
 
 
         var treatmentButton: some View {
         var treatmentButton: some View {
-            Button {
+            var treatmentButtonBackground = Color(.systemBlue)
+            if limitExceeded {
+                treatmentButtonBackground = Color(.systemRed)
+            } else if disableTaskButton {
+                treatmentButtonBackground = Color(.systemGray)
+            }
+
+            return Button {
                 state.invokeTreatmentsTask()
                 state.invokeTreatmentsTask()
             } label: {
             } label: {
-                taskButtonLabel
-                    .font(.headline)
-                    .foregroundStyle(Color.white)
-                    .frame(maxWidth: .infinity, alignment: .center)
-                    .frame(height: 35)
+                HStack {
+                    if state.isBolusInProgress && state
+                        .amount > 0 && !state.externalInsulin && (state.carbs == 0 || state.fat == 0 || state.protein == 0)
+                    {
+                        ProgressView()
+                    }
+                    taskButtonLabel
+                }
+                .font(.headline)
+                .foregroundStyle(Color.white)
+                .frame(maxWidth: .infinity, alignment: .center)
+                .frame(height: 35)
             }
             }
             .disabled(disableTaskButton)
             .disabled(disableTaskButton)
-            .listRowBackground(
-                limitExceeded ? Color(.systemRed) :
-                    disableTaskButton ? Color(.systemGray) :
-                    Color(.systemBlue)
-            )
+            .listRowBackground(treatmentButtonBackground)
             .shadow(radius: 3)
             .shadow(radius: 3)
             .clipShape(RoundedRectangle(cornerRadius: 8))
             .clipShape(RoundedRectangle(cornerRadius: 8))
         }
         }
 
 
         private var taskButtonLabel: some View {
         private var taskButtonLabel: some View {
             if pumpBolusLimitExceeded {
             if pumpBolusLimitExceeded {
-                return Text("Max Bolus of \(state.maxBolus.description) U Exceeded")
+                return Text("Max Bolus of \(state.maxBolus.description) U E== 0xceeded")
             } else if externalBolusLimitExceeded {
             } else if externalBolusLimitExceeded {
                 return Text("Max External Bolus of \(state.maxExternal.description) U Exceeded")
                 return Text("Max External Bolus of \(state.maxExternal.description) U Exceeded")
             } else if carbLimitExceeded {
             } else if carbLimitExceeded {
@@ -402,6 +412,10 @@ extension Treatments {
             let hasFatOrProtein = state.fat > 0 || state.protein > 0
             let hasFatOrProtein = state.fat > 0 || state.protein > 0
             let bolusString = state.externalInsulin ? "External Insulin" : "Enact Bolus"
             let bolusString = state.externalInsulin ? "External Insulin" : "Enact Bolus"
 
 
+            if state.isBolusInProgress && hasInsulin && !state.externalInsulin && (!hasCarbs || !hasFatOrProtein) {
+                return Text("Bolus In Progress...")
+            }
+
             switch (hasInsulin, hasCarbs, hasFatOrProtein) {
             switch (hasInsulin, hasCarbs, hasFatOrProtein) {
             case (true, true, true):
             case (true, true, true):
                 return Text("Log Meal and \(bolusString)")
                 return Text("Log Meal and \(bolusString)")
@@ -447,7 +461,11 @@ extension Treatments {
         }
         }
 
 
         private var disableTaskButton: Bool {
         private var disableTaskButton: Bool {
-            state.addButtonPressed || limitExceeded
+            (
+                state.isBolusInProgress && state
+                    .amount > 0 && !state.externalInsulin && (state.carbs == 0 || state.fat == 0 || state.protein == 0)
+            ) || state
+                .addButtonPressed || limitExceeded
         }
         }
     }
     }
 
 

+ 0 - 35
FreeAPS/Sources/Services/Network/Nightscout/NightscoutAPI.swift

@@ -286,41 +286,6 @@ extension NightscoutAPI {
         }
         }
     }
     }
 
 
-    func fetchAnnouncement(sinceDate: Date? = nil) -> AnyPublisher<[Announcement], Swift.Error> {
-        var components = URLComponents()
-        components.scheme = url.scheme
-        components.host = url.host
-        components.port = url.port
-        components.path = Config.treatmentsPath
-        components.queryItems = [
-            URLQueryItem(name: "find[eventType]", value: "Announcement"),
-            URLQueryItem(
-                name: "find[enteredBy]",
-                value: Announcement.remote.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
-            )
-        ]
-        if let date = sinceDate {
-            let dateItem = URLQueryItem(
-                name: "find[created_at][$gte]",
-                value: Formatter.iso8601withFractionalSeconds.string(from: date)
-            )
-            components.queryItems?.append(dateItem)
-        }
-
-        var request = URLRequest(url: components.url!)
-        request.allowsConstrainedNetworkAccess = false
-        request.timeoutInterval = Config.timeout
-
-        if let secret = secret {
-            request.addValue(secret.sha1(), forHTTPHeaderField: "api-secret")
-        }
-
-        return service.run(request)
-            .retry(Config.retryCount)
-            .decode(type: [Announcement].self, decoder: JSONCoding.decoder)
-            .eraseToAnyPublisher()
-    }
-
     func uploadTreatments(_ treatments: [NightscoutTreatment]) async throws {
     func uploadTreatments(_ treatments: [NightscoutTreatment]) async throws {
         var components = URLComponents()
         var components = URLComponents()
         components.scheme = url.scheme
         components.scheme = url.scheme

+ 0 - 16
FreeAPS/Sources/Services/Network/Nightscout/NightscoutManager.swift

@@ -9,7 +9,6 @@ protocol NightscoutManager: GlucoseSource {
     func fetchGlucose(since date: Date) async -> [BloodGlucose]
     func fetchGlucose(since date: Date) async -> [BloodGlucose]
     func fetchCarbs() async -> [CarbsEntry]
     func fetchCarbs() async -> [CarbsEntry]
     func fetchTempTargets() async -> [TempTarget]
     func fetchTempTargets() async -> [TempTarget]
-    func fetchAnnouncements() -> AnyPublisher<[Announcement], Never>
     func deleteCarbs(withID id: String) async
     func deleteCarbs(withID id: String) async
     func deleteInsulin(withID id: String) async
     func deleteInsulin(withID id: String) async
     func deleteManualGlucose(withID id: String) async
     func deleteManualGlucose(withID id: String) async
@@ -35,7 +34,6 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     @Injected() private var carbsStorage: CarbsStorage!
     @Injected() private var carbsStorage: CarbsStorage!
     @Injected() private var pumpHistoryStorage: PumpHistoryStorage!
     @Injected() private var pumpHistoryStorage: PumpHistoryStorage!
     @Injected() private var storage: FileStorage!
     @Injected() private var storage: FileStorage!
-    @Injected() private var announcementsStorage: AnnouncementsStorage!
     @Injected() private var settingsManager: SettingsManager!
     @Injected() private var settingsManager: SettingsManager!
     @Injected() private var broadcaster: Broadcaster!
     @Injected() private var broadcaster: Broadcaster!
     @Injected() private var reachabilityManager: ReachabilityManager!
     @Injected() private var reachabilityManager: ReachabilityManager!
@@ -319,23 +317,9 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
         }
     }
     }
 
 
-    func fetchAnnouncements() -> AnyPublisher<[Announcement], Never> {
-        guard let nightscout = nightscoutAPI, isNetworkReachable, isDownloadEnabled else {
-            return Just([]).eraseToAnyPublisher()
-        }
-
-        let since = announcementsStorage.syncDate()
-        return nightscout.fetchAnnouncement(sinceDate: since)
-            .replaceError(with: [])
-            .eraseToAnyPublisher()
-    }
-
     func deleteCarbs(withID id: String) async {
     func deleteCarbs(withID id: String) async {
         guard let nightscout = nightscoutAPI, isUploadEnabled else { return }
         guard let nightscout = nightscoutAPI, isUploadEnabled else { return }
 
 
-        // TODO: - healthkit rewrite, deletion of FPUs
-//        healthkitManager.deleteCarbs(syncID: arg1, fpuID: arg2)
-
         do {
         do {
             try await nightscout.deleteCarbs(withId: id)
             try await nightscout.deleteCarbs(withId: id)
             debug(.nightscout, "Carbs deleted")
             debug(.nightscout, "Carbs deleted")

+ 0 - 1
LiveActivity/Views/WidgetItems/LiveActivityIOBLabelView.swift

@@ -16,7 +16,6 @@ struct LiveActivityIOBLabelView: View {
         let formatter = NumberFormatter()
         let formatter = NumberFormatter()
         formatter.numberStyle = .decimal
         formatter.numberStyle = .decimal
         formatter.maximumFractionDigits = 1
         formatter.maximumFractionDigits = 1
-        formatter.decimalSeparator = "."
         return formatter
         return formatter
     }
     }