Merge pull request #169 from LukasKorba/138_onbordingUI_enhancements

138 onbording UI enhancements
This commit is contained in:
Francisco Gindre 2022-02-24 11:22:09 -03:00 committed by GitHub
commit 4f08c8cd92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 926 additions and 135 deletions

View File

@ -82,6 +82,8 @@
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; };
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */; };
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; };
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; };
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9322DBF273B555C00C105B5 /* NavigationLinks.swift */; };
F93673D62742CB840099C6AF /* Previews.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93673D52742CB840099C6AF /* Previews.swift */; };
F93874F0273C4DE200F0E875 /* HomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874ED273C4DE200F0E875 /* HomeStore.swift */; };
@ -209,6 +211,8 @@
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = "<group>"; };
66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtonStyle.swift; sourceTree = "<group>"; };
66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardButtonStyle.swift; sourceTree = "<group>"; };
9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicDesignModifier.swift; sourceTree = "<group>"; };
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = "<group>"; };
F9322DBF273B555C00C105B5 /* NavigationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationLinks.swift; sourceTree = "<group>"; };
F93673D52742CB840099C6AF /* Previews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Previews.swift; sourceTree = "<group>"; };
F93874ED273C4DE200F0E875 /* HomeStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeStore.swift; sourceTree = "<group>"; };
@ -445,6 +449,7 @@
isa = PBXGroup;
children = (
0D8A43C3272AEEDE005A6414 /* SecantTextStyles.swift */,
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */,
);
path = FontStyles;
sourceTree = "<group>";
@ -562,6 +567,7 @@
663FAB9F271D876200E495F8 /* PrimaryButton.swift */,
663FABA1271D876C00E495F8 /* SecondaryButton.swift */,
66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */,
9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */,
);
path = Buttons;
sourceTree = "<group>";
@ -1000,11 +1006,13 @@
0DC487C32772574C00BE6A63 /* ValidationSucceededView.swift in Sources */,
0D8A43C4272AEEDE005A6414 /* SecantTextStyles.swift in Sources */,
0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */,
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */,
0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */,
0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift in Sources */,
0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */,
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */,
6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */,
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */,
0DDB6A5127737D4A0012A410 /* ValidationFailedView.swift in Sources */,
0D6D628B276A528E002FB4CC /* DropDelegate.swift in Sources */,
F9971A5327680DD000A2DB75 /* Profile.swift in Sources */,

View File

@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.725",
"red" : "1.000"
"blue" : "0x00",
"green" : "0xB9",
"red" : "0xFF"
}
},
"idiom" : "universal"

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.341",
"green" : "0.200",
"red" : "0.149"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.200",
"blue" : "0x28",
"green" : "0xB7",
"red" : "0xF4"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.902",
"green" : "0.867",
"red" : "0.804"
"blue" : "0x57",
"green" : "0x33",
"red" : "0x26"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.514",
"green" : "0.486",
"red" : "0.443"
"blue" : "0.000",
"green" : "0.847",
"red" : "1.000"
}
},
"idiom" : "universal"

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.330",
"blue" : "0x36",
"green" : "0x2C",
"red" : "0x27"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.000",
"blue" : "0x36",
"green" : "0x2C",
"red" : "0x27"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.820",
"green" : "0.722",
"red" : "0.631"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.150",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.992",
"green" : "0.980",
"red" : "0.969"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.150",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.937",
"green" : "0.863",
"red" : "0.784"
"blue" : "0xFD",
"green" : "0xF7",
"red" : "0xF1"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.937",
"green" : "0.863",
"red" : "0.784"
"blue" : "217",
"green" : "192",
"red" : "167"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xD9",
"green" : "0xC0",
"red" : "0xA7"
"blue" : "0xFC",
"green" : "0xF8",
"red" : "0xF5"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xD9",
"green" : "0xC0",
"red" : "0xA7"
"blue" : "0xEF",
"green" : "0xDC",
"red" : "0xC8"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.984",
"green" : "0.953",
"red" : "0.910"
"blue" : "0xFD",
"green" : "0xF7",
"red" : "0xF1"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.851",
"green" : "0.753",
"red" : "0.655"
"blue" : "217",
"green" : "192",
"red" : "167"
}
},
"idiom" : "universal"

View File

@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "0.200",
"blue" : "0.933",
"green" : "0.863",
"red" : "0.780"
"blue" : "0xEF",
"green" : "0xDC",
"red" : "0xC8"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.996",
"green" : "0.988",
"red" : "0.984"
"blue" : "253",
"green" : "250",
"red" : "244"
}
},
"idiom" : "universal"

View File

@ -4,7 +4,7 @@
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"alpha" : "0.000",
"blue" : "0xFF",
"green" : "0xFF",
"red" : "0xFF"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
"blue" : "246",
"green" : "234",
"red" : "222"
}
},
"idiom" : "universal"
@ -22,10 +22,10 @@
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.200",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
"alpha" : "1.000",
"blue" : "106",
"green" : "72",
"red" : "61"
}
},
"idiom" : "universal"

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "69",
"green" : "32",
"red" : "19"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "66",
"green" : "30",
"red" : "21"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "117",
"green" : "80",
"red" : "69"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "233",
"green" : "221",
"red" : "209"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "106",
"green" : "63",
"red" : "44"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFD",
"green" : "0xF7",
"red" : "0xF1"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x62",
"green" : "0x33",
"red" : "0x22"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.820",
"green" : "0.722",
"red" : "0.631"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.271",
"green" : "0.125",
"red" : "0.075"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.992",
"green" : "0.980",
"red" : "0.969"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.345",
"green" : "0.196",
"red" : "0.157"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -2,12 +2,12 @@
"colors" : [
{
"color" : {
"color-space" : "extended-linear-srgb",
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF3",
"green" : "0xE4",
"red" : "0xD2"
"blue" : "243",
"green" : "228",
"red" : "210"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x5A",
"green" : "0x36",
"red" : "0x29"
"blue" : "0x55",
"green" : "0x31",
"red" : "0x24"
}
},
"idiom" : "universal"

View File

@ -2,12 +2,12 @@
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF9",
"green" : "0xEF",
"red" : "0xE3"
"blue" : "249",
"green" : "239",
"red" : "227"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x55",
"green" : "0x31",
"red" : "0x24"
"blue" : "0x5A",
"green" : "0x36",
"red" : "0x29"
}
},
"idiom" : "universal"

View File

@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.333",
"green" : "0.192",
"red" : "0.141"
"blue" : "0x52",
"green" : "0x31",
"red" : "0x26"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x59",
"green" : "0x35",
"red" : "0x28"
"blue" : "0x47",
"green" : "0x37",
"red" : "0x2D"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
"blue" : "0x00",
"green" : "0x00",
"red" : "0x00"
}
},
"idiom" : "universal"

View File

@ -39,6 +39,7 @@ enum OnboardingAction: Equatable {
case back
case skip
case createNewWallet
case importExistingWallet
}
typealias OnboardingReducer = Reducer<OnboardingState, OnboardingAction, Void>
@ -69,6 +70,9 @@ extension OnboardingReducer {
case .createNewWallet:
return .none
case .importExistingWallet:
return .none
}
}
}

View File

@ -44,9 +44,14 @@ internal enum Asset {
}
internal enum Buttons {
internal static let activeButton = ColorAsset(name: "ActiveButton")
internal static let activeButtonDisabled = ColorAsset(name: "ActiveButtonDisabled")
internal static let activeButtonPressed = ColorAsset(name: "ActiveButtonPressed")
internal static let buttonsTitleShadow = ColorAsset(name: "ButtonsTitleShadow")
internal static let createButton = ColorAsset(name: "CreateButton")
internal static let createButtonDisabled = ColorAsset(name: "CreateButtonDisabled")
internal static let createButtonPressed = ColorAsset(name: "CreateButtonPressed")
internal static let neumorphicButtonDarkSide = ColorAsset(name: "NeumorphicButtonDarkSide")
internal static let neumorphicButtonLightSide = ColorAsset(name: "NeumorphicButtonLightSide")
internal static let onboardingNavigation = ColorAsset(name: "OnboardingNavigation")
internal static let onboardingNavigationPressed = ColorAsset(name: "OnboardingNavigationPressed")
internal static let primaryButton = ColorAsset(name: "PrimaryButton")
@ -56,9 +61,15 @@ internal enum Asset {
internal static let secondaryButtonPressed = ColorAsset(name: "SecondaryButtonPressed")
}
internal enum Onboarding {
internal static let circularFrame = ColorAsset(name: "CircularFrame")
internal static let badgeShadow = ColorAsset(name: "BadgeShadow")
internal static let circularFrameDarkOutlineGradientEnd = ColorAsset(name: "CircularFrameDarkOutlineGradientEnd")
internal static let circularFrameDarkOutlineGradientStart = ColorAsset(name: "CircularFrameDarkOutlineGradientStart")
internal static let circularFrameGradientEnd = ColorAsset(name: "CircularFrameGradientEnd")
internal static let circularFrameGradientStart = ColorAsset(name: "CircularFrameGradientStart")
internal static let navigationButtonDisabled = ColorAsset(name: "NavigationButtonDisabled")
internal static let navigationButtonEnabled = ColorAsset(name: "NavigationButtonEnabled")
internal static let neumorphicDarkSide = ColorAsset(name: "NeumorphicDarkSide")
internal static let neumorphicLightSide = ColorAsset(name: "NeumorphicLightSide")
}
internal enum ProgressIndicator {
internal static let gradientLeft = ColorAsset(name: "GradientLeft")

View File

@ -41,7 +41,7 @@ struct OnboardingContentView: View {
}
)
)
.frame(width: width * 0.85, height: width * 0.85)
.frame(width: circularFrameUniformSize, height: circularFrameUniformSize)
.badgeIcons(
store.actionless.scope(
state: { state in
@ -52,7 +52,7 @@ struct OnboardingContentView: View {
}
)
)
.offset(y: viewStore.offset - height / 7)
.offset(y: viewStore.offset - height / circularFrameOffsetCoeffcient)
.transition(.scale(scale: 2).combined(with: .opacity))
}
}
@ -61,34 +61,90 @@ struct OnboardingContentView: View {
VStack(spacing: viewStore.isFinalStep ? 50 : 15) {
HStack {
Text(viewStore.steps[stepIndex].title)
.font(.custom(FontFamily.Roboto.bold.name, size: 30))
.fontWeight(.regular)
.titleText()
.lineLimit(0)
.minimumScaleFactor(0.1)
if !viewStore.isFinalStep {
Spacer()
}
}
Text(viewStore.steps[stepIndex].description)
.font(.custom(FontFamily.Roboto.regular.name, size: 15))
.lineSpacing(5)
.paragraphText()
.lineSpacing(2)
.opacity(0.53)
}
.opacity(stepIndex == viewStore.index ? 1: 0)
.padding(.horizontal, 35)
.frame(width: width, height: height)
}
}
.offset(y: viewStore.isFinalStep ? width / 2.3 : viewStore.offset + width / 2.3)
.offset(y: viewStore.isFinalStep ? width / 2.5 : viewStore.offset + height / descriptionOffsetCoefficient)
}
}
}
/// Following computations are necessary to handle properly sizing and positioning of elements
/// on different devices (apects). iPhone SE and iPhone 8 are similar aspect family devices
/// while iPhone X, 11, etc are different family devices, capable to use more of the space.
extension OnboardingContentView {
var circularFrameUniformSize: CGFloat {
var deviceMultiplier = 1.0
if width > 0.0 {
let aspect = height / width
deviceMultiplier = 1.0 + (((aspect / 1.725) - 1.0) * 2.0)
}
return width * 0.6 * deviceMultiplier
}
var circularFrameOffsetCoeffcient: CGFloat {
var deviceMultiplier = 1.0
if width > 0.0 {
let aspect = height / width
deviceMultiplier = aspect / 1.725
}
return 4.4 * deviceMultiplier
}
var descriptionOffsetCoefficient: Double {
if width > 0.0 {
let aspect = height / width
let deviceMultiplier = 1.0 + (((aspect / 1.725) - 1.0) * 2.5)
if abs(deviceMultiplier) > 0.0 {
return 8.0 / deviceMultiplier
}
}
return 8.0
}
}
struct OnboardingContentView_Previews: PreviewProvider {
static var previews: some View {
let store = Store(
initialState: OnboardingState(index: 2),
initialState: OnboardingState(index: 0),
reducer: OnboardingReducer.default,
environment: ()
)
OnboardingContentView_Previews.example(store)
.previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)"))
OnboardingContentView_Previews.example(store)
.previewDevice(PreviewDevice(rawValue: "iPhone 8"))
OnboardingContentView_Previews.example(store)
.previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro"))
}
}
extension OnboardingContentView_Previews {
static func example(_ store: Store<OnboardingState, OnboardingAction>) -> some View {
GeometryReader { proxy in
ZStack {
OnboardingHeaderView(
@ -114,8 +170,9 @@ struct OnboardingContentView_Previews: PreviewProvider {
width: proxy.size.width,
height: proxy.size.height
)
.preferredColorScheme(.light)
}
}
.applyScreenBackground()
.preferredColorScheme(.light)
}
}

View File

@ -13,61 +13,86 @@ struct OnboardingFooterView: View {
let animationDuration: CGFloat = 0.8
var body: some View {
GeometryReader { proxy in
WithViewStore(self.store) { viewStore in
VStack(spacing: 5) {
Spacer()
if viewStore.isFinalStep {
Button("Create New Wallet") {
withAnimation(.easeInOut(duration: animationDuration)) {
viewStore.send(.createNewWallet)
}
WithViewStore(self.store) { viewStore in
VStack(spacing: 5) {
Spacer()
if viewStore.isFinalStep {
Button("Create New Wallet") {
withAnimation(.easeInOut(duration: animationDuration)) {
viewStore.send(.createNewWallet)
}
.primaryButtonStyle
.frame(height: proxy.size.height / 12)
.padding(.horizontal, 15)
.transition(.opacity)
} else {
Button("Next") {
withAnimation(.easeInOut(duration: animationDuration)) {
viewStore.send(.next)
}
}
.primaryButtonStyle
.frame(height: proxy.size.height / 12)
.padding(.horizontal, 15)
.transition(.opacity)
}
.createButtonStyle
.onboardingFooterButtonLayout()
Button("Import an Existing Wallet") {
withAnimation(.easeInOut(duration: animationDuration)) {
viewStore.send(.createNewWallet)
}
}
.secondaryButtonStyle
.onboardingFooterButtonLayout()
} else {
Button("Next") {
withAnimation(.easeInOut(duration: animationDuration)) {
viewStore.send(.next)
}
}
.primaryButtonStyle
.onboardingFooterButtonLayout()
ProgressView(
"\(viewStore.index + 1)/\(viewStore.steps.count)",
String(format: "%02d", viewStore.index + 1),
value: Double(viewStore.index + 1),
total: Double(viewStore.steps.count)
)
.onboardingProgressStyle
.padding(.horizontal, 30)
.padding([.vertical], 20)
.padding(.vertical, 20)
}
}
}
}
}
// swiftlint:disable:next private_over_fileprivate strict_fileprivate
fileprivate struct OnboardingFooterButtonLayout: ViewModifier {
func body(content: Content) -> some View {
content
.frame(height: 60)
.padding(.horizontal, 28)
.transition(.opacity)
}
}
extension View {
func onboardingFooterButtonLayout() -> some View {
modifier(OnboardingFooterButtonLayout())
}
}
struct OnboardingFooterView_Previews: PreviewProvider {
static var previews: some View {
let store = Store<OnboardingState, OnboardingAction>(
initialState: OnboardingState(index: 0),
initialState: OnboardingState(index: 3),
reducer: OnboardingReducer.default,
environment: ()
)
Group {
OnboardingFooterView(store: store)
.applyScreenBackground()
.preferredColorScheme(.light)
.previewDevice("iPhone 13 Pro Max")
OnboardingFooterView(store: store)
.applyScreenBackground()
.preferredColorScheme(.dark)
.previewDevice("iPhone 13 Pro Max")
OnboardingFooterView(store: store)
.applyScreenBackground()
.preferredColorScheme(.dark)
.previewDevice("iPhone 13 mini")
}

View File

@ -55,7 +55,7 @@ struct OnboardingHeaderView: View {
Spacer()
}
.padding(.top, 20)
.padding(.top, 5)
}
}
}
@ -85,5 +85,6 @@ struct OnboardingHeaderView_Previews: PreviewProvider {
)
)
.preferredColorScheme(.light)
.applyScreenBackground()
}
}

View File

@ -56,5 +56,56 @@ struct OnboardingScreen_Previews: PreviewProvider {
)
)
.preferredColorScheme(.light)
.previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)"))
OnboardingScreen(
store: Store(
initialState: OnboardingState(),
reducer: OnboardingReducer.default,
environment: ()
)
)
.preferredColorScheme(.light)
.previewDevice(PreviewDevice(rawValue: "iPhone 8"))
OnboardingScreen(
store: Store(
initialState: OnboardingState(),
reducer: OnboardingReducer.default,
environment: ()
)
)
.preferredColorScheme(.light)
.previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro"))
OnboardingScreen(
store: Store(
initialState: OnboardingState(),
reducer: OnboardingReducer.default,
environment: ()
)
)
.preferredColorScheme(.dark)
.previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)"))
OnboardingScreen(
store: Store(
initialState: OnboardingState(),
reducer: OnboardingReducer.default,
environment: ()
)
)
.preferredColorScheme(.dark)
.previewDevice(PreviewDevice(rawValue: "iPhone 8"))
OnboardingScreen(
store: Store(
initialState: OnboardingState(),
reducer: OnboardingReducer.default,
environment: ()
)
)
.preferredColorScheme(.dark)
.previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro"))
}
}

View File

@ -13,7 +13,8 @@ extension Button {
StandardButtonStyle(
foregroundColor: Asset.Colors.Text.activeButtonText.color,
background: Asset.Colors.Buttons.activeButton.color,
pressedBackgroundColor: Asset.Colors.Buttons.activeButton.color
pressedBackgroundColor: Asset.Colors.Buttons.activeButtonPressed.color,
disabledBackgroundColor: Asset.Colors.Buttons.activeButtonDisabled.color
)
)
}

View File

@ -13,7 +13,8 @@ extension Button {
StandardButtonStyle(
foregroundColor: Asset.Colors.Text.button.color,
background: Asset.Colors.Buttons.createButton.color,
pressedBackgroundColor: Asset.Colors.Buttons.createButtonPressed.color
pressedBackgroundColor: Asset.Colors.Buttons.createButtonPressed.color,
disabledBackgroundColor: Asset.Colors.Buttons.createButtonDisabled.color
)
)
}

View File

@ -23,6 +23,7 @@ struct NavigationButtonStyle: ButtonStyle {
Asset.Colors.Buttons.onboardingNavigation.color
)
.cornerRadius(.infinity)
.neumorphicButton(configuration.isPressed)
}
}
@ -39,12 +40,14 @@ struct NavigationModifier_Previews: PreviewProvider {
Button("Back") { dump("Example button") }
.navigationButtonStyle
.frame(width: 80, height: 40)
.applyScreenBackground()
.previewLayout(.fixed(width: 300, height: 100))
.preferredColorScheme(.dark)
Button("Skip") { dump("Example button") }
.navigationButtonStyle
.frame(width: 80, height: 40)
.applyScreenBackground()
.previewLayout(.fixed(width: 300, height: 100))
.preferredColorScheme(.light)
}

View File

@ -0,0 +1,84 @@
//
// NeumorphicDesignModifier.swift
// secant-testnet
//
// Created by Lukáš Korba on 02/21/22.
//
import SwiftUI
/// Neumorphic design is charasterictical with two shadows (light & dark) around the view
/// Appereance in our case is influenced by two parameters:
/// - Parameters:
/// - colorScheme: The light is using full neumorphic design while dark is limited to soft shadow only
/// - isPressed: When the button is pressed, there are different behaviours for light vs. dark colorScheme
/// This design is mostly used for CircularFrame, not designed for a button (see NeumorphicButtonDesign)
// swiftlint:disable:next private_over_fileprivate strict_fileprivate
fileprivate struct Neumorphic: ViewModifier {
@Environment(\.colorScheme) var colorScheme
let isPressed: Bool
init(_ isPressed: Bool) {
self.isPressed = isPressed
}
func body(content: Content) -> some View {
content
.shadow(
color: Asset.Colors.Onboarding.neumorphicDarkSide.color,
radius: 15,
x: colorScheme == .light && !isPressed ? 10 : -10,
y: 10
)
.shadow(
color: Asset.Colors.Onboarding.neumorphicLightSide.color,
radius: 10,
x: colorScheme == .light && !isPressed ? -12 : 12,
y: -12
)
}
}
/// Neumorphic design is charasterictical with two shadows (light & dark) around the button
/// Appereance in our case is influenced by two parameters:
/// - Parameters:
/// - colorScheme: The light is using full neumorphic design while dark is limited to soft shadow only
/// - isPressed: When the button is pressed, there are different behaviours for light vs. dark colorScheme
/// This design is specifically crafted for buttons. The colors and positions of the shadows are different.
// swiftlint:disable:next private_over_fileprivate strict_fileprivate
fileprivate struct NeumorphicButton: ViewModifier {
@Environment(\.colorScheme) var colorScheme
let isPressed: Bool
init(_ isPressed: Bool) {
self.isPressed = isPressed
}
func body(content: Content) -> some View {
content
.shadow(
color: Asset.Colors.Buttons.neumorphicButtonDarkSide.color,
radius: 15,
x: colorScheme == .light && !isPressed ? 10 : 0,
y: colorScheme == .light && !isPressed ? 10 : 0
)
.shadow(
color: Asset.Colors.Buttons.neumorphicButtonLightSide.color,
radius: 10,
x: colorScheme == .light && !isPressed ? -12 : 0,
y: colorScheme == .light && !isPressed ? -12 : 0
)
}
}
extension View {
func neumorphic(_ isPressed: Bool = false) -> some View {
self.modifier(Neumorphic(isPressed))
}
func neumorphicButton(_ isPressed: Bool = false) -> some View {
self.modifier(NeumorphicButton(isPressed))
}
}

View File

@ -12,8 +12,9 @@ extension Button {
buttonStyle(
StandardButtonStyle(
foregroundColor: Asset.Colors.Text.button.color,
background: Asset.Colors.Buttons.primaryButtonPressed.color,
pressedBackgroundColor: Asset.Colors.Buttons.primaryButtonPressed.color
background: Asset.Colors.Buttons.primaryButton.color,
pressedBackgroundColor: Asset.Colors.Buttons.primaryButtonPressed.color,
disabledBackgroundColor: Asset.Colors.Buttons.primaryButtonDisabled.color
)
)
}
@ -26,11 +27,13 @@ struct PrimaryButton_Previews: PreviewProvider {
.frame(width: 250, height: 50)
.previewLayout(.fixed(width: 300, height: 100))
.preferredColorScheme(.light)
.applyScreenBackground()
Button("Primary Button") { dump("Primary button") }
.primaryButtonStyle
.frame(width: 250, height: 50)
.previewLayout(.fixed(width: 300, height: 100))
.preferredColorScheme(.dark)
.applyScreenBackground()
}
}

View File

@ -13,7 +13,8 @@ extension Button {
StandardButtonStyle(
foregroundColor: Asset.Colors.Text.secondaryButtonText.color,
background: Asset.Colors.Buttons.secondaryButton.color,
pressedBackgroundColor: Asset.Colors.Buttons.secondaryButtonPressed.color
pressedBackgroundColor: Asset.Colors.Buttons.secondaryButtonPressed.color,
disabledBackgroundColor: Asset.Colors.Buttons.secondaryButton.color
)
)
}

View File

@ -8,12 +8,16 @@
import SwiftUI
struct StandardButtonStyle: ButtonStyle {
@Environment(\.isEnabled) private var isEnabled: Bool
let foregroundColor: Color
let background: Color
let pressedBackgroundColor: Color
let disabledBackgroundColor: Color
func makeBody(configuration: Configuration) -> some View {
configuration.label
.shadow(color: Asset.Colors.Buttons.buttonsTitleShadow.color, radius: 2, x: 0, y: 2)
.frame(
minWidth: 0,
maxWidth: .infinity,
@ -22,9 +26,12 @@ struct StandardButtonStyle: ButtonStyle {
)
.foregroundColor(foregroundColor)
.background(
configuration.isPressed ? pressedBackgroundColor : background
isEnabled ?
(configuration.isPressed ? pressedBackgroundColor : background)
: disabledBackgroundColor
)
.cornerRadius(12)
.neumorphicButton(configuration.isPressed)
}
}
@ -34,7 +41,8 @@ private extension Button {
StandardButtonStyle(
foregroundColor: Asset.Colors.Text.button.color,
background: Asset.Colors.Buttons.createButton.color,
pressedBackgroundColor: Asset.Colors.Buttons.createButtonPressed.color
pressedBackgroundColor: Asset.Colors.Buttons.createButtonPressed.color,
disabledBackgroundColor: Asset.Colors.Buttons.createButtonDisabled.color
)
)
}

View File

@ -8,22 +8,44 @@
import SwiftUI
struct CircularFrame: View {
@Environment(\.colorScheme) var colorScheme
var body: some View {
GeometryReader { proxy in
let lineWidth = proxy.size.width * 0.05
let lineWidth = proxy.size.width * 0.06
Circle()
.stroke(lineWidth: lineWidth)
.foregroundColor(Asset.Colors.Onboarding.circularFrame.color)
// Add two points to the frame to properly mask edges
.frame(
width: proxy.size.width - lineWidth + 2,
height: proxy.size.height - lineWidth + 2,
alignment: .center
.stroke(
LinearGradient(
colors: [
Asset.Colors.Onboarding.circularFrameGradientStart.color,
Asset.Colors.Onboarding.circularFrameGradientEnd.color
],
startPoint: colorScheme == .light ? .topLeading : .top,
endPoint: colorScheme == .light ? .bottomTrailing : .bottom
),
style: StrokeStyle(
lineWidth: lineWidth
)
)
// Update the offset to account for the 2 extra points
.offset(x: lineWidth / 2 - 1, y: lineWidth / 2 - 1)
.shadow(radius: 10)
.padding(colorScheme == .light ? 0 : 10)
if colorScheme == .dark {
Circle()
.stroke(
LinearGradient(
colors: [
Asset.Colors.Onboarding.circularFrameDarkOutlineGradientStart.color,
Asset.Colors.Onboarding.circularFrameDarkOutlineGradientEnd.color
],
startPoint: .top,
endPoint: .bottom
),
style: StrokeStyle(
lineWidth: lineWidth * 0.15
)
)
}
}
}
}
@ -114,7 +136,8 @@ struct CircularFramePreviewHelper: View {
struct CircularFrame_Previews: PreviewProvider {
static var previews: some View {
CircularFramePreviewHelper()
.preferredColorScheme(.light)
.preferredColorScheme(.dark)
.previewLayout(.device)
.applyScreenBackground()
}
}

View File

@ -26,6 +26,7 @@ struct CircularFrameBackgroundImages: Animatable, ViewModifier {
.opacity(imageIndex == viewStore.index ? 1 : 0)
.offset(x: imageIndex <= viewStore.index ? 0 : 25)
.mask(Circle())
.neumorphic()
}
content
@ -43,6 +44,7 @@ struct CircularFrameBackgroundImage: Animatable, ViewModifier {
.resizable()
.aspectRatio(1.3, contentMode: .fill)
.mask(Circle())
.neumorphic()
content
}
@ -66,18 +68,26 @@ struct CircularFrameBackground_Previews: PreviewProvider {
CircularFrame()
.backgroundImage(Asset.Assets.Backgrounds.callout0.image)
.frame(width: 300, height: 300)
.applyScreenBackground()
.neumorphic()
CircularFrame()
.backgroundImage(Asset.Assets.Backgrounds.callout1.image)
.frame(width: 300, height: 300)
.applyScreenBackground()
.neumorphic()
CircularFrame()
.backgroundImage(Asset.Assets.Backgrounds.callout2.image)
.frame(width: 300, height: 300)
.applyScreenBackground()
.neumorphic()
CircularFrame()
.backgroundImage(Asset.Assets.Backgrounds.callout3.image)
.frame(width: 300, height: 300)
.applyScreenBackground()
.neumorphic()
}
.preferredColorScheme(.light)
.previewLayout(.fixed(width: size + 50, height: size + 50))

View File

@ -77,6 +77,12 @@ struct BadgesOverlay: Animatable, ViewModifier {
y: proxy.size.height * 0.15
)
.opacity(badgeIndex == viewStore.index ? 1 : 0)
.shadow(
color: Asset.Colors.Onboarding.badgeShadow.color,
radius: 10,
x: 0,
y: 0
)
}
}
@ -114,6 +120,12 @@ struct BadgeOverlay: Animatable, ViewModifier {
)
.transition(.scale(scale: 2))
.transition(.opacity)
.shadow(
color: Asset.Colors.Onboarding.badgeShadow.color,
radius: 10,
x: 0,
y: 0
)
Spacer()
}
}

View File

@ -118,11 +118,11 @@ struct ButtonGuide: View {
.primaryButtonStyle
.frame(height: buttonHeight)
// TODO: Pressed Primary Button
// Pressed Primary Button
Button(action: {}) {
Text("Pressed Primary Button")
}
.primaryButtonStyle
.primaryButtonPressedStyle
.frame(height: buttonHeight)
// Disabled Primary Button
@ -140,14 +140,14 @@ struct ButtonGuide: View {
.activeButtonStyle
.frame(height: buttonHeight)
// TODO: Pressed Active Button
// Pressed Active Button
Button(action: {}) {
Text("Pressed Active Button")
}
.activeButtonStyle
.activeButtonPressedStyle
.frame(height: buttonHeight)
// TODO: Disabled Active Button
// Disabled Active Button
Button(action: {}) {
Text("Disabled Active Button")
}
@ -189,3 +189,29 @@ struct DesignGuide_Previews: PreviewProvider {
.previewLayout(.fixed(width: 1086, height: 1080))
}
}
// MARK: - Pressed Simulated
extension Button {
var primaryButtonPressedStyle: some View {
buttonStyle(
StandardButtonStyle(
foregroundColor: Asset.Colors.Text.button.color,
background: Asset.Colors.Buttons.primaryButtonPressed.color,
pressedBackgroundColor: Asset.Colors.Buttons.primaryButtonPressed.color,
disabledBackgroundColor: Asset.Colors.Buttons.primaryButtonDisabled.color
)
)
}
var activeButtonPressedStyle: some View {
buttonStyle(
StandardButtonStyle(
foregroundColor: Asset.Colors.Text.activeButtonText.color,
background: Asset.Colors.Buttons.activeButtonPressed.color,
pressedBackgroundColor: Asset.Colors.Buttons.activeButtonPressed.color,
disabledBackgroundColor: Asset.Colors.Buttons.activeButtonDisabled.color
)
)
}
}

View File

@ -0,0 +1,23 @@
//
// SecantButtonStyles.swift
// secant-testnet
//
// Created by Lukáš Korba on 02/22/22.
//
import SwiftUI
extension Button {
func titleText() -> some View {
self.modifier(TitleTextStyle())
}
private struct TitleTextStyle: ViewModifier {
func body(content: Content) -> some View {
content
.foregroundColor(Asset.Colors.Text.heading.color)
.font(.custom(FontFamily.Rubik.regular.name, size: 15))
.shadow(color: Asset.Colors.Text.captionTextShadow.color, radius: 1, x: 0, y: 1)
}
}
}

View File

@ -21,6 +21,10 @@ extension Text {
self.modifier(TitleTextStyle())
}
func paragraphText() -> some View {
self.modifier(ParagraphStyle())
}
/// Body text style. Used for content. Roboto-Regular 18pt
private struct BodyTextStyle: ViewModifier {
func body(content: Content) -> some View {
@ -30,11 +34,20 @@ extension Text {
}
}
/// Used for additional information, explanations, context (usually paragraphs)
private struct ParagraphStyle: ViewModifier {
func body(content: Content) -> some View {
content
.foregroundColor(Asset.Colors.Text.heading.color)
.font(.custom(FontFamily.Rubik.regular.name, size: 16))
}
}
private struct TitleTextStyle: ViewModifier {
func body(content: Content) -> some View {
content
.foregroundColor(Asset.Colors.Text.heading.color)
.font(.custom(FontFamily.Rubik.regular.name, size: 33))
.font(.custom(FontFamily.Rubik.regular.name, size: 33, relativeTo: .callout))
.shadow(color: Asset.Colors.Text.captionTextShadow.color, radius: 1, x: 0, y: 1)
}
}

View File

@ -15,8 +15,8 @@ struct OnboardingProgressStyle: ProgressViewStyle {
Asset.Colors.ProgressIndicator.gradientLeft.color,
Asset.Colors.ProgressIndicator.gradientRight.color
],
startPoint: UnitPoint(x: 0.00, y: 0.00),
endPoint: UnitPoint(x: 1.00, y: 0.00)
startPoint: .leading,
endPoint: .trailing
)
func makeBody(configuration: Configuration) -> some View {
@ -25,7 +25,9 @@ struct OnboardingProgressStyle: ProgressViewStyle {
return VStack {
HStack {
configuration.label
.foregroundColor(Asset.Colors.ProgressIndicator.negativeSpace.color)
.foregroundColor(Asset.Colors.Text.heading.color)
.font(.custom(FontFamily.Rubik.regular.name, size: 16))
.opacity(0.3)
Spacer()
}