Commit 21cbb461 authored by Jose Blaya's avatar Jose Blaya
Browse files

WIP

parent 58afd6f2
......@@ -291,6 +291,7 @@
DDD824E82189C0EE00151709 /* BrandableNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD824E62189C0E800151709 /* BrandableNavigationBar.swift */; };
DDD824EA2189CD5700151709 /* NavigationLogoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD824E92189CD5700151709 /* NavigationLogoView.swift */; };
DDE27E0422E1B1A700503A89 /* ProductTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE27E0322E1B1A700503A89 /* ProductTests.swift */; };
DDE93C5722F9847E0054FE28 /* PurchaseTrialViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE93C5622F9847E0054FE28 /* PurchaseTrialViewController.swift */; };
DDFCFAA821E924A70081F235 /* TileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFCFAA721E924A70081F235 /* TileProvider.swift */; };
DDFCFAA921E924AD0081F235 /* TileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFCFAA721E924A70081F235 /* TileProvider.swift */; };
DDFCFAAB21E925160081F235 /* DefaultTileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFCFAAA21E925160081F235 /* DefaultTileProvider.swift */; };
......@@ -584,6 +585,7 @@
DDD824E62189C0E800151709 /* BrandableNavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrandableNavigationBar.swift; sourceTree = "<group>"; };
DDD824E92189CD5700151709 /* NavigationLogoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationLogoView.swift; sourceTree = "<group>"; };
DDE27E0322E1B1A700503A89 /* ProductTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ProductTests.swift; path = "../../../../../../System/Volumes/Data/Users/ueshiba/Projects/PIA/client-library-apple/PIALibraryTests/ProductTests.swift"; sourceTree = "<group>"; };
DDE93C5622F9847E0054FE28 /* PurchaseTrialViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseTrialViewController.swift; sourceTree = "<group>"; };
DDFCFAA721E924A70081F235 /* TileProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileProvider.swift; sourceTree = "<group>"; };
DDFCFAAA21E925160081F235 /* DefaultTileProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTileProvider.swift; sourceTree = "<group>"; };
DDFCFAAC21E925B60081F235 /* TileableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TileableCell.swift; sourceTree = "<group>"; };
......@@ -1136,6 +1138,7 @@
0E48A8521FDAD60900B9A4C0 /* OptionsViewController.swift */,
0EB8C0531F9CD38A005857E4 /* PIAWelcomeViewController.swift */,
0EB8C0551F9CD38A005857E4 /* PurchaseViewController.swift */,
DDE93C5622F9847E0054FE28 /* PurchaseTrialViewController.swift */,
DD0DE84F22366090002A6E82 /* GDPRViewController.swift */,
0EA8072320A18C6B0033EC1A /* RedeemViewController.swift */,
84D5DA6F2126CE2900F753F8 /* QRCameraScannerViewController.swift */,
......@@ -1838,6 +1841,7 @@
0E392DA31FE3247E0002160D /* Endpoint.swift in Sources */,
0E53A8581FE5DA16000C2A18 /* MockInAppProvider.swift in Sources */,
DDD824E32189969400151709 /* Preset.swift in Sources */,
DDE93C5722F9847E0054FE28 /* PurchaseTrialViewController.swift in Sources */,
0E9D62721FDE83BD009A90CF /* GlossServersBundle.swift in Sources */,
0E492C6A1FE61485007F23DF /* Client+Database.swift in Sources */,
0E48A8531FDAD60900B9A4C0 /* OptionsViewController.swift in Sources */,
......
{
"images" : [
{
"idiom" : "universal",
"filename" : "computer-7.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "computer-7@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "computer-7@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "globe-turn-7.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "globe-turn-7@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "globe-turn-7@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "shield-7.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "shield-7@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "shield-7@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
......@@ -214,7 +214,7 @@ public extension TextStyle {
)
static let textStyle22 = TextStyle(
font: UIFont.mediumFontWith(size: 24),
font: UIFont.mediumFontWith(size: 26),
color: UIColor.piaWhite,
foregroundColor: nil,
backgroundColor: nil,
......@@ -223,7 +223,7 @@ public extension TextStyle {
)
static let textStyle23 = TextStyle(
font: UIFont.mediumFontWith(size: 24),
font: UIFont.mediumFontWith(size: 26),
color: UIColor.piaGrey6,
foregroundColor: nil,
backgroundColor: nil,
......
......@@ -20,6 +20,8 @@
internal enum Asset {
internal static let centeredDarkMap = ImageAsset(name: "centered-dark-map")
internal static let centeredLightMap = ImageAsset(name: "centered-light-map")
internal static let computerIcon = ImageAsset(name: "computer-icon")
internal static let globeIcon = ImageAsset(name: "globe-icon")
internal static let iconBack = ImageAsset(name: "icon-back")
internal static let iconCamera = ImageAsset(name: "icon-camera")
internal static let iconClose = ImageAsset(name: "icon-close")
......@@ -28,6 +30,7 @@ internal enum Asset {
internal static let logoLight = ImageAsset(name: "logo-light")
internal static let planSelected = ImageAsset(name: "plan-selected")
internal static let planUnselected = ImageAsset(name: "plan-unselected")
internal static let shieldIcon = ImageAsset(name: "shield-icon")
internal static let closeIcon = ImageAsset(name: "close-icon")
internal static let imageAccountFailed = ImageAsset(name: "image-account-failed")
internal static let imageNoInternet = ImageAsset(name: "image-no-internet")
......
......@@ -25,6 +25,8 @@ internal enum StoryboardScene {
internal static let loginViewController = SceneType<PIALibrary.LoginViewController>(storyboard: Welcome.self, identifier: "LoginViewController")
internal static let purchaseViewController = SceneType<PIALibrary.PurchaseViewController>(storyboard: Welcome.self, identifier: "PurchaseViewController")
internal static let purchaseTrialViewController = SceneType<PIALibrary.PurchaseTrialViewController>(storyboard: Welcome.self, identifier: "PurchaseTrialViewController")
internal static let redeemViewController = SceneType<PIALibrary.RedeemViewController>(storyboard: Welcome.self, identifier: "RedeemViewController")
internal static let restoreViewController = SceneType<PIALibrary.RestoreSignupViewController>(storyboard: Welcome.self, identifier: "RestoreSignupViewController")
......
......@@ -30,6 +30,7 @@ internal enum StoryboardSegue {
case signupViaRecoverSegue = "SignupViaRecoverSegue"
case signupViaRedeemSegue = "SignupViaRedeemSegue"
case signupViaRestoreSegue = "SignupViaRestoreSegue"
case viewMoreVPNPlansSegue = "ViewMoreVPNPlansSegue"
}
}
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
......
......@@ -47,12 +47,6 @@ internal enum L10n {
}
}
internal enum Purchase {
internal enum Subscription {
internal enum Apple {
/// Payment will be charged to your Apple ID account at the confirmation of purchase. Subscription automatically renews unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions by going to your account settings on the App Store after purchase.
internal static let terms = L10n.tr("Signup", "purchase.subscription.apple.terms")
}
}
internal enum Uncredited {
internal enum Alert {
/// You have uncredited transactions. Do you want to recover your account details?
......
......@@ -327,6 +327,12 @@ public class Theme {
label.textAlignment = textAlignment
}
public func applySmallSubtitle(_ label: UILabel) {
let textAlignment = label.textAlignment
label.style(style: TextStyle.textStyle21)
label.textAlignment = textAlignment
}
/// :nodoc:
public func applyBody1Monospace(_ textView: UITextView, appearance: Appearance) {
textView.font = typeface.monospaceFont(size: 14.0)
......
//
// PurchaseTrialViewController.swift
// PIALibrary-iOS
//
// Created by Jose Antonio Blaya Garcia on 06/08/2019.
// Copyright © 2019 London Trust Media. All rights reserved.
//
import UIKit
class PurchaseTrialViewController: AutolayoutViewController, BrandableNavigationBar, WelcomeChild {
@IBOutlet private weak var scrollView: UIScrollView!
@IBOutlet private weak var textAgreement: UITextView!
@IBOutlet private weak var buttonPurchase: PIAButton!
@IBOutlet private weak var buttonMorePlans: PIAButton!
@IBOutlet private weak var headerTitleLabel: UILabel!
@IBOutlet private weak var subtitleLabel: UILabel!
@IBOutlet private weak var smallTitleLabel: UILabel!
@IBOutlet private weak var protectionImageView: UIImageView!
@IBOutlet private weak var protectionTitleLabel: UILabel!
@IBOutlet private weak var protectionSubtitleLabel: UILabel!
@IBOutlet private weak var devicesImageView: UIImageView!
@IBOutlet private weak var devicesTitleLabel: UILabel!
@IBOutlet private weak var devicesSubtitleLabel: UILabel!
@IBOutlet private weak var serversImageView: UIImageView!
@IBOutlet private weak var serversTitleLabel: UILabel!
@IBOutlet private weak var serversSubtitleLabel: UILabel!
var preset: Preset?
weak var completionDelegate: WelcomeCompletionDelegate?
var omitsSiblingLink = false
private var allPlans: [PurchasePlan] = [.dummy, .dummy]
private var selectedPlanIndex: Int?
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
guard let _ = self.preset else {
fatalError("Preset not propagated")
}
self.navigationItem.leftBarButtonItem = UIBarButtonItem(
image: Theme.current.palette.navigationBarBackIcon?.withRenderingMode(.alwaysOriginal),
style: .plain,
target: self,
action: #selector(back(_:))
)
self.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Welcome.Redeem.Accessibility.back
headerTitleLabel.text = "Try free for 7 days!"
subtitleLabel.text = "Pay only $74,99/year after"
smallTitleLabel.text = "7 day money back guarantee"
protectionTitleLabel.text = "1 year of privacy and identity protection"
protectionSubtitleLabel.text = "Browse anonymously with a hidden ip."
protectionImageView.image = Asset.shieldIcon.image.withRenderingMode(.alwaysTemplate)
devicesTitleLabel.text = "Support 10 devices at once"
devicesSubtitleLabel.text = "Protect yourself on up to 10 devices at a time."
devicesImageView.image = Asset.computerIcon.image.withRenderingMode(.alwaysTemplate)
serversTitleLabel.text = "Connect to any region easily"
serversSubtitleLabel.text = "3341 + Servers in 32 countries"
serversImageView.image = Asset.globeIcon.image.withRenderingMode(.alwaysTemplate)
textAgreement.attributedText = Theme.current.agreementText(
withMessage: L10n.Welcome.Agreement.message,
tos: L10n.Welcome.Agreement.Message.tos,
tosUrl: Client.configuration.tosUrl,
privacy: L10n.Welcome.Agreement.Message.privacy,
privacyUrl: Client.configuration.privacyUrl
)
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(productsDidFetch(notification:)), name: .__InAppDidFetchProducts, object: nil)
styleButtons()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let products = preset?.accountProvider.planProducts {
refreshPlans(products)
} else {
disableInteractions(fully: false)
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
@objc private func back(_ sender: Any?) {
self.navigationController?.popViewController(animated: true)
}
override func didRefreshOrientationConstraints() {
scrollView.isScrollEnabled = (traitCollection.verticalSizeClass == .compact)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == StoryboardSegue.Welcome.confirmPurchaseVPNPlanSegue.rawValue) {
if let vc = segue.destination as? ConfirmVPNPlanViewController,
let selectedIndex = selectedPlanIndex {
vc.preset = preset
vc.completionDelegate = completionDelegate
vc.populateViewWith(plans: allPlans,
andSelectedPlanIndex: selectedIndex)
}
} else if (segue.identifier == StoryboardSegue.Welcome.viewMoreVPNPlansSegue.rawValue) {
if let vc = segue.destination as? PurchaseViewController {
vc.preset = preset
vc.completionDelegate = completionDelegate
}
}
}
// MARK: Actions
private func refreshPlans(_ plans: [Plan: InAppProduct]) {
if let yearly = plans[.yearly] {
let purchase = PurchasePlan(
plan: .yearly,
product: yearly,
monthlyFactor: 12.0
)
purchase.title = L10n.Welcome.Plan.Yearly.title
let currencySymbol = purchase.product.priceLocale.currencySymbol ?? ""
purchase.detail = L10n.Welcome.Plan.Yearly.detailFormat(currencySymbol, purchase.product.price.description)
purchase.bestValue = true
subtitleLabel.text = "Pay only \(L10n.Welcome.Plan.Yearly.detailFormat(currencySymbol, purchase.product.price.description)) after"
allPlans[0] = purchase
selectedPlanIndex = 0
}
}
private func disableInteractions(fully: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.showLoadingAnimation()
}
if fully {
parent?.view.isUserInteractionEnabled = false
}
}
private func enableInteractions() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.hideLoadingAnimation()
}
parent?.view.isUserInteractionEnabled = true
}
// MARK: Notifications
@objc private func productsDidFetch(notification: Notification) {
let products: [Plan: InAppProduct] = notification.userInfo(for: .products)
refreshPlans(products)
enableInteractions()
}
// MARK: Restylable
override func viewShouldRestyle() {
super.viewShouldRestyle()
Theme.current.applyPrincipalBackground(view)
Theme.current.applyLinkAttributes(textAgreement)
Theme.current.applyBigTitle(headerTitleLabel, appearance: .dark)
Theme.current.applySubtitle(subtitleLabel)
Theme.current.applySmallSubtitle(smallTitleLabel)
Theme.current.applySettingsCellTitle(protectionTitleLabel, appearance: .dark)
Theme.current.applySmallSubtitle(protectionSubtitleLabel)
protectionImageView.tintColor = .white
Theme.current.applySettingsCellTitle(devicesTitleLabel, appearance: .dark)
Theme.current.applySmallSubtitle(devicesSubtitleLabel)
devicesImageView.tintColor = .white
Theme.current.applySettingsCellTitle(serversTitleLabel, appearance: .dark)
Theme.current.applySmallSubtitle(serversSubtitleLabel)
serversImageView.tintColor = .white
}
private func styleButtons() {
buttonPurchase.setRounded()
buttonMorePlans.setRounded()
buttonPurchase.style(style: TextStyle.Buttons.piaGreenButton)
buttonMorePlans.style(style: TextStyle.Buttons.piaPlainTextButton)
buttonPurchase.setTitle("Start subscription".uppercased(),
for: [])
buttonMorePlans.setTitle("See all available plans",
for: [])
}
}
......@@ -11,7 +11,7 @@ import SwiftyBeaver
private let log = SwiftyBeaver.self
class PurchaseViewController: AutolayoutViewController, WelcomeChild {
class PurchaseViewController: AutolayoutViewController, BrandableNavigationBar, WelcomeChild {
private struct Cells {
static let plan = "PlanCell"
......@@ -49,6 +49,14 @@ class PurchaseViewController: AutolayoutViewController, WelcomeChild {
collectionPlans.isUserInteractionEnabled = false
self.navigationItem.leftBarButtonItem = UIBarButtonItem(
image: Theme.current.palette.navigationBarBackIcon?.withRenderingMode(.alwaysOriginal),
style: .plain,
target: self,
action: #selector(back(_:))
)
self.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Welcome.Redeem.Accessibility.back
labelTitle.text = L10n.Welcome.Purchase.title
labelSubtitle.text = L10n.Welcome.Purchase.subtitle
textAgreement.attributedText = Theme.current.agreementText(
......@@ -85,6 +93,10 @@ class PurchaseViewController: AutolayoutViewController, WelcomeChild {
scrollView.isScrollEnabled = (traitCollection.verticalSizeClass == .compact)
}
@objc private func back(_ sender: Any?) {
self.navigationController?.popViewController(animated: true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == StoryboardSegue.Welcome.confirmPurchaseVPNPlanSegue.rawValue) {
if let vc = segue.destination as? ConfirmVPNPlanViewController,
......
......@@ -26,7 +26,8 @@ class WelcomePageViewController: UIPageViewController {
source.append(vc)
}
if preset.pages.contains(.purchase) {
let vc = StoryboardScene.Welcome.purchaseViewController.instantiate()
//let vc = StoryboardScene.Welcome.purchaseViewController.instantiate()
let vc = StoryboardScene.Welcome.purchaseTrialViewController.instantiate()
source.append(vc)
}
if preset.pages.contains(.restore) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment