diff --git a/litewallet/Assets.xcassets/Branding/lofigirl.imageset/Contents.json b/litewallet/Assets.xcassets/Branding/lofigirl.imageset/Contents.json new file mode 100644 index 000000000..2d4119bf2 --- /dev/null +++ b/litewallet/Assets.xcassets/Branding/lofigirl.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Screenshot 2023-12-12 at 12.16.04 PM.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/litewallet/Assets.xcassets/Branding/lofigirl.imageset/Screenshot 2023-12-12 at 12.16.04\342\200\257PM.png" "b/litewallet/Assets.xcassets/Branding/lofigirl.imageset/Screenshot 2023-12-12 at 12.16.04\342\200\257PM.png" new file mode 100644 index 000000000..31d20b09e Binary files /dev/null and "b/litewallet/Assets.xcassets/Branding/lofigirl.imageset/Screenshot 2023-12-12 at 12.16.04\342\200\257PM.png" differ diff --git a/litewallet/CheckboxesStepView.swift b/litewallet/CheckboxesStepView.swift index 7f7dc0843..63a8b9621 100644 --- a/litewallet/CheckboxesStepView.swift +++ b/litewallet/CheckboxesStepView.swift @@ -6,19 +6,11 @@ struct CheckboxesStepView: View { var viewModel: StartViewModel let paragraphFont: Font = .barlowSemiBold(size: 22.0) + let calloutFont: Font = .barlowLight(size: 12.0) - let appDelegate = UIApplication.shared.delegate as! AppDelegate + let genericPad = 5.0 - @State - private var didAcceptPush: Bool = false - - @State - private var didTapEmailSignUp: Bool = false - - @State - private var urlString = "https://litewallet.io" - - @State var showSafari = false + @State private var scroll = false var body: some View { GeometryReader { geometry in @@ -32,89 +24,20 @@ struct CheckboxesStepView: View { .backgroundColor .edgesIgnoringSafeArea(.all) VStack { - Text(S.CreateStep.MainTitle.checkboxes.localize()) - .font(.headline) - .foregroundColor(.white) - .padding([.bottom, .top], 20.0) - HStack { - Text(S.CreateStep.DetailedMessage.checkboxes.localize()) - .font(paragraphFont) - .foregroundColor(.white) - .frame(width: width * 0.6, alignment: .leading) - .padding([.leading, .trailing], 20.0) - - Spacer() - - Image(systemName: didAcceptPush ? "checkmark.circle.fill" : "checkmark.circle") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 30, height: 30, alignment: .leading) - .foregroundColor(didAcceptPush ? .litewalletGreen : .litecoinSilver) - .padding() - } - .onTapGesture { - didAcceptPush.toggle() - let pushOptions: UNAuthorizationOptions = [.alert, .sound, .badge] - UNUserNotificationCenter.current().requestAuthorization(options: pushOptions) { granted, error in - if granted { - DispatchQueue.main.async { - UIApplication.shared.registerForRemoteNotifications() - } - } - if let error = error { - print("[PushNotifications] - \(error.localizedDescription)") + WebView(url: URL(string: C.signupURL)!, + scrollToSignup: $scroll) + .frame(width: width * 0.9) + .padding([.leading, .trailing], genericPad) + .edgesIgnoringSafeArea(.all) + .onAppear { + delay(2.0) { + scroll = true } - } - } - .padding(.bottom, 20.0) - HStack { - Text(S.CreateStep.ExtendedMessage.checkboxes.localize()) - .font(paragraphFont) - .foregroundColor(.white) - .frame(width: width * 0.6, alignment: .leading) - .padding([.leading, .trailing], 20.0) - .padding(.bottom, 20.0) - - Spacer() - - Image(systemName: didTapEmailSignUp ? "checkmark.circle.fill" : "checkmark.circle") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 30, height: 30, alignment: .leading) - .foregroundColor(didTapEmailSignUp ? .litewalletGreen : .litecoinSilver) - .padding() - } - .onTapGesture { - self.showSafari = true - } - .sheet(isPresented: $showSafari) { - SafariView(url: URL(string: self.urlString)!) - } - .padding(.bottom, 20.0) - - Spacer() - - Button(action: { - // - viewModel.didTapIndex = 2 - }) { - ZStack { - RoundedRectangle(cornerRadius: bigButtonCornerRadius) - .frame(width: width * 0.6, height: 60, alignment: .center) - .foregroundColor(.litewalletLightGray) - .shadow(radius: 3, x: 3.0, y: 3.0) - - Text(S.WritePaperPhrase.next.localize()) - .frame(width: width * 0.6, height: 60, alignment: .center) - .font(paragraphFont) - .foregroundColor(.litewalletBlue) - .overlay( - RoundedRectangle(cornerRadius: bigButtonCornerRadius) - .stroke(.white, lineWidth: 2.0) - ) - } - } - .padding(.all, 8.0) + }.mask( + RoundedRectangle(cornerRadius: 12.0) + .frame(width: width * 0.9, + height: height * 0.9) + ) } .frame(width: width * 0.9) } diff --git a/litewallet/CreateStepConfiguration.swift b/litewallet/CreateStepConfiguration.swift index 996908386..5ea79edda 100644 --- a/litewallet/CreateStepConfiguration.swift +++ b/litewallet/CreateStepConfiguration.swift @@ -11,13 +11,13 @@ enum CreateStepConfig { var backgroundColor: Color { switch self { case .intro: - return .litewalletLightGray + return .white case .checkboxes: - return .litewalletOrange + return .white case .seedPhrase: - return .litewalletGreen + return .white case .finished: - return .liteWalletDarkBlue + return .white } } diff --git a/litewallet/CreateStepTabView.swift b/litewallet/CreateStepTabView.swift index 1895098ae..d37ad54cb 100644 --- a/litewallet/CreateStepTabView.swift +++ b/litewallet/CreateStepTabView.swift @@ -19,23 +19,34 @@ struct CreateStepTabView: View { let height = geometry.size.height VStack { - HStack { - Image(systemName: "triangle.inset.filled") - .resizable() - .foregroundColor(.white) - .aspectRatio(contentMode: .fit) - .frame(width: 25.0, - height: 25.0) - .rotationEffect(.degrees(30)) - .onTapGesture { - presentationMode.wrappedValue.dismiss() - } - .padding(.leading, 10.0) - Spacer() + ZStack { + HStack { + Image(systemName: "chevron.left") + .resizable() + .foregroundColor(.white) + .aspectRatio(contentMode: .fit) + .frame(width: 25.0, + height: 25.0) + .onTapGesture { + presentationMode + .wrappedValue + .dismiss() + viewModel.tappedIndex = 0 + } + .padding(.leading, 10.0) + Spacer() + } + + HStack { + Text(viewModel.headerTitle) + .font(.barlowBold(size: 30.0)) + .foregroundColor(.litecoinGray) + .padding([.bottom, .top], 10.00) + } + .frame(height: 25.0) } - .frame(height: 25.0) - TabView(selection: $viewModel.didTapIndex) { + TabView(selection: $viewModel.tappedIndex) { ForEach(0 ..< stepViews.count, id: \.self) { index in ZStack { let currentStepView = stepViews[index] diff --git a/litewallet/IntroStepView.swift b/litewallet/IntroStepView.swift index 5122f8f4e..d57fd0ae7 100644 --- a/litewallet/IntroStepView.swift +++ b/litewallet/IntroStepView.swift @@ -1,16 +1,20 @@ +import PushNotifications import SwiftUI struct IntroStepView: View { @EnvironmentObject var viewModel: StartViewModel - let paragraphFont: Font = .barlowSemiBold(size: 22.0) + let paragraphFont: Font = .barlowBold(size: 35.0) + + let genericPad = 5.0 + + let appDelegate = UIApplication.shared.delegate as! AppDelegate var body: some View { GeometryReader { geometry in let width = geometry.size.width - let height = geometry.size.height ZStack { CreateStepConfig @@ -18,57 +22,33 @@ struct IntroStepView: View { .backgroundColor .edgesIgnoringSafeArea(.all) VStack { - Text(S.CreateStep.MainTitle.intro.localize()) - .font(.barlowBold(size: 24.0)) - .foregroundColor(.litewalletDarkBlue) - .padding([.bottom, .top], 20.0) - Text(S.CreateStep.DetailedMessage.intro.localize()) .font(paragraphFont) - .foregroundColor(.litewalletDarkBlue) - .frame(width: width * 0.8, alignment: .leading) - .padding([.leading, .trailing], 20.0) - .padding(.bottom, 20.0) + .foregroundColor(.liteWalletBlue) + .frame(width: width * 0.9, alignment: .leading) + .padding([.leading, .trailing], genericPad) + .padding([.bottom], genericPad) - Text(S.CreateStep.ExtendedMessage.intro.localize()) - .font(paragraphFont) - .foregroundColor(.litewalletDarkBlue) - .frame(width: width * 0.8, alignment: .leading) - .padding([.leading, .trailing], 20.0) - .padding(.bottom, 20.0) + Image("lofigirl") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: width * 0.9, alignment: .center) + .mask { + RoundedRectangle(cornerRadius: 12.0) + }.padding() - Text(S.CreateStep.Bullet1.intro.localize()) + Text(S.CreateStep.ExtendedMessage.intro.localize()) .font(paragraphFont) - .foregroundColor(.litewalletDarkBlue) - .frame(width: width * 0.8, alignment: .leading) - .padding([.leading, .trailing], 20.0) - .padding(.bottom, 20.0) - Spacer() - - Button(action: { - // - viewModel.didTapIndex = 1 - }) { - ZStack { - RoundedRectangle(cornerRadius: bigButtonCornerRadius) - .frame(width: width * 0.6, height: 60, alignment: .center) - .foregroundColor(.litewalletLightGray) - .shadow(radius: 3, x: 3.0, y: 3.0) - - Text(S.Button.ok.localize()) - .frame(width: width * 0.6, height: 60, alignment: .center) - .font(paragraphFont) - .foregroundColor(.litewalletBlue) - .overlay( - RoundedRectangle(cornerRadius: bigButtonCornerRadius) - .stroke(.white, lineWidth: 2.0) - ) - } - } - .padding(.all, 8.0) - Spacer() + .foregroundColor(.liteWalletBlue) + .frame(width: width * 0.9, alignment: .leading) + .padding([.leading, .trailing], genericPad) + .padding([.bottom], genericPad) } .frame(width: width * 0.9) + }.onAppear { + delay(2.0) { + appDelegate.pushNotifications.registerForRemoteNotifications() + } } } } @@ -77,3 +57,58 @@ struct IntroStepView: View { #Preview { IntroStepView() } + +// let pushOptions: UNAuthorizationOptions = [.alert, .sound, .badge] +// UNUserNotificationCenter.current().requestAuthorization(options: pushOptions) { granted, error in +// if granted { +// DispatchQueue.main.async { +// UIApplication.shared.registerForRemoteNotifications() +// } +// } +// if let error = error { +// print("[PushNotifications] - \(error.localizedDescription)") +// } +// } + +// +// func registerPushNotification(_ application: UIApplication){ +// +// UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in +// +// if granted { +// print("Notification: Granted") +// +// } else { +// print("Notification: not granted") +// +// } +// } +// +// application.registerForRemoteNotifications() +// } +// +// } + +// Button(action: { +// // +// viewModel.didTapIndex = 1 +// }) { +// ZStack { +// RoundedRectangle(cornerRadius: bigButtonCornerRadius) +// .frame(width: width * 0.6, height: 60, alignment: .center) +// .foregroundColor(.litewalletLightGray) +// .shadow(radius: 3, x: 3.0, y: 3.0) +// +// Text(S.Button.ok.localize()) +// .frame(width: width * 0.6, height: 60, alignment: .center) +// .font(paragraphFont) +// .foregroundColor(.litewalletBlue) +// .overlay( +// RoundedRectangle(cornerRadius: bigButtonCornerRadius) +// .stroke(.white, lineWidth: 2.0) +// ) +// } +// } +// .padding(.all, 8.0) + +// viewModel.updatePushPreference(didAcceptPush: didAcceptPush) diff --git a/litewallet/SeedPhraseStepView.swift b/litewallet/SeedPhraseStepView.swift index 5a8fe7dee..1ed66b36e 100644 --- a/litewallet/SeedPhraseStepView.swift +++ b/litewallet/SeedPhraseStepView.swift @@ -1,11 +1,9 @@ import SwiftUI import UIKit + let seedViewWidth: CGFloat = 65.0 let fieldViewHeight: CGFloat = 35.0 -private -let pinPad = 110.0 - struct SeedPhraseStepView: View { @EnvironmentObject var viewModel: StartViewModel @@ -15,6 +13,11 @@ struct SeedPhraseStepView: View { let paragraphFont: Font = .barlowSemiBold(size: 22.0) + let genericPad = 5.0 + + private + let pinPad = 110.0 + var columns: [GridItem] = [ GridItem(.flexible(minimum: seedViewWidth)), GridItem(.flexible(minimum: seedViewWidth)), @@ -34,10 +37,6 @@ struct SeedPhraseStepView: View { .backgroundColor .edgesIgnoringSafeArea(.all) VStack { - Text(S.CreateStep.MainTitle.seedPhrase.localize()) - .font(.headline) - .foregroundColor(.white) - .padding([.bottom, .top], 20.0) HStack { Text(S.CreateStep.DetailedMessage.seedPhrase.localize()) .font(paragraphFont) @@ -54,7 +53,8 @@ struct SeedPhraseStepView: View { LazyVGrid(columns: columns) { ForEach(viewModel.seedWords) { word in SeedWordView(seedWord: word) - .frame(height: fieldViewHeight).padding(.all, 4.0) + .frame(height: fieldViewHeight) + .padding(.all, 4.0) } } } @@ -71,14 +71,14 @@ struct SeedPhraseStepView: View { .frame(width: width * 0.4) .opacity(0.7) .onAppear(perform: { - print(":::\(viewModel.pinViewRect)") + print("::: viewRect \(viewModel.pinViewRect)") }) Spacer() Button(action: { hideKeyboard() delay(0.5) { - viewModel.didTapIndex = 3 + viewModel.tappedIndex = 3 } }) { HStack { @@ -102,7 +102,12 @@ struct SeedPhraseStepView: View { } func hideKeyboard() { - UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) + UIApplication + .shared + .sendAction(#selector(UIResponder.resignFirstResponder), + to: nil, + from: nil, + for: nil) } // #Preview { diff --git a/litewallet/StartViewModel.swift b/litewallet/StartViewModel.swift index fe327a497..9e3eab8cb 100644 --- a/litewallet/StartViewModel.swift +++ b/litewallet/StartViewModel.swift @@ -10,7 +10,7 @@ class StartViewModel: ObservableObject { var currentLanguage: LanguageSelection = .English @Published - var didTapIndex: Int = 0 + var tappedIndex: Int = 0 @Published var walletCreationDidFail: Bool = false @@ -30,6 +30,9 @@ class StartViewModel: ObservableObject { @Published var pinViewRect = CGRect() + @Published + var headerTitle = S.CreateStep.MainTitle.intro.localize() + // MARK: - Public Variables var staticTagline = "" @@ -72,6 +75,21 @@ class StartViewModel: ObservableObject { } } + func updateHeader() { + switch tappedIndex { + case 0: + headerTitle = S.CreateStep.MainTitle.intro.localize() + case 1: + headerTitle = S.CreateStep.MainTitle.checkboxes.localize() + case 2: + headerTitle = S.CreateStep.MainTitle.seedPhrase.localize() + case 3: + headerTitle = S.CreateStep.MainTitle.finished.localize() + default: + headerTitle = S.CreateStep.MainTitle.intro.localize() + } + } + func speakLanguage() { if let url = Bundle.main.url(forResource: currentLanguage.voiceFilename, withExtension: "mp3") { var id: SystemSoundID = 0 diff --git a/litewallet/src/AppDelegate.swift b/litewallet/src/AppDelegate.swift index 84dff6d4c..ca9c320a0 100644 --- a/litewallet/src/AppDelegate.swift +++ b/litewallet/src/AppDelegate.swift @@ -9,6 +9,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? let applicationController = ApplicationController() let pushNotifications = PushNotifications.shared + var didSetDeviceToken = false + + func didDecidePushPreference(completion: @escaping (Bool) -> Void) { + completion(didSetDeviceToken) + } func application(_ application: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { @@ -86,6 +91,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { /// Pusher Related funcs func application(_: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { pushNotifications.registerDeviceToken(deviceToken) + didSetDeviceToken = true } func application(_: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], diff --git a/litewallet/src/Constants/Constants.swift b/litewallet/src/Constants/Constants.swift index 496d47a35..bf56ed2c3 100644 --- a/litewallet/src/Constants/Constants.swift +++ b/litewallet/src/Constants/Constants.swift @@ -64,6 +64,8 @@ struct C { static let supportEmail = "support@litecoinfoundation.zendesk.com" static let reviewLink = "https://itunes.apple.com/app/loafwallet-litecoin-wallet/id1119332592?action=write-review" + static let signupURL = "https://litewallet.io/mobile-signup/signup.html" + static var standardPort: Int { return E.isTestnet ? 19335 : 9333 } diff --git a/litewallet/src/Constants/Strings.swift b/litewallet/src/Constants/Strings.swift index 277ab0f7c..43b4da356 100644 --- a/litewallet/src/Constants/Strings.swift +++ b/litewallet/src/Constants/Strings.swift @@ -3,7 +3,7 @@ import Foundation enum S { enum CreateStep { enum MainTitle { - static let intro = Localization(key: "MainTitle.intro", value: "Litewallet Quick Start", comment: "Litewallet Quick Start") + static let intro = Localization(key: "MainTitle.intro", value: "Quick Start", comment: "Litewallet Quick Start") static let checkboxes = Localization(key: "MainTitle.checkboxes", value: "Stay Connected", comment: "Stay Connected") static let seedPhrase = Localization(key: "MainTitle.seedPhrase", value: "Protect your Litecoin!", comment: "Protect your Litecoin!") static let finished = Localization(key: "MainTitle.finished", value: "Confirm and Go", comment: "Confirm and Go") diff --git a/litewallet/src/Extensions/SafariServices+Extension.swift b/litewallet/src/Extensions/SafariServices+Extension.swift index a47c208f7..531fd6363 100644 --- a/litewallet/src/Extensions/SafariServices+Extension.swift +++ b/litewallet/src/Extensions/SafariServices+Extension.swift @@ -2,13 +2,30 @@ import Foundation import SafariServices import SwiftUI import UIKit +import WebKit -struct SafariView: UIViewControllerRepresentable { +// inspired https://www.swiftyplace.com/blog/loading-a-web-view-in-swiftui-with-wkwebview + +struct WebView: UIViewRepresentable { let url: URL + @Binding var scrollToSignup: Bool - func makeUIViewController(context _: UIViewControllerRepresentableContext) -> SFSafariViewController { - return SFSafariViewController(url: url) + func makeUIView(context _: Context) -> WKWebView { + let webview = WKWebView() + // webview.scrollView.setZoomScale(0.3, animated: true) + let request = URLRequest(url: url) + webview.load(request) + return webview } - func updateUIViewController(_: SFSafariViewController, context _: UIViewControllerRepresentableContext) {} + func updateUIView(_ webview: WKWebView, context _: Context) { + print("::: webview \(webview.frame.size)") + if scrollToSignup { + let point = CGPoint(x: 0, y: webview.scrollView.contentSize.height - webview.frame.size.height / 2) + webview.scrollView.setContentOffset(point, animated: true) + DispatchQueue.main.async { + self.scrollToSignup = false + } + } + } } diff --git a/litewallet/src/Extensions/UIColor+Extension.swift b/litewallet/src/Extensions/UIColor+Extension.swift index 3c17e208b..be94a9c4d 100644 --- a/litewallet/src/Extensions/UIColor+Extension.swift +++ b/litewallet/src/Extensions/UIColor+Extension.swift @@ -44,6 +44,10 @@ extension UIColor { return #colorLiteral(red: 0.09019607843, green: 0.6196078431, blue: 0.1529411765, alpha: 1) } + static var litewalletLime: UIColor { // D9E76C + return #colorLiteral(red: 0.8509803922, green: 0.9058823529, blue: 0.4235294118, alpha: 1) + } + // MARK: Buttons static var primaryButton: UIColor { diff --git a/litewallet/src/StartView.swift b/litewallet/src/StartView.swift index ebac35c83..3eedda902 100644 --- a/litewallet/src/StartView.swift +++ b/litewallet/src/StartView.swift @@ -63,7 +63,6 @@ struct StartView: View { alignment: .center) .padding(.top, height * 0.02) .padding(.bottom, height * 0.08) - .animation(.interpolatingSpring) .onAppear { currentTagline = startViewModel.staticTagline }