Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions LoopFollow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
6589CC712E9E814F00BB18FE /* AlarmSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6589CC702E9E814F00BB18FE /* AlarmSelectionView.swift */; };
6589CC752E9EAFB700BB18FE /* SettingsMigrationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6589CC742E9EAFB700BB18FE /* SettingsMigrationManager.swift */; };
65E153C32E4BB69100693A4F /* URLTokenValidationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */; };
65E153C32E4BB69100693A4F /* URLTokenValidationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */; };
65E8A2862E44B0300065037B /* VolumeButtonHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E8A2852E44B0300065037B /* VolumeButtonHandler.swift */; };
DD0247592DB2E89600FCADF6 /* AlarmCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0247582DB2E89600FCADF6 /* AlarmCondition.swift */; };
DD0247712DB4337700FCADF6 /* BuildExpireCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD02475B2DB2E8FB00FCADF6 /* BuildExpireCondition.swift */; };
Expand Down Expand Up @@ -71,6 +70,7 @@
DD16AF112C997B4600FB655A /* LoadingButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD16AF102C997B4600FB655A /* LoadingButtonView.swift */; };
DD1D52B92E1EB5DC00432050 /* TabPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1D52B82E1EB5DC00432050 /* TabPosition.swift */; };
DD1D52BB2E1EB60B00432050 /* MoreMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1D52BA2E1EB60B00432050 /* MoreMenuViewController.swift */; };
DD1D52C02E4C100000000001 /* AppearanceMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1D52BF2E4C100000000001 /* AppearanceMode.swift */; };
DD2C2E4F2D3B8AF1006413A5 /* NightscoutSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2C2E4E2D3B8AEC006413A5 /* NightscoutSettingsView.swift */; };
DD2C2E512D3B8B0C006413A5 /* NightscoutSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2C2E502D3B8B0B006413A5 /* NightscoutSettingsViewModel.swift */; };
DD485F142E454B2600CE8CBF /* SecureMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD485F132E454B2600CE8CBF /* SecureMessenger.swift */; };
Expand Down Expand Up @@ -434,7 +434,6 @@
6589CC702E9E814F00BB18FE /* AlarmSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmSelectionView.swift; sourceTree = "<group>"; };
6589CC742E9EAFB700BB18FE /* SettingsMigrationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsMigrationManager.swift; sourceTree = "<group>"; };
65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLTokenValidationView.swift; sourceTree = "<group>"; };
65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLTokenValidationView.swift; sourceTree = "<group>"; };
65E8A2852E44B0300065037B /* VolumeButtonHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeButtonHandler.swift; sourceTree = "<group>"; };
A7D55B42A22051DAD69E89D0 /* Pods_LoopFollow.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LoopFollow.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DD0247582DB2E89600FCADF6 /* AlarmCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmCondition.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -472,6 +471,7 @@
DD16AF102C997B4600FB655A /* LoadingButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingButtonView.swift; sourceTree = "<group>"; };
DD1D52B82E1EB5DC00432050 /* TabPosition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabPosition.swift; sourceTree = "<group>"; };
DD1D52BA2E1EB60B00432050 /* MoreMenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreMenuViewController.swift; sourceTree = "<group>"; };
DD1D52BF2E4C100000000001 /* AppearanceMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceMode.swift; sourceTree = "<group>"; };
DD2C2E4E2D3B8AEC006413A5 /* NightscoutSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutSettingsView.swift; sourceTree = "<group>"; };
DD2C2E502D3B8B0B006413A5 /* NightscoutSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutSettingsViewModel.swift; sourceTree = "<group>"; };
DD485F132E454B2600CE8CBF /* SecureMessenger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureMessenger.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1538,6 +1538,7 @@
DD026E582EA2C8A200A39CB5 /* InsulinPrecisionManager.swift */,
656F8C112E49F3780008DC1D /* QRCodeGenerator.swift */,
DD4A407D2E6AFEE6007B318B /* AuthService.swift */,
DD1D52BF2E4C100000000001 /* AppearanceMode.swift */,
DD1D52B82E1EB5DC00432050 /* TabPosition.swift */,
DD83164B2DE4DB3A004467AA /* BinaryFloatingPoint+localized.swift */,
DD4AFB3A2DB55CB600BB593F /* TimeOfDay.swift */,
Expand Down Expand Up @@ -2144,6 +2145,7 @@
DD493AE52ACF2383009A6922 /* Treatments.swift in Sources */,
DD7F4C112DD51ED900D449E9 /* TempTargetStartAlarmEditor.swift in Sources */,
DD1D52B92E1EB5DC00432050 /* TabPosition.swift in Sources */,
DD1D52C02E4C100000000001 /* AppearanceMode.swift in Sources */,
DD50C7552D0862770057AE6F /* ContactImageUpdater.swift in Sources */,
654132EA2E19F24800BDBE08 /* TOTPGenerator.swift in Sources */,
6541341C2E1DC28000BDBE08 /* DateExtensions.swift in Sources */,
Expand Down Expand Up @@ -2211,7 +2213,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "$(LF_DEVELOPMENT_TEAM)";
DEVELOPMENT_TEAM = "$(LF_DEVELOPMENT_TEAM)";
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
Expand All @@ -2238,7 +2240,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "$(LF_DEVELOPMENT_TEAM)";
DEVELOPMENT_TEAM = "$(LF_DEVELOPMENT_TEAM)";
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Alarm/AddAlarm/AddAlarmSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ struct AddAlarmSheet: View {
}
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
}
}
2 changes: 1 addition & 1 deletion LoopFollow/Alarm/AlarmEditing/AlarmEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct AlarmEditor: View {
}
.navigationTitle(alarm.type.rawValue)
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
}

@ViewBuilder
Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Alarm/AlarmListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ struct AlarmListView: View {
Button { sheetInfo = .picker } label: { Image(systemName: "plus") }
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
}

// MARK: - Views
Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Alarm/AlarmSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ struct AlarmSettingsView: View {
}
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Alarm Settings", displayMode: .inline)
}
}
2 changes: 1 addition & 1 deletion LoopFollow/Alarm/AlarmsContainerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ struct AlarmsContainerView: View {
}
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct BackgroundRefreshSettingsView: View {
stopTimer()
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Background Refresh Settings", displayMode: .inline)
}

Expand Down
7 changes: 5 additions & 2 deletions LoopFollow/Controllers/Nightscout/DeviceStatus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,13 @@ extension MainViewController {
LoopStatusLabel.textAlignment = .right
LoopStatusLabel.font = UIFont.systemFont(ofSize: 17)

if Storage.shared.forceDarkMode.value {
switch Storage.shared.appearanceMode.value {
case .dark:
LoopStatusLabel.textColor = UIColor.white
} else {
case .light:
LoopStatusLabel.textColor = UIColor.black
case .system:
LoopStatusLabel.textColor = UIColor.label
}
}
}
Expand Down
40 changes: 40 additions & 0 deletions LoopFollow/Helpers/AppearanceMode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// LoopFollow
// AppearanceMode.swift

import SwiftUI

extension Notification.Name {
static let appearanceDidChange = Notification.Name("appearanceDidChange")
}

enum AppearanceMode: String, CaseIterable, Codable {
case system
case light
case dark

var displayName: String {
switch self {
case .system: return "System"
case .light: return "Light"
case .dark: return "Dark"
}
}

/// Returns the ColorScheme for SwiftUI's preferredColorScheme modifier
var colorScheme: ColorScheme? {
switch self {
case .system: return nil
case .light: return .light
case .dark: return .dark
}
}

/// Returns the UIUserInterfaceStyle for UIKit views
var userInterfaceStyle: UIUserInterfaceStyle {
switch self {
case .system: return .unspecified
case .light: return .light
case .dark: return .dark
}
}
}
9 changes: 4 additions & 5 deletions LoopFollow/Helpers/Views/SimpleQRCodeScannerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ struct SimpleQRCodeScannerView: UIViewControllerRepresentable {

let navController = UINavigationController(rootViewController: scannerVC)

// Apply dark mode if needed
if Storage.shared.forceDarkMode.value {
scannerVC.overrideUserInterfaceStyle = .dark
navController.overrideUserInterfaceStyle = .dark
}
// Apply appearance mode
let style = Storage.shared.appearanceMode.value.userInterfaceStyle
scannerVC.overrideUserInterfaceStyle = style
navController.overrideUserInterfaceStyle = style

return navController
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct InfoDisplaySettingsView: View {
NotificationCenter.default.post(name: NSNotification.Name("refresh"), object: nil)
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Information Display Settings", displayMode: .inline)
}
}
2 changes: 1 addition & 1 deletion LoopFollow/Log/LogView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct LogView: View {
viewModel.loadLogEntries()
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Today's Logs", displayMode: .inline)
}
}
2 changes: 1 addition & 1 deletion LoopFollow/Nightscout/NightscoutSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct NightscoutSettingsView: View {
viewModel.dismiss()
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Nightscout Settings", displayMode: .inline)
}

Expand Down
39 changes: 35 additions & 4 deletions LoopFollow/Remote/RemoteViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,42 @@ import SwiftUI
import UIKit

class RemoteViewController: UIViewController {
private var cancellable: AnyCancellable?
private var cancellables = Set<AnyCancellable>()
private var hostingController: UIHostingController<AnyView>?

override func viewDidLoad() {
super.viewDidLoad()

cancellable = Storage.shared.device.$value
// Apply initial appearance
overrideUserInterfaceStyle = Storage.shared.appearanceMode.value.userInterfaceStyle

Storage.shared.device.$value
.removeDuplicates()
.sink { [weak self] _ in
DispatchQueue.main.async {
self?.updateView()
}
}
.store(in: &cancellables)

// Listen for appearance setting changes
Storage.shared.appearanceMode.$value
.receive(on: DispatchQueue.main)
.sink { [weak self] mode in
self?.overrideUserInterfaceStyle = mode.userInterfaceStyle
self?.hostingController?.overrideUserInterfaceStyle = mode.userInterfaceStyle
}
.store(in: &cancellables)

// Listen for system appearance changes (when in System mode)
NotificationCenter.default.publisher(for: .appearanceDidChange)
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
let style = Storage.shared.appearanceMode.value.userInterfaceStyle
self?.overrideUserInterfaceStyle = style
self?.hostingController?.overrideUserInterfaceStyle = style
}
.store(in: &cancellables)
}

private func updateView() {
Expand Down Expand Up @@ -89,7 +112,15 @@ class RemoteViewController: UIViewController {
updateView()
}

deinit {
cancellable?.cancel()
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

if Storage.shared.appearanceMode.value == .system,
previousTraitCollection?.userInterfaceStyle != traitCollection.userInterfaceStyle
{
let style = Storage.shared.appearanceMode.value.userInterfaceStyle
overrideUserInterfaceStyle = style
hostingController?.overrideUserInterfaceStyle = style
}
}
}
2 changes: 1 addition & 1 deletion LoopFollow/Remote/Settings/RemoteSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ struct RemoteSettingsView: View {
// The sheet will be shown automatically due to the binding
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationTitle("Remote Settings")
.navigationBarTitleDisplayMode(.inline)
}
Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Settings/AdvancedSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct AdvancedSettingsView: View {
}
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Advanced Settings", displayMode: .inline)
}
}
2 changes: 1 addition & 1 deletion LoopFollow/Settings/CalendarSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct CalendarSettingsView: View {
await requestCalendarAccessAndLoad()
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Calendar", displayMode: .inline)
}

Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Settings/ContactSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ struct ContactSettingsView: View {
Alert(title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("OK")))
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Contact", displayMode: .inline)
}

Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Settings/DexcomSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct DexcomSettingsView: View {
importSection
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Dexcom Settings", displayMode: .inline)
}

Expand Down
10 changes: 7 additions & 3 deletions LoopFollow/Settings/GeneralSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SwiftUI
struct GeneralSettingsView: View {
@ObservedObject var colorBGText = Storage.shared.colorBGText
@ObservedObject var appBadge = Storage.shared.appBadge
@ObservedObject var forceDarkMode = Storage.shared.forceDarkMode
@ObservedObject var appearanceMode = Storage.shared.appearanceMode
@ObservedObject var showStats = Storage.shared.showStats
@ObservedObject var useIFCC = Storage.shared.useIFCC
@ObservedObject var showSmallGraph = Storage.shared.showSmallGraph
Expand Down Expand Up @@ -36,7 +36,11 @@ struct GeneralSettingsView: View {
}

Section("Display") {
Toggle("Force Dark Mode (restart app)", isOn: $forceDarkMode.value)
Picker("Appearance", selection: $appearanceMode.value) {
ForEach(AppearanceMode.allCases, id: \.self) { mode in
Text(mode.displayName).tag(mode)
}
}
Toggle("Display Stats", isOn: $showStats.value)
Toggle("Use IFCC A1C", isOn: $useIFCC.value)
Toggle("Display Small Graph", isOn: $showSmallGraph.value)
Expand Down Expand Up @@ -115,7 +119,7 @@ struct GeneralSettingsView: View {
}
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("General Settings", displayMode: .inline)
}
}
2 changes: 1 addition & 1 deletion LoopFollow/Settings/GraphSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct GraphSettingsView: View {
}
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
.navigationBarTitle("Graph Settings", displayMode: .inline)
}

Expand Down
2 changes: 1 addition & 1 deletion LoopFollow/Settings/TabCustomizationModal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ struct TabCustomizationModal: View {
}
}
}
.preferredColorScheme(Storage.shared.forceDarkMode.value ? .dark : nil)
.preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
}

private func checkForChanges() {
Expand Down
Loading