From 8eb224a6df92cd03da7b323b08686423d849a67a Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:37:35 -0800 Subject: [PATCH 01/20] #106 --- ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift | 4 ++-- ENGAGEHF/SharedExtensions/Account+Binding.swift | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift b/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift index bed50096..979b0eea 100644 --- a/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift +++ b/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift @@ -31,7 +31,7 @@ enum SymptomsType: String, CaseIterable, Identifiable, CustomStringConvertible, case .physical: "Physical" case .social: "Social" case .quality: "Quality" - case .specific: "Specific" + case .specific: "Symptoms" case .dizziness: "Dizziness" } } @@ -44,7 +44,7 @@ enum SymptomsType: String, CaseIterable, Identifiable, CustomStringConvertible, case .physical: "Physical Limits Score" case .social: "Social Limits Score" case .quality: "Quality of Life Score" - case .specific: "Specific Symptoms Score" + case .specific: "Symptom Frequency Score" case .dizziness: "Dizziness Score" } } diff --git a/ENGAGEHF/SharedExtensions/Account+Binding.swift b/ENGAGEHF/SharedExtensions/Account+Binding.swift index 56d53637..8e1866d8 100644 --- a/ENGAGEHF/SharedExtensions/Account+Binding.swift +++ b/ENGAGEHF/SharedExtensions/Account+Binding.swift @@ -11,6 +11,7 @@ import SpeziViews import SwiftUI extension Account { + // TODO: Talk to Andreas about putting this into SpeziAccount. @MainActor func detailsBinding( for key: Key.Type, From 0711bbd76c61b68dd8281e2c75bfdce88c080e0a Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:18:42 -0800 Subject: [PATCH 02/20] Update UI Tests for #106 --- ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift b/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift index c7e982e9..9862a13e 100644 --- a/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift +++ b/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift @@ -277,15 +277,15 @@ extension XCUIApplication { } fileprivate func testEmptySymptomScores() { - XCTAssert(buttons["Symptoms"].waitForExistence(timeout: 0.5)) - buttons["Symptoms"].tap() + XCTAssert(buttons["Symptoms"].firstMatch.waitForExistence(timeout: 0.5)) + buttons["Symptoms"].firstMatch.tap() let symptomTypes = [ "Overall", "Physical Limits", "Social Limits", "Quality of Life", - "Specific Symptoms", + "Symptom Frequency", "Dizziness" ] let symptomLabels = [ @@ -293,7 +293,7 @@ extension XCUIApplication { "Physical", "Social", "Quality", - "Specific", + "Symptoms", "Dizziness" ] @@ -306,8 +306,8 @@ extension XCUIApplication { XCTAssert(buttons["\(symptomTypes[idx]) Score, Symptoms Picker Chevron"].waitForExistence(timeout: 0.5)) images["Symptoms Picker Chevron"].tap() - XCTAssert(buttons["\(symptomLabels[nextIdx])"].waitForExistence(timeout: 0.5)) - buttons["\(symptomLabels[nextIdx])"].tap() + XCTAssert(buttons["\(symptomLabels[nextIdx])"].firstMatch.waitForExistence(timeout: 0.5)) + buttons["\(symptomLabels[nextIdx])"].firstMatch.tap() testEmptyForSpecificType(scoreType: symptomTypes[nextIdx]) } From 935642ed9a2ee35e928b0d13c755882d5f2704f0 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:33:13 -0800 Subject: [PATCH 03/20] Update Account+Binding.swift --- ENGAGEHF/SharedExtensions/Account+Binding.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/ENGAGEHF/SharedExtensions/Account+Binding.swift b/ENGAGEHF/SharedExtensions/Account+Binding.swift index 8e1866d8..56d53637 100644 --- a/ENGAGEHF/SharedExtensions/Account+Binding.swift +++ b/ENGAGEHF/SharedExtensions/Account+Binding.swift @@ -11,7 +11,6 @@ import SpeziViews import SwiftUI extension Account { - // TODO: Talk to Andreas about putting this into SpeziAccount. @MainActor func detailsBinding( for key: Key.Type, From afb82f25edf2cc4943cb05f02585c6b8bbf2699e Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:48:47 -0800 Subject: [PATCH 04/20] #116 --- .../Symptoms/AnyAxisContent+CustomAxes.swift | 30 ++++++++++++++++++- ENGAGEHF/Resources/Localizable.xcstrings | 18 +++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/ENGAGEHF/HeartHealth/Symptoms/AnyAxisContent+CustomAxes.swift b/ENGAGEHF/HeartHealth/Symptoms/AnyAxisContent+CustomAxes.swift index 7c8fa314..60fed692 100644 --- a/ENGAGEHF/HeartHealth/Symptoms/AnyAxisContent+CustomAxes.swift +++ b/ENGAGEHF/HeartHealth/Symptoms/AnyAxisContent+CustomAxes.swift @@ -24,12 +24,40 @@ extension AnyAxisContent { } } + // Dizziness scores range between 0 and 5, and each has a specific desired label. + @AxisContentBuilder private static var dizzinessYAxisModifierBuilder: some AxisContent { + AxisMarks(values: [0, 1, 2, 3, 4, 5]) { value in + switch value.as(Int.self) { + case 5: + AxisValueLabel("Very Severe") + case 4: + AxisValueLabel("Severe") + case 3: + AxisValueLabel("Moderate") + case 2: + AxisValueLabel("Mild") + case 1: + AxisValueLabel("Minimal") + case 0: + AxisValueLabel("None") + default: + AxisValueLabel("") + } + } + + AxisMarks( + values: [0, 1, 2, 3, 4, 5] + ) { + AxisGridLine() + } + } + static var percentageYAxisModifier: AnyAxisContent { AnyAxisContent(percentageYAxisModifierBuilder) } static var dizzinessYAxisModifier: AnyAxisContent { - AnyAxisContent(AxisMarks(values: .automatic(desiredCount: 5))) + AnyAxisContent(dizzinessYAxisModifierBuilder) } } diff --git a/ENGAGEHF/Resources/Localizable.xcstrings b/ENGAGEHF/Resources/Localizable.xcstrings index 7318fc41..5c599bc5 100644 --- a/ENGAGEHF/Resources/Localizable.xcstrings +++ b/ENGAGEHF/Resources/Localizable.xcstrings @@ -407,6 +407,15 @@ }, "Messages" : { + }, + "Mild" : { + + }, + "Minimal" : { + + }, + "Moderate" : { + }, "No Contacts Available" : { @@ -425,6 +434,9 @@ }, "No vitals" : { + }, + "None" : { + }, "Not on this med that may help your heart." : { "comment" : "No action required legend entry." @@ -541,6 +553,9 @@ }, "Series" : { + }, + "Severe" : { + }, "Share Link" : { @@ -707,6 +722,9 @@ } } } + }, + "Very Severe" : { + }, "Vitals" : { From 23f6958d5e2ba3f04a6fa3800f934cc0f1e7c7a0 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:52:03 -0800 Subject: [PATCH 05/20] #113 General medication styling. --- .../xcshareddata/swiftpm/Package.resolved | 58 +++++++++---------- .../MedicationDetails.swift | 4 +- .../MedicationsManager.swift | 19 +++++- .../ColorKeyEntryView.swift | 4 +- .../Medications/RecommendationStyle.swift | 7 ++- ENGAGEHF/Resources/Localizable.xcstrings | 3 + .../Dashboard/RecentVitalsUITests.swift | 2 + 7 files changed, 60 insertions(+), 37 deletions(-) diff --git a/ENGAGEHF.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ENGAGEHF.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1b1a331c..98fd4ca6 100644 --- a/ENGAGEHF.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ENGAGEHF.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -60,8 +60,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk.git", "state" : { - "revision" : "1fc52ab0e172e7c5a961f975a76c2611f4f22852", - "version" : "11.2.0" + "revision" : "dbdfdc44bee8b8e4eaa5ec27eb12b9338f3f2bc1", + "version" : "11.5.0" } }, { @@ -69,8 +69,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { - "revision" : "07a2f57d147d2bf368a0d2dcb5579ff082d9e44f", - "version" : "11.1.0" + "revision" : "4f234bcbdae841d7015258fbbf8e7743a39b8200", + "version" : "11.4.0" } }, { @@ -186,8 +186,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/Spezi", "state" : { - "revision" : "d5c8eec55255fd753367422c49db1ec16610c48b", - "version" : "1.7.4" + "revision" : "4513a697572e8e1faea1e0ee52e6fad4b8d3dd8d", + "version" : "1.8.0" } }, { @@ -195,8 +195,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziAccount.git", "state" : { - "revision" : "397a55a7b0f108088d3db510ee48fc974a322c87", - "version" : "2.0.0-beta.8" + "revision" : "0e4dcc7d3284b439b17fae621c5c6e73d9213696", + "version" : "2.1.0" } }, { @@ -204,8 +204,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziBluetooth.git", "state" : { - "revision" : "8ee8ba902cff833aa6a6062fc8433e5d0e0338f3", - "version" : "3.0.1" + "revision" : "977cc675d8c2dca51eabd52dc0e9476702c678eb", + "version" : "3.1.0" } }, { @@ -222,8 +222,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziDevices.git", "state" : { - "revision" : "dc8dcd53773b9bb4041870b0f65cec32f7ed5108", - "version" : "1.3.0" + "revision" : "397c0e8217350a32621a3e6abdec0d86f8c651a6", + "version" : "1.4.1" } }, { @@ -231,8 +231,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziFirebase.git", "state" : { - "revision" : "5aae93f567091b29f7683863baa2241f7c95290d", - "version" : "2.0.0-beta.4" + "revision" : "7c6829624884f6f1d700e0316b2580b39d3b0c5f", + "version" : "2.0.0" } }, { @@ -240,8 +240,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziFoundation", "state" : { - "revision" : "17bd0e03e69e0cc722d4cd28148d04443f4e2aba", - "version" : "2.0.0-beta.2" + "revision" : "5b4ad1b343154b52a68c33a6bfe02d9cb07cb9dc", + "version" : "2.0.0" } }, { @@ -267,8 +267,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziNetworking", "state" : { - "revision" : "26f1ed49e1916ae4fdc1bd033127a873a9e6dd0a", - "version" : "2.1.3" + "revision" : "89fad797897bb741fc148027859c1bab3129999a", + "version" : "2.2.0" } }, { @@ -294,8 +294,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziStorage.git", "state" : { - "revision" : "60962375bbce7cc0599bc3da4ebda08231922371", - "version" : "1.2.0" + "revision" : "0f4a54430e51f82d29da63a7ce5f61bad7dfb9cd", + "version" : "1.2.1" } }, { @@ -303,8 +303,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziViews.git", "state" : { - "revision" : "427f4f3a7acb0e00ea11c4c3ca7b60e36d2557a0", - "version" : "1.6.0" + "revision" : "f87514406bb57ae67d0040eec5454fff55104143", + "version" : "1.7.0" } }, { @@ -364,10 +364,10 @@ { "identity" : "swift-syntax", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", + "location" : "https://github.com/swiftlang/swift-syntax.git", "state" : { - "revision" : "2bc86522d115234d1f588efe2bcb4ce4be8f8b82", - "version" : "510.0.3" + "revision" : "cb53fa1bd3219b0b23ded7dfdd3b2baff266fd25", + "version" : "600.0.0" } }, { @@ -384,8 +384,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/realm/SwiftLint.git", "state" : { - "revision" : "b515723b16eba33f15c4677ee65f3fef2ce8c255", - "version" : "0.55.1" + "revision" : "25f2776977e663305bee71309ea1e34d435065f1", + "version" : "0.57.1" } }, { @@ -411,8 +411,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordBDHG/XCTestExtensions.git", "state" : { - "revision" : "aad6c161a09d658f30c7170deb4a61e8916a4a4c", - "version" : "1.0.0" + "revision" : "5379d70249cae926927105bfb6686770f03ee5b9", + "version" : "1.1.0" } }, { diff --git a/ENGAGEHF/Managers/MedicationsManager/MedicationDetails.swift b/ENGAGEHF/Managers/MedicationsManager/MedicationDetails.swift index 71caddc2..11ebbe5e 100644 --- a/ENGAGEHF/Managers/MedicationsManager/MedicationDetails.swift +++ b/ENGAGEHF/Managers/MedicationsManager/MedicationDetails.swift @@ -26,8 +26,8 @@ enum MedicationRecommendationType: String, Decodable, Comparable { case .targetDoseReached: .targetReached case .personalTargetDoseReached: .targetReached case .improvementAvailable: .improvementAvailable - case .moreLabObservationsRequired: .improvementAvailable - case .morePatientObservationsRequired: .improvementAvailable + case .moreLabObservationsRequired: .actionRequired + case .morePatientObservationsRequired: .actionRequired case .noActionRequired: .notStarted case .notStarted: .notStarted } diff --git a/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift b/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift index 73f10835..6233c9ed 100644 --- a/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift +++ b/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift @@ -183,7 +183,7 @@ extension MedicationsManager { unit: "mg" ) ), - // Multi-ingredient, single schedule, at minimum dose + // Multi-ingredient, single schedule, at minimum dose, improvement available. MedicationDetails( id: UUID().uuidString, title: "Sacubitril-Valsartan", @@ -197,7 +197,8 @@ extension MedicationsManager { unit: "mg" ) ), - // Single ingredient, below minimum dose, non-integer frequency + // Single ingredient, below minimum dose, non-integer frequency. + // Not on the med, but action required. MedicationDetails( id: UUID().uuidString, title: "Spironolactone", @@ -211,6 +212,20 @@ extension MedicationsManager { unit: "mg" ) ), + // On the med but action required. + MedicationDetails( + id: UUID().uuidString, + title: "Dapagliflozin", + subtitle: "SGLT2i", + description: "More lab observations required for recommendations.", + videoPath: nil, + type: .moreLabObservationsRequired, + dosageInformation: DosageInformation( + currentSchedule: [DoseSchedule(frequency: 1.5, quantity: [15])], + targetSchedule: [DoseSchedule(frequency: 1.5, quantity: [25])], + unit: "mg" + ) + ), // Single ingredient, single schedule, not started yet MedicationDetails( id: UUID().uuidString, diff --git a/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift b/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift index 7dae74ba..a107ed4e 100644 --- a/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift +++ b/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift @@ -15,10 +15,10 @@ struct ColorKeyEntryView: View { var body: some View { - HStack { + HStack(alignment: .center) { Circle() .fill(color) - .frame(width: 12) + .frame(width: 24) Text(interpretation) } } diff --git a/ENGAGEHF/Medications/RecommendationStyle.swift b/ENGAGEHF/Medications/RecommendationStyle.swift index 1174eee7..7685de2f 100644 --- a/ENGAGEHF/Medications/RecommendationStyle.swift +++ b/ENGAGEHF/Medications/RecommendationStyle.swift @@ -11,14 +11,15 @@ import SwiftUI /// Defines the color and interpretation associated with a `MedicationRecommendation` in the UI. enum RecommendationStyle: CaseIterable { - case targetReached, improvementAvailable, notStarted + case targetReached, improvementAvailable, actionRequired, notStarted var color: Color { switch self { case .targetReached: .green case .improvementAvailable: .yellow - case .notStarted: .blue + case .actionRequired: .blue.opacity(0.6) + case .notStarted: .accent.opacity(0.6) } } @@ -28,6 +29,8 @@ enum RecommendationStyle: CaseIterable { String(localized: "You're on your target dose.", comment: "Target dose reached color legend entry.") case .improvementAvailable: String(localized: "On the med but may benefit from a higher dose.", comment: "Improvement available color legend entry.") + case .actionRequired: + String(localized: "More information is needed to make a recommendation.", comment: "Action required color legend entry.") case .notStarted: String(localized: "Not on this med that may help your heart.", comment: "No action required legend entry.") } diff --git a/ENGAGEHF/Resources/Localizable.xcstrings b/ENGAGEHF/Resources/Localizable.xcstrings index 5c599bc5..75225a23 100644 --- a/ENGAGEHF/Resources/Localizable.xcstrings +++ b/ENGAGEHF/Resources/Localizable.xcstrings @@ -416,6 +416,9 @@ }, "Moderate" : { + }, + "More information is needed to make a recommendation." : { + "comment" : "Action required color legend entry." }, "No Contacts Available" : { diff --git a/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift b/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift index 1d095e42..db6d205c 100644 --- a/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift +++ b/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift @@ -64,6 +64,8 @@ final class RecentVitalsUITests: XCTestCase { XCTAssert(app.staticTexts["Body Weight"].waitForExistence(timeout: 2.0)) } + // TODO: Reproduce Development UI tests with same simulator, iOS version, XCode version. Tag Andreas today/tmrw about infinite sign up. + func testHeartRateAndBloodPressure() throws { let app = XCUIApplication() From ac11371e26c04737bd574ba034ada9069e6111e7 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:53:09 -0800 Subject: [PATCH 06/20] #110 --- ENGAGEHF.xcodeproj/project.pbxproj | 4 +++ .../Managers/VideoManager/VideoManager.swift | 9 ++++++ .../FirebaseAuth+Continuation.swift | 29 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift diff --git a/ENGAGEHF.xcodeproj/project.pbxproj b/ENGAGEHF.xcodeproj/project.pbxproj index 0f06be49..88afe4bb 100644 --- a/ENGAGEHF.xcodeproj/project.pbxproj +++ b/ENGAGEHF.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 211755492CC1B58600A81E24 /* ColorLegend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211755482CC1B58300A81E24 /* ColorLegend.swift */; }; 2117554B2CC1B7E400A81E24 /* RecommendationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2117554A2CC1B7C500A81E24 /* RecommendationStyle.swift */; }; 2117554D2CC1D3AB00A81E24 /* ExpandableSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2117554C2CC1D39900A81E24 /* ExpandableSection.swift */; }; + 21193C8E2CF6AAD000D44B23 /* FirebaseAuth+Continuation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21193C8D2CF6AAC900D44B23 /* FirebaseAuth+Continuation.swift */; }; 213AD98D2CBDF74A005C6D69 /* MedicationsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 213AD98C2CBDF744005C6D69 /* MedicationsSection.swift */; }; 213AD9942CBE02BB005C6D69 /* ColorKeyEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 213AD9922CBE02B1005C6D69 /* ColorKeyEntryView.swift */; }; 2F49B7762980407C00BCB272 /* Spezi in Frameworks */ = {isa = PBXBuildFile; productRef = 2F49B7752980407B00BCB272 /* Spezi */; }; @@ -245,6 +246,7 @@ 211755482CC1B58300A81E24 /* ColorLegend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorLegend.swift; sourceTree = ""; }; 2117554A2CC1B7C500A81E24 /* RecommendationStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendationStyle.swift; sourceTree = ""; }; 2117554C2CC1D39900A81E24 /* ExpandableSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableSection.swift; sourceTree = ""; }; + 21193C8D2CF6AAC900D44B23 /* FirebaseAuth+Continuation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FirebaseAuth+Continuation.swift"; sourceTree = ""; }; 213AD98C2CBDF744005C6D69 /* MedicationsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MedicationsSection.swift; sourceTree = ""; }; 213AD9922CBE02B1005C6D69 /* ColorKeyEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorKeyEntryView.swift; sourceTree = ""; }; 2F4E237D2989A2FE0013F3D9 /* LaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchTests.swift; sourceTree = ""; }; @@ -887,6 +889,7 @@ 9B1864872C9226E90042AC81 /* AccountDetails+Key.swift */, 9B18648A2C9227040042AC81 /* AccountNotifications+Extras.swift */, 9B1864972C9350D30042AC81 /* Account+Binding.swift */, + 21193C8D2CF6AAC900D44B23 /* FirebaseAuth+Continuation.swift */, ); path = SharedExtensions; sourceTree = ""; @@ -1484,6 +1487,7 @@ 4D0F38A22C0A7AD900DA12F7 /* ExpandableText.swift in Sources */, 4D8CE0FD2C753A4700560327 /* NotificationRegistrationSchema.swift in Sources */, 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */, + 21193C8E2CF6AAD000D44B23 /* FirebaseAuth+Continuation.swift in Sources */, 4D8402702C4EBE7D00817495 /* AddMeasurementView.swift in Sources */, 2117554D2CC1D3AB00A81E24 /* ExpandableSection.swift in Sources */, 4D2D1D602C2B859C00ABDC19 /* GraphPicker.swift in Sources */, diff --git a/ENGAGEHF/Managers/VideoManager/VideoManager.swift b/ENGAGEHF/Managers/VideoManager/VideoManager.swift index feb5773d..1750b753 100644 --- a/ENGAGEHF/Managers/VideoManager/VideoManager.swift +++ b/ENGAGEHF/Managers/VideoManager/VideoManager.swift @@ -6,12 +6,14 @@ // SPDX-License-Identifier: MIT // +import FirebaseAuth import FirebaseFirestore import Foundation import OSLog import Spezi import SpeziAccount + @Observable @MainActor final class VideoManager: Module, EnvironmentAccessible, DefaultInitializable { @@ -43,6 +45,13 @@ final class VideoManager: Module, EnvironmentAccessible, DefaultInitializable { } if event.newEnrolledAccountDetails != nil { + // Refresh Firebase token to ensure proper permissions for accessing educational videos. + // TODO: Reproduce error to test if this workaround fixes it. + do { + try await Auth.auth().getToken(forcingRefresh: true) + } catch { + logger.error("Failed to get token: \(error.localizedDescription)") + } videoCollections = await getVideoSections() } else if event.accountDetails == nil { videoCollections = [] diff --git a/ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift b/ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift new file mode 100644 index 00000000..b076d6f2 --- /dev/null +++ b/ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift @@ -0,0 +1,29 @@ +// +// This source file is part of the ENGAGE-HF project based on the Stanford Spezi Template Application project +// +// SPDX-FileCopyrightText: 2023 Stanford University +// +// SPDX-License-Identifier: MIT +// + +import FirebaseAuth +import Foundation + + +extension Auth { + @discardableResult + func getToken(forcingRefresh: Bool = false) async throws -> String { + try await withCheckedThrowingContinuation { continuation in + self.getToken(forcingRefresh: forcingRefresh) { token, error in + switch (token, error) { + case let (.some(token), _): + continuation.resume(returning: token) + case let (_, .some(error)): + continuation.resume(throwing: error) + case (.none, .none): + continuation.resume(throwing: AuthErrorCode.nullUser) + } + } + } + } +} From 50b37e032e12f0b88658338631df919c3a0af40f Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:12:16 -0800 Subject: [PATCH 07/20] Remove TODO --- ENGAGEHF/Managers/VideoManager/VideoManager.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/ENGAGEHF/Managers/VideoManager/VideoManager.swift b/ENGAGEHF/Managers/VideoManager/VideoManager.swift index 1750b753..9e403f2e 100644 --- a/ENGAGEHF/Managers/VideoManager/VideoManager.swift +++ b/ENGAGEHF/Managers/VideoManager/VideoManager.swift @@ -46,7 +46,6 @@ final class VideoManager: Module, EnvironmentAccessible, DefaultInitializable { if event.newEnrolledAccountDetails != nil { // Refresh Firebase token to ensure proper permissions for accessing educational videos. - // TODO: Reproduce error to test if this workaround fixes it. do { try await Auth.auth().getToken(forcingRefresh: true) } catch { From 9802e2093c880cb795d66f78da89a7eca10637a1 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:13:29 -0800 Subject: [PATCH 08/20] Remove TODO --- ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift b/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift index db6d205c..1d095e42 100644 --- a/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift +++ b/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift @@ -64,8 +64,6 @@ final class RecentVitalsUITests: XCTestCase { XCTAssert(app.staticTexts["Body Weight"].waitForExistence(timeout: 2.0)) } - // TODO: Reproduce Development UI tests with same simulator, iOS version, XCode version. Tag Andreas today/tmrw about infinite sign up. - func testHeartRateAndBloodPressure() throws { let app = XCUIApplication() From 35495e1b49841f9b8819c050448225fdab0e9039 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:25:19 -0800 Subject: [PATCH 09/20] Remove template text from onboarding. --- ENGAGEHF/Resources/Localizable.xcstrings | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/ENGAGEHF/Resources/Localizable.xcstrings b/ENGAGEHF/Resources/Localizable.xcstrings index 75225a23..95adecdf 100644 --- a/ENGAGEHF/Resources/Localizable.xcstrings +++ b/ENGAGEHF/Resources/Localizable.xcstrings @@ -78,7 +78,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "The ENGAGE-HF demonstrates the usage of the Firebase Account Module." + "value" : "Sign in or create an account." } } } @@ -148,18 +148,6 @@ }, "Cancel" : { - }, - "CLOSE" : { - "comment" : "MARK: General", - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Close" - } - } - } }, "Color Key" : { From 7154a7854678854ff5f13f72ef586cb0bc009a8b Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Tue, 3 Dec 2024 17:54:11 -0800 Subject: [PATCH 10/20] Update Fastfile --- fastlane/Fastfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 9ae50e34..ea9cfe8d 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -20,7 +20,7 @@ platform :ios do skip_build: true, derived_data_path: ".derivedData", code_coverage: true, - devices: ["iPhone 15 Pro"], + devices: ["iPhone 16 Pro"], disable_slide_to_type: false, concurrent_workers: 1, max_concurrent_simulators: 1, From 2912056e171b8c7dbfc46b20fb4a1217961d5826 Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Tue, 3 Dec 2024 23:42:48 -0800 Subject: [PATCH 11/20] Fix UI Tests --- ENGAGEHF/Account/InvitationCodeModule.swift | 1 + .../Dashboard/RecentVitalsUITests.swift | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ENGAGEHF/Account/InvitationCodeModule.swift b/ENGAGEHF/Account/InvitationCodeModule.swift index 9c9f36e3..f905ee8f 100644 --- a/ENGAGEHF/Account/InvitationCodeModule.swift +++ b/ENGAGEHF/Account/InvitationCodeModule.swift @@ -100,6 +100,7 @@ class InvitationCodeModule: Module, EnvironmentAccessible { details.password = password details.name = PersonNameComponents(givenName: "Leland", familyName: "Stanford") try await accountService.signUp(with: details) + try await Task.sleep(for: .seconds(0.5)) try await verifyOnboardingCode(invitationCode) } catch { logger.error("Failed setting up test account : \(error)") diff --git a/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift b/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift index 1d095e42..96e577f0 100644 --- a/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift +++ b/ENGAGEHFUITests/Dashboard/RecentVitalsUITests.swift @@ -9,6 +9,16 @@ import XCTest final class RecentVitalsUITests: XCTestCase { + private var expectedFormattedMeasurementDate: String { + let expectedDateComponents = DateComponents(year: 2024, month: 6, day: 5, hour: 12, minute: 33, second: 11) + let expectedDate = Calendar.current.date(from: expectedDateComponents) ?? .now + let daylightSavingTimeOffset = TimeZone.current.daylightSavingTimeOffset(for: expectedDate) + let formatter = DateFormatter() + formatter.dateFormat = "M/d/yyyy, h:mm a" + return formatter.string(from: expectedDate.addingTimeInterval(daylightSavingTimeOffset)) + } + + override func setUpWithError() throws { try super.setUpWithError() @@ -58,7 +68,7 @@ final class RecentVitalsUITests: XCTestCase { XCTAssert(app.staticTexts["Recent Vitals"].waitForExistence(timeout: 0.5)) XCTAssert(app.staticTexts["Weight Quantity: \(expectedWeight)"].exists) XCTAssert(app.staticTexts["Weight Unit: \(weightUnit)"].exists) - XCTAssert(app.staticTexts["Weight Date: 6/5/2024, 12:33 PM"].exists) + XCTAssert(app.staticTexts["Weight Date: \(expectedFormattedMeasurementDate)"].exists) app.staticTexts["Weight Quantity: \(expectedWeight)"].tap() XCTAssert(app.staticTexts["Body Weight"].waitForExistence(timeout: 2.0)) @@ -103,7 +113,7 @@ final class RecentVitalsUITests: XCTestCase { let heartRateQuantityText = "Heart Rate Quantity: 62" XCTAssert(app.staticTexts[heartRateQuantityText].exists) XCTAssert(app.staticTexts["Heart Rate Unit: BPM"].exists) - XCTAssert(app.staticTexts["Heart Rate Date: 6/5/2024, 12:33 PM"].exists) + XCTAssert(app.staticTexts["Heart Rate Date: \(expectedFormattedMeasurementDate)"].exists) app.staticTexts[heartRateQuantityText].tap() XCTAssert(app.staticTexts["Heart Rate"].waitForExistence(timeout: 2.0)) @@ -114,7 +124,7 @@ final class RecentVitalsUITests: XCTestCase { let bloodPressureQuantityText = "Blood Pressure Quantity: 103/64" XCTAssert(app.staticTexts[bloodPressureQuantityText].exists) XCTAssert(app.staticTexts["Blood Pressure Unit: mmHg"].exists) - XCTAssert(app.staticTexts["Blood Pressure Date: 6/5/2024, 12:33 PM"].exists) + XCTAssert(app.staticTexts["Blood Pressure Date: \(expectedFormattedMeasurementDate)"].exists) app.staticTexts[bloodPressureQuantityText].tap() XCTAssert(app.staticTexts["Blood Pressure"].waitForExistence(timeout: 2.0)) From 904fcb88ec4e5bcf29002924c63781a8d9e4cb65 Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Wed, 4 Dec 2024 00:24:54 -0800 Subject: [PATCH 12/20] Reduice Dif --- ENGAGEHF/Account/InvitationCodeModule.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/ENGAGEHF/Account/InvitationCodeModule.swift b/ENGAGEHF/Account/InvitationCodeModule.swift index f905ee8f..9c9f36e3 100644 --- a/ENGAGEHF/Account/InvitationCodeModule.swift +++ b/ENGAGEHF/Account/InvitationCodeModule.swift @@ -100,7 +100,6 @@ class InvitationCodeModule: Module, EnvironmentAccessible { details.password = password details.name = PersonNameComponents(givenName: "Leland", familyName: "Stanford") try await accountService.signUp(with: details) - try await Task.sleep(for: .seconds(0.5)) try await verifyOnboardingCode(invitationCode) } catch { logger.error("Failed setting up test account : \(error)") From d6f8cc6b94202a03ed477358fd7c88d871368778 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:47:11 -0800 Subject: [PATCH 13/20] Undo initial attempt at fixing token refresh --- ENGAGEHF.xcodeproj/project.pbxproj | 4 --- .../Managers/VideoManager/VideoManager.swift | 6 ---- ENGAGEHF/Resources/Localizable.xcstrings | 6 ++-- .../FirebaseAuth+Continuation.swift | 29 ------------------- 4 files changed, 3 insertions(+), 42 deletions(-) delete mode 100644 ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift diff --git a/ENGAGEHF.xcodeproj/project.pbxproj b/ENGAGEHF.xcodeproj/project.pbxproj index 4888f09e..c7cd868b 100644 --- a/ENGAGEHF.xcodeproj/project.pbxproj +++ b/ENGAGEHF.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 211755492CC1B58600A81E24 /* ColorLegend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211755482CC1B58300A81E24 /* ColorLegend.swift */; }; 2117554B2CC1B7E400A81E24 /* RecommendationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2117554A2CC1B7C500A81E24 /* RecommendationStyle.swift */; }; 2117554D2CC1D3AB00A81E24 /* ExpandableSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2117554C2CC1D39900A81E24 /* ExpandableSection.swift */; }; - 21193C8E2CF6AAD000D44B23 /* FirebaseAuth+Continuation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21193C8D2CF6AAC900D44B23 /* FirebaseAuth+Continuation.swift */; }; 213AD98D2CBDF74A005C6D69 /* MedicationsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 213AD98C2CBDF744005C6D69 /* MedicationsSection.swift */; }; 213AD9942CBE02BB005C6D69 /* ColorKeyEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 213AD9922CBE02B1005C6D69 /* ColorKeyEntryView.swift */; }; 21B93B782D039E310034EC86 /* ManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21B93B772D039E1B0034EC86 /* ManagerProtocol.swift */; }; @@ -248,7 +247,6 @@ 211755482CC1B58300A81E24 /* ColorLegend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorLegend.swift; sourceTree = ""; }; 2117554A2CC1B7C500A81E24 /* RecommendationStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendationStyle.swift; sourceTree = ""; }; 2117554C2CC1D39900A81E24 /* ExpandableSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableSection.swift; sourceTree = ""; }; - 21193C8D2CF6AAC900D44B23 /* FirebaseAuth+Continuation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FirebaseAuth+Continuation.swift"; sourceTree = ""; }; 213AD98C2CBDF744005C6D69 /* MedicationsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MedicationsSection.swift; sourceTree = ""; }; 213AD9922CBE02B1005C6D69 /* ColorKeyEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorKeyEntryView.swift; sourceTree = ""; }; 21B93B772D039E1B0034EC86 /* ManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagerProtocol.swift; sourceTree = ""; }; @@ -894,7 +892,6 @@ 9B1864872C9226E90042AC81 /* AccountDetails+Key.swift */, 9B18648A2C9227040042AC81 /* AccountNotifications+Extras.swift */, 9B1864972C9350D30042AC81 /* Account+Binding.swift */, - 21193C8D2CF6AAC900D44B23 /* FirebaseAuth+Continuation.swift */, ); path = SharedExtensions; sourceTree = ""; @@ -1494,7 +1491,6 @@ 4D0F38A22C0A7AD900DA12F7 /* ExpandableText.swift in Sources */, 4D8CE0FD2C753A4700560327 /* NotificationRegistrationSchema.swift in Sources */, 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */, - 21193C8E2CF6AAD000D44B23 /* FirebaseAuth+Continuation.swift in Sources */, 4D8402702C4EBE7D00817495 /* AddMeasurementView.swift in Sources */, 2117554D2CC1D3AB00A81E24 /* ExpandableSection.swift in Sources */, 4D2D1D602C2B859C00ABDC19 /* GraphPicker.swift in Sources */, diff --git a/ENGAGEHF/Managers/VideoManager/VideoManager.swift b/ENGAGEHF/Managers/VideoManager/VideoManager.swift index 51db457b..0240b5d5 100644 --- a/ENGAGEHF/Managers/VideoManager/VideoManager.swift +++ b/ENGAGEHF/Managers/VideoManager/VideoManager.swift @@ -45,12 +45,6 @@ final class VideoManager: Manager { } if event.newEnrolledAccountDetails != nil { - // Refresh Firebase token to ensure proper permissions for accessing educational videos. - do { - try await Auth.auth().getToken(forcingRefresh: true) - } catch { - logger.error("Failed to get token: \(error.localizedDescription)") - } videoCollections = await getVideoSections() } else if event.accountDetails == nil { videoCollections = [] diff --git a/ENGAGEHF/Resources/Localizable.xcstrings b/ENGAGEHF/Resources/Localizable.xcstrings index daaefae6..f886fc68 100644 --- a/ENGAGEHF/Resources/Localizable.xcstrings +++ b/ENGAGEHF/Resources/Localizable.xcstrings @@ -148,9 +148,6 @@ }, "Cancel" : { - }, - "Color Key" : { - }, "Contacts" : { @@ -373,6 +370,9 @@ }, "Invitation Code" : { + }, + "Legend" : { + }, "LICENSE_INFO_TITLE" : { "localizations" : { diff --git a/ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift b/ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift deleted file mode 100644 index b076d6f2..00000000 --- a/ENGAGEHF/SharedExtensions/FirebaseAuth+Continuation.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// This source file is part of the ENGAGE-HF project based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import FirebaseAuth -import Foundation - - -extension Auth { - @discardableResult - func getToken(forcingRefresh: Bool = false) async throws -> String { - try await withCheckedThrowingContinuation { continuation in - self.getToken(forcingRefresh: forcingRefresh) { token, error in - switch (token, error) { - case let (.some(token), _): - continuation.resume(returning: token) - case let (_, .some(error)): - continuation.resume(throwing: error) - case (.none, .none): - continuation.resume(throwing: AuthErrorCode.nullUser) - } - } - } - } -} From b67f5a6c9e4f2943a3ef6fbfdd95dfc0790746fd Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:48:25 -0800 Subject: [PATCH 14/20] UI Styling Fixes --- ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift | 2 +- ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift | 2 +- ENGAGEHF/Medications/ColorLegendSection/ColorLegend.swift | 2 +- ENGAGEHF/Medications/RecommendationStyle.swift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift b/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift index 979b0eea..8f29d718 100644 --- a/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift +++ b/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift @@ -30,7 +30,7 @@ enum SymptomsType: String, CaseIterable, Identifiable, CustomStringConvertible, case .overall: "Overall" case .physical: "Physical" case .social: "Social" - case .quality: "Quality" + case .quality: "Quality of Life" case .specific: "Symptoms" case .dizziness: "Dizziness" } diff --git a/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift b/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift index a107ed4e..59463834 100644 --- a/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift +++ b/ENGAGEHF/Medications/ColorLegendSection/ColorKeyEntryView.swift @@ -18,7 +18,7 @@ struct ColorKeyEntryView: View { HStack(alignment: .center) { Circle() .fill(color) - .frame(width: 24) + .frame(width: 12) Text(interpretation) } } diff --git a/ENGAGEHF/Medications/ColorLegendSection/ColorLegend.swift b/ENGAGEHF/Medications/ColorLegendSection/ColorLegend.swift index 90e90b89..6bdc196d 100644 --- a/ENGAGEHF/Medications/ColorLegendSection/ColorLegend.swift +++ b/ENGAGEHF/Medications/ColorLegendSection/ColorLegend.swift @@ -22,7 +22,7 @@ struct ColorLegend: View { } }, header: { - Text("Color Key") + Text("Legend") .padding(.horizontal, -16) } ) diff --git a/ENGAGEHF/Medications/RecommendationStyle.swift b/ENGAGEHF/Medications/RecommendationStyle.swift index 7685de2f..c924b1a7 100644 --- a/ENGAGEHF/Medications/RecommendationStyle.swift +++ b/ENGAGEHF/Medications/RecommendationStyle.swift @@ -19,7 +19,7 @@ enum RecommendationStyle: CaseIterable { case .targetReached: .green case .improvementAvailable: .yellow case .actionRequired: .blue.opacity(0.6) - case .notStarted: .accent.opacity(0.6) + case .notStarted: .gray.opacity(0.6) } } From c856b64319d9408f7249c58da01c882e0fee8099 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:58:09 -0800 Subject: [PATCH 15/20] Fix UI tests, edit legend text --- .../Symptoms/SymptomsGraphSection.swift | 4 ++++ .../HeartHealth/Vitals/VitalsGraphSection.swift | 5 +++++ ENGAGEHF/Medications/RecommendationStyle.swift | 6 +++--- ENGAGEHF/Resources/Localizable.xcstrings | 14 +++++++------- .../HeartHealth/HeartHealthUITests.swift | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ENGAGEHF/HeartHealth/Symptoms/SymptomsGraphSection.swift b/ENGAGEHF/HeartHealth/Symptoms/SymptomsGraphSection.swift index 5ca77575..079ae32b 100644 --- a/ENGAGEHF/HeartHealth/Symptoms/SymptomsGraphSection.swift +++ b/ENGAGEHF/HeartHealth/Symptoms/SymptomsGraphSection.swift @@ -58,7 +58,11 @@ struct SymptomsGraphSection: View { content: { VitalsGraph(data: graphData, options: options) .environment(\.customChartYAxis, symptomsType == .dizziness ? .dizzinessYAxisModifier : .percentageYAxisModifier ) +#if TEST + .disabled(true) +#else .disabled(vitalsManager.symptomHistory.isEmpty) +#endif }, header: { SymptomsPicker(symptomsType: $symptomsType) diff --git a/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift b/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift index ac2caf3e..9fa97f48 100644 --- a/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift +++ b/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift @@ -43,7 +43,12 @@ struct VitalsGraphSection: View { dateResolution: granularity.defaultDateUnit, targetValue: vitalsType == .weight ? vitalsManager.latestDryWeight : nil ) +#if TEST + .disabled(true) +#else .disabled(data.isEmpty) +#endif + }, header: { HStack { diff --git a/ENGAGEHF/Medications/RecommendationStyle.swift b/ENGAGEHF/Medications/RecommendationStyle.swift index c924b1a7..26ff2e09 100644 --- a/ENGAGEHF/Medications/RecommendationStyle.swift +++ b/ENGAGEHF/Medications/RecommendationStyle.swift @@ -26,13 +26,13 @@ enum RecommendationStyle: CaseIterable { var localizedInterpretation: String { switch self { case .targetReached: - String(localized: "You're on your target dose.", comment: "Target dose reached color legend entry.") + String(localized: "You are on your target dose.", comment: "Target dose reached color legend entry.") case .improvementAvailable: - String(localized: "On the med but may benefit from a higher dose.", comment: "Improvement available color legend entry.") + String(localized: "You are on this medication, but may benefit from a higher dose.", comment: "Improvement available color legend entry.") case .actionRequired: String(localized: "More information is needed to make a recommendation.", comment: "Action required color legend entry.") case .notStarted: - String(localized: "Not on this med that may help your heart.", comment: "No action required legend entry.") + String(localized: "You are not in this medication, but it might be helpful in the future.", comment: "No action required legend entry.") } } } diff --git a/ENGAGEHF/Resources/Localizable.xcstrings b/ENGAGEHF/Resources/Localizable.xcstrings index f886fc68..ff942469 100644 --- a/ENGAGEHF/Resources/Localizable.xcstrings +++ b/ENGAGEHF/Resources/Localizable.xcstrings @@ -428,9 +428,6 @@ }, "None" : { - }, - "Not on this med that may help your heart." : { - "comment" : "No action required legend entry." }, "Not Started" : { @@ -478,9 +475,6 @@ }, "Notifications" : { - }, - "On the med but may benefit from a higher dose." : { - "comment" : "Improvement available color legend entry." }, "Organization" : { @@ -856,7 +850,13 @@ } } }, - "You're on your target dose." : { + "You are not in this medication, but it might be helpful in the future." : { + "comment" : "No action required legend entry." + }, + "You are on this medication, but may benefit from a higher dose." : { + "comment" : "Improvement available color legend entry." + }, + "You are on your target dose." : { "comment" : "Target dose reached color legend entry." } }, diff --git a/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift b/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift index 4c47f9ea..5e9113a8 100644 --- a/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift +++ b/ENGAGEHFUITests/HeartHealth/HeartHealthUITests.swift @@ -293,7 +293,7 @@ extension XCUIApplication { "Overall", "Physical", "Social", - "Quality", + "Quality of Life", "Symptoms", "Dizziness" ] From 1f7126467204cb7e9c1579e6ed63ac079355dc5f Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Wed, 11 Dec 2024 00:12:54 -0800 Subject: [PATCH 16/20] Fix SwiftLint --- ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift b/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift index 9fa97f48..080cbef6 100644 --- a/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift +++ b/ENGAGEHF/HeartHealth/Vitals/VitalsGraphSection.swift @@ -48,7 +48,6 @@ struct VitalsGraphSection: View { #else .disabled(data.isEmpty) #endif - }, header: { HStack { From 5162201fc8812b21e34543958d43ec3819b9a5f4 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:57:27 -0800 Subject: [PATCH 17/20] Small cleanup --- ENGAGEHF/Managers/VideoManager/VideoManager.swift | 1 - ENGAGEHF/Medications/RecommendationStyle.swift | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ENGAGEHF/Managers/VideoManager/VideoManager.swift b/ENGAGEHF/Managers/VideoManager/VideoManager.swift index 0240b5d5..0b6c1c12 100644 --- a/ENGAGEHF/Managers/VideoManager/VideoManager.swift +++ b/ENGAGEHF/Managers/VideoManager/VideoManager.swift @@ -6,7 +6,6 @@ // SPDX-License-Identifier: MIT // -import FirebaseAuth import FirebaseFirestore import Foundation import OSLog diff --git a/ENGAGEHF/Medications/RecommendationStyle.swift b/ENGAGEHF/Medications/RecommendationStyle.swift index 26ff2e09..5afa0926 100644 --- a/ENGAGEHF/Medications/RecommendationStyle.swift +++ b/ENGAGEHF/Medications/RecommendationStyle.swift @@ -32,7 +32,7 @@ enum RecommendationStyle: CaseIterable { case .actionRequired: String(localized: "More information is needed to make a recommendation.", comment: "Action required color legend entry.") case .notStarted: - String(localized: "You are not in this medication, but it might be helpful in the future.", comment: "No action required legend entry.") + String(localized: "You are not on this medication, but it might be helpful in the future.", comment: "No action required legend entry.") } } } From aa96c1fc6cb8be037a4dbe4f11bd8a432fad9ea2 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:57:59 -0800 Subject: [PATCH 18/20] Make the OR statement AND in expectedSheetContent --- ENGAGEHF/ContentView.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ENGAGEHF/ContentView.swift b/ENGAGEHF/ContentView.swift index 66e70a5a..13af1022 100644 --- a/ENGAGEHF/ContentView.swift +++ b/ENGAGEHF/ContentView.swift @@ -36,8 +36,7 @@ struct ContentView: View { return .auth } guard FeatureFlags.disableFirebase - || !(account?.details?.isIncomplete ?? true) - || account?.details?.invitationCode != nil else { + || (!(account?.details?.isIncomplete ?? true) && account?.details?.invitationCode != nil) else { return .auth } return nil From 71c1fb17a3dba80e5a254220d05dc719a6db1a05 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:58:20 -0800 Subject: [PATCH 19/20] Add regression test for education videos appearing --- ENGAGEHFUITests/Account/OnboardingUITests.swift | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ENGAGEHFUITests/Account/OnboardingUITests.swift b/ENGAGEHFUITests/Account/OnboardingUITests.swift index f704d704..b197b68e 100644 --- a/ENGAGEHFUITests/Account/OnboardingUITests.swift +++ b/ENGAGEHFUITests/Account/OnboardingUITests.swift @@ -146,10 +146,19 @@ extension XCUIApplication { } fileprivate func assertOnboardingComplete() { - XCTAssert(staticTexts["Home"].waitForExistence(timeout: 10)) - let tabBar = tabBars["Tab Bar"] - XCTAssert(tabBar.buttons["Home"].waitForExistence(timeout: 2)) + + // Regression test: make sure the videos appeared correctly + XCTAssert(tabBar.buttons["Education"].waitForExistence(timeout: 2)) + tabBar.buttons["Education"].tap() + XCTAssertFalse(staticTexts["No Educational Videos"].exists) + + // Navigate back to home page + XCTAssert(tabBar.buttons["Home"].waitForExistence(timeout: 0.5)) + tabBar.buttons["Home"].tap() + + XCTAssert(staticTexts["Home"].waitForExistence(timeout: 4)) + } fileprivate func assertAccountInformation(email: String) throws { From 2aa19a8ddf40253317ab6597f917a0c8694341c7 Mon Sep 17 00:00:00 2001 From: nriedman <108841122+nriedman@users.noreply.github.com> Date: Sun, 22 Dec 2024 00:02:00 -0800 Subject: [PATCH 20/20] Linting --- ENGAGEHFUITests/Account/OnboardingUITests.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/ENGAGEHFUITests/Account/OnboardingUITests.swift b/ENGAGEHFUITests/Account/OnboardingUITests.swift index b197b68e..2bdcefc0 100644 --- a/ENGAGEHFUITests/Account/OnboardingUITests.swift +++ b/ENGAGEHFUITests/Account/OnboardingUITests.swift @@ -158,7 +158,6 @@ extension XCUIApplication { tabBar.buttons["Home"].tap() XCTAssert(staticTexts["Home"].waitForExistence(timeout: 4)) - } fileprivate func assertAccountInformation(email: String) throws {