Skip to content

Commit

Permalink
Initial setup of onboarding flow
Browse files Browse the repository at this point in the history
  • Loading branch information
vishnuravi committed Mar 30, 2024
1 parent d5c95c3 commit b90beb7
Show file tree
Hide file tree
Showing 18 changed files with 294 additions and 105 deletions.
7 changes: 1 addition & 6 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ on:
workflow_call:

jobs:
reuse_action:
name: REUSE Compliance Check
uses: StanfordBDHG/.github/.github/workflows/reuse.yml@v2
permissions:
contents: read
swiftlint:
name: SwiftLint
uses: StanfordBDHG/.github/.github/workflows/swiftlint.yml@v2
Expand All @@ -31,7 +26,7 @@ jobs:
contents: read
buildandtest:
name: Build and Test
uses: StanfordSpezi/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2
uses: StanfordBDHG/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2
permissions:
contents: read
with:
Expand Down
16 changes: 8 additions & 8 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This source file is part of the StrokeCog based on the Stanford Spezi Template Application project
# This source file is part of the StrokeCog proejct based on the Stanford Spezi Template Application project
#
# SPDX-FileCopyrightText: 2023 Stanford University
#
Expand All @@ -9,13 +9,13 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
- family-names: "Schmiedmayer"
given-names: "Paul"
orcid: "https://orcid.org/0000-0002-8607-9148"
- family-names: "Ravi"
given-names: "Vishnu"
orcid: "https://orcid.org/0000-0003-0359-1275"
- family-names: "Aalami"
given-names: "Oliver"
orcid: "https://orcid.org/0000-0002-7799-2429"
title: "StrokeCog"
- family-names: "Dobrota Lai"
given-names: "Sylvie"
orcid: "https://orcid.org/0000-0001-5134-2105"
- family-names: "Odden"
given-names: "Michelle"
orcid: "https://orcid.org/0000-0002-5974-3648"
title: "StrokeCog"
6 changes: 2 additions & 4 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,5 @@ SPDX-License-Identifier: MIT
StrokeCog Contributors
=================================

* [Paul Schmiedmayer](https://github.com/PSchmiedmayer)
* [Andreas Bauer](https://github.com/Supereg)
* [Philipp Zagar](https://github.com/philippzagar)
* [Nikolai Madlener](https://github.com/NikolaiMadlener)
* [Vishnu Ravi](https://github.com/vishnuravi)
* [Sylvie Dobrata Lai](https://github.com/sylvieddl)
9 changes: 0 additions & 9 deletions LICENSE.md

This file was deleted.

18 changes: 8 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,21 @@ SPDX-License-Identifier: MIT

# StrokeCog

This repository contains the StrokeCog.
The StrokeCog is using the [Spezi](https://github.com/StanfordSpezi/Spezi) ecosystem and builds on top of the [Stanford Spezi Template Application](https://github.com/StanfordSpezi/SpeziTemplateApplication).
This repository contains the mobile application for the StrokeCog study at Stanford University.

> [!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)
The StrokeCog study was built using the [Spezi](https://github.com/StanfordSpezi/Spezi) ecosystem and builds on top of the [Stanford Spezi Template Application](https://github.com/StanfordSpezi/SpeziTemplateApplication).


## StrokeCog Features

*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)*
- Location data collection
- Health data collection
- Daily surveys


## Contributing

*Ensure that you add an adequate contribution section to this README.*
- Vishnu Ravi (vishnur@stanford.edu)
- Sylvie Dobrota Lai (sylvied@stanford.edu)


## License

This project is licensed under the MIT License. See [Licenses](LICENSES) for more information.
[Odden Research Lab at Stanford University](https://michelleodden.com)
22 changes: 15 additions & 7 deletions StrokeCog.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
5680DD392AB8983D004E6D4A /* PackageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5680DD382AB8983D004E6D4A /* PackageCell.swift */; };
5680DD3E2AB8CD84004E6D4A /* ContributionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5680DD3D2AB8CD84004E6D4A /* ContributionsTest.swift */; };
56F6F2A02AB441930022FE5A /* ContributionsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56F6F29F2AB441930022FE5A /* ContributionsList.swift */; };
63BBF8162BB8993B006890CE /* StudyIDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63BBF8152BB8993B006890CE /* StudyIDView.swift */; };
63BBF8192BB89CF7006890CE /* studyIDs.csv in Resources */ = {isa = PBXBuildFile; fileRef = 63BBF8182BB89CF7006890CE /* studyIDs.csv */; };
653A2551283387FE005D4D48 /* StrokeCog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A2550283387FE005D4D48 /* StrokeCog.swift */; };
653A255528338800005D4D48 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 653A255428338800005D4D48 /* Assets.xcassets */; };
653A256228338800005D4D48 /* StrokeCogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A256128338800005D4D48 /* StrokeCogTests.swift */; };
Expand Down Expand Up @@ -140,6 +142,8 @@
5680DD382AB8983D004E6D4A /* PackageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackageCell.swift; sourceTree = "<group>"; };
5680DD3D2AB8CD84004E6D4A /* ContributionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributionsTest.swift; sourceTree = "<group>"; };
56F6F29F2AB441930022FE5A /* ContributionsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributionsList.swift; sourceTree = "<group>"; };
63BBF8152BB8993B006890CE /* StudyIDView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyIDView.swift; sourceTree = "<group>"; };
63BBF8182BB89CF7006890CE /* studyIDs.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = studyIDs.csv; sourceTree = "<group>"; };
653A254D283387FE005D4D48 /* StrokeCog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StrokeCog.app; sourceTree = BUILT_PRODUCTS_DIR; };
653A2550283387FE005D4D48 /* StrokeCog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrokeCog.swift; sourceTree = "<group>"; };
653A255428338800005D4D48 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -241,6 +245,7 @@
2FE5DC2F29EDD7CA004B9AB4 /* Consent.swift */,
2FE5DC3029EDD7CA004B9AB4 /* HealthKitPermissions.swift */,
2F65B44D2A3B8B0600A36932 /* NotificationPermissions.swift */,
63BBF8152BB8993B006890CE /* StudyIDView.swift */,
);
path = Onboarding;
sourceTree = "<group>";
Expand All @@ -250,6 +255,7 @@
children = (
653A255428338800005D4D48 /* Assets.xcassets */,
2FA0BFEC2ACC977500E0EF83 /* Localizable.xcstrings */,
63BBF8182BB89CF7006890CE /* studyIDs.csv */,
2FE5DC2C29EDD78E004B9AB4 /* ConsentDocument.md */,
2FE5DC2A29EDD78D004B9AB4 /* AppIcon.png */,
2FE5DC5529EDD811004B9AB4 /* SocialSupportQuestionnaire.json */,
Expand Down Expand Up @@ -537,6 +543,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
63BBF8192BB89CF7006890CE /* studyIDs.csv in Resources */,
2FC3439229EE634B002D773C /* ConsentDocument.md in Resources */,
2FC3439129EE6349002D773C /* AppIcon.png in Resources */,
653A255528338800005D4D48 /* Assets.xcassets in Resources */,
Expand Down Expand Up @@ -615,6 +622,7 @@
5680DD392AB8983D004E6D4A /* PackageCell.swift in Sources */,
2F5E32BD297E05EA003432F8 /* StrokeCogDelegate.swift in Sources */,
2FE5DC5229EDD7FA004B9AB4 /* StrokeCogScheduler.swift in Sources */,
63BBF8162BB8993B006890CE /* StudyIDView.swift in Sources */,
A9FE7AD02AA39BAB0077B045 /* AccountSheet.swift in Sources */,
653A2551283387FE005D4D48 /* StrokeCog.swift in Sources */,
2FE5DC3629EDD7CA004B9AB4 /* HealthKitPermissions.swift in Sources */,
Expand Down Expand Up @@ -751,10 +759,10 @@
INFOPLIST_KEY_NSMotionUsageDescription = "This message should never appear. Please adjust this when you start using motion information. We have to put this in here as ResearchKit has the possibility to use it and not putting it here returns an error on AppStore Connect.";
INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "This message should never appear. Please adjust this when you start using speecg information. We have to put this in here as ResearchKit has the possibility to use it and not putting it here returns an error on AppStore Connect.";
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_UIStrokeCoglicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIStrokeCoglicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -953,10 +961,10 @@
INFOPLIST_KEY_NSMotionUsageDescription = "This message should never appear. Please adjust this when you start using motion information. We have to put this in here as ResearchKit has the possibility to use it and not putting it here returns an error on AppStore Connect.";
INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "This message should never appear. Please adjust this when you start using speecg information. We have to put this in here as ResearchKit has the possibility to use it and not putting it here returns an error on AppStore Connect.";
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_UIStrokeCoglicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIStrokeCoglicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -1000,10 +1008,10 @@
INFOPLIST_KEY_NSMotionUsageDescription = "This message should never appear. Please adjust this when you start using motion information. We have to put this in here as ResearchKit has the possibility to use it and not putting it here returns an error on AppStore Connect.";
INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "This message should never appear. Please adjust this when you start using speecg information. We have to put this in here as ResearchKit has the possibility to use it and not putting it here returns an error on AppStore Connect.";
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_UIStrokeCoglicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIStrokeCoglicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -1012,7 +1020,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.odden.strokecog;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "StrokeCog";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = StrokeCog;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
Expand Down
4 changes: 2 additions & 2 deletions StrokeCog.xcodeproj/xcshareddata/xcschemes/StrokeCog.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
<CommandLineArguments>
<CommandLineArgument
argument = "--disableFirebase"
isEnabled = "YES">
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--showOnboarding"
Expand All @@ -95,7 +95,7 @@
</CommandLineArgument>
<CommandLineArgument
argument = "--useFirebaseEmulator"
isEnabled = "NO">
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
</LaunchAction>
Expand Down
6 changes: 3 additions & 3 deletions StrokeCog/Contacts/Contacts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ struct Contacts: View {
let contacts = [
Contact(
name: PersonNameComponents(
givenName: "Leland",
familyName: "Stanford"
givenName: "Dr. Michelle",
familyName: "Odden"
),
image: Image(systemName: "figure.wave.circle"), // swiftlint:disable:this accessibility_label_for_image
title: "University Founder",
title: "Principal Investigator",
description: String(localized: "LELAND_STANFORD_BIO"),
organization: "Stanford University",
address: {
Expand Down
8 changes: 0 additions & 8 deletions StrokeCog/Onboarding/InterestingModules.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ struct InterestingModules: View {
SequentialOnboardingView.Content(
title: "INTERESTING_MODULES_AREA2_TITLE",
description: "INTERESTING_MODULES_AREA2_DESCRIPTION"
),
SequentialOnboardingView.Content(
title: "INTERESTING_MODULES_AREA3_TITLE",
description: "INTERESTING_MODULES_AREA3_DESCRIPTION"
),
SequentialOnboardingView.Content(
title: "INTERESTING_MODULES_AREA4_TITLE",
description: "INTERESTING_MODULES_AREA4_DESCRIPTION"
)
],
actionText: "INTERESTING_MODULES_BUTTON",
Expand Down
1 change: 1 addition & 0 deletions StrokeCog/Onboarding/OnboardingFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct OnboardingFlow: View {
OnboardingStack(onboardingFlowComplete: $completedOnboardingFlow) {
Welcome()
InterestingModules()
StudyIDView()

if !FeatureFlags.disableFirebase {
AccountOnboarding()
Expand Down
98 changes: 98 additions & 0 deletions StrokeCog/Onboarding/StudyIDView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//
// StudyIDView.swift
// StrokeCog
//
// Created by Vishnu Ravi on 3/30/24.
//

import SpeziOnboarding
import SpeziValidation
import SpeziViews
import SwiftUI

struct StudyIDView: View {
@Environment(OnboardingNavigationPath.self) private var onboardingNavigationPath
@State private var studyID = ""
@State private var showInvalidIDAlert = false
@ValidationState private var validation

var body: some View {
VStack(spacing: 32) {
OnboardingView(
titleView: {
OnboardingTitleView(
title: "Study ID",
subtitle: "Welcome to the StrokeCog study. To get started, please enter your study ID."
)
},
contentView: {
studyIDEntryView
},
actionView: {
OnboardingActionsView(
"Next",
action: {
guard validation.validateSubviews() else {
return

Check warning on line 36 in StrokeCog/Onboarding/StudyIDView.swift

View check run for this annotation

Codecov / codecov/patch

StrokeCog/Onboarding/StudyIDView.swift#L36

Added line #L36 was not covered by tests
}

if verify(id: studyID) {
onboardingNavigationPath.nextStep()
} else {
showInvalidIDAlert = true

Check warning on line 42 in StrokeCog/Onboarding/StudyIDView.swift

View check run for this annotation

Codecov / codecov/patch

StrokeCog/Onboarding/StudyIDView.swift#L42

Added line #L42 was not covered by tests
}
}
)
}
)
}
}

@ViewBuilder private var studyIDEntryView: some View {
VerifiableTextField(
LocalizedStringResource("Tap here and enter your Study ID"),
text: $studyID
)
.autocorrectionDisabled()
.textInputAutocapitalization(.characters)
.textContentType(.oneTimeCode)
.validate(input: studyID, rules: [validationRule])
.receiveValidation(in: $validation)
.alert(
"Error",
isPresented: $showInvalidIDAlert
) {
Text("You've entered an invalid study ID.")
Button("Try Again") { }
}
}

private var validationRule: ValidationRule {
ValidationRule(
rule: { studyID in
studyID.count >= 4
},
message: "A study ID should be at least 4 characters long."
)
}

private func verify(id: String) -> Bool {
var validStudyIDs = [String]()

if let studyIDsURL = Bundle.main.url(forResource: "studyIDs", withExtension: ".csv"),
let studyIDs = try? String(contentsOf: studyIDsURL) {
let allStudyIDs = studyIDs.components(separatedBy: "\n")

for studyID in allStudyIDs {
validStudyIDs.append(studyID.filter { !$0.isWhitespace })
}

return validStudyIDs.contains(id)
}
return false

Check warning on line 92 in StrokeCog/Onboarding/StudyIDView.swift

View check run for this annotation

Codecov / codecov/patch

StrokeCog/Onboarding/StudyIDView.swift#L92

Added line #L92 was not covered by tests
}
}

#Preview {
StudyIDView()
}
4 changes: 2 additions & 2 deletions StrokeCog/Onboarding/Welcome.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ struct Welcome: View {
areas: [
OnboardingInformationView.Content(
icon: {
Image(systemName: "apps.iphone")
Image(systemName: "map")
.accessibilityHidden(true)
},
title: "WELCOME_AREA1_TITLE",
description: "WELCOME_AREA1_DESCRIPTION"
),
OnboardingInformationView.Content(
icon: {
Image(systemName: "shippingbox.fill")
Image(systemName: "figure.run")
.accessibilityHidden(true)
},
title: "WELCOME_AREA2_TITLE",
Expand Down
Loading

0 comments on commit b90beb7

Please sign in to comment.