From acd3063392d76682ac6c9c463e17b0844e123bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B6rkert?= Date: Thu, 3 Jul 2025 21:04:42 +0200 Subject: [PATCH 1/2] Make Second Tab Configurable --- LoopFollow.xcodeproj/project.pbxproj | 8 +++ LoopFollow/Alarm/AlarmsContainerView.swift | 23 ++++++++ .../ViewControllers/AlarmViewController.swift | 29 ++++++++++ .../ViewControllers/MainViewController.swift | 53 +++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 LoopFollow/Alarm/AlarmsContainerView.swift create mode 100644 LoopFollow/ViewControllers/AlarmViewController.swift diff --git a/LoopFollow.xcodeproj/project.pbxproj b/LoopFollow.xcodeproj/project.pbxproj index 93733a164..0087f389e 100644 --- a/LoopFollow.xcodeproj/project.pbxproj +++ b/LoopFollow.xcodeproj/project.pbxproj @@ -31,6 +31,8 @@ DD0C0C6D2C48606200DBADDF /* CarbMetric.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0C0C6C2C48606200DBADDF /* CarbMetric.swift */; }; DD0C0C702C4AFFE800DBADDF /* RemoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0C0C6F2C4AFFE800DBADDF /* RemoteViewController.swift */; }; DD0C0C722C4B000800DBADDF /* TrioNightscoutRemoteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0C0C712C4B000800DBADDF /* TrioNightscoutRemoteView.swift */; }; + DD12D4852E1705D9004E0112 /* AlarmViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD12D4842E1705D9004E0112 /* AlarmViewController.swift */; }; + DD12D4872E1705E6004E0112 /* AlarmsContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD12D4862E1705E6004E0112 /* AlarmsContainerView.swift */; }; DD13BC752C3FD6210062313B /* InfoType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD13BC742C3FD6200062313B /* InfoType.swift */; }; DD13BC772C3FD64E0062313B /* InfoData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD13BC762C3FD64E0062313B /* InfoData.swift */; }; DD13BC792C3FE63A0062313B /* InfoManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD13BC782C3FE63A0062313B /* InfoManager.swift */; }; @@ -403,6 +405,8 @@ DD0C0C6C2C48606200DBADDF /* CarbMetric.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbMetric.swift; sourceTree = ""; }; DD0C0C6F2C4AFFE800DBADDF /* RemoteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteViewController.swift; sourceTree = ""; }; DD0C0C712C4B000800DBADDF /* TrioNightscoutRemoteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrioNightscoutRemoteView.swift; sourceTree = ""; }; + DD12D4842E1705D9004E0112 /* AlarmViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmViewController.swift; sourceTree = ""; }; + DD12D4862E1705E6004E0112 /* AlarmsContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmsContainerView.swift; sourceTree = ""; }; DD13BC742C3FD6200062313B /* InfoType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoType.swift; sourceTree = ""; }; DD13BC762C3FD64E0062313B /* InfoData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoData.swift; sourceTree = ""; }; DD13BC782C3FE63A0062313B /* InfoManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoManager.swift; sourceTree = ""; }; @@ -1113,6 +1117,7 @@ DDCF9A7E2D85FCE6004DF4DD /* Alarm */ = { isa = PBXGroup; children = ( + DD12D4862E1705E6004E0112 /* AlarmsContainerView.swift */, DDDC31CA2E13A7D2009EA0F3 /* AddAlarm */, DDCC3A502DDC5BD4006F1C10 /* DataStructs */, DDC6CA3B2DD7B9050060EE25 /* AlarmType */, @@ -1481,6 +1486,7 @@ FCC68871248A736700A0279D /* ViewControllers */ = { isa = PBXGroup; children = ( + DD12D4842E1705D9004E0112 /* AlarmViewController.swift */, FC97881B2485969B00A7906C /* MainViewController.swift */, FC97881D2485969B00A7906C /* NightScoutViewController.swift */, FCFEECA1248857A600402A7F /* SettingsViewController.swift */, @@ -1852,6 +1858,7 @@ DD7F4C072DD5042F00D449E9 /* OverrideStartAlarmEditor.swift in Sources */, DDCC3A4B2DDBB5E4006F1C10 /* BatteryCondition.swift in Sources */, DDDF6F492D479AF000884336 /* NoRemoteView.swift in Sources */, + DD12D4872E1705E6004E0112 /* AlarmsContainerView.swift in Sources */, DD83164A2DE4C504004467AA /* SettingsStepperRow.swift in Sources */, DD0650ED2DCE9371004D3B41 /* HighBgAlarmEditor.swift in Sources */, DD7F4C172DD63FA700D449E9 /* RecBolusCondition.swift in Sources */, @@ -1978,6 +1985,7 @@ DD4AFB3B2DB55CB600BB593F /* TimeOfDay.swift in Sources */, DDEF503C2D31BE2D00999A5D /* TaskScheduler.swift in Sources */, DD0650EB2DCE8385004D3B41 /* LowBGCondition.swift in Sources */, + DD12D4852E1705D9004E0112 /* AlarmViewController.swift in Sources */, DD0C0C6B2C48562000DBADDF /* InsulinMetric.swift in Sources */, DD493AD92ACF2171009A6922 /* Carbs.swift in Sources */, DD493AE92ACF2445009A6922 /* BGData.swift in Sources */, diff --git a/LoopFollow/Alarm/AlarmsContainerView.swift b/LoopFollow/Alarm/AlarmsContainerView.swift new file mode 100644 index 000000000..ec7a289ae --- /dev/null +++ b/LoopFollow/Alarm/AlarmsContainerView.swift @@ -0,0 +1,23 @@ +// LoopFollow +// AlarmsContainerView.swift +// Created by Jonas Björkert. + +import SwiftUI + +struct AlarmsContainerView: View { + var body: some View { + NavigationStack { + AlarmListView() + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + NavigationLink { + AlarmSettingsView() + } label: { + Image(systemName: "gearshape") + } + } + } + } + .preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil) + } +} diff --git a/LoopFollow/ViewControllers/AlarmViewController.swift b/LoopFollow/ViewControllers/AlarmViewController.swift new file mode 100644 index 000000000..17bfde9a9 --- /dev/null +++ b/LoopFollow/ViewControllers/AlarmViewController.swift @@ -0,0 +1,29 @@ +// LoopFollow +// AlarmViewController.swift +// Created by Jon Fawcett. + +import SwiftUI +import UIKit + +class AlarmViewController: UIViewController { + override func viewDidLoad() { + super.viewDidLoad() + + let alarmsView = AlarmsContainerView() + + let hostingController = UIHostingController(rootView: alarmsView) + + addChild(hostingController) + view.addSubview(hostingController.view) + + hostingController.view.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), + hostingController.view.topAnchor.constraint(equalTo: view.topAnchor), + hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + hostingController.didMove(toParent: self) + } +} diff --git a/LoopFollow/ViewControllers/MainViewController.swift b/LoopFollow/ViewControllers/MainViewController.swift index 79b202f46..769c9e909 100644 --- a/LoopFollow/ViewControllers/MainViewController.swift +++ b/LoopFollow/ViewControllers/MainViewController.swift @@ -16,6 +16,11 @@ func IsNightscoutEnabled() -> Bool { return !Storage.shared.url.value.isEmpty } +private enum SecondTab { + case remote + case alarms +} + class MainViewController: UIViewController, UITableViewDataSource, ChartViewDelegate, UNUserNotificationCenterDelegate, UIScrollViewDelegate { @IBOutlet var BGText: UILabel! @IBOutlet var DeltaText: UILabel! @@ -273,9 +278,57 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele } .store(in: &cancellables) + Storage.shared.remoteType.$value + .receive(on: DispatchQueue.main) + .sink { [weak self] remoteType in + if remoteType == .none { + // If remote is disabled, show the Alarms tab. + self?.updateSecondTab(to: .alarms) + } else { + // Otherwise, show the Remote tab. + self?.updateSecondTab(to: .remote) + } + } + .store(in: &cancellables) + updateQuickActions() } + private func updateSecondTab(to tab: SecondTab) { + guard let tabBarController = tabBarController, + var viewControllers = tabBarController.viewControllers, + viewControllers.count > 1 + else { + return + } + + let storyboard = UIStoryboard(name: "Main", bundle: nil) + let newViewController: UIViewController + let newTabBarItem: UITabBarItem + + switch tab { + case .remote: + newViewController = storyboard.instantiateViewController(withIdentifier: "RemoteViewController") + newTabBarItem = UITabBarItem( + title: "Remote", + image: UIImage(systemName: "antenna.radiowaves.left.and.right"), + tag: 1 + ) + case .alarms: + newViewController = storyboard.instantiateViewController(withIdentifier: "AlarmViewController") + newTabBarItem = UITabBarItem( + title: "Alarms", + image: UIImage(systemName: "alarm"), + tag: 1 + ) + } + + newViewController.tabBarItem = newTabBarItem + viewControllers[1] = newViewController + + tabBarController.setViewControllers(viewControllers, animated: false) + } + // Update the Home Screen Quick Action for toggling the "Speak BG" feature based on the current speakBG setting. func updateQuickActions() { let iconName = Storage.shared.speakBG.value ? "pause.circle.fill" : "play.circle.fill" From ab3b3eae371445faf79f353df28613187bd0e135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B6rkert?= Date: Sat, 5 Jul 2025 18:16:07 +0200 Subject: [PATCH 2/2] Lint fix --- LoopFollow/ViewControllers/AlarmViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopFollow/ViewControllers/AlarmViewController.swift b/LoopFollow/ViewControllers/AlarmViewController.swift index 17bfde9a9..a95f2a6a0 100644 --- a/LoopFollow/ViewControllers/AlarmViewController.swift +++ b/LoopFollow/ViewControllers/AlarmViewController.swift @@ -1,6 +1,6 @@ // LoopFollow // AlarmViewController.swift -// Created by Jon Fawcett. +// Created by Jonas Björkert. import SwiftUI import UIKit