diff --git a/README.md b/README.md index c49d764..8015f8d 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,54 @@ The CS342 2024 Stronger application is using the [Spezi](https://github.com/Stan *Provide a comprehensive description of your application, including figures showing the application. You can learn more on how to structure a README in the [Stanford Spezi Documentation Guide](https://swiftpackageindex.com/stanfordspezi/spezi/documentation/spezi/documentation-guide)* + +The Stronger App consists of three main screens. + + + +Home, Workout, and Food Tracking. + +### Home +#### Daily Protein +#### Weekly Fitness Progress +The bottom half of the *Home* page is the weekly fitness progress. +It shows the current week and last week's progress. If it is the first week for the participant, only one week will be shown. +THe three buttons will navigate to workout selection. +Each button has a text below that will show if the exercise day was on average "Easy", "Medium", "Hard" or of it is incomplete. + + + +### Workout + +#### Workout selection +For week selection We use the account information. See Account info for more details. +To determine the exercise it queries the firestore to see what exercises are there. THere must be exercises for all workouts of a day for it to move onto the next exercise. +For example, if Day 1 consists of Squats, Pushups, Lunge Left and Lunge Right, there must be all 4 exercises for the workout to move onto the next date. + +#### Workout Input + + +#### Workout Makeup Selection. +If the user wants to submit a workout for a particular week or exercise day, They can navigate here and select the exact week and day. + + +### Foodtracking + + +## Account details +Account has been augmented to include a startdate, weight, and height. + +THe current week is determined by the amount of weeks from the Monday of the startdate selected. i.e. Monday is considered the start of a week. + > [!NOTE] > Do you want to learn more about the Stanford Spezi Template Application and how to use, extend, and modify this application? Check out the [Stanford Spezi Template Application documentation](https://stanfordspezi.github.io/SpeziTemplateApplication) ## Contributing -*Ensure that you add an adequate contribution section to this README.* +Theo: Augmenting Account. Weekly summary on Home Page. Workout Selection, Workout day and week selection. +Logic for determining current week and curreent exercise day. + ## License diff --git a/Stronger.xcodeproj/project.pbxproj b/Stronger.xcodeproj/project.pbxproj index a928ade..75c4241 100644 --- a/Stronger.xcodeproj/project.pbxproj +++ b/Stronger.xcodeproj/project.pbxproj @@ -7,25 +7,16 @@ objects = { /* Begin PBXBuildFile section */ - 1E88BEE12B71712000A4BCEE /* SelectNeworSaved.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E88BEE02B71712000A4BCEE /* SelectNeworSaved.swift */; }; - 1E88BEE32B71725600A4BCEE /* SelectSavedMeal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E88BEE22B71725600A4BCEE /* SelectSavedMeal.swift */; }; - 1E88BEE62B7180FF00A4BCEE /* EditSavedMeal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E88BEE52B7180FF00A4BCEE /* EditSavedMeal.swift */; }; - 1E88BEE92B71B8F500A4BCEE /* MealReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E88BEE82B71B8F500A4BCEE /* MealReport.swift */; }; - 1E88BEEF2B73E55800A4BCEE /* EditSavedMealContents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E88BEEE2B73E55800A4BCEE /* EditSavedMealContents.swift */; }; - 1E88BEF22B73EB8500A4BCEE /* ChooseNewFoodOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E88BEF12B73EB8500A4BCEE /* ChooseNewFoodOptions.swift */; }; - 1E88BEF52B73EB9100A4BCEE /* CommonlySavedItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E88BEF42B73EB9100A4BCEE /* CommonlySavedItems.swift */; }; 1E9330CB2B968B1800BC620A /* FoodClassifierApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9330CA2B968B1800BC620A /* FoodClassifierApp.swift */; }; 1E9330CD2B968BF900BC620A /* MobileNetV2.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 1E9330CC2B968BF900BC620A /* MobileNetV2.mlmodel */; }; 1E9330CF2B968C0700BC620A /* MobileNet.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 1E9330CE2B968C0700BC620A /* MobileNet.mlmodel */; }; 1E9330D22B968FA800BC620A /* ChatWindowAfterCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9330D12B968FA800BC620A /* ChatWindowAfterCamera.swift */; }; 1EE815C52BA21E920035B81F /* SeeFood.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 1EE815C42BA21E910035B81F /* SeeFood.mlmodel */; }; - 27FA29902A388E9B009CAC45 /* ModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27FA298F2A388E9B009CAC45 /* ModalView.swift */; }; 2F1AC9DF2B4E840E00C24973 /* Stronger.docc in Sources */ = {isa = PBXBuildFile; fileRef = 2F1AC9DE2B4E840E00C24973 /* Stronger.docc */; }; 2F3D4ABC2A4E7C290068FB2F /* SpeziScheduler in Frameworks */ = {isa = PBXBuildFile; productRef = 2F3D4ABB2A4E7C290068FB2F /* SpeziScheduler */; }; 2F49B7762980407C00BCB272 /* Spezi in Frameworks */ = {isa = PBXBuildFile; productRef = 2F49B7752980407B00BCB272 /* Spezi */; }; 2F4E237E2989A2FE0013F3D9 /* LaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E237D2989A2FE0013F3D9 /* LaunchTests.swift */; }; 2F4E23832989D51F0013F3D9 /* StrongerTestingSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23822989D51F0013F3D9 /* StrongerTestingSetup.swift */; }; - 2F4FC8D729EE69D300BFFE26 /* MockUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4FC8D629EE69D300BFFE26 /* MockUpload.swift */; }; 2F5E32BD297E05EA003432F8 /* StrongerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F5E32BC297E05EA003432F8 /* StrongerDelegate.swift */; }; 2FA0BFED2ACC977500E0EF83 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2FA0BFEC2ACC977500E0EF83 /* Localizable.xcstrings */; }; 2FB099AF2A875DF100B20952 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 2FB099AE2A875DF100B20952 /* FirebaseAuth */; }; @@ -36,7 +27,6 @@ 2FC3439029EE6346002D773C /* SocialSupportQuestionnaire.json in Resources */ = {isa = PBXBuildFile; fileRef = 2FE5DC5529EDD811004B9AB4 /* SocialSupportQuestionnaire.json */; }; 2FC3439229EE634B002D773C /* ConsentDocument.md in Resources */ = {isa = PBXBuildFile; fileRef = 2FE5DC2C29EDD78E004B9AB4 /* ConsentDocument.md */; }; 2FC975A82978F11A00BA99FE /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FC975A72978F11A00BA99FE /* Home.swift */; }; - 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC2529EDD38A004B9AB4 /* Contacts.swift */; }; 2FE5DC3529EDD7CA004B9AB4 /* Consent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC2F29EDD7CA004B9AB4 /* Consent.swift */; }; 2FE5DC3629EDD7CA004B9AB4 /* HealthKitPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3029EDD7CA004B9AB4 /* HealthKitPermissions.swift */; }; 2FE5DC3729EDD7CA004B9AB4 /* OnboardingFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3129EDD7CA004B9AB4 /* OnboardingFlow.swift */; }; @@ -47,12 +37,6 @@ 2FE5DC4529EDD7F2004B9AB4 /* Binding+Negate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4229EDD7F2004B9AB4 /* Binding+Negate.swift */; }; 2FE5DC4629EDD7F2004B9AB4 /* Bundle+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4329EDD7F2004B9AB4 /* Bundle+Image.swift */; }; 2FE5DC4729EDD7F2004B9AB4 /* CodableArray+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4429EDD7F2004B9AB4 /* CodableArray+RawRepresentable.swift */; }; - 2FE5DC4E29EDD7FA004B9AB4 /* ScheduleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4829EDD7FA004B9AB4 /* ScheduleView.swift */; }; - 2FE5DC4F29EDD7FA004B9AB4 /* EventContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4929EDD7FA004B9AB4 /* EventContext.swift */; }; - 2FE5DC5029EDD7FA004B9AB4 /* EventContextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4A29EDD7FA004B9AB4 /* EventContextView.swift */; }; - 2FE5DC5129EDD7FA004B9AB4 /* StrongerTaskContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4B29EDD7FA004B9AB4 /* StrongerTaskContext.swift */; }; - 2FE5DC5229EDD7FA004B9AB4 /* StrongerScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4C29EDD7FA004B9AB4 /* StrongerScheduler.swift */; }; - 2FE5DC5329EDD7FA004B9AB4 /* Bundle+Questionnaire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC4D29EDD7FA004B9AB4 /* Bundle+Questionnaire.swift */; }; 2FE5DC6429EDD883004B9AB4 /* SpeziAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC6329EDD883004B9AB4 /* SpeziAccount */; }; 2FE5DC6729EDD894004B9AB4 /* SpeziContact in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC6629EDD894004B9AB4 /* SpeziContact */; }; 2FE5DC7229EDD8D3004B9AB4 /* SpeziHealthKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC7129EDD8D3004B9AB4 /* SpeziHealthKit */; }; @@ -88,11 +72,8 @@ 4002F0AC2B9AFC4D00AD3D47 /* MissedWorkoutTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4002F0AB2B9AFC4D00AD3D47 /* MissedWorkoutTest.swift */; }; 4002F0AF2B9BAA2000AD3D47 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4002F0AE2B9BAA2000AD3D47 /* OnboardingTests.swift */; }; 4011141D2B83FCD1000083A2 /* SummaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4011141C2B83FCD1000083A2 /* SummaryView.swift */; }; - 401114232B8489D1000083A2 /* GoalResist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401114222B8489D1000083A2 /* GoalResist.swift */; }; 401114252B84913F000083A2 /* ExerciseWeek.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401114242B84913F000083A2 /* ExerciseWeek.swift */; }; - 40223A412B6C544D005FC0BF /* HomeReal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40223A402B6C544D005FC0BF /* HomeReal.swift */; }; 40223A562B6CB6CB005FC0BF /* Summary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40223A552B6CB6CB005FC0BF /* Summary.swift */; }; - 40223A592B6CC02E005FC0BF /* Nutrition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40223A582B6CC02E005FC0BF /* Nutrition.swift */; }; 4036AE6B2B9543ED00F4DDBB /* exercise_list.json in Resources */ = {isa = PBXBuildFile; fileRef = 4036AE6A2B9543ED00F4DDBB /* exercise_list.json */; }; 405133482B8C808E00ED62BA /* WorkoutSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405133472B8C808E00ED62BA /* WorkoutSelection.swift */; }; 4051334D2B8C8D5400ED62BA /* WorkoutHome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4051334C2B8C8D5400ED62BA /* WorkoutHome.swift */; }; @@ -101,7 +82,9 @@ 4051335A2B8F449300ED62BA /* StartDatePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405133592B8F449300ED62BA /* StartDatePicker.swift */; }; 405239E02B574BA500EEA67A /* AppIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 405239DF2B574BA500EEA67A /* AppIcon.png */; }; 40644ECF2B7C4E7E009F9E28 /* Weight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40644ECE2B7C4E7E009F9E28 /* Weight.swift */; }; - 406605B52B731AE30073E024 /* NavButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 406605B42B731AE30073E024 /* NavButton.swift */; }; + 4084C2A92BA27FF200A6B8C3 /* LLMTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4084C2A82BA27FF200A6B8C3 /* LLMTests.swift */; }; + 4089E9382BA12B7700DB051B /* TestImageNav.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4089E9372BA12B7700DB051B /* TestImageNav.swift */; }; + 4089E9422BA14EC700DB051B /* testLoggedIn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4089E9412BA14EC700DB051B /* testLoggedIn.swift */; }; 40D4E47F2B97CB9900261632 /* HomeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D4E47E2B97CB9900261632 /* HomeTest.swift */; }; 40D4E4822B97CBB800261632 /* TapSwitchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D4E4812B97CBB800261632 /* TapSwitchTest.swift */; }; 40D4E4842B97CD0A00261632 /* WorkoutTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D4E4832B97CD0A00261632 /* WorkoutTest.swift */; }; @@ -159,29 +142,19 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 1E88BEE02B71712000A4BCEE /* SelectNeworSaved.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectNeworSaved.swift; sourceTree = ""; }; - 1E88BEE22B71725600A4BCEE /* SelectSavedMeal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectSavedMeal.swift; sourceTree = ""; }; - 1E88BEE52B7180FF00A4BCEE /* EditSavedMeal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSavedMeal.swift; sourceTree = ""; }; - 1E88BEE82B71B8F500A4BCEE /* MealReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealReport.swift; sourceTree = ""; }; - 1E88BEEE2B73E55800A4BCEE /* EditSavedMealContents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSavedMealContents.swift; sourceTree = ""; }; - 1E88BEF12B73EB8500A4BCEE /* ChooseNewFoodOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseNewFoodOptions.swift; sourceTree = ""; }; - 1E88BEF42B73EB9100A4BCEE /* CommonlySavedItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonlySavedItems.swift; sourceTree = ""; }; 1E9330CA2B968B1800BC620A /* FoodClassifierApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoodClassifierApp.swift; sourceTree = ""; }; 1E9330CC2B968BF900BC620A /* MobileNetV2.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = MobileNetV2.mlmodel; sourceTree = ""; }; 1E9330CE2B968C0700BC620A /* MobileNet.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = MobileNet.mlmodel; sourceTree = ""; }; 1E9330D12B968FA800BC620A /* ChatWindowAfterCamera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatWindowAfterCamera.swift; sourceTree = ""; }; 1EE815C42BA21E910035B81F /* SeeFood.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = SeeFood.mlmodel; sourceTree = ""; }; - 27FA298F2A388E9B009CAC45 /* ModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalView.swift; sourceTree = ""; }; 2F1AC9DE2B4E840E00C24973 /* Stronger.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = Stronger.docc; sourceTree = ""; }; 2F4E237D2989A2FE0013F3D9 /* LaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchTests.swift; sourceTree = ""; }; 2F4E23822989D51F0013F3D9 /* StrongerTestingSetup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrongerTestingSetup.swift; sourceTree = ""; }; - 2F4FC8D629EE69D300BFFE26 /* MockUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUpload.swift; sourceTree = ""; }; 2F5E32BC297E05EA003432F8 /* StrongerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrongerDelegate.swift; sourceTree = ""; }; 2FA0BFEC2ACC977500E0EF83 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 2FAEC07F297F583900C11C42 /* Stronger.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Stronger.entitlements; sourceTree = ""; }; 2FC94CD4298B0A1D009C8209 /* Stronger.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Stronger.xctestplan; sourceTree = ""; }; 2FC975A72978F11A00BA99FE /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; - 2FE5DC2529EDD38A004B9AB4 /* Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contacts.swift; sourceTree = ""; }; 2FE5DC2C29EDD78E004B9AB4 /* ConsentDocument.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = ConsentDocument.md; sourceTree = ""; }; 2FE5DC2F29EDD7CA004B9AB4 /* Consent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Consent.swift; sourceTree = ""; }; 2FE5DC3029EDD7CA004B9AB4 /* HealthKitPermissions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HealthKitPermissions.swift; sourceTree = ""; }; @@ -193,12 +166,6 @@ 2FE5DC4229EDD7F2004B9AB4 /* Binding+Negate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Binding+Negate.swift"; sourceTree = ""; }; 2FE5DC4329EDD7F2004B9AB4 /* Bundle+Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bundle+Image.swift"; sourceTree = ""; }; 2FE5DC4429EDD7F2004B9AB4 /* CodableArray+RawRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CodableArray+RawRepresentable.swift"; sourceTree = ""; }; - 2FE5DC4829EDD7FA004B9AB4 /* ScheduleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduleView.swift; sourceTree = ""; }; - 2FE5DC4929EDD7FA004B9AB4 /* EventContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventContext.swift; sourceTree = ""; }; - 2FE5DC4A29EDD7FA004B9AB4 /* EventContextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventContextView.swift; sourceTree = ""; }; - 2FE5DC4B29EDD7FA004B9AB4 /* StrongerTaskContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StrongerTaskContext.swift; sourceTree = ""; }; - 2FE5DC4C29EDD7FA004B9AB4 /* StrongerScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StrongerScheduler.swift; sourceTree = ""; }; - 2FE5DC4D29EDD7FA004B9AB4 /* Bundle+Questionnaire.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bundle+Questionnaire.swift"; sourceTree = ""; }; 2FE5DC5529EDD811004B9AB4 /* SocialSupportQuestionnaire.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = SocialSupportQuestionnaire.json; sourceTree = ""; }; 2FE5DCAC29EE6107004B9AB4 /* AccountOnboarding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountOnboarding.swift; sourceTree = ""; }; 2FF53D8C2A8729D600042B76 /* StrongerStandard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StrongerStandard.swift; sourceTree = ""; }; @@ -222,11 +189,8 @@ 4002F0AB2B9AFC4D00AD3D47 /* MissedWorkoutTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MissedWorkoutTest.swift; sourceTree = ""; }; 4002F0AE2B9BAA2000AD3D47 /* OnboardingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTests.swift; sourceTree = ""; }; 4011141C2B83FCD1000083A2 /* SummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SummaryView.swift; sourceTree = ""; }; - 401114222B8489D1000083A2 /* GoalResist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalResist.swift; sourceTree = ""; }; 401114242B84913F000083A2 /* ExerciseWeek.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExerciseWeek.swift; sourceTree = ""; }; - 40223A402B6C544D005FC0BF /* HomeReal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeReal.swift; sourceTree = ""; }; 40223A552B6CB6CB005FC0BF /* Summary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Summary.swift; sourceTree = ""; }; - 40223A582B6CC02E005FC0BF /* Nutrition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Nutrition.swift; sourceTree = ""; }; 4036AE6A2B9543ED00F4DDBB /* exercise_list.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = exercise_list.json; sourceTree = ""; }; 405133472B8C808E00ED62BA /* WorkoutSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutSelection.swift; sourceTree = ""; }; 4051334C2B8C8D5400ED62BA /* WorkoutHome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutHome.swift; sourceTree = ""; }; @@ -235,7 +199,9 @@ 405133592B8F449300ED62BA /* StartDatePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartDatePicker.swift; sourceTree = ""; }; 405239DF2B574BA500EEA67A /* AppIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = AppIcon.png; sourceTree = ""; }; 40644ECE2B7C4E7E009F9E28 /* Weight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weight.swift; sourceTree = ""; }; - 406605B42B731AE30073E024 /* NavButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavButton.swift; sourceTree = ""; }; + 4084C2A82BA27FF200A6B8C3 /* LLMTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMTests.swift; sourceTree = ""; }; + 4089E9372BA12B7700DB051B /* TestImageNav.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestImageNav.swift; sourceTree = ""; }; + 4089E9412BA14EC700DB051B /* testLoggedIn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = testLoggedIn.swift; sourceTree = ""; }; 40D4E47E2B97CB9900261632 /* HomeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTest.swift; sourceTree = ""; }; 40D4E4812B97CBB800261632 /* TapSwitchTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TapSwitchTest.swift; sourceTree = ""; }; 40D4E4832B97CD0A00261632 /* WorkoutTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutTest.swift; sourceTree = ""; }; @@ -321,28 +287,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 1E88BEDF2B7170FA00A4BCEE /* SavedMeals */ = { - isa = PBXGroup; - children = ( - 1E88BEE02B71712000A4BCEE /* SelectNeworSaved.swift */, - 1E88BEE22B71725600A4BCEE /* SelectSavedMeal.swift */, - 1E88BEE52B7180FF00A4BCEE /* EditSavedMeal.swift */, - 1E88BEEE2B73E55800A4BCEE /* EditSavedMealContents.swift */, - 1E88BEF12B73EB8500A4BCEE /* ChooseNewFoodOptions.swift */, - 1E88BEF42B73EB9100A4BCEE /* CommonlySavedItems.swift */, - 1E88BEE82B71B8F500A4BCEE /* MealReport.swift */, - ); - path = SavedMeals; - sourceTree = ""; - }; - 2F4FC8D529EE69BE00BFFE26 /* MockUpload */ = { - isa = PBXGroup; - children = ( - 2F4FC8D629EE69D300BFFE26 /* MockUpload.swift */, - ); - path = MockUpload; - sourceTree = ""; - }; 2FC9759D2978E30800BA99FE /* Supporting Files */ = { isa = PBXGroup; children = ( @@ -354,14 +298,6 @@ path = "Supporting Files"; sourceTree = ""; }; - 2FE5DC2729EDD38D004B9AB4 /* Contacts */ = { - isa = PBXGroup; - children = ( - 2FE5DC2529EDD38A004B9AB4 /* Contacts.swift */, - ); - path = Contacts; - sourceTree = ""; - }; 2FE5DC2829EDD398004B9AB4 /* Onboarding */ = { isa = PBXGroup; children = ( @@ -403,20 +339,6 @@ path = Resources; sourceTree = ""; }; - 2FE5DC3B29EDD7D0004B9AB4 /* Schedule */ = { - isa = PBXGroup; - children = ( - 2FE5DC4D29EDD7FA004B9AB4 /* Bundle+Questionnaire.swift */, - 2FE5DC4929EDD7FA004B9AB4 /* EventContext.swift */, - 2FE5DC4A29EDD7FA004B9AB4 /* EventContextView.swift */, - 2FE5DC4829EDD7FA004B9AB4 /* ScheduleView.swift */, - 2FE5DC4C29EDD7FA004B9AB4 /* StrongerScheduler.swift */, - 2FE5DC4B29EDD7FA004B9AB4 /* StrongerTaskContext.swift */, - 27FA298F2A388E9B009CAC45 /* ModalView.swift */, - ); - path = Schedule; - sourceTree = ""; - }; 2FE5DC3C29EDD7DA004B9AB4 /* SharedContext */ = { isa = PBXGroup; children = ( @@ -433,19 +355,10 @@ 2FE5DC4229EDD7F2004B9AB4 /* Binding+Negate.swift */, 2FE5DC4329EDD7F2004B9AB4 /* Bundle+Image.swift */, 2FE5DC4429EDD7F2004B9AB4 /* CodableArray+RawRepresentable.swift */, - 406605B42B731AE30073E024 /* NavButton.swift */, ); path = Helper; sourceTree = ""; }; - 40223A472B6C56EC005FC0BF /* Nutrition */ = { - isa = PBXGroup; - children = ( - 40223A582B6CC02E005FC0BF /* Nutrition.swift */, - ); - path = Nutrition; - sourceTree = ""; - }; 40223A4F2B6CB63B005FC0BF /* Exercise */ = { isa = PBXGroup; children = ( @@ -524,22 +437,16 @@ 7DE98D7E2B69D90400449C81 /* Workout */, 40223A512B6CB64C005FC0BF /* Info */, 40223A4F2B6CB63B005FC0BF /* Exercise */, - 40223A472B6C56EC005FC0BF /* Nutrition */, 6301EA562B68CF44005BDFB3 /* ProteinTracker */, 653A2550283387FE005D4D48 /* Stronger.swift */, - 40223A402B6C544D005FC0BF /* HomeReal.swift */, 2F5E32BC297E05EA003432F8 /* StrongerDelegate.swift */, 2FF53D8C2A8729D600042B76 /* StrongerStandard.swift */, 2F4E23822989D51F0013F3D9 /* StrongerTestingSetup.swift */, 2FC975A72978F11A00BA99FE /* Home.swift */, 6325F3992B83138A00A31314 /* MainPage.swift */, - 1E88BEDF2B7170FA00A4BCEE /* SavedMeals */, A9720E412ABB68B300872D23 /* Account */, 2FE5DC2829EDD398004B9AB4 /* Onboarding */, - 2FE5DC3B29EDD7D0004B9AB4 /* Schedule */, - 2FE5DC2729EDD38D004B9AB4 /* Contacts */, 56F6F29E2AB441640022FE5A /* Contributions */, - 2F4FC8D529EE69BE00BFFE26 /* MockUpload */, 2FE5DC3C29EDD7DA004B9AB4 /* SharedContext */, 2FE5DC3D29EDD7E4004B9AB4 /* Helper */, 2FE5DC2D29EDD792004B9AB4 /* Resources */, @@ -560,12 +467,15 @@ isa = PBXGroup; children = ( 2F4E237D2989A2FE0013F3D9 /* LaunchTests.swift */, + 4089E9372BA12B7700DB051B /* TestImageNav.swift */, 40D4E47E2B97CB9900261632 /* HomeTest.swift */, 40D4E4812B97CBB800261632 /* TapSwitchTest.swift */, 40D4E4832B97CD0A00261632 /* WorkoutTest.swift */, 4002F0AB2B9AFC4D00AD3D47 /* MissedWorkoutTest.swift */, 7DB088152BA12ED40006A3AA /* InputFormTest.swift */, 4002F0AE2B9BAA2000AD3D47 /* OnboardingTests.swift */, + 4089E9412BA14EC700DB051B /* testLoggedIn.swift */, + 4084C2A82BA27FF200A6B8C3 /* LLMTests.swift */, ); path = StrongerUITests; sourceTree = ""; @@ -592,7 +502,6 @@ A9720E422ABB68CC00872D23 /* AccountSetupHeader.swift */, A9DFE8A82ABE551400428242 /* AccountButton.swift */, 40644ECE2B7C4E7E009F9E28 /* Weight.swift */, - 401114222B8489D1000083A2 /* GoalResist.swift */, 40EFC2A52B87DAD2006B3B59 /* Height.swift */, 405133512B8D632200ED62BA /* Sex.swift */, 405133562B8F332100ED62BA /* StartDate.swift */, @@ -831,19 +740,14 @@ 1EE815C52BA21E920035B81F /* SeeFood.mlmodel in Sources */, 2FE5DC4129EDD7EE004B9AB4 /* StorageKeys.swift in Sources */, 2FE5DCB129EE6107004B9AB4 /* AccountOnboarding.swift in Sources */, - 2F4FC8D729EE69D300BFFE26 /* MockUpload.swift in Sources */, 38C4563E2B96CF3B009D69AA /* WorkoutHomeButton.swift in Sources */, - 1E88BEE32B71725600A4BCEE /* SelectSavedMeal.swift in Sources */, 2FE5DC3A29EDD7CA004B9AB4 /* Welcome.swift in Sources */, - 1E88BEEF2B73E55800A4BCEE /* EditSavedMealContents.swift in Sources */, 4051334D2B8C8D5400ED62BA /* WorkoutHome.swift in Sources */, 2FE5DC3829EDD7CA004B9AB4 /* InterestingModules.swift in Sources */, 40EFC2A62B87DAD2006B3B59 /* Height.swift in Sources */, - 40223A412B6C544D005FC0BF /* HomeReal.swift in Sources */, 2FE5DC3529EDD7CA004B9AB4 /* Consent.swift in Sources */, 2FE5DC4529EDD7F2004B9AB4 /* Binding+Negate.swift in Sources */, 2FC975A82978F11A00BA99FE /* Home.swift in Sources */, - 2FE5DC4E29EDD7FA004B9AB4 /* ScheduleView.swift in Sources */, A9DFE8A92ABE551400428242 /* AccountButton.swift in Sources */, 63A315812B6C7A3F00B6B9E4 /* LLMOpenAITokenOnboarding.swift in Sources */, 1E9330CD2B968BF900BC620A /* MobileNetV2.mlmodel in Sources */, @@ -856,36 +760,24 @@ A9720E432ABB68CC00872D23 /* AccountSetupHeader.swift in Sources */, 4051335A2B8F449300ED62BA /* StartDatePicker.swift in Sources */, 2FE5DC4029EDD7EE004B9AB4 /* FeatureFlags.swift in Sources */, - 406605B52B731AE30073E024 /* NavButton.swift in Sources */, 2FE5DC4629EDD7F2004B9AB4 /* Bundle+Image.swift in Sources */, - 2FE5DC4F29EDD7FA004B9AB4 /* EventContext.swift in Sources */, - 1E88BEF22B73EB8500A4BCEE /* ChooseNewFoodOptions.swift in Sources */, - 2FE5DC5029EDD7FA004B9AB4 /* EventContextView.swift in Sources */, - 40223A592B6CC02E005FC0BF /* Nutrition.swift in Sources */, 6325F3932B830B9C00A31314 /* ProteinRing.swift in Sources */, 4011141D2B83FCD1000083A2 /* SummaryView.swift in Sources */, 7DBE5D1F2B9A5AB7001C2E7C /* WorkoutSelections.swift in Sources */, 2F4E23832989D51F0013F3D9 /* StrongerTestingSetup.swift in Sources */, 7DE98D812B69D96300449C81 /* InputForm.swift in Sources */, - 2FE5DC5329EDD7FA004B9AB4 /* Bundle+Questionnaire.swift in Sources */, - 1E88BEE62B7180FF00A4BCEE /* EditSavedMeal.swift in Sources */, - 1E88BEE92B71B8F500A4BCEE /* MealReport.swift in Sources */, - 1E88BEE12B71712000A4BCEE /* SelectNeworSaved.swift in Sources */, 401114252B84913F000083A2 /* ExerciseWeek.swift in Sources */, 40E0C4702B97A457001116EB /* SharedWeekModel.swift in Sources */, 6301EA5A2B68CF9E005BDFB3 /* ChatWindow.swift in Sources */, 1E9330CF2B968C0700BC620A /* MobileNet.mlmodel in Sources */, 405133522B8D632200ED62BA /* Sex.swift in Sources */, - 2FE5DC5129EDD7FA004B9AB4 /* StrongerTaskContext.swift in Sources */, 56F6F2A02AB441930022FE5A /* ContributionsList.swift in Sources */, 1E9330CB2B968B1800BC620A /* FoodClassifierApp.swift in Sources */, 63A3157E2B6C760C00B6B9E4 /* LLMOnboardingView.swift in Sources */, 566155292AB8447C00209B80 /* Package+LicenseType.swift in Sources */, 5680DD392AB8983D004E6D4A /* PackageCell.swift in Sources */, - 401114232B8489D1000083A2 /* GoalResist.swift in Sources */, 2F5E32BD297E05EA003432F8 /* StrongerDelegate.swift in Sources */, 405133482B8C808E00ED62BA /* WorkoutSelection.swift in Sources */, - 2FE5DC5229EDD7FA004B9AB4 /* StrongerScheduler.swift in Sources */, 405133572B8F332100ED62BA /* StartDate.swift in Sources */, 63935E9B2B8C21C500ADB7D1 /* ProteinStats.swift in Sources */, 6325F39A2B83138A00A31314 /* MainPage.swift in Sources */, @@ -894,9 +786,6 @@ 2FE5DC3629EDD7CA004B9AB4 /* HealthKitPermissions.swift in Sources */, 1E9330D22B968FA800BC620A /* ChatWindowAfterCamera.swift in Sources */, 5661552E2AB854C000209B80 /* PackageHelper.swift in Sources */, - 27FA29902A388E9B009CAC45 /* ModalView.swift in Sources */, - 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */, - 1E88BEF52B73EB9100A4BCEE /* CommonlySavedItems.swift in Sources */, 40644ECF2B7C4E7E009F9E28 /* Weight.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -915,10 +804,13 @@ buildActionMask = 2147483647; files = ( 4002F0AF2B9BAA2000AD3D47 /* OnboardingTests.swift in Sources */, + 4084C2A92BA27FF200A6B8C3 /* LLMTests.swift in Sources */, 40D4E47F2B97CB9900261632 /* HomeTest.swift in Sources */, 2F4E237E2989A2FE0013F3D9 /* LaunchTests.swift in Sources */, + 4089E9382BA12B7700DB051B /* TestImageNav.swift in Sources */, 40D4E4822B97CBB800261632 /* TapSwitchTest.swift in Sources */, 4002F0AC2B9AFC4D00AD3D47 /* MissedWorkoutTest.swift in Sources */, + 4089E9422BA14EC700DB051B /* testLoggedIn.swift in Sources */, 7DB088162BA12ED40006A3AA /* InputFormTest.swift in Sources */, 40D4E4842B97CD0A00261632 /* WorkoutTest.swift in Sources */, ); diff --git a/Stronger/Account/GoalResist.swift b/Stronger/Account/GoalResist.swift deleted file mode 100644 index d3dff5f..0000000 --- a/Stronger/Account/GoalResist.swift +++ /dev/null @@ -1,74 +0,0 @@ -// -// This source file is part of the STRONGER based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// -import SpeziAccount -import SpeziFoundation -import SpeziValidation -import SpeziViews -import SwiftUI - -/// The resistance of a user. -public struct GoalResistanceKey: AccountKey { - public typealias Value = Int - public static let name = LocalizedStringResource("GOAL_RESISTANCE") - public static let category: AccountKeyCategory = .personalDetails -} - - -extension AccountKeys { - /// this is the resistanceKey of the user - public var goalresistance: GoalResistanceKey.Type { - GoalResistanceKey.self - } -} - - -extension AccountValues { - /// this is the resistance value to be stored - public var goalresistance: Int? { - storage[GoalResistanceKey.self] - } -} - - -// MARK: - UI -extension GoalResistanceKey { - public struct DataDisplay: DataDisplayView { - public typealias Key = GoalResistanceKey - private let goalresistance: Int - public init(_ value: Int) { - self.goalresistance = value - } - public var body: some View { - HStack { - Text(GoalResistanceKey.name) - Spacer() - Text("\(goalresistance) kg") - .foregroundColor(.secondary) - } - .accessibilityElement(children: .combine) - } - } -} - -extension GoalResistanceKey { - public struct DataEntry: DataEntryView { - public typealias Key = GoalResistanceKey - @Binding private var goalresistance: Int - public var body: some View { - HStack { - Text(GoalResistanceKey.name) - Spacer() - TextField("Goal Resistance", value: $goalresistance, formatter: NumberFormatter()) - .frame(width: 120) // set frame width to enable more spaces. - } - } - public init(_ value: Binding) { - self._goalresistance = value - } - } -} diff --git a/Stronger/Contacts/Contacts.swift b/Stronger/Contacts/Contacts.swift deleted file mode 100644 index b63fd01..0000000 --- a/Stronger/Contacts/Contacts.swift +++ /dev/null @@ -1,111 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import Foundation -import SpeziContact -import SwiftUI - - -/// Displays the contacts for the Stronger. -struct Contacts: View { - let contacts = [ - Contact( - name: PersonNameComponents( - givenName: "Mike", - familyName: "Baiocchi, PhD" - ), - image: Image(systemName: "figure.wave.circle"), // swiftlint:disable:this accessibility_label_for_image - title: "Principal Investigator", - description: String(localized: "MICHAEL_BAIOCCHI_BIO"), - organization: "Stanford University", - address: { - let address = CNMutablePostalAddress() - address.country = "USA" - address.state = "CA" - address.postalCode = "94305" - address.city = "Stanford" - address.street = "1265 Welch Road" - return address - }(), - contactOptions: [ - .call("+1 (650) 723-2300"), - .text("+1 (650) 723-2300"), - .email(addresses: ["baiocchi@stanford.edu"]), - ContactOption( - image: Image(systemName: "safari.fill"), // swiftlint:disable:this accessibility_label_for_image - title: "Website", - action: { - if let url = URL(string: "https://profiles.stanford.edu/michael-baiocchi") { - UIApplication.shared.open(url) - } - } - ) - ] - ), - Contact( - name: PersonNameComponents( - givenName: "Marily", - familyName: "Oppezzo, PhD, MS, RDN, DipACLM" - ), - image: Image(systemName: "figure.wave.circle"), // swiftlint:disable:this accessibility_label_for_image - title: "Principal Investigator", - description: String(localized: "MARILY_OPPEZZO_BIO"), - organization: "Stanford University", - address: { - let address = CNMutablePostalAddress() - address.country = "USA" - address.state = "CA" - address.postalCode = "94305" - address.city = "Stanford" - address.street = "Mail Code: 5411" - return address - }(), - contactOptions: [ - .call("+1 (650) 723-2300"), - .text("+1 (650) 723-2300"), - .email(addresses: ["moppezzo@stanford.edu"]), - ContactOption( - image: Image(systemName: "safari.fill"), // swiftlint:disable:this accessibility_label_for_image - title: "Website", - action: { - if let url = URL(string: "https://profiles.stanford.edu/marily-oppezzo") { - UIApplication.shared.open(url) - } - } - ) - ] - ) - ] - - @Binding var presentingAccount: Bool - - - var body: some View { - NavigationStack { - ContactsList(contacts: contacts) - .navigationTitle(String(localized: "CONTACTS_NAVIGATION_TITLE")) - .toolbar { - if AccountButton.shouldDisplay { - AccountButton(isPresented: $presentingAccount) - } - } - } - } - - - init(presentingAccount: Binding) { - self._presentingAccount = presentingAccount - } -} - - -#if DEBUG -#Preview { - Contacts(presentingAccount: .constant(false)) -} -#endif diff --git a/Stronger/Exercise/WorkoutSelection.swift b/Stronger/Exercise/WorkoutSelection.swift index d333b1f..3e179aa 100644 --- a/Stronger/Exercise/WorkoutSelection.swift +++ b/Stronger/Exercise/WorkoutSelection.swift @@ -375,12 +375,6 @@ extension String { } } -extension String { - func removingNonAlphabeticCharacters3() -> String { - self.filter { $0.isLetter } - } -} - struct ContentView_Previews: PreviewProvider { static var previews: some View { WorkoutSelection(presentingAccount: .constant(false), selectedWeek: nil) diff --git a/Stronger/Helper/NavButton.swift b/Stronger/Helper/NavButton.swift deleted file mode 100644 index f0b816a..0000000 --- a/Stronger/Helper/NavButton.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziAccount -import SpeziMockWebService -import SwiftUI - -struct NavButton: ViewModifier { - func body(content: Content) -> some View { - content - .padding() - .foregroundColor(.white) - .background(Color.green) - .cornerRadius(8) - .frame(maxWidth: .infinity) - } -} diff --git a/Stronger/Home.swift b/Stronger/Home.swift index 1ffb10d..3a946c7 100644 --- a/Stronger/Home.swift +++ b/Stronger/Home.swift @@ -83,8 +83,8 @@ struct HomeView: View { return HomeView() .previewWith(standard: StrongerStandard()) { - StrongerScheduler() - MockWebService() +// StrongerScheduler() +// MockWebService() AccountConfiguration(building: details, active: MockUserIdPasswordAccountService()) } } @@ -93,8 +93,8 @@ struct HomeView: View { CommandLine.arguments.append("--disableFirebase") // make sure the MockWebService is displayed return HomeView() .previewWith(standard: StrongerStandard()) { - StrongerScheduler() - MockWebService() +// StrongerScheduler() +// MockWebService() AccountConfiguration { MockUserIdPasswordAccountService() } diff --git a/Stronger/HomeReal.swift b/Stronger/HomeReal.swift deleted file mode 100644 index 10607a8..0000000 --- a/Stronger/HomeReal.swift +++ /dev/null @@ -1,88 +0,0 @@ -// -// Summary.swift -// Stronger -// -// Created by Theodore Kanell on 1/31/24. -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziAccount -import SpeziMockWebService -import SwiftUI - - -struct HomeReal: View { - static var accountEnabled: Bool { - !FeatureFlags.disableFirebase && !FeatureFlags.skipOnboarding - } - - @State private var presentingAccount = false - - var body: some View { - NavigationView { - VStack { - Text("Stronger") - .font(.largeTitle) - Spacer() - // Top section with SummaryInfo component - Summary(presentingAccount: $presentingAccount) - // Bottom section with navigation buttons - Spacer() - HStack(spacing: 10) { - NavigationLink(destination: SelectNeworSaved()) { - Text("Nutrition") - .modifier(NavButton()) - } - -// NavigationLink(destination: WorkoutHome()) { -// Text("Exercise") -// .modifier(NavButton()) -// } - } - .padding() - .frame(maxWidth: .infinity) - .frame(width: UIScreen.main.bounds.width * 0.9) - } - .navigationBarTitle("Home") - .navigationBarHidden(true) - .sheet(isPresented: $presentingAccount) { - AccountSheet() - } - .accountRequired(Self.accountEnabled) { - AccountSheet() - } - .verifyRequiredAccountDetails(Self.accountEnabled) - } - } -} - - -#if DEBUG -#Preview { - let details = AccountDetails.Builder() - .set(\.userId, value: "lelandstanford@stanford.edu") - .set(\.name, value: PersonNameComponents(givenName: "Leland", familyName: "Stanford")) - - return HomeReal() - .previewWith(standard: StrongerStandard()) { - StrongerScheduler() - MockWebService() - AccountConfiguration(building: details, active: MockUserIdPasswordAccountService()) - } -} - -// #Preview { -// CommandLine.arguments.append("--disableFirebase") // make sure the MockWebService is displayed -// return HomeView() -// .previewWith(standard: StrongerStandard()) { -// StrongerScheduler() -// MockWebService() -// AccountConfiguration { -// MockUserIdPasswordAccountService() -// } -// } -// } -#endif diff --git a/Stronger/MockUpload/MockUpload.swift b/Stronger/MockUpload/MockUpload.swift deleted file mode 100644 index 3d94465..0000000 --- a/Stronger/MockUpload/MockUpload.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziMockWebService -import SwiftUI - - -struct MockUpload: View { - @Binding var presentingAccount: Bool - - var body: some View { - NavigationStack { - RequestList() - .toolbar { - if AccountButton.shouldDisplay { - AccountButton(isPresented: $presentingAccount) - } - } - } - } - - - init(presentingAccount: Binding) { - self._presentingAccount = presentingAccount - } -} - - -#if DEBUG -#Preview { - MockUpload(presentingAccount: .constant(false)) - .previewWith { - MockWebService() - } -} -#endif diff --git a/Stronger/Nutrition/Nutrition.swift b/Stronger/Nutrition/Nutrition.swift deleted file mode 100644 index 56ef617..0000000 --- a/Stronger/Nutrition/Nutrition.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// Nutrition.swift -// Stronger -// -// Created by Theodore Kanell on 2/1/24. -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SwiftUI - -struct Nutrition: View { - var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) - .navigationBarTitle("Food") - } -} - -#Preview { - Nutrition() -} diff --git a/Stronger/Onboarding/OnboardingFlow.swift b/Stronger/Onboarding/OnboardingFlow.swift index e93fb86..2a05b8c 100644 --- a/Stronger/Onboarding/OnboardingFlow.swift +++ b/Stronger/Onboarding/OnboardingFlow.swift @@ -16,7 +16,7 @@ import SwiftUI /// Displays an multi-step onboarding flow for the Stronger. struct OnboardingFlow: View { @Environment(HealthKit.self) private var healthKitDataSource - @Environment(StrongerScheduler.self) private var scheduler +// @Environment(StrongerScheduler.self) private var scheduler @AppStorage(StorageKeys.onboardingFlowComplete) private var completedOnboardingFlow = false @@ -62,7 +62,7 @@ struct OnboardingFlow: View { MockUserIdPasswordAccountService() } - StrongerScheduler() +// StrongerScheduler() } } #endif diff --git a/Stronger/Resources/Localizable.xcstrings b/Stronger/Resources/Localizable.xcstrings index 45cea7e..0b27de0 100644 --- a/Stronger/Resources/Localizable.xcstrings +++ b/Stronger/Resources/Localizable.xcstrings @@ -3,9 +3,6 @@ "strings" : { "" : { - }, - "[%lld] grams of protein" : { - }, "%@" : { @@ -20,16 +17,6 @@ } } }, - "%@, [%lld] g of protein" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "%1$@, [%2$lld] g of protein" - } - } - } - }, "%@: inches" : { }, @@ -41,9 +28,6 @@ }, "%lld inches" : { - }, - "%lld kg" : { - }, "%lld lbs" : { @@ -98,36 +82,18 @@ } } } - }, - "Are you logging a new or saved meal?" : { - }, "Average Protein Intake" : { - }, - "Change Food" : { - - }, - "Change Portion Size" : { - - }, - "Change Protein Content" : { - }, "Choose an option" : { }, "Choose from Library" : { - }, - "Choose From Your Common foods" : { - }, "Classification" : { - }, - "Click an item image to edit or next to continue" : { - }, "Close" : { @@ -150,6 +116,7 @@ }, "COMPLETED_TASK_LABEL %@" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -170,6 +137,7 @@ } }, "CONTACTS_NAVIGATION_TITLE" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -232,12 +200,6 @@ }, "Edit Classification" : { - }, - "Edit Meal Content" : { - - }, - "Edit Saved Meal" : { - }, "Enter Missed Workout" : { @@ -272,21 +234,12 @@ }, "Finish Logging" : { - }, - "Food" : { - - }, - "Food Change Options" : { - }, "Food Image Classifier" : { }, "Food Logged" : { - }, - "food name placeholder" : { - }, "Food Tracking" : { @@ -302,11 +255,9 @@ } } } - }, - "Goal Resistance" : { - }, "GOAL_RESISTANCE" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -387,12 +338,6 @@ }, "Hello %@" : { - }, - "Hello, World!" : { - - }, - "Home" : { - }, "HOME_TAB_TITLE" : { "comment" : "MARK: - Home", @@ -404,9 +349,6 @@ } } } - }, - "How do you want to change your food option?" : { - }, "How to estimate" : { @@ -416,9 +358,6 @@ }, "Incomplete" : { - }, - "Input New Food to Chat" : { - }, "Input with Camera" : { @@ -540,6 +479,9 @@ } } } + }, + "Is this your last set for this exercise?" : { + }, "Large portion" : { @@ -568,9 +510,6 @@ }, "Log more with ProBot!" : { - }, - "Lunch 02/05/2024" : { - }, "Male" : { @@ -585,15 +524,6 @@ } } } - }, - "meal picture" : { - - }, - "Meal Report Placeholder" : { - - }, - "Medium portion" : { - }, "MICHAEL_BAIOCCHI_BIO" : { "extractionState" : "manual", @@ -614,9 +544,6 @@ }, "No workout available" : { - }, - "Nutrition" : { - }, "OK" : { @@ -626,9 +553,6 @@ }, "Please select week." : { - }, - "Please select which saved meal to log" : { - }, "Please sign-in to continue your Stronger journey" : { @@ -654,9 +578,6 @@ } } } - }, - "Protein Content" : { - }, "Protein intake (grams)" : { @@ -679,17 +600,12 @@ }, "Reps" : { - }, - "Save Changes" : { - }, "Save Classification" : { - }, - "Saved Meal" : { - }, "SCHEDULE_LIST_TITLE" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -710,9 +626,6 @@ }, "Select Resistance" : { - }, - "Select Saved Meal" : { - }, "Select Week to input results" : { @@ -732,9 +645,6 @@ } } } - }, - "Small portion" : { - }, "START_DATE_TITLE" : { "localizations" : { @@ -762,6 +672,7 @@ }, "TASK_CONTEXT_ACTION_QUESTIONNAIRE" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -772,6 +683,7 @@ } }, "TASK_CONTEXT_ACTION_TEST" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -782,6 +694,7 @@ } }, "TASK_LABEL %@" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -792,6 +705,7 @@ } }, "TASK_NEW_QUESTIONNAIRE_DESCRIPTION" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -802,6 +716,7 @@ } }, "TASK_NEW_QUESTIONNAIRE_TITLE" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { diff --git a/Stronger/SavedMeals/ChooseNewFoodOptions.swift b/Stronger/SavedMeals/ChooseNewFoodOptions.swift deleted file mode 100644 index 7913691..0000000 --- a/Stronger/SavedMeals/ChooseNewFoodOptions.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// Created by Kevin Zhu - -import SwiftUI - -struct ChooseNewFoodOptions: View { - @Binding var selectedMealItem: MealItem - - var body: some View { - VStack { - Text("How do you want to change your food option?") - .font(.title) - .bold() - .multilineTextAlignment(.center) - .padding() - - // Custom Divider - Rectangle() - .frame(height: 2) - .foregroundColor(.gray) - .padding(.vertical) - - Spacer() - // change destination later to chat - NavigationLink(destination: ChatWindow()) { - Text("Input New Food to Chat") - .foregroundColor(.black) - .font(.headline) // can incease size - .padding(.vertical, 20) - .padding(.horizontal, 40) - .overlay(RoundedRectangle(cornerRadius: 12) - .stroke(Color.orange, lineWidth: 2)) - }.padding(.bottom, 70) - - NavigationLink(destination: CommonlySavedItems(selectedItem: $selectedMealItem)) { - Text("Choose From Your Common foods") - .foregroundColor(.black) - .font(.headline) // can incease size - .padding(.vertical, 20) - .padding(.horizontal, 40) - .overlay(RoundedRectangle(cornerRadius: 12) - .stroke(Color.orange, lineWidth: 2)) - } - - Spacer() - } - } -} - - -// #Preview { -// ChooseNewFoodOptions() -// } diff --git a/Stronger/SavedMeals/CommonlySavedItems.swift b/Stronger/SavedMeals/CommonlySavedItems.swift deleted file mode 100644 index 9b70fc4..0000000 --- a/Stronger/SavedMeals/CommonlySavedItems.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// Created by Kevin Zhu - -import SwiftUI - -struct CommonlySavedItems: View { - @Environment(\.presentationMode) var presentationMode - @Binding var selectedItem: MealItem - - let commonItems: [MealItem] = [ - MealItem(name: "Salmon", size: "large portion", protein: 23, imageName: "salmon"), - MealItem(name: "Rice", size: "small portion", protein: 4, imageName: "rice"), - MealItem(name: "Turkey", size: "medium portion", protein: 15, imageName: "turkey"), - MealItem(name: "Toast", size: "small portion", protein: 7, imageName: "toast"), - MealItem(name: "Banana", size: "small portion", protein: 5, imageName: "banana"), - MealItem(name: "Pear", size: "small portion", protein: 3, imageName: "pear") - ] - - var body: some View { - VStack { - Text("Commonly Saved Items") - .font(.title) - .bold() - .padding() - .foregroundColor(.black) - Divider() - ScrollView { - ForEach(commonItems, id: \.id) { item in - Button(action: { - selectedItem = item - presentationMode.wrappedValue.dismiss() - presentationMode.wrappedValue.dismiss() - presentationMode.wrappedValue.dismiss() - presentationMode.wrappedValue.dismiss() - }) { - HStack { - VStack(alignment: .leading) { - Text(item.name) - .foregroundColor(.black) - .font(.headline) - Text("\(item.size), [\(item.protein)] g of protein") - .font(.subheadline) - .foregroundColor(.black) - } - Spacer() - Image(item.imageName) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 50, height: 50) - .accessibilityLabel("food name placeholder") - } - .padding() - } - } - } - } - } -} - - -// #Preview { -// CommonlySavedItems() -// } diff --git a/Stronger/SavedMeals/EditSavedMealContents.swift b/Stronger/SavedMeals/EditSavedMealContents.swift deleted file mode 100644 index 72d84ec..0000000 --- a/Stronger/SavedMeals/EditSavedMealContents.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// Created by Kevin Zhu -import SwiftUI - -struct ChangeFoodOptions: View { - @ObservedObject var mealData: MealData - var mealIndex: Int - - var body: some View { - Text("Food Change Options") - } -} - -struct EditSavedMealContents: View { - @ObservedObject var mealData: MealData - var mealIndex: Int - - @State private var selectedSize: String - @State private var newProteinContent: String = "" - - var body: some View { - VStack { - changeFoodOptionLink - portionSizePicker - proteinContentInput - saveChangesButton - Spacer() - } - .navigationTitle("Edit Meal Content") - .navigationBarTitleDisplayMode(.inline) - } - - private var changeFoodOptionLink: some View { - NavigationLink(destination: ChooseNewFoodOptions(selectedMealItem: $mealData.mealItems[mealIndex])) { - Text("Change Food") - } - } - - private var portionSizePicker: some View { - Picker("Change Portion Size", selection: $selectedSize) { - Text("Large portion").tag("large portion") - Text("Medium portion").tag("medium portion") - Text("Small portion").tag("small portion") - } - .pickerStyle(MenuPickerStyle()) - } - - private var proteinContentInput: some View { - HStack { - Text("Change Protein Content") - TextField("Protein Content", text: $newProteinContent) - .keyboardType(.numberPad) - } - } - - private var saveChangesButton: some View { - Button("Save Changes") { - if let index = mealData.mealItems.firstIndex(where: { $0.id == mealData.mealItems[mealIndex].id }), - !newProteinContent.isEmpty, - let newProtein = Int(newProteinContent) { - mealData.mealItems[mealIndex].size = selectedSize - mealData.mealItems[mealIndex].protein = newProtein - } - } - } - init(mealData: MealData, mealIndex: Int, selectedSize: String? = nil) { - self.mealData = mealData - self.mealIndex = mealIndex - _selectedSize = State(initialValue: selectedSize ?? mealData.mealItems[mealIndex].size) - } -} diff --git a/Stronger/SavedMeals/MealReport.swift b/Stronger/SavedMeals/MealReport.swift deleted file mode 100644 index f5c86c3..0000000 --- a/Stronger/SavedMeals/MealReport.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// Created by Kevin Zhu - -import SwiftUI - -struct MealReport: View { - var body: some View { - Text("Meal Report Placeholder") - } -} - -#Preview { - MealReport() -} diff --git a/Stronger/SavedMeals/SelectNeworSaved.swift b/Stronger/SavedMeals/SelectNeworSaved.swift deleted file mode 100644 index 51112ea..0000000 --- a/Stronger/SavedMeals/SelectNeworSaved.swift +++ /dev/null @@ -1,52 +0,0 @@ -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// Created by Kevin Zhu -import SwiftUI - -struct SelectNeworSaved: View { - var body: some View { - VStack { - Text("Are you logging a new or saved meal?") - .font(.title) - .bold() - .multilineTextAlignment(.center) - .padding() - - Divider().frame(height: 2).foregroundColor(.black).padding(.vertical) - - Spacer() - - NavigationLink(destination: ChatWindow()) { - Text("New Meal") - .foregroundColor(.black) - .font(.headline) - .padding(.vertical, 20) - .padding(.horizontal, 40) - .background(RoundedRectangle(cornerRadius: 12).stroke(Color.orange, lineWidth: 2)) - } - .padding(.bottom, 70) - - NavigationLink(destination: SelectSavedMeal()) { - Text("Saved Meal") - .foregroundColor(.black) - .font(.headline) - .padding(.vertical, 20) - .padding(.horizontal, 40) - .background(RoundedRectangle(cornerRadius: 12).stroke(Color.orange, lineWidth: 2)) - } - - Spacer() - .navigationBarTitle("", displayMode: .inline) - // .navigationBarHidden(true) - } - } -} -// preview -struct SelectNeworSaved_Previews: PreviewProvider { - static var previews: some View { - SelectNeworSaved() - } -} diff --git a/Stronger/SavedMeals/SelectSavedMeal.swift b/Stronger/SavedMeals/SelectSavedMeal.swift deleted file mode 100644 index 97eb023..0000000 --- a/Stronger/SavedMeals/SelectSavedMeal.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// Created by Kevin Zhu -import SwiftUI - -struct SelectSavedMeal: View { - let mealData = MealData(mealItems: [ - MealItem(name: "Chicken Salad", size: "large portion", protein: 18, imageName: "chickenSalad"), - MealItem(name: "Garlic Breadsticks", size: "medium portion", protein: 12, imageName: "garlicBreadsticks"), - MealItem(name: "Cheese Stick", size: "small portion", protein: 7, imageName: "cheeseStick"), - MealItem(name: "Glass of Milk", size: "medium portion", protein: 8, imageName: "glassOfMilk"), - MealItem(name: "Chocolate Chip Cookie", size: "small portion", protein: 2, imageName: "chocolateChipCookie") - ]) - - private var mealTitles: [String] { - [ - "1. Lunch 02/05/2024", - "2. Dinner 02/04/2024", - "3. Lunch 02/03/2024", - "4. Breakfast 02/03/2024", - "5. Dinner 02/02/2024" - ] - } - - var body: some View { - VStack { - Text("Please select which saved meal to log") - .font(.title2) - .bold() - .padding() - .multilineTextAlignment(.center) - Divider() - mealOptionsSection - } - .navigationTitle("Select Saved Meal") - .navigationBarTitleDisplayMode(.inline) - } - - - private var mealOptionsSection: some View { - ForEach(Array(mealTitles.enumerated()), id: \.offset) { index, title in - mealOptionLink(title: title, index: index) - } - } - - private func mealOptionLink(title: String, index: Int) -> some View { - NavigationLink(destination: EditSavedMeal(mealData: mealData)) { - Text(title) - .foregroundColor(.black) - .padding() - .frame(maxWidth: .infinity) - .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.orange, lineWidth: 2)) - } - .padding(.horizontal) - .padding(.bottom, 5) - } -} - -// Preview -struct SelectSavedMeal_Previews: PreviewProvider { - static var previews: some View { - SelectSavedMeal() - } -} diff --git a/Stronger/Schedule/Bundle+Questionnaire.swift b/Stronger/Schedule/Bundle+Questionnaire.swift deleted file mode 100644 index 886d2cd..0000000 --- a/Stronger/Schedule/Bundle+Questionnaire.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import Foundation -import SpeziQuestionnaire - - -extension Foundation.Bundle { - func questionnaire(withName name: String) -> Questionnaire { - guard let resourceURL = self.url(forResource: name, withExtension: "json") else { - fatalError("Could not find the questionnaire \"\(name).json\" in the bundle.") - } - - do { - let resourceData = try Data(contentsOf: resourceURL) - return try JSONDecoder().decode(Questionnaire.self, from: resourceData) - } catch { - fatalError("Could not decode the FHIR questionnaire named \"\(name).json\": \(error)") - } - } -} diff --git a/Stronger/Schedule/EventContext.swift b/Stronger/Schedule/EventContext.swift deleted file mode 100644 index 763b71b..0000000 --- a/Stronger/Schedule/EventContext.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziScheduler - - -struct EventContext: Comparable, Identifiable { - let event: Event - let task: Task - - - var id: Event.ID { - event.id - } - - - static func < (lhs: EventContext, rhs: EventContext) -> Bool { - lhs.event.scheduledAt < rhs.event.scheduledAt - } -} diff --git a/Stronger/Schedule/EventContextView.swift b/Stronger/Schedule/EventContextView.swift deleted file mode 100644 index 0ffcbea..0000000 --- a/Stronger/Schedule/EventContextView.swift +++ /dev/null @@ -1,81 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziScheduler -import SwiftUI - - -struct EventContextView: View { - let eventContext: EventContext - - - var body: some View { - HStack { - VStack(alignment: .leading) { - HStack { - if eventContext.event.complete { - Image(systemName: "checkmark.circle.fill") - .foregroundColor(.accentColor) - .font(.system(size: 30)) - .accessibilityHidden(true) - } - VStack(alignment: .leading, spacing: 8) { - Text(verbatim: eventContext.task.title) - .font(.headline) - .accessibilityLabel( - eventContext.event.complete - ? "COMPLETED_TASK_LABEL \(eventContext.task.title)" - : "TASK_LABEL \(eventContext.task.title)" - ) - Text(verbatim: format(eventDate: eventContext.event.scheduledAt)) - .font(.subheadline) - } - } - Divider() - Text(eventContext.task.description) - .font(.callout) - if !eventContext.event.complete { - Text(eventContext.task.context.actionType) - .frame(maxWidth: .infinity, minHeight: 50) - .foregroundColor(.white) - .background(Color.accentColor) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .padding(.top, 8) - } - } - } - .disabled(eventContext.event.complete) - .contentShape(Rectangle()) - } - - - private func format(eventDate: Date) -> String { - let dateFormatter = DateFormatter() - dateFormatter.dateStyle = .none - dateFormatter.timeStyle = .short - return dateFormatter.string(from: eventDate) - } -} - - -#if DEBUG -#Preview(traits: .sizeThatFitsLayout) { - let task = StrongerScheduler.socialSupportTask - - return EventContextView( - eventContext: EventContext( - // We use a force unwrap in the preview as we can not recover from an error here - // and the code will never end up in a production environment. - // swiftlint:disable:next force_unwrapping - event: task.events(from: .now.addingTimeInterval(-60 * 60 * 24)).first!, - task: task - ) - ) - .padding() -} -#endif diff --git a/Stronger/Schedule/ModalView.swift b/Stronger/Schedule/ModalView.swift deleted file mode 100644 index 1d3650c..0000000 --- a/Stronger/Schedule/ModalView.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziViews -import SwiftUI - - -struct ModalView: View { - @Environment(\.dismiss) private var dismiss - - let text: String - let buttonText: String - let onClose: () async -> Void - - - var body: some View { - VStack { - Spacer() - Text(text) - .padding() - Spacer() - AsyncButton { - self.dismiss() - await self.onClose() - } label: { - Text(buttonText) - .frame(maxWidth: .infinity, minHeight: 38) - } - .padding() - .buttonStyle(.borderedProminent) - } - } -} - - -#if DEBUG -#Preview { - ModalView(text: "Preview Modal", buttonText: "Close") { - print("Preview Modal closed.") - } -} -#endif diff --git a/Stronger/Schedule/ScheduleView.swift b/Stronger/Schedule/ScheduleView.swift deleted file mode 100644 index 2fcae44..0000000 --- a/Stronger/Schedule/ScheduleView.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziAccount -import SpeziQuestionnaire -import SpeziScheduler -import SwiftUI - - -struct ScheduleView: View { - @Environment(StrongerStandard.self) private var standard - @Environment(StrongerScheduler.self) private var scheduler - @State private var eventContextsByDate: [Date: [EventContext]] = [:] - @State private var presentedContext: EventContext? - - - @Binding private var presentingAccount: Bool - - - private var startOfDays: [Date] { - Array(eventContextsByDate.keys) - } - - - var body: some View { - NavigationStack { - List(startOfDays, id: \.timeIntervalSinceNow) { startOfDay in - Section(format(startOfDay: startOfDay)) { - ForEach(eventContextsByDate[startOfDay] ?? [], id: \.event) { eventContext in - EventContextView(eventContext: eventContext) - .onTapGesture { - if !eventContext.event.complete { - presentedContext = eventContext - } - } - } - } - } - .onChange(of: scheduler) { - calculateEventContextsByDate() - } - .task { - calculateEventContextsByDate() - } - .sheet(item: $presentedContext) { presentedContext in - destination(withContext: presentedContext) - } - .toolbar { - if AccountButton.shouldDisplay { - AccountButton(isPresented: $presentingAccount) - } - } - .navigationTitle("SCHEDULE_LIST_TITLE") - } - } - - - init(presentingAccount: Binding) { - self._presentingAccount = presentingAccount - } - - - private func destination(withContext eventContext: EventContext) -> some View { - @ViewBuilder var destination: some View { - switch eventContext.task.context { - case let .questionnaire(questionnaire): - QuestionnaireView(questionnaire: questionnaire) { result in - presentedContext = nil - - guard case let .completed(response) = result else { - return // user cancelled the task - } - - eventContext.event.complete(true) - await standard.add(response: response) - } - case let .test(string): - ModalView(text: string, buttonText: String(localized: "CLOSE")) { - await eventContext.event.complete(true) - } - } - } - return destination - } - - - private func format(startOfDay: Date) -> String { - let dateFormatter = DateFormatter() - dateFormatter.dateStyle = .long - dateFormatter.timeStyle = .none - return dateFormatter.string(from: startOfDay) - } - - private func calculateEventContextsByDate() { - let eventContexts = scheduler.tasks.flatMap { task in - task - .events( - from: Calendar.current.startOfDay(for: .now), - to: .numberOfEventsOrEndDate(100, .now) - ) - .map { event in - EventContext(event: event, task: task) - } - } - .sorted() - - let newEventContextsByDate = Dictionary(grouping: eventContexts) { eventContext in - Calendar.current.startOfDay(for: eventContext.event.scheduledAt) - } - - eventContextsByDate = newEventContextsByDate - } -} - - -#if DEBUG -#Preview("ScheduleView") { - ScheduleView(presentingAccount: .constant(false)) - .previewWith(standard: StrongerStandard()) { - StrongerScheduler() - AccountConfiguration { - MockUserIdPasswordAccountService() - } - } -} -#endif diff --git a/Stronger/Schedule/StrongerScheduler.swift b/Stronger/Schedule/StrongerScheduler.swift deleted file mode 100644 index 4603d72..0000000 --- a/Stronger/Schedule/StrongerScheduler.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import Foundation -import SpeziScheduler - - -/// A `Scheduler` using the ``StrongerTaskContext`` to schedule and manage tasks and events in the -/// Stronger. -typealias StrongerScheduler = Scheduler - - -extension StrongerScheduler { - static var socialSupportTask: SpeziScheduler.Task { - let dateComponents: DateComponents - if FeatureFlags.testSchedule { - // Adds a task at the current time for UI testing if the `--testSchedule` feature flag is set - dateComponents = DateComponents( - hour: Calendar.current.component(.hour, from: .now), - minute: Calendar.current.component(.minute, from: .now) - ) - } else { - // For the normal app usage, we schedule the task for every day at 8:00 AM - dateComponents = DateComponents(hour: 8, minute: 0) - } - - return Task( - title: String(localized: "TASK_NEW_QUESTIONNAIRE_TITLE"), - description: String(localized: "TASK_NEW_QUESTIONNAIRE_DESCRIPTION"), - schedule: Schedule( - start: Calendar.current.startOfDay(for: Date()), - repetition: .matching(dateComponents), - end: .numberOfEvents(365) - ), - notifications: true, - context: StrongerTaskContext.questionnaire(Bundle.main.questionnaire(withName: "SocialSupportQuestionnaire")) - ) - } - - /// Creates a default instance of the ``StrongerScheduler`` by scheduling the tasks listed below. - convenience init() { - self.init(tasks: [Self.socialSupportTask]) - } -} diff --git a/Stronger/Schedule/StrongerTaskContext.swift b/Stronger/Schedule/StrongerTaskContext.swift deleted file mode 100644 index c9bfeb7..0000000 --- a/Stronger/Schedule/StrongerTaskContext.swift +++ /dev/null @@ -1,40 +0,0 @@ -// -// This source file is part of the Stronger based on the Stanford Spezi Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import Foundation -import ModelsR4 - - -/// The context attached to each task in the Stronger. -/// -/// We currently only support `Questionnaire`s, more cases can be added in the future. -enum StrongerTaskContext: Codable, Identifiable { - /// The task should display a `Questionnaire`. - case questionnaire(Questionnaire) - /// The task is used for UI testing. - case test(String) - - - var id: FHIRPrimitive? { - switch self { - case let .questionnaire(questionnaire): - return questionnaire.id - case .test: - return FHIRPrimitive(FHIRString(UUID().uuidString)) - } - } - - var actionType: LocalizedStringResource { - switch self { - case .questionnaire: - return LocalizedStringResource("TASK_CONTEXT_ACTION_QUESTIONNAIRE") - case .test: - return LocalizedStringResource("TASK_CONTEXT_ACTION_TEST") - } - } -} diff --git a/Stronger/StrongerDelegate.swift b/Stronger/StrongerDelegate.swift index 4bee051..13333c6 100644 --- a/Stronger/StrongerDelegate.swift +++ b/Stronger/StrongerDelegate.swift @@ -56,7 +56,7 @@ class StrongerDelegate: SpeziAppDelegate { healthKit } - StrongerScheduler() +// StrongerScheduler() OnboardingDataSource() LLMRunner { diff --git a/StrongerUITests/HomeTest.swift b/StrongerUITests/HomeTest.swift index fef23fe..43b86f1 100644 --- a/StrongerUITests/HomeTest.swift +++ b/StrongerUITests/HomeTest.swift @@ -28,10 +28,52 @@ class HomeTests: XCTestCase { XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Home"].waitForExistence(timeout: 2)) app.tabBars["Tab Bar"].buttons["Home"].tap() - XCTAssertTrue(app.buttons["Weekly Stats"].waitForExistence(timeout: 2)) - XCTAssertTrue(app.buttons["Workout 1"].waitForExistence(timeout: 2)) + app.navigationBars["_TtGC7SwiftUI32NavigationStackHosting"].buttons["Your Account"].tap() - app.buttons["Weekly Stats"].tap() - XCTAssert(app.staticTexts["Protein Intake Data"].waitForExistence(timeout: 2)) + let notLoggedIn = app.staticTexts["Please sign-in to continue your Stronger journey"].exists + if notLoggedIn { + let scrollViewsQuery = XCUIApplication().scrollViews + let elementsQuery = scrollViewsQuery.otherElements + XCTAssertTrue(elementsQuery.textFields["E-Mail Address"].waitForExistence(timeout: 2)) + elementsQuery.textFields["E-Mail Address"].tap() + elementsQuery.textFields["E-Mail Address"].typeText("tak@g.com") + let passwordSecureTextField = elementsQuery.secureTextFields["Password"] + + XCTAssertTrue(passwordSecureTextField.waitForExistence(timeout: 2)) + passwordSecureTextField.tap() + UIPasteboard.general.string = "password" + elementsQuery.secureTextFields["Password"].tap(withNumberOfTaps: 2, numberOfTouches: 1) + passwordSecureTextField.typeText("password") + XCTAssertTrue(app.buttons["Login"].waitForExistence(timeout: 2)) + app.buttons["Login"].tap() + let canClose = app.navigationBars.buttons["Close"].exists + if canClose { + app.navigationBars.buttons["Close"].tap() + } + } else { + app.navigationBars.buttons["Close"].tap() + } + + + let account = app.navigationBars["_TtGC7SwiftUI32NavigationStackHosting"].buttons["Your Account"] + XCTAssertTrue(account.waitForExistence(timeout: 2)) + + account.tap() + + XCTAssertTrue(app.collectionViews.staticTexts["Name, E-Mail Address"].waitForExistence(timeout: 2)) + app.collectionViews.staticTexts["Name, E-Mail Address"].tap() + + app.navigationBars.buttons.element(boundBy: 0).tap() + + app.collectionViews.staticTexts["License Information"].tap() + app.navigationBars.buttons.element(boundBy: 0).tap() + + app.collectionViews.staticTexts["License Information"].tap() + app.navigationBars.buttons.element(boundBy: 0).tap() + + app.navigationBars.buttons["Close"].tap() + + XCTAssertTrue(app.buttons["Weekly Stats"].waitForExistence(timeout: 2)) + XCTAssertTrue(app.buttons["Workout 1"].waitForExistence(timeout: 2)) } } diff --git a/StrongerUITests/InputFormTest.swift b/StrongerUITests/InputFormTest.swift index 8329a32..610ce58 100644 --- a/StrongerUITests/InputFormTest.swift +++ b/StrongerUITests/InputFormTest.swift @@ -43,6 +43,7 @@ class InputFormTest: XCTestCase { XCTAssertTrue(repsTextField.exists, "The reps text field does not exist.") repsTextField.tap() repsTextField.typeText("10") + XCTAssertTrue(repsTextField.waitForExistence(timeout: 2), "The 'reps' button does not exist.") XCTAssertEqual(repsTextField.value as? String, "10", "The reps text field does not contain the expected text '10'.") let submitButton = app.buttons["Submit"] diff --git a/StrongerUITests/LLMTests.swift b/StrongerUITests/LLMTests.swift new file mode 100644 index 0000000..8577f05 --- /dev/null +++ b/StrongerUITests/LLMTests.swift @@ -0,0 +1,51 @@ +// +// This source file is part of the Stronger based on the Stanford Spezi Template Application project +// +// SPDX-FileCopyrightText: 2023 Stanford University +// +// SPDX-License-Identifier: MIT +// + +import XCTest + + +class LLMTests: XCTestCase { + override func setUpWithError() throws { + try super.setUpWithError() + + continueAfterFailure = false + + let app = XCUIApplication() + app.launchArguments = ["--skipOnboarding"] + app.launch() + } + + + func testLLMUI() throws { + let app = XCUIApplication() + XCTAssertEqual(app.state, .runningForeground) + + XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Food Tracking"].waitForExistence(timeout: 2)) + app.tabBars["Tab Bar"].buttons["Food Tracking"].tap() + + + XCTAssertTrue(app.buttons["Input with ChatBot"].waitForExistence(timeout: 2)) + app.buttons["Input with ChatBot"].tap() + + XCTAssertTrue(app.textFields["OpenAI API Key"].waitForExistence(timeout: 2)) + app.textFields["OpenAI API Key"].tap() + + app.textFields["OpenAI API Key"].typeText("FAKEAPIKEY") + app.buttons["Next"].tap() + +// XCTAssertTrue(app.textFields["Message Input Textfield"].waitForExistence(timeout: 2)) +// app.textFields["Message"].tap() +// app.textFields["Message"].typeText("Hello, I ate a lot of food") +// +// XCTAssertTrue(app.textFields["Send Message"].waitForExistence(timeout: 2)) +// +// app.textFields["Send Message"].tap() +// XCTAssertTrue(app.buttons["Select or Take Picture"].waitForExistence(timeout: 2)) +// app.buttons["Select or Take Picture"].tap() + } +} diff --git a/StrongerUITests/OnboardingTests.swift b/StrongerUITests/OnboardingTests.swift index c6deceb..78da4c0 100644 --- a/StrongerUITests/OnboardingTests.swift +++ b/StrongerUITests/OnboardingTests.swift @@ -7,7 +7,7 @@ // import XCTest - +import XCTestExtensions class OnboardingTests: XCTestCase { override func setUpWithError() throws { @@ -16,7 +16,7 @@ class OnboardingTests: XCTestCase { continueAfterFailure = false let app = XCUIApplication() - app.launchArguments = ["--showOnboarding"] + app.launchArguments = ["--showOnboarding", "--useFirebaseEmulator"] app.launch() } @@ -31,44 +31,54 @@ class OnboardingTests: XCTestCase { XCTAssertTrue(app.buttons["Next"].waitForExistence(timeout: 2)) app.buttons["Next"].tap() } + let loggedIn = app.buttons["Logout"].exists + if loggedIn { + app.buttons["Logout"].tap() + } +// try app.buttons["Log out"].tap() XCTAssertTrue(app.buttons["Signup"].waitForExistence(timeout: 2)) app.buttons["Signup"].tap() - XCTAssertTrue(app.textFields["E-Mail Address"].waitForExistence(timeout: 2)) -// app.textFields["E-Mail Address"].firstMatch.tap() - XCTAssertTrue(app.secureTextFields["Password"].waitForExistence(timeout: 2)) - XCTAssertTrue(app.textFields["enter first name"].waitForExistence(timeout: 2)) - XCTAssertTrue(app.textFields["enter last name"].waitForExistence(timeout: 2)) - XCTAssertTrue(app.buttons["Female"].waitForExistence(timeout: 2)) - XCTAssertTrue(app.textFields["Weight: lbs"].waitForExistence(timeout: 2)) - XCTAssertTrue(app.textFields["Height"].waitForExistence(timeout: 2)) -// -// do { -// try app.textFields["E-Mail Address"].tap() -// } catch { -// XCTFail("Failed to tap on the text field: \(error)") -// } -//// app.textFields["E-Mail Address"].typeText("test@gmail.com") -// -// -// enterText(textField: app.textFields["E-Mail Address"], text: "test@gmail.com") -// enterText(textField: app.secureTextFields["Password"], text: "password") -// enterText(textField: app.textFields["enter first name"], text: "testName") -// enterText(textField: app.textFields["enter last name"], text: "testLastName") -// enterText(textField: app.textFields["Weight: lbs"], text: "140") -// enterText(textField: app.textFields["Height"], text: "65") -// + let collectionViewsQuery = app.collectionViews + + collectionViewsQuery.textFields["E-Mail Address"].tap() +// collectionViewsQuery/*@START_MENU_TOKEN@*/.textFields["E-Mail Address"]/*[[".cells.textFields[\"E-Mail Address\"]",".textFields[\"E-Mail Address\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap() + collectionViewsQuery.textFields["E-Mail Address"].typeText("email@g.com") +// collectionViewsQuery.textFields["E-Mail Address"].typeText(text) + let passwordSecureTextField = collectionViewsQuery.secureTextFields["Password"] + // let passwordSecureTextField = collectionViewsQuery/*@START_MENU_TOKEN@*/.secureTextFields["Password"]/*[[".cells.secureTextFields[\"Password\"]",".secureTextFields[\"Password\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/ + passwordSecureTextField.tap() + passwordSecureTextField.typeText("password") + + collectionViewsQuery.staticTexts["PERSONAL DETAILS"].tap() + app.swipeUp() + + let enterFirstNameTextField = collectionViewsQuery.textFields["enter first name"] +// let enterFirstNameTextField = collectionViewsQuery + enterFirstNameTextField.tap() + enterFirstNameTextField.typeText("first name") + + let enterLastNameTextField = collectionViewsQuery.textFields["enter last name"] + enterLastNameTextField.tap() + + enterLastNameTextField.typeText("last name") +// collectionViewsQuery/*@START_MENU_TOKEN@*/.staticTexts["PERSONAL DETAILS"]/*[[".cells.staticTexts[\"PERSONAL DETAILS\"]",".staticTexts[\"PERSONAL DETAILS\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap() + + enterText(textField: collectionViewsQuery.textFields["Weight: lbs"], text: "140") + enterText(textField: collectionViewsQuery.textFields["Height"], text: "65") + // XCTAssertTrue(app.datePickers["Date of Birth"].waitForExistence(timeout: 2)) // // let datePicker = app.datePickers["Date of Birth"] // enterDate(datePicker: datePicker, dateDifference: 20) -// -// // Optionally, tap "Done" or outside the date picker to dismiss it + // +//// // Optionally, tap "Done" or outside the date picker to dismiss it // app.buttons["Done"].tap() } + // func enterDate(datePicker: XCUIElement, dateDifference: Int) { // datePicker.tap() // @@ -93,7 +103,8 @@ class OnboardingTests: XCTestCase { func enterText(textField: XCUIElement, text: String) { // Tap on the text field to focus on it -// textField.tap() + textField.tap() + // Type the text into the text field textField.typeText(text) diff --git a/StrongerUITests/TestImageNav.swift b/StrongerUITests/TestImageNav.swift new file mode 100644 index 0000000..2d972de --- /dev/null +++ b/StrongerUITests/TestImageNav.swift @@ -0,0 +1,39 @@ +// +// This source file is part of the Stronger based on the Stanford Spezi Template Application project +// +// SPDX-FileCopyrightText: 2023 Stanford University +// +// SPDX-License-Identifier: MIT +// + +import XCTest + + +class SelectImageTests: XCTestCase { + override func setUpWithError() throws { + try super.setUpWithError() + + continueAfterFailure = false + + let app = XCUIApplication() + app.launchArguments = ["--skipOnboarding"] + app.launch() + } + + + func testSelectImage() throws { + let app = XCUIApplication() + XCTAssertEqual(app.state, .runningForeground) + + XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Food Tracking"].waitForExistence(timeout: 2)) + app.tabBars["Tab Bar"].buttons["Food Tracking"].tap() + + XCTAssertTrue(app.buttons["Input with Camera"].waitForExistence(timeout: 2)) + + + app.buttons["Input with Camera"].tap() + + XCTAssertTrue(app.buttons["Select or Take Picture"].waitForExistence(timeout: 2)) + app.buttons["Select or Take Picture"].tap() + } +} diff --git a/StrongerUITests/testLoggedIn.swift b/StrongerUITests/testLoggedIn.swift new file mode 100644 index 0000000..14db91c --- /dev/null +++ b/StrongerUITests/testLoggedIn.swift @@ -0,0 +1,88 @@ +// +// testLoggedIn.swift +// StrongerUITests +// +// Created by Theodore Kanell on 3/12/24. +// + +import Foundation +// +// This source file is part of the Stronger based on the Stanford Spezi Template Application project +// +// SPDX-FileCopyrightText: 2023 Stanford University +// +// SPDX-License-Identifier: MIT +// + +import XCTest + + +class LoggedInTests: XCTestCase { + override func setUpWithError() throws { + try super.setUpWithError() + + continueAfterFailure = false + + let app = XCUIApplication() + app.launchArguments = ["--skipOnboarding"] + app.launch() + } + + + func testApplicationLoggedIn() throws { + let app = XCUIApplication() + XCTAssertEqual(app.state, .runningForeground) + + XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Home"].waitForExistence(timeout: 2)) + app.tabBars["Tab Bar"].buttons["Home"].tap() + + app.navigationBars["_TtGC7SwiftUI32NavigationStackHosting"].buttons["Your Account"].tap() + + let notLoggedIn = app.staticTexts["Please sign-in to continue your Stronger journey"].exists + if notLoggedIn { + let scrollViewsQuery = XCUIApplication().scrollViews + let elementsQuery = scrollViewsQuery.otherElements + XCTAssertTrue(elementsQuery.textFields["E-Mail Address"].waitForExistence(timeout: 2)) + elementsQuery.textFields["E-Mail Address"].tap() + elementsQuery.textFields["E-Mail Address"].typeText("tak@g.com") + // + let passwordSecureTextField = elementsQuery.secureTextFields["Password"] + + XCTAssertTrue(passwordSecureTextField.waitForExistence(timeout: 2)) + passwordSecureTextField.tap() + UIPasteboard.general.string = "password" + elementsQuery.secureTextFields["Password"].tap(withNumberOfTaps: 2, numberOfTouches: 1) + passwordSecureTextField.typeText("password") +// app.menuItems["Paste"].tap() + // + XCTAssertTrue(app.buttons["Login"].waitForExistence(timeout: 2)) + // + app.buttons["Login"].tap() + } else { + app.navigationBars.buttons["Close"].tap() + } + + XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Workout"].waitForExistence(timeout: 2)) + app.tabBars["Tab Bar"].buttons["Workout"].tap() + + XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Home"].waitForExistence(timeout: 2)) + app.tabBars["Tab Bar"].buttons["Home"].tap() + + XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Workout"].waitForExistence(timeout: 2)) + app.tabBars["Tab Bar"].buttons["Workout"].tap() + + XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Home"].waitForExistence(timeout: 2)) + app.tabBars["Tab Bar"].buttons["Home"].tap() + + XCTAssertTrue(app.buttons["Weekly Stats"].waitForExistence(timeout: 2)) + app.buttons["Weekly Stats"].tap() + XCTAssertTrue(app.staticTexts["Protein Intake Data"].waitForExistence(timeout: 2)) + app.navigationBars.buttons.element(boundBy: 0).tap() + + XCTAssertTrue(app.buttons["Workout 1"].waitForExistence(timeout: 2)) + let firstWorkout = app.buttons["Workout 1"].firstMatch + firstWorkout.tap() + // app.buttons["Workout 1"].tap() + // XCTAssert(app.staticTexts["Protein Intake Data"].waitForExistence(timeout: 2)) + } +}