Skip to content

Commit

Permalink
Merge pull request #435 from PermanentOrg/feature/VSP-1397-Chart-your…
Browse files Browse the repository at this point in the history
…-path-screen

VSP-1397 [iOS] Chart your path
  • Loading branch information
luciancerbu-vsp authored May 16, 2024
2 parents f940d2d + a1adcfd commit d9cdc50
Show file tree
Hide file tree
Showing 11 changed files with 351 additions and 16 deletions.
12 changes: 12 additions & 0 deletions Permanent.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
5E07D45028915FB7008C0A6B /* RightSideMenuPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E07D44F28915FB7008C0A6B /* RightSideMenuPage.swift */; };
5E07D4522891600A008C0A6B /* PrivateFilesPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E07D4512891600A008C0A6B /* PrivateFilesPage.swift */; };
5E07D45528917D83008C0A6B /* UploadFilesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E07D45428917D83008C0A6B /* UploadFilesUITests.swift */; };
5E086BE62BEBEC91007B1AF3 /* OnboardingChartYourPathView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E086BE52BEBEC91007B1AF3 /* OnboardingChartYourPathView.swift */; };
5E086BE82BED2572007B1AF3 /* OnboardingPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E086BE72BED2572007B1AF3 /* OnboardingPath.swift */; };
5E086BEA2BEE4408007B1AF3 /* PathItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E086BE92BEE4408007B1AF3 /* PathItemView.swift */; };
5E0ADB8D279052A500F39E7E /* PublicProfileLocationSetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E0ADB8C279052A500F39E7E /* PublicProfileLocationSetViewController.swift */; };
5E0B1BD42B961CE800B10BB5 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E0B1BD32B961CE800B10BB5 /* OnboardingView.swift */; };
5E0E3C2E2886DBCA001C7F10 /* ShareExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E0E3C2D2886DBCA001C7F10 /* ShareExtensionTests.swift */; };
Expand Down Expand Up @@ -979,6 +982,9 @@
5E07D44F28915FB7008C0A6B /* RightSideMenuPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RightSideMenuPage.swift; sourceTree = "<group>"; };
5E07D4512891600A008C0A6B /* PrivateFilesPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivateFilesPage.swift; sourceTree = "<group>"; };
5E07D45428917D83008C0A6B /* UploadFilesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadFilesUITests.swift; sourceTree = "<group>"; };
5E086BE52BEBEC91007B1AF3 /* OnboardingChartYourPathView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingChartYourPathView.swift; sourceTree = "<group>"; };
5E086BE72BED2572007B1AF3 /* OnboardingPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPath.swift; sourceTree = "<group>"; };
5E086BE92BEE4408007B1AF3 /* PathItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PathItemView.swift; sourceTree = "<group>"; };
5E0ADB8C279052A500F39E7E /* PublicProfileLocationSetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicProfileLocationSetViewController.swift; sourceTree = "<group>"; };
5E0B1BD32B961CE800B10BB5 /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = "<group>"; };
5E0E3C2D2886DBCA001C7F10 /* ShareExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareExtensionTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1859,6 +1865,8 @@
5ED9A7B52BBF3294009BDD70 /* OnboardingSelectArchiveTypeView.swift */,
5EE3E9DF2BCD447100A5EFE5 /* OnboardingArchiveName.swift */,
5ED9A7B72BBF3BD6009BDD70 /* ArchiveTypeView.swift */,
5E086BE52BEBEC91007B1AF3 /* OnboardingChartYourPathView.swift */,
5E086BE92BEE4408007B1AF3 /* PathItemView.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -3698,6 +3706,7 @@
5E3A6EE8275F610B00AD6DCC /* FieldNameUI.swift */,
5E781EA72787006B0007E397 /* ProfileItemOperation.swift */,
5E3A05FF29E44D7900A6C531 /* Workspace.swift */,
5E086BE72BED2572007B1AF3 /* OnboardingPath.swift */,
);
path = Enums;
sourceTree = "<group>";
Expand Down Expand Up @@ -4533,6 +4542,7 @@
92E3FB512A17681A00E9E5A6 /* LegacyPlanningStatusViewController.swift in Sources */,
5E6673172A7A3A78001C49CC /* AppendFilenameViewModel.swift in Sources */,
BC59BAEA25C2CC8E005A45D3 /* NotificationType.swift in Sources */,
5E086BE82BED2572007B1AF3 /* OnboardingPath.swift in Sources */,
F5853D2026E9FA5A0050E377 /* Permission.swift in Sources */,
5E181B822AF10100002DE69A /* GiftStorageViewModel.swift in Sources */,
5E9977B0285098FD003E0C46 /* AVCaptureDeviceExtension.swift in Sources */,
Expand Down Expand Up @@ -4758,6 +4768,7 @@
BCE8DA7F256674D300842ABD /* BottomActionSheet.swift in Sources */,
BC3DF862252DB8BA003D3829 /* LocalAuthErrors.swift in Sources */,
BCD948D4258BA54600089F86 /* ItemVO.swift in Sources */,
5E086BE62BEBEC91007B1AF3 /* OnboardingChartYourPathView.swift in Sources */,
BC6D3B432513664C00390927 /* AuthViewModel.swift in Sources */,
BC6D3B552514F26F00390927 /* APIError.swift in Sources */,
5E991EDF2A48E05C006229C0 /* MetadataEditView.swift in Sources */,
Expand Down Expand Up @@ -4806,6 +4817,7 @@
F5853CFA26DEBB9D0050E377 /* PRMNTActionSheetViewController.swift in Sources */,
BC59BAB425C2B7D6005A45D3 /* SharePreviewViewModelDelegate.swift in Sources */,
5E6FB7582A73E15800984B84 /* MetadataEditFileNamesView.swift in Sources */,
5E086BEA2BEE4408007B1AF3 /* PathItemView.swift in Sources */,
5EDDAE5A2A9E312E00415D9A /* EditDateAndTimeView.swift in Sources */,
5EB4C6382BD2F00100561F0F /* CustomBorderTextField.swift in Sources */,
5EA94A122B3486B000AD67F5 /* BottomInvalidAlertMessageView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ import SwiftUI

struct RoundButtonRightImageView: View {
enum ButtonType {
case fillColor, noColor
case fillColor, noColor, noBorder
}

var type: ButtonType = .fillColor
var isDisabled: Bool = false
var isLoading: Bool = false
let text: String
let rightImage: Image = Image(.rightArrowShort)
var rightImage: Image = Image(.rightArrowShort)
let action: () -> Void

var body: some View {
Button(action: action, label: {
if type == .fillColor {
switch type {
case .fillColor:
ZStack {
Color(.white)
HStack() {
Expand Down Expand Up @@ -53,8 +54,7 @@ struct RoundButtonRightImageView: View {
.frame(height: 56)
.cornerRadius(12)
.frame(maxWidth: .infinity)
}
if type == .noColor {
case .noColor:
ZStack {
HStack() {
if Constants.Design.isPhone {
Expand Down Expand Up @@ -91,6 +91,39 @@ struct RoundButtonRightImageView: View {
.stroke(.white.opacity(0.32), lineWidth: 1)

)
case .noBorder:
ZStack {
HStack() {
Spacer()
if Constants.Design.isPhone {
Text(text)
.textStyle(UsualSmallXMediumTextStyle())
.foregroundColor(.white)
.lineLimit(1)
.minimumScaleFactor(0.8)
} else {
Text(text)
.textStyle(UsualRegularMediumTextStyle())
.foregroundColor(.white)
.lineLimit(1)
.minimumScaleFactor(0.8)
}
if isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.frame(width: 24, height: 24)
} else {
rightImage
.frame(width: 24, height: 24, alignment: .center)
.accentColor(.white)
}
Spacer()
}
.padding(.horizontal, 24)
}
.frame(height: 56)
.cornerRadius(12)
.frame(maxWidth: .infinity)
}
})
.disabled(isDisabled || isLoading)
Expand Down
9 changes: 9 additions & 0 deletions Permanent/Common/Constants/Colors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,13 @@ extension Gradient {
startPoint: UnitPoint(x: 0, y: 0),
endPoint: UnitPoint(x: 1, y: 1)
)

static var lightDarkPurpleGradient = LinearGradient(stops:
[
Gradient.Stop(color: Color(red: 0.5, green: 0, blue: 0.5), location: 0.00),
Gradient.Stop(color: Color(red: 0.72, green: 0.26, blue: 0.65), location: 1.00),
],
startPoint: UnitPoint(x: 0, y: 0),
endPoint: UnitPoint(x: 1, y: 1)
)
}
34 changes: 34 additions & 0 deletions Permanent/Common/Models/Enums/OnboardingPath.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// OnboardingPath.swift
// Permanent
//
// Created by Lucian Cerbu on 09.05.2024.

import Foundation

enum OnboardingPath: String, CaseIterable, Identifiable {
var id: String { return self.rawValue }

case capture, digitize, collaborate, createPublicArchive, shareArchive, createPlan, organize, somethingElse = ""

var description: String {
switch self {
case .capture:
return "Capture and preserve memories for storytelling"
case .digitize:
return "Digitize or transfer my materials securely"
case .collaborate:
return "Collaborate with others to build my archive"
case .createPublicArchive:
return "Create a public archive to share a legacy"
case .shareArchive:
return "Share my archive with others securely"
case .createPlan:
return "Create a plan for passing on my digital materials"
case .organize:
return "Organize my materials"
case .somethingElse:
return "Something else..."
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SwiftUI
class OnboardingStorageValues: ObservableObject {
@Published var archiveType: ArchiveType = .person
@Published var textFieldText: String = ""
@Published var selectedPath: [OnboardingPath] = []
@Published var fullName: String = AuthenticationManager.shared.session?.account.fullName ?? ""

let welcomeMessage: String = "We’re so glad you’re here!\n\nAt Permanent, it is our mission to provide a safe and secure place to store, preserve, and share the digital legacy of all people, whether that's for you or for your friends, family, interests or organizations.\n\nWe know that starting this journey can sometimes be overwhelming, but don’t worry. We’re here to help you every step of the way."
Expand All @@ -20,4 +21,13 @@ class OnboardingStorageValues: ObservableObject {
}
return "a"
}

func togglePath(path: OnboardingPath) {
if let index = selectedPath.firstIndex(of: path)
{
selectedPath.remove(at: index)
} else {
selectedPath.append(path)
}
}
}
118 changes: 118 additions & 0 deletions Permanent/Modules/Onboarding/Views/OnboardingChartYourPathView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//
// OnboardingChartYourPathView.swift
// Permanent
//
// Created by Lucian Cerbu on 08.05.2024.

import SwiftUI

struct OnboardingChartYourPathView: View {
@State var presentSelectArchivesType: Bool = false
@ObservedObject var onboardingValues: OnboardingStorageValues

var backButton: (() -> Void)
var nextButton: (() -> Void)
var skipButton: (() -> Void)
@State var isKeyboardPresented = false
@State var textFieldText: String = ""

var body: some View {
if Constants.Design.isPhone {
iPhoneBody
} else {
iPadBody
}
}

var iPhoneBody: some View {
ZStack(alignment: .bottom) {
VStack {
ScrollViewReader { scrollReader in
ScrollView(showsIndicators: false) {
VStack(alignment: .leading, spacing: 24) {
Text("Chart your \npath to success")
.textStyle(UsualXLargeLightTextStyle())
.foregroundColor(.white)
Text("Let’s set some goals. Everyone has unique goals for preserving their legacy. We want to learn more about how we can help you achieve yours.")
.textStyle(UsualSmallXRegularTextStyle())
.foregroundColor(.blue25)
.lineSpacing(8.0)
VStack(alignment: .leading) {
ForEach(OnboardingPath.allCases, id: \.id) { path in
Button {
onboardingValues.togglePath(path: path)
} label: {
PathItemView(path: path, isSelected: onboardingValues.selectedPath.contains(path))
}
}
}
}
}
}
Spacer(minLength: 160)
}
VStack {
RoundButtonRightImageView(type: .noBorder, text: "Skip this step", rightImage: Image(.onboardingForward), action: skipButton)
HStack(alignment: .center) {
SmallRoundButtonImageView(type: .noColor, imagePlace: .onLeft, text: "Back", image: Image(.leftArrowShort), action: backButton)
SmallRoundButtonImageView(isDisabled: onboardingValues.textFieldText.isEmpty, text: "Next", action: nextButton)
}
}
.padding(.bottom, 40)
.sheet(isPresented: $presentSelectArchivesType, content: {
OnboardingSelectArchiveTypeView(onboardingValues: onboardingValues)
})
}
}

var iPadBody: some View {
HStack(alignment: .top, spacing: 64) {
ScrollView(showsIndicators: false) {
VStack {
HStack() {
Text("Create your \n\(onboardingValues.archiveType.onboardingType) archive")
.textStyle(UsualXXLargeLightTextStyle())
.foregroundColor(.white)
.multilineTextAlignment(.leading)
Spacer()
}
Spacer()
}
}
ZStack(alignment: .bottom) {
ScrollViewReader { scrollReader in
ScrollView(showsIndicators: false) {
VStack(alignment: .leading, spacing: 64) {
Text("Name your new archive. This is the legal or official name of the person, family, group, or organization the archive is about. You can edit the name later if needed.")
.textStyle(UsualRegularTextStyle())
.foregroundColor(.blue25)
.lineSpacing(8.0)
CustomBorderTextField(textFieldText: $onboardingValues.textFieldText, placeholder: "Name...")
}
}
.onReceive(keyboardPublisher) { keyboard in
if keyboard.isFirstResponder {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
withAnimation {
scrollReader.scrollTo(1, anchor: .center)
}
})
}
}
.onAppear {
UIScrollView.appearance().bounces = false
}
.onDisappear {
UIScrollView.appearance().bounces = true
}
}
HStack(spacing: 32) {
SmallRoundButtonImageView(type: .noColor, imagePlace: .onLeft, text: "Back", image: Image(.backArrowOnboarding), action: backButton)
.frame(width: 120)
RoundButtonRightImageView(isDisabled: onboardingValues.textFieldText.isEmpty, text: "Create the archive", action: nextButton)
}
.padding(.bottom, 40)
}
}
}
}
29 changes: 28 additions & 1 deletion Permanent/Modules/Onboarding/Views/OnboardingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct OnboardingView: View {
@State private var contentType: ContentType = .welcome

enum ContentType {
case none, welcome, createArchive, setArchiveName
case none, welcome, createArchive, setArchiveName, chartYourPath
}

@State var bottomButtonsPadding: CGFloat = 40
Expand Down Expand Up @@ -76,6 +76,26 @@ struct OnboardingView: View {
contentType = .createArchive
}
} nextButton: {
isBack = false
withAnimation {
contentType = .chartYourPath
}
}
.transition(AnyTransition.asymmetric(
insertion:.move(edge: isBack ? .leading : .trailing),
removal: .opacity)
)

case .chartYourPath:
OnboardingChartYourPathView(onboardingValues: onboardingValues) {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
isBack = true
withAnimation {
contentType = .setArchiveName
}
} nextButton: {

} skipButton: {

}
.transition(AnyTransition.asymmetric(
Expand Down Expand Up @@ -103,14 +123,21 @@ struct OnboardingView: View {
DividerSmallBarView(type: .empty)
DividerSmallBarView(type: .empty)
DividerSmallBarView(type: .empty)

case .welcome:
DividerSmallBarView(type: .empty)
DividerSmallBarView(type: .empty)
DividerSmallBarView(type: .empty)

case .createArchive, .setArchiveName:
DividerSmallBarView(type: .gradient)
DividerSmallBarView(type: .empty)
DividerSmallBarView(type: .empty)

case .chartYourPath:
DividerSmallBarView(type: .gradient)
DividerSmallBarView(type: .gradient)
DividerSmallBarView(type: .empty)
}
}
.padding(.top, 24)
Expand Down
Loading

0 comments on commit d9cdc50

Please sign in to comment.