diff --git a/Client/KarhooConfig.swift b/Client/KarhooConfig.swift index 84e82c32c..73e9017a8 100644 --- a/Client/KarhooConfig.swift +++ b/Client/KarhooConfig.swift @@ -12,9 +12,10 @@ import KarhooUISDK final class KarhooConfig: KarhooUISDKConfiguration { static var auth: AuthenticationMethod = .karhooUser + static var environment: KarhooEnvironment = .sandbox func environment() -> KarhooEnvironment { - return Keys.staging() + return KarhooConfig.environment } func authenticationMethod() -> AuthenticationMethod { diff --git a/Client/ViewController.swift b/Client/ViewController.swift index 7ea5576ac..d25878af7 100644 --- a/Client/ViewController.swift +++ b/Client/ViewController.swift @@ -14,25 +14,48 @@ class ViewController: UIViewController { private var booking: Screen? - private lazy var guestBookingButton: UIButton = { + private lazy var authenticatedBraintreeBookingButton: UIButton = { let button = UIButton() - button.setTitle("Guest Booking Flow", for: .normal) + button.setTitle("Authenticated Booking Flow [Braintree]", for: .normal) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + private lazy var guestBraintreeBookingButton: UIButton = { + let button = UIButton() + button.setTitle("Guest Booking Flow [Braintree]", for: .normal) button.tintColor = .blue button.translatesAutoresizingMaskIntoConstraints = false return button }() - - private lazy var authenticatedBookingButton: UIButton = { + + private lazy var tokenExchangeBraintreeBookingButton: UIButton = { + let button = UIButton() + button.setTitle("Token Exchange Booking Flow [Braintree]", for: .normal) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + private lazy var authenticatedAdyenBookingButton: UIButton = { let button = UIButton() - button.setTitle("Authenticated Booking Flow", for: .normal) + button.setTitle("Authenticated Booking Flow [Adyen]", for: .normal) button.translatesAutoresizingMaskIntoConstraints = false return button }() + + private lazy var guestAdyenBookingButton: UIButton = { + let button = UIButton() + button.setTitle("Guest Booking Flow [Adyen]", for: .normal) + button.tintColor = .blue - private lazy var tokenExchangeBookingButton: UIButton = { + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + private lazy var tokenExchangeAdyenBookingButton: UIButton = { let button = UIButton() - button.setTitle("Token Exchange Booking Flow", for: .normal) + button.setTitle("Token Exchange Booking Flow [Adyen]", for: .normal) button.translatesAutoresizingMaskIntoConstraints = false return button }() @@ -40,59 +63,98 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .black - guestBookingButton.addTarget(self, action: #selector(guestBookingTapped), + authenticatedBraintreeBookingButton.addTarget(self, action: #selector(authenticatedBraintreeBookingTapped), + for: .touchUpInside) + guestBraintreeBookingButton.addTarget(self, action: #selector(guestBraintreeBookingTapped), for: .touchUpInside) - authenticatedBookingButton.addTarget(self, action: #selector(authenticatedBookingTapped), + tokenExchangeBraintreeBookingButton.addTarget(self, action: #selector(tokenExchangeBraintreeBookingTapped), + for: .touchUpInside) + authenticatedAdyenBookingButton.addTarget(self, action: #selector(authenticatedAdyenBookingTapped), for: .touchUpInside) - tokenExchangeBookingButton.addTarget(self, action: #selector(tokenExchangeBookingTapped), + guestAdyenBookingButton.addTarget(self, action: #selector(guestAdyenBookingTapped), + for: .touchUpInside) + tokenExchangeAdyenBookingButton.addTarget(self, action: #selector(tokenExchangeAdyenBookingTapped), for: .touchUpInside) } override func loadView() { super.loadView() - [guestBookingButton, authenticatedBookingButton, tokenExchangeBookingButton].forEach { button in + [authenticatedBraintreeBookingButton, guestBraintreeBookingButton, tokenExchangeBraintreeBookingButton, + authenticatedAdyenBookingButton, guestAdyenBookingButton, tokenExchangeAdyenBookingButton].forEach { button in self.view.addSubview(button) } + + authenticatedBraintreeBookingButton.centerX(inView: view) + authenticatedBraintreeBookingButton.anchor(top: view.safeAreaLayoutGuide.topAnchor, paddingTop: 80) + + guestBraintreeBookingButton.centerX(inView: view) + guestBraintreeBookingButton.anchor(top: authenticatedBraintreeBookingButton.bottomAnchor, paddingTop: 30) + + tokenExchangeBraintreeBookingButton.centerX(inView: view) + tokenExchangeBraintreeBookingButton.anchor(top: guestBraintreeBookingButton.bottomAnchor, paddingTop: 30) - guestBookingButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true - guestBookingButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true + authenticatedAdyenBookingButton.centerX(inView: view) + authenticatedAdyenBookingButton.anchor(top: tokenExchangeBraintreeBookingButton.bottomAnchor, paddingTop: 80) - authenticatedBookingButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true - authenticatedBookingButton.topAnchor.constraint(equalTo: guestBookingButton.bottomAnchor, - constant: -100).isActive = true + guestAdyenBookingButton.centerX(inView: view) + guestAdyenBookingButton.anchor(top: authenticatedAdyenBookingButton.bottomAnchor, paddingTop: 30) - tokenExchangeBookingButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true - tokenExchangeBookingButton.topAnchor.constraint(equalTo: authenticatedBookingButton.bottomAnchor, - constant: -100).isActive = true + tokenExchangeAdyenBookingButton.centerX(inView: view) + tokenExchangeAdyenBookingButton.anchor(top: guestAdyenBookingButton.bottomAnchor, paddingTop: 30) + + } + + @objc func guestAdyenBookingTapped(sender: UIButton) { + let guestSettings = GuestSettings(identifier: Keys.adyenGuestIdentifier, + referer: Keys.referer, + organisationId: Keys.adyenGuestOrganisationId) + KarhooConfig.auth = .guest(settings: guestSettings) + KarhooConfig.environment = Keys.adyenGuestEnvironment + showKarhoo() } - @objc func guestBookingTapped(sender: UIButton) { + @objc func guestBraintreeBookingTapped(sender: UIButton) { let guestSettings = GuestSettings(identifier: Keys.braintreeGuestIdentifier, referer: Keys.referer, organisationId: Keys.braintreeGuestOrganisationId) KarhooConfig.auth = .guest(settings: guestSettings) + KarhooConfig.environment = Keys.braintreeGuestEnvironment showKarhoo() } - @objc func authenticatedBookingTapped(sender: UIButton) { + @objc func authenticatedAdyenBookingTapped(sender: UIButton) { KarhooConfig.auth = .karhooUser - usernamePasswordLoginAndShowKarhoo() + KarhooConfig.environment = Keys.adyenUserServiceEnvironment + usernamePasswordLoginAndShowKarhoo(username: Keys.adyenUserServiceEmail, password: Keys.adyenUserServicePassword) + } + + @objc func authenticatedBraintreeBookingTapped(sender: UIButton) { + KarhooConfig.auth = .karhooUser + KarhooConfig.environment = Keys.braintreeUserServiceEnvironment + usernamePasswordLoginAndShowKarhoo(username: Keys.braintreeUserServiceEmail, password: Keys.braintreeUserServicePassword) } - @objc func tokenExchangeBookingTapped(sender: UIButton) { + @objc func tokenExchangeBraintreeBookingTapped(sender: UIButton) { let tokenExchangeSettings = TokenExchangeSettings(clientId: Keys.braintreeTokenClientId, scope: Keys.braintreeTokenScope) KarhooConfig.auth = .tokenExchange(settings: tokenExchangeSettings) - tokenLoginAndShowKarhoo() + KarhooConfig.environment = Keys.braintreeTokenEnvironment + tokenLoginAndShowKarhoo(token: Keys.braintreeAuthToken) } - private func usernamePasswordLoginAndShowKarhoo() { - KarhooConfig.auth = .karhooUser + @objc func tokenExchangeAdyenBookingTapped(sender: UIButton) { + let tokenExchangeSettings = TokenExchangeSettings(clientId: Keys.adyenTokenClientId, scope: Keys.adyenTokenScope) + KarhooConfig.auth = .tokenExchange(settings: tokenExchangeSettings) + KarhooConfig.environment = Keys.adyenTokenEnvironment + tokenLoginAndShowKarhoo(token: Keys.adyenAuthToken) + } + + private func usernamePasswordLoginAndShowKarhoo(username: String, password: String) { let userService = Karhoo.getUserService() userService.logout().execute(callback: { _ in}) - let userLogin = UserLogin(username: Keys.userServiceEmailBraintree, - password: Keys.userServicePasswordBraintree) + let userLogin = UserLogin(username: username, + password: password) userService.login(userLogin: userLogin).execute(callback: { result in print("login: \(result)") if result.isSuccess() { @@ -101,10 +163,10 @@ class ViewController: UIViewController { }) } - private func tokenLoginAndShowKarhoo() { + private func tokenLoginAndShowKarhoo(token: String) { let authService = Karhoo.getAuthService() - authService.login(token: Keys.braintreeAuthToken).execute { result in + authService.login(token: token).execute { result in print("token login: \(result)") if result.isSuccess() { self.showKarhoo() @@ -131,22 +193,36 @@ class ViewController: UIViewController { // locale: "en") booking = KarhooUI().screens().booking().buildBookingScreen(journeyInfo: journeyInfo, - passengerDetails: passangerDetails, - callback: { [weak self] result in - switch result { - case .completed(let bookingScreenResult): - switch bookingScreenResult { - case .tripAllocated(let trip): (self?.booking as? BookingScreen)?.openTrip(trip) - default: break - } - default: break - } - }) as? BookingScreen - + passengerDetails: passangerDetails, + callback: { [weak self] result in + self?.handleBookingScreenResult(result: result) + }) as? BookingScreen self.present(booking!, animated: true, completion: nil) } + + private func handleBookingScreenResult(result: ScreenResult) { + switch result { + + case .completed(let bookingScreenResult): + switch bookingScreenResult { + + case .tripAllocated(let trip): + (booking as? BookingScreen)?.openTrip(trip) + + case .prebookConfirmed(let trip, let prebookConfirmationAction): + if case .rideDetails = prebookConfirmationAction { + (booking as? BookingScreen)?.openRideDetailsFor(trip) + } + + default: + break + } + default: + break + } + } private func logout() { if Karhoo.configuration.authenticationMethod().isGuest() { diff --git a/KarhooUISDK.podspec b/KarhooUISDK.podspec index f2cb4c8f4..bc48134dc 100644 --- a/KarhooUISDK.podspec +++ b/KarhooUISDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "KarhooUISDK" - s.version = "1.6.4" + s.version = "1.7.0" s.summary = "Karhoo UI SDK" s.homepage = "https://developer.karhoo.com/docs/build-apps-using-sdks" s.license = 'BSD 2-Clause' diff --git a/KarhooUISDK.xcodeproj/project.pbxproj b/KarhooUISDK.xcodeproj/project.pbxproj index fb775c697..75cccd7ca 100644 --- a/KarhooUISDK.xcodeproj/project.pbxproj +++ b/KarhooUISDK.xcodeproj/project.pbxproj @@ -25,7 +25,7 @@ 092F281D22B25B0700AF8E0E /* BraintreeThreeDSecureProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 092F281822B25B0700AF8E0E /* BraintreeThreeDSecureProvider.swift */; }; 092F281F22B25B3700AF8E0E /* OperationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 092F281E22B25B3700AF8E0E /* OperationResult.swift */; }; 094551A321B9818200F029D1 /* AddressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0991067221B8291900BD7E6F /* AddressViewController.swift */; }; - 0946CB5D21CBDF0400DBDD42 /* BookingRequestScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0946CB5C21CBDF0400DBDD42 /* BookingRequestScreenBuilder.swift */; }; + 0946CB5D21CBDF0400DBDD42 /* CheckoutScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0946CB5C21CBDF0400DBDD42 /* CheckoutScreenBuilder.swift */; }; 094AE85421C913020046EC3C /* DatePickerScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 094AE85321C913020046EC3C /* DatePickerScreenBuilder.swift */; }; 094AE85D21C9145D0046EC3C /* DatePickerMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 094AE85621C9145D0046EC3C /* DatePickerMVP.swift */; }; 094AE85E21C9145D0046EC3C /* DatePickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 094AE85821C9145D0046EC3C /* DatePickerViewController.swift */; }; @@ -68,10 +68,6 @@ 0999CBB0220DDA0300A93AF9 /* KarhooUIScreenRouting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0999CBAF220DDA0300A93AF9 /* KarhooUIScreenRouting.swift */; }; 09A1F88F225CBCFF00B3DBE2 /* MenuContentMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A1F88E225CBCFF00B3DBE2 /* MenuContentMVP.swift */; }; 09B30F692253986B007768CF /* mockImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 09B30F682253986B007768CF /* mockImage.png */; }; - 09BDD19121C2CAD00074421C /* FlightDetailsMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BDD18A21C2CAD00074421C /* FlightDetailsMVP.swift */; }; - 09BDD19221C2CAD00074421C /* KarhooFlightDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BDD18C21C2CAD00074421C /* KarhooFlightDetailsPresenter.swift */; }; - 09BDD19421C2CAD00074421C /* FlightDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BDD18F21C2CAD00074421C /* FlightDetailsViewController.swift */; }; - 09BDD19521C2CAD00074421C /* FlightDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BDD19021C2CAD00074421C /* FlightDetails.swift */; }; 09C169B8227C8EFF00CF7E66 /* AddressType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09C169B7227C8EFF00CF7E66 /* AddressType.swift */; }; 09C7649321DE665000CD81AB /* BookingScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09C7649221DE665000CD81AB /* BookingScreenBuilder.swift */; }; 09C7659B21DE688100CD81AB /* QuoteListPanelLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09C7656121DE688000CD81AB /* QuoteListPanelLayout.swift */; }; @@ -109,13 +105,10 @@ 09DA1A3122F1A866004C6B20 /* FeedbackButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09DA1A3022F1A866004C6B20 /* FeedbackButtonView.swift */; }; 09DA1A3322F1A8F4004C6B20 /* FeedbackButtonMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09DA1A3222F1A8F4004C6B20 /* FeedbackButtonMVP.swift */; }; 09DE8D46221C658B00451B3C /* BraintreePaymentScreensBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09DE8D45221C658B00451B3C /* BraintreePaymentScreensBuilder.swift */; }; - 09E0249B21C2D7D40071E367 /* FlightDetailsScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E0249A21C2D7D40071E367 /* FlightDetailsScreenBuilder.swift */; }; - 09E024A021C2D9FD0071E367 /* FlightNumberValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E0249F21C2D9FD0071E367 /* FlightNumberValidator.swift */; }; 09E683212374236100BFF5B9 /* KarhooAddressMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E683202374236100BFF5B9 /* KarhooAddressMapView.swift */; }; 09E683232374522900BFF5B9 /* KarhooAddressMapPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E683222374522900BFF5B9 /* KarhooAddressMapPresenter.swift */; }; 09F60CDF226623A200023C74 /* SideMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F60CDE226623A200023C74 /* SideMenu.swift */; }; 09F60CE9226756AF00023C74 /* SideMenuHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F60CE8226756AF00023C74 /* SideMenuHandler.swift */; }; - 11835BEF4BCC4A95D6F37450 /* Pods_KarhooUISDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9F928AAF8C70E5FFDE416BC /* Pods_KarhooUISDK.framework */; }; 1413303225DBDC3100EDAD3B /* Keys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1413303125DBDC3100EDAD3B /* Keys.swift */; }; 14707C3925D54C2100CAD083 /* MockRidesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F542211D38E00FB6BB5 /* MockRidesView.swift */; }; 14707C3A25D54C2100CAD083 /* DestinationSetStrategySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E35D6A21E5118A003E840C /* DestinationSetStrategySpec.swift */; }; @@ -159,14 +152,14 @@ 14707C6025D54C2100CAD083 /* BookingAddressBarPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E35D6D21E5118A003E840C /* BookingAddressBarPresenterSpec.swift */; }; 14707C6125D54C2100CAD083 /* MockAddressMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A5B9AE25C1C61000986616 /* MockAddressMapView.swift */; }; 14707C6225D54C2100CAD083 /* KarhooPrebookConfirmationPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAD1BFF22087CA600C3AD1D /* KarhooPrebookConfirmationPresenterSpec.swift */; }; - 14707C6325D54C2100CAD083 /* MockBookingRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC13584A21D6752F005054AE /* MockBookingRequestView.swift */; }; + 14707C6325D54C2100CAD083 /* MockCheckoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC13584A21D6752F005054AE /* MockCheckoutView.swift */; }; 14707C6425D54C2100CAD083 /* MockTripScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC83E30A221F1839008FE26D /* MockTripScreenBuilder.swift */; }; 14707C6525D54C2100CAD083 /* MockFareService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408AB682234F418B00B351B2 /* MockFareService.swift */; }; 14707C6625D54C2100CAD083 /* MockAddressService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9D9919242CED15004F1DBD /* MockAddressService.swift */; }; 14707C6725D54C2100CAD083 /* MockPaymentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC658F612216D9C1006C48F2 /* MockPaymentService.swift */; }; 14707C6825D54C2100CAD083 /* MockCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0968F0F621BE850F00745370 /* MockCall.swift */; }; 14707C6925D54C2100CAD083 /* ResizingSwitcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC13584121D64E8C005054AE /* ResizingSwitcherTests.swift */; }; - 14707C6A25D54C2100CAD083 /* MockBookingRequestScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC658F462216D0BB006C48F2 /* MockBookingRequestScreenBuilder.swift */; }; + 14707C6A25D54C2100CAD083 /* MockCheckoutScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC658F462216D0BB006C48F2 /* MockCheckoutScreenBuilder.swift */; }; 14707C6B25D54C2100CAD083 /* MockTripService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC13585121D67971005054AE /* MockTripService.swift */; }; 14707C6C25D54C2100CAD083 /* KarhooAddressPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09DCC7F121BE7CE000DF02B9 /* KarhooAddressPresenterSpec.swift */; }; 14707C6D25D54C2100CAD083 /* TripMapPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC83E2DD221EECB0008FE26D /* TripMapPresenterSpec.swift */; }; @@ -175,7 +168,6 @@ 14707C7025D54C2100CAD083 /* MockRidesListActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F662211D3DD00FB6BB5 /* MockRidesListActions.swift */; }; 14707C7125D54C2100CAD083 /* MockDataFormatterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0949545B2201C2BA00D930C0 /* MockDataFormatterType.swift */; }; 14707C7225D54C2100CAD083 /* MockTripRatingCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095D7455231825C7002253C0 /* MockTripRatingCache.swift */; }; - 14707C7325D54C2100CAD083 /* MockFlightDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E1475421C7ED06003BB30B /* MockFlightDetailsView.swift */; }; 14707C7425D54C2100CAD083 /* MockBookingMapStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09C169B922819BBF00CF7E66 /* MockBookingMapStrategy.swift */; }; 14707C7525D54C2100CAD083 /* KarhooTripSummaryPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC83E2EA221EED94008FE26D /* KarhooTripSummaryPresenterSpec.swift */; }; 14707C7625D54C2100CAD083 /* MockUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BDD18721C2C20A0074421C /* MockUserDefaults.swift */; }; @@ -184,7 +176,7 @@ 14707C7925D54C2100CAD083 /* MockTripsSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F6B2211D76100FB6BB5 /* MockTripsSorter.swift */; }; 14707C7A25D54C2100CAD083 /* MockAddressScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC658F472216D0BB006C48F2 /* MockAddressScreenBuilder.swift */; }; 14707C7B25D54C2100CAD083 /* MockPaymentNonceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 092F282022B25C7800AF8E0E /* MockPaymentNonceProvider.swift */; }; - 14707C7C25D54C2100CAD083 /* KarhooBookingRequestPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC13584621D64F66005054AE /* KarhooBookingRequestPresenterSpec.swift */; }; + 14707C7C25D54C2100CAD083 /* KarhooCheckoutPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC13584621D64F66005054AE /* KarhooCheckoutPresenterSpec.swift */; }; 14707C7D25D54C2100CAD083 /* MockQuoteSortView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E35D5621E5117C003E840C /* MockQuoteSortView.swift */; }; 14707C7E25D54C2100CAD083 /* KarhooDateFormatterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D293C422C651C10051C455 /* KarhooDateFormatterSpec.swift */; }; 14707C7F25D54C2100CAD083 /* BookingMapPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E35D6921E5118A003E840C /* BookingMapPresenterSpec.swift */; }; @@ -225,7 +217,6 @@ 14707CA325D54C2200CAD083 /* KarhooTripMetaDataPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F482211D34000FB6BB5 /* KarhooTripMetaDataPresenterSpec.swift */; }; 14707CA425D54C2200CAD083 /* MockKarhooPaymentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C20976F244475660097BA3A /* MockKarhooPaymentView.swift */; }; 14707CA525D54C2200CAD083 /* TripSummaryInfoViewModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC83E2E8221EED8F008FE26D /* TripSummaryInfoViewModelSpec.swift */; }; - 14707CA625D54C2200CAD083 /* FlightNumberValidatorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09AAEF9521C4270800A04EEC /* FlightNumberValidatorSpec.swift */; }; 14707CA725D54C2200CAD083 /* CancelRideBehaviourSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B30F5A224CE8BF007768CF /* CancelRideBehaviourSpec.swift */; }; 14707CA825D54C2200CAD083 /* MockRideDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F5A2211D3D700FB6BB5 /* MockRideDetailsView.swift */; }; 14707CA925D54C2200CAD083 /* MockTripMetaDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F592211D3D700FB6BB5 /* MockTripMetaDataView.swift */; }; @@ -246,12 +237,11 @@ 14707CB925D54C2200CAD083 /* MockPrebookConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAD1C0D220884CC00C3AD1D /* MockPrebookConfirmationView.swift */; }; 14707CBA25D54C2200CAD083 /* TestBroadcaster.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F86F7F222D60AB008C86DE /* TestBroadcaster.swift */; }; 14707CBB25D54C2200CAD083 /* MockAddressSearchProviderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0968F0E821BE7FF100745370 /* MockAddressSearchProviderDelegate.swift */; }; - 14707CBC25D54C2200CAD083 /* MockFlightDetailsScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC658F432216D0BB006C48F2 /* MockFlightDetailsScreenBuilder.swift */; }; 14707CBD25D54C2200CAD083 /* PrebookConfirmationViewModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAD1C0122087CA600C3AD1D /* PrebookConfirmationViewModelSpec.swift */; }; 14707CBE25D54C2200CAD083 /* MockBookingDetailsObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F86F85222D8553008C86DE /* MockBookingDetailsObserver.swift */; }; 14707CBF25D54C2200CAD083 /* UnitTestSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 096192F521BEAB9C0052B71C /* UnitTestSetup.swift */; }; 14707CC025D54C2200CAD083 /* MockFeedbackMailComposter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F712211D7F500FB6BB5 /* MockFeedbackMailComposter.swift */; }; - 14707CC125D54C2200CAD083 /* KarhooGuestBookingRequestPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4038DF43244617960014539B /* KarhooGuestBookingRequestPresenterSpec.swift */; }; + 14707CC125D54C2200CAD083 /* KarhooGuestCheckoutPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4038DF43244617960014539B /* KarhooGuestCheckoutPresenterSpec.swift */; }; 14707CC225D54C2200CAD083 /* CurrencyCodeConverterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A5B96A25C19BEE00986616 /* CurrencyCodeConverterSpec.swift */; }; 14707CC325D54C2200CAD083 /* MockQuoteCategoryBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E35D4E21E5117C003E840C /* MockQuoteCategoryBarView.swift */; }; 14707CC425D54C2200CAD083 /* QtaStringFormatterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D293C322C651C10051C455 /* QtaStringFormatterSpec.swift */; }; @@ -279,14 +269,12 @@ 14707CDA25D54C2200CAD083 /* MockRideDetailsScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4B92EC222E982400FE33B4 /* MockRideDetailsScreenBuilder.swift */; }; 14707CDB25D54C2200CAD083 /* KarhooRidesListPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F4A2211D34000FB6BB5 /* KarhooRidesListPresenterSpec.swift */; }; 14707CDC25D54C2200CAD083 /* MockPopupDialogScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F12DC82232ABD30024D6E9 /* MockPopupDialogScreenBuilder.swift */; }; - 14707CDD25D54C2200CAD083 /* FlightDetailsPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BDD19721C2CBCF0074421C /* FlightDetailsPresenterSpec.swift */; }; 14707CDE25D54C2200CAD083 /* PrebookConfirmationFormatterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAD1C0022087CA600C3AD1D /* PrebookConfirmationFormatterSpec.swift */; }; 14707CDF25D54C2200CAD083 /* MockTripSummaryScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC83E30C221F18F3008FE26D /* MockTripSummaryScreenBuilder.swift */; }; 14A5B93325C1823C00986616 /* KarhooConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A5B93225C1823C00986616 /* KarhooConfig.swift */; }; 23391EAC22C65525007D704E /* AddressCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23391EAB22C65525007D704E /* AddressCellViewModel.swift */; }; 2396A2AB255566DC007BD9E1 /* JourneyInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2396A2AA255566DC007BD9E1 /* JourneyInfo.swift */; }; - 2A9BC10FB50E39DBB73C43FF /* Pods_Client.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FF975DAE636DFA8CA47C6F2 /* Pods_Client.framework */; }; - 400BE99222CF4D27002942CC /* KarhooPaymentPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 400BE99122CF4D27002942CC /* KarhooPaymentPresenter.swift */; }; + 400BE99222CF4D27002942CC /* KarhooAddPaymentPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 400BE99122CF4D27002942CC /* KarhooAddPaymentPresenter.swift */; }; 4010B0DA2458847500E7B0F1 /* KarhooTextInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4010B0D92458847500E7B0F1 /* KarhooTextInputView.swift */; }; 4010B0DC245C5DD900E7B0F1 /* KarhooInputViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4010B0DB245C5DD900E7B0F1 /* KarhooInputViewState.swift */; }; 4010B0DE245C5DFE00E7B0F1 /* KarhooTextInputViewContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4010B0DD245C5DFE00E7B0F1 /* KarhooTextInputViewContentType.swift */; }; @@ -299,8 +287,6 @@ 4038DF3A2444BAC40014539B /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4038DF392444BAC40014539B /* Utils.swift */; }; 4038DF3D2444C6E00014539B /* KarhooPhoneInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4038DF3C2444C6E00014539B /* KarhooPhoneInputView.swift */; }; 4038DF3F2444D6810014539B /* KarhooInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4038DF3E2444D6810014539B /* KarhooInputView.swift */; }; - 4038DF422445D5340014539B /* KarhooPhoneInputViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4038DF412445D5340014539B /* KarhooPhoneInputViewDataSource.swift */; }; - 403E907922C5287F00F39B91 /* KarhooPaymentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 403E907822C5287F00F39B91 /* KarhooPaymentView.swift */; }; 403F448222F19A38008147FC /* BaseStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 403F448122F19A38008147FC /* BaseStackView.swift */; }; 403F448422F1EC92008147FC /* KarhooTripFeedbackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 403F448322F1EC92008147FC /* KarhooTripFeedbackViewController.swift */; }; 404E9C4B23C8BB2B00289F43 /* LineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 404E9C4A23C8BB2B00289F43 /* LineView.swift */; }; @@ -379,7 +365,7 @@ 40A2851F22B2476F0020D78F /* QuoteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40A2851E22B2476F0020D78F /* QuoteViewModel.swift */; }; 40C1CD7223C9EC7900EDEA84 /* TripStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40C1CD7123C9EC7900EDEA84 /* TripStatusView.swift */; }; 40C7DC5B23D0A13500975AD3 /* MetaDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40C7DC5A23D0A13500975AD3 /* MetaDataView.swift */; }; - 40E54AC42460DF9D00D13E10 /* KarhooAddCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40E54AC32460DF9D00D13E10 /* KarhooAddCardView.swift */; }; + 40E54AC42460DF9D00D13E10 /* KarhooAddPaymentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40E54AC32460DF9D00D13E10 /* KarhooAddPaymentView.swift */; }; 40E6693523D5B99E00DE63BA /* RideDetailsViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40E6693423D5B99E00DE63BA /* RideDetailsViewContainer.swift */; }; 40FE0CEA22D7D28B003F65B5 /* RateButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FE0CE922D7D28B003F65B5 /* RateButton.swift */; }; 40FE0CED22D7D2D4003F65B5 /* RateButtonViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FE0CEC22D7D2D4003F65B5 /* RateButtonViewModel.swift */; }; @@ -403,42 +389,66 @@ 5C2E26142420F8AC00B1FF0C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E26132420F8AC00B1FF0C /* ViewController.swift */; }; 5C2E26192420F8AD00B1FF0C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5C2E26182420F8AD00B1FF0C /* Assets.xcassets */; }; 5C2E261C2420F8AD00B1FF0C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5C2E261A2420F8AD00B1FF0C /* LaunchScreen.storyboard */; }; - 5C3C66B724468B7800C736E9 /* KarhooPaymentMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3C66B624468B7800C736E9 /* KarhooPaymentMVP.swift */; }; + 5C3C66B724468B7800C736E9 /* KarhooAddPaymentMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3C66B624468B7800C736E9 /* KarhooAddPaymentMVP.swift */; }; 5C4252592518D06000CCCB5D /* CardRegistrationFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C4252582518D06000CCCB5D /* CardRegistrationFlow.swift */; }; 5C6267EA252CC24500AB6CD2 /* PaymentFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6267E9252CC24500AB6CD2 /* PaymentFactory.swift */; }; 5C626861252DFC0A00AB6CD2 /* AdyenResponseHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C626860252DFC0A00AB6CD2 /* AdyenResponseHandler.swift */; }; 5C7233C0226510B9001078B6 /* KarhooUISDKError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7233BF226510B9001078B6 /* KarhooUISDKError.swift */; }; 5C7B185225310E170001CFE6 /* TouchAreaEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7B185125310E170001CFE6 /* TouchAreaEdgeInsets.swift */; }; - 5C7B191C2534B2120001CFE6 /* FlightDetailsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 09BDD18E21C2CAD00074421C /* FlightDetailsViewController.xib */; }; 5C7F6EF1233A375F0039F3E2 /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7F6EF0233A375F0039F3E2 /* BaseView.swift */; }; 5C831686246218E700BAA926 /* KarhooComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C831685246218E700BAA926 /* KarhooComponents.swift */; }; 5C8316BB246A0B6200BAA926 /* EmptyMapBookingStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C8316BA246A0B6200BAA926 /* EmptyMapBookingStrategy.swift */; }; 5C8316C1246B6D0700BAA926 /* SharedPassengerDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C8316C0246B6D0700BAA926 /* SharedPassengerDetails.swift */; }; - 5CBA2A7424F5D8CC0091D783 /* BookingRequestMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6024F5D8CC0091D783 /* BookingRequestMVP.swift */; }; - 5CBA2A7524F5D8CC0091D783 /* FormBookingRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6224F5D8CC0091D783 /* FormBookingRequestViewController.swift */; }; - 5CBA2A7624F5D8CC0091D783 /* FormBookingRequestPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6324F5D8CC0091D783 /* FormBookingRequestPresenter.swift */; }; - 5CBA2A7724F5D8CC0091D783 /* FormCheckoutHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6424F5D8CC0091D783 /* FormCheckoutHeaderView.swift */; }; + 5CBA2A7424F5D8CC0091D783 /* KarhooCheckoutMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6024F5D8CC0091D783 /* KarhooCheckoutMVP.swift */; }; + 5CBA2A7524F5D8CC0091D783 /* KarhooCheckoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6224F5D8CC0091D783 /* KarhooCheckoutViewController.swift */; }; + 5CBA2A7624F5D8CC0091D783 /* KarhooCheckoutPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6324F5D8CC0091D783 /* KarhooCheckoutPresenter.swift */; }; + 5CBA2A7724F5D8CC0091D783 /* KarhooCheckoutHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6424F5D8CC0091D783 /* KarhooCheckoutHeaderView.swift */; }; 5CBA2A7824F5D8CC0091D783 /* PassengerDetailsMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6624F5D8CC0091D783 /* PassengerDetailsMVP.swift */; }; - 5CBA2A7924F5D8CC0091D783 /* PassengerDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6724F5D8CC0091D783 /* PassengerDetailsView.swift */; }; - 5CBA2A7A24F5D8CC0091D783 /* BookingButtonMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6A24F5D8CC0091D783 /* BookingButtonMVP.swift */; }; + 5CBA2A7A24F5D8CC0091D783 /* KarhooBookingButtonMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6A24F5D8CC0091D783 /* KarhooBookingButtonMVP.swift */; }; 5CBA2A7B24F5D8CC0091D783 /* KarhooBookingButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6B24F5D8CC0091D783 /* KarhooBookingButtonView.swift */; }; - 5CBA2A7C24F5D8CC0091D783 /* KarhooBookingRequestPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6C24F5D8CC0091D783 /* KarhooBookingRequestPresenter.swift */; }; - 5CBA2A7D24F5D8CC0091D783 /* SupplierView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6E24F5D8CC0091D783 /* SupplierView.swift */; }; - 5CBA2A7E24F5D8CC0091D783 /* KarhooBookingRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A6F24F5D8CC0091D783 /* KarhooBookingRequestViewController.swift */; }; 5CBA2A7F24F5D8CC0091D783 /* KarhooTimePriceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A7124F5D8CC0091D783 /* KarhooTimePriceView.swift */; }; - 5CBA2A8024F5D8CC0091D783 /* TimePriceMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A7224F5D8CC0091D783 /* TimePriceMVP.swift */; }; + 5CBA2A8024F5D8CC0091D783 /* KarhooTimePriceMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBA2A7224F5D8CC0091D783 /* KarhooTimePriceMVP.swift */; }; 5CBA2A8124F5D8CC0091D783 /* KarhooTimePriceView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5CBA2A7324F5D8CC0091D783 /* KarhooTimePriceView.xib */; }; - 5CC253712441FD4000603D84 /* PaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC253702441FD4000603D84 /* PaymentMethod.swift */; }; 5CD9CFAA22DCAB580086E7A0 /* RatingViewMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CD9CFA922DCAB580086E7A0 /* RatingViewMVP.swift */; }; 5CDACF2E23CCAC8700FD4F56 /* KarhooMKMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDACF2D23CCAC8700FD4F56 /* KarhooMKMapView.swift */; }; 5CDACF3023CCB8DC00FD4F56 /* MapAnnotationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDACF2F23CCB8DC00FD4F56 /* MapAnnotationViewModel.swift */; }; 5CED9268227F1CFB00E0C960 /* ScreenBuilders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CED9267227F1CFB00E0C960 /* ScreenBuilders.swift */; }; + 6B2633D326FCD0930027BCF5 /* CountryFlags.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B2633D226FCD0930027BCF5 /* CountryFlags.xcassets */; }; + 6B4C15A92731881A00C10EAE /* QuoteCategory+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B4C15A82731881A00C10EAE /* QuoteCategory+Extensions.swift */; }; + 6B5B035326D7B8010001B2DB /* KarhooAddPassengerDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B035226D7B8010001B2DB /* KarhooAddPassengerDetailsView.swift */; }; + 6B5B035526D7B81F0001B2DB /* KarhooAddPassengerDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B035426D7B81F0001B2DB /* KarhooAddPassengerDetailsPresenter.swift */; }; + 6B5B035726D7B83F0001B2DB /* KarhooAddPassengerDetailsMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B035626D7B83F0001B2DB /* KarhooAddPassengerDetailsMVP.swift */; }; + 6B5B035926D7C2D90001B2DB /* KarhooCheckoutViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B035826D7C2D90001B2DB /* KarhooCheckoutViewController+Extensions.swift */; }; + 6B5D607D26E8E45900163EFE /* MockPassengerDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5D607C26E8E45900163EFE /* MockPassengerDetailsViewController.swift */; }; + 6B5D607F26E8E60C00163EFE /* PassengerDetailsPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5D607E26E8E60C00163EFE /* PassengerDetailsPresenterSpec.swift */; }; + 6B5E25F326D672090017BFB3 /* PassengerDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5E25F226D672090017BFB3 /* PassengerDetailsViewController.swift */; }; + 6B5E25F526D67DCA0017BFB3 /* PassengerDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5E25F426D67DCA0017BFB3 /* PassengerDetailsPresenter.swift */; }; + 6B7BE3F3271968A600682AA1 /* PassengerDetails+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B7BE3F2271968A600682AA1 /* PassengerDetails+Extensions.swift */; }; + 6BA3544F27304E400003B888 /* QuoteVehicle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA3544E27304E400003B888 /* QuoteVehicle+Extensions.swift */; }; + 6BE3695226EB34D000F0FE86 /* CountryCodeSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE3695126EB34D000F0FE86 /* CountryCodeSelectionViewController.swift */; }; + 6BE3695426EB34E000F0FE86 /* CountryCodeSelectionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE3695326EB34E000F0FE86 /* CountryCodeSelectionPresenter.swift */; }; + 6BE3695626EB352700F0FE86 /* CountryCodeSelectionMVP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE3695526EB352700F0FE86 /* CountryCodeSelectionMVP.swift */; }; + 6BE36B5726EBB1F300F0FE86 /* CountryCodeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE36B5626EBB1F300F0FE86 /* CountryCodeTableViewCell.swift */; }; + 6BE36B5926EBB24400F0FE86 /* CountryCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE36B5826EBB24400F0FE86 /* CountryCodeView.swift */; }; + 6BE36B5B26EBB37E00F0FE86 /* CountryCodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE36B5A26EBB37E00F0FE86 /* CountryCodeViewModel.swift */; }; + 6BE36B5D26EF8A3400F0FE86 /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE36B5C26EF8A3400F0FE86 /* Country.swift */; }; + 6BE36B5F26EF8DFD00F0FE86 /* KarhooCountryParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE36B5E26EF8DFD00F0FE86 /* KarhooCountryParser.swift */; }; + 6BE36B6126EF8E3B00F0FE86 /* KarhooFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE36B6026EF8E3B00F0FE86 /* KarhooFileManager.swift */; }; 6F4235BF2391800C00233C02 /* AddressGoogleLogoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F4235BE2391800C00233C02 /* AddressGoogleLogoView.swift */; }; 6F89EA0D248E5CA300F47C1B /* KarhooAddressDisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F89EA0C248E5CA300F47C1B /* KarhooAddressDisplayView.swift */; }; + 7311338799B6FA2263683FE5 /* Pods_Client.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AC8D4F24E607275C42382EA5 /* Pods_Client.framework */; }; + 791A9CDE26C4EC2A00B52DA1 /* KarhooAddPassengerDetailsAndPaymentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791A9CDD26C4EC2A00B52DA1 /* KarhooAddPassengerDetailsAndPaymentView.swift */; }; + 79793ED8270F2E2200944896 /* UIViewController+extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79793ED7270F2E2200944896 /* UIViewController+extensions.swift */; }; 799DC592268F66EC00A48589 /* MapAnnotationViewModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799DC591268F66EC00A48589 /* MapAnnotationViewModelSpec.swift */; }; + 79ACDCE426CCB3A9008820B5 /* KarhooLearnMoreButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79ACDCE326CCB3A9008820B5 /* KarhooLearnMoreButton.swift */; }; + 79ACDCE626CCB5FB008820B5 /* KarhooFleetCapabilitiesDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79ACDCE526CCB5FB008820B5 /* KarhooFleetCapabilitiesDetailsView.swift */; }; + 79ACDCE826CCBAA9008820B5 /* KarhooRideInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79ACDCE726CCBAA9008820B5 /* KarhooRideInfoView.swift */; }; + 79ACDCED26CFC3E7008820B5 /* KarhooFareInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79ACDCEC26CFC3E7008820B5 /* KarhooFareInfoView.swift */; }; 986578A0F928780978136BC5 /* RidesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 986573E003E549DB4C06EA7A /* RidesViewController.xib */; }; A1A0312626171A4E00B01E1F /* KarhooQuoteListPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A0312526171A4E00B01E1F /* KarhooQuoteListPresenterSpec.swift */; }; + A2F57788B9E24B8BCDB8AC3E /* Pods_KarhooUISDKTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74CD3B9E97F3F71C70E70B9A /* Pods_KarhooUISDKTests.framework */; }; AE4AC8A425F12C28000F9E57 /* AdyenThreeDSecureUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE4AC8A325F12C28000F9E57 /* AdyenThreeDSecureUtils.swift */; }; + D0FC00230C27E6227EBAC4AD /* Pods_KarhooUISDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0FC889910C10F74B4D3774E /* Pods_KarhooUISDK.framework */; }; D8263F4E262096C30042F259 /* TimeFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8263F4D262096C30042F259 /* TimeFormatter.swift */; }; D88BC2862620C51C00F1EA60 /* TimeFormatterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88BC2852620C51C00F1EA60 /* TimeFormatterSpec.swift */; }; D8D8ED2A261F1FDA0061066D /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = D8D8ED2D261F1FDA0061066D /* Localizable.stringsdict */; }; @@ -474,7 +484,6 @@ FC435F422211BB5900FB6BB5 /* TimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F412211BB5900FB6BB5 /* TimeScheduler.swift */; }; FC435F442211BB8B00FB6BB5 /* KarhooTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F432211BB8B00FB6BB5 /* KarhooTimeScheduler.swift */; }; FC435F7A2211DDB400FB6BB5 /* RideCellViewModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC435F792211DDB400FB6BB5 /* RideCellViewModelSpec.swift */; }; - FC45D6D817F54C9C62E8B7A0 /* Pods_KarhooUISDKTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA979AB3B77F9708C97C2E84 /* Pods_KarhooUISDKTests.framework */; }; FC705B0D2212DE6E0001036E /* RidesScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC705B0C2212DE6E0001036E /* RidesScreenBuilder.swift */; }; FC705B0F22130B990001036E /* RidesListScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC705B0E22130B990001036E /* RidesListScreenBuilder.swift */; }; FC705B15221321650001036E /* PopupDialogScreenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC705B14221321650001036E /* PopupDialogScreenBuilder.swift */; }; @@ -561,7 +570,7 @@ 092F282022B25C7800AF8E0E /* MockPaymentNonceProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MockPaymentNonceProvider.swift; path = KarhooUISDKTests/Mocks/Classes/MockPaymentNonceProvider.swift; sourceTree = SOURCE_ROOT; }; 092F282222B2607D00AF8E0E /* PrimitiveUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimitiveUtil.swift; sourceTree = ""; }; 093D2E6D2224346C00D5F031 /* PopupDialogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupDialogView.swift; sourceTree = ""; }; - 0946CB5C21CBDF0400DBDD42 /* BookingRequestScreenBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookingRequestScreenBuilder.swift; sourceTree = ""; }; + 0946CB5C21CBDF0400DBDD42 /* CheckoutScreenBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckoutScreenBuilder.swift; sourceTree = ""; }; 0949543E21FF5A8800D930C0 /* MockBookingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockBookingView.swift; sourceTree = ""; }; 0949544221FF5F0800D930C0 /* MockQuoteService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockQuoteService.swift; sourceTree = ""; }; 0949545421FF7CDB00D930C0 /* MockKarhooMapView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockKarhooMapView.swift; sourceTree = ""; }; @@ -640,18 +649,11 @@ 0991530021BFDB6400B46D9F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 0999CBAF220DDA0300A93AF9 /* KarhooUIScreenRouting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooUIScreenRouting.swift; sourceTree = ""; }; 09A1F88E225CBCFF00B3DBE2 /* MenuContentMVP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuContentMVP.swift; sourceTree = ""; }; - 09AAEF9521C4270800A04EEC /* FlightNumberValidatorSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightNumberValidatorSpec.swift; sourceTree = ""; }; 09AAEF9721C4283200A04EEC /* MockValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockValidator.swift; sourceTree = ""; }; 09B30F5A224CE8BF007768CF /* CancelRideBehaviourSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancelRideBehaviourSpec.swift; sourceTree = ""; }; 09B30F5B224CE8BF007768CF /* TripsListSorterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TripsListSorterSpec.swift; sourceTree = ""; }; 09B30F682253986B007768CF /* mockImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mockImage.png; sourceTree = ""; }; 09BDD18721C2C20A0074421C /* MockUserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUserDefaults.swift; sourceTree = ""; }; - 09BDD18A21C2CAD00074421C /* FlightDetailsMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlightDetailsMVP.swift; sourceTree = ""; }; - 09BDD18C21C2CAD00074421C /* KarhooFlightDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooFlightDetailsPresenter.swift; sourceTree = ""; }; - 09BDD18E21C2CAD00074421C /* FlightDetailsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FlightDetailsViewController.xib; sourceTree = ""; }; - 09BDD18F21C2CAD00074421C /* FlightDetailsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlightDetailsViewController.swift; sourceTree = ""; }; - 09BDD19021C2CAD00074421C /* FlightDetails.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlightDetails.swift; sourceTree = ""; }; - 09BDD19721C2CBCF0074421C /* FlightDetailsPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlightDetailsPresenterSpec.swift; sourceTree = ""; }; 09C169B7227C8EFF00CF7E66 /* AddressType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressType.swift; sourceTree = ""; }; 09C169B922819BBF00CF7E66 /* MockBookingMapStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBookingMapStrategy.swift; sourceTree = ""; }; 09C169BB22819C1A00CF7E66 /* MockPickupOnlyStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPickupOnlyStrategy.swift; sourceTree = ""; }; @@ -698,9 +700,6 @@ 09DCC7F121BE7CE000DF02B9 /* KarhooAddressPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooAddressPresenterSpec.swift; sourceTree = ""; }; 09DCC7F321BE7CE000DF02B9 /* KarhooAddressSearchProviderSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooAddressSearchProviderSpec.swift; sourceTree = ""; }; 09DE8D45221C658B00451B3C /* BraintreePaymentScreensBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BraintreePaymentScreensBuilder.swift; sourceTree = ""; }; - 09E0249A21C2D7D40071E367 /* FlightDetailsScreenBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightDetailsScreenBuilder.swift; sourceTree = ""; }; - 09E0249F21C2D9FD0071E367 /* FlightNumberValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlightNumberValidator.swift; sourceTree = ""; }; - 09E1475421C7ED06003BB30B /* MockFlightDetailsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockFlightDetailsView.swift; sourceTree = ""; }; 09E35D4921E5117C003E840C /* MockBookingAllocationSpinnerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockBookingAllocationSpinnerView.swift; sourceTree = ""; }; 09E35D4C21E5117C003E840C /* MockQuoteListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockQuoteListView.swift; sourceTree = ""; }; 09E35D4E21E5117C003E840C /* MockQuoteCategoryBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockQuoteCategoryBarView.swift; sourceTree = ""; }; @@ -728,7 +727,6 @@ 09F86F7F222D60AB008C86DE /* TestBroadcaster.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestBroadcaster.swift; sourceTree = ""; }; 09F86F83222D84A8008C86DE /* MockAppStateNotifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockAppStateNotifier.swift; sourceTree = ""; }; 09F86F85222D8553008C86DE /* MockBookingDetailsObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockBookingDetailsObserver.swift; sourceTree = ""; }; - 1061B90ED3BAE79634610DAC /* Pods-KarhooUISDKTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDKTests.release.xcconfig"; path = "Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests.release.xcconfig"; sourceTree = ""; }; 1413303125DBDC3100EDAD3B /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = ""; }; 145EC6F225C98CC800F1FC94 /* MockQuoteSorter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockQuoteSorter.swift; sourceTree = ""; }; 14A5B93225C1823C00986616 /* KarhooConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooConfig.swift; sourceTree = ""; }; @@ -742,9 +740,10 @@ 14A5B9AE25C1C61000986616 /* MockAddressMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAddressMapView.swift; sourceTree = ""; }; 14A5B9C625C1CFCB00986616 /* KarhooRideDetailsPresenterSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooRideDetailsPresenterSpec.swift; sourceTree = ""; }; 23391EAB22C65525007D704E /* AddressCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressCellViewModel.swift; sourceTree = ""; }; - 2372675E70509D3779F8061D /* Pods-KarhooUISDKTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDKTests.debug.xcconfig"; path = "Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests.debug.xcconfig"; sourceTree = ""; }; 2396A2AA255566DC007BD9E1 /* JourneyInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JourneyInfo.swift; sourceTree = ""; }; - 400BE99122CF4D27002942CC /* KarhooPaymentPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooPaymentPresenter.swift; sourceTree = ""; }; + 31B3B4A018455D19516D4105 /* Pods-Client.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Client.release.xcconfig"; path = "Target Support Files/Pods-Client/Pods-Client.release.xcconfig"; sourceTree = ""; }; + 3CDC92F5EF4385593DC9E7C1 /* Pods-Client.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Client.debug.xcconfig"; path = "Target Support Files/Pods-Client/Pods-Client.debug.xcconfig"; sourceTree = ""; }; + 400BE99122CF4D27002942CC /* KarhooAddPaymentPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooAddPaymentPresenter.swift; sourceTree = ""; }; 4010B0D92458847500E7B0F1 /* KarhooTextInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooTextInputView.swift; sourceTree = ""; }; 4010B0DB245C5DD900E7B0F1 /* KarhooInputViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooInputViewState.swift; sourceTree = ""; }; 4010B0DD245C5DFE00E7B0F1 /* KarhooTextInputViewContentType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooTextInputViewContentType.swift; sourceTree = ""; }; @@ -757,9 +756,7 @@ 4038DF392444BAC40014539B /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 4038DF3C2444C6E00014539B /* KarhooPhoneInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooPhoneInputView.swift; sourceTree = ""; }; 4038DF3E2444D6810014539B /* KarhooInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooInputView.swift; sourceTree = ""; }; - 4038DF412445D5340014539B /* KarhooPhoneInputViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooPhoneInputViewDataSource.swift; sourceTree = ""; }; - 4038DF43244617960014539B /* KarhooGuestBookingRequestPresenterSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooGuestBookingRequestPresenterSpec.swift; sourceTree = ""; }; - 403E907822C5287F00F39B91 /* KarhooPaymentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooPaymentView.swift; sourceTree = ""; }; + 4038DF43244617960014539B /* KarhooGuestCheckoutPresenterSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooGuestCheckoutPresenterSpec.swift; sourceTree = ""; }; 403F448122F19A38008147FC /* BaseStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseStackView.swift; sourceTree = ""; }; 403F448322F1EC92008147FC /* KarhooTripFeedbackViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooTripFeedbackViewController.swift; sourceTree = ""; }; 404E9C4A23C8BB2B00289F43 /* LineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineView.swift; sourceTree = ""; }; @@ -842,14 +839,13 @@ 40C1CD7123C9EC7900EDEA84 /* TripStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TripStatusView.swift; sourceTree = ""; }; 40C7DC5A23D0A13500975AD3 /* MetaDataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetaDataView.swift; sourceTree = ""; }; 40D741AC22C676C20003B09B /* KarhooPaymentPresenterSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooPaymentPresenterSpec.swift; sourceTree = ""; }; - 40E54AC32460DF9D00D13E10 /* KarhooAddCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooAddCardView.swift; sourceTree = ""; }; + 40E54AC32460DF9D00D13E10 /* KarhooAddPaymentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooAddPaymentView.swift; sourceTree = ""; }; 40E6693423D5B99E00DE63BA /* RideDetailsViewContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RideDetailsViewContainer.swift; sourceTree = ""; }; 40FE0CE922D7D28B003F65B5 /* RateButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RateButton.swift; sourceTree = ""; }; 40FE0CEC22D7D2D4003F65B5 /* RateButtonViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RateButtonViewModel.swift; sourceTree = ""; }; 40FE0CEF22D7D31A003F65B5 /* KarhooRatingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooRatingView.swift; sourceTree = ""; }; 40FE0CF122D7D333003F65B5 /* KarhooRatingPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooRatingPresenter.swift; sourceTree = ""; }; - 424F848C513A1D30E2DC8308 /* Pods-KarhooUISDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDK.release.xcconfig"; path = "Target Support Files/Pods-KarhooUISDK/Pods-KarhooUISDK.release.xcconfig"; sourceTree = ""; }; - 5A6218A52CFEDECA5CD3884E /* Pods-Client.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Client.release.xcconfig"; path = "Target Support Files/Pods-Client/Pods-Client.release.xcconfig"; sourceTree = ""; }; + 4AEFE9B70C37266D3CDE762F /* Pods-KarhooUISDKTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDKTests.release.xcconfig"; path = "Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests.release.xcconfig"; sourceTree = ""; }; 5C089DF72507A2E100B3D4CA /* AdyenCardRegistrationFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdyenCardRegistrationFlow.swift; sourceTree = ""; }; 5C1B298625247E4E00E3CEEF /* AdyenPaymentNonceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdyenPaymentNonceProvider.swift; sourceTree = ""; }; 5C1CD0A1241A5D88004AFF7D /* TripOptionsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TripOptionsViewModel.swift; sourceTree = ""; }; @@ -871,7 +867,7 @@ 5C2E26182420F8AD00B1FF0C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 5C2E261B2420F8AD00B1FF0C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 5C2E261D2420F8AD00B1FF0C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5C3C66B624468B7800C736E9 /* KarhooPaymentMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooPaymentMVP.swift; sourceTree = ""; }; + 5C3C66B624468B7800C736E9 /* KarhooAddPaymentMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooAddPaymentMVP.swift; sourceTree = ""; }; 5C3C671024603B5700C736E9 /* MockURLOpener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockURLOpener.swift; sourceTree = ""; }; 5C4252582518D06000CCCB5D /* CardRegistrationFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardRegistrationFlow.swift; sourceTree = ""; }; 5C4397CF22615F37006BC6C4 /* MockRidesScreenBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRidesScreenBuilder.swift; sourceTree = ""; }; @@ -886,41 +882,70 @@ 5C8316C0246B6D0700BAA926 /* SharedPassengerDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedPassengerDetails.swift; sourceTree = ""; }; 5C9D9917242CEBC3004F1DBD /* MockAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockAnalytics.swift; sourceTree = ""; }; 5C9D9919242CED15004F1DBD /* MockAddressService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockAddressService.swift; sourceTree = ""; }; - 5CBA2A6024F5D8CC0091D783 /* BookingRequestMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookingRequestMVP.swift; sourceTree = ""; }; - 5CBA2A6224F5D8CC0091D783 /* FormBookingRequestViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormBookingRequestViewController.swift; sourceTree = ""; }; - 5CBA2A6324F5D8CC0091D783 /* FormBookingRequestPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormBookingRequestPresenter.swift; sourceTree = ""; }; - 5CBA2A6424F5D8CC0091D783 /* FormCheckoutHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormCheckoutHeaderView.swift; sourceTree = ""; }; + 5CBA2A6024F5D8CC0091D783 /* KarhooCheckoutMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooCheckoutMVP.swift; sourceTree = ""; }; + 5CBA2A6224F5D8CC0091D783 /* KarhooCheckoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooCheckoutViewController.swift; sourceTree = ""; }; + 5CBA2A6324F5D8CC0091D783 /* KarhooCheckoutPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooCheckoutPresenter.swift; sourceTree = ""; }; + 5CBA2A6424F5D8CC0091D783 /* KarhooCheckoutHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooCheckoutHeaderView.swift; sourceTree = ""; }; 5CBA2A6624F5D8CC0091D783 /* PassengerDetailsMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PassengerDetailsMVP.swift; sourceTree = ""; }; - 5CBA2A6724F5D8CC0091D783 /* PassengerDetailsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PassengerDetailsView.swift; sourceTree = ""; }; - 5CBA2A6A24F5D8CC0091D783 /* BookingButtonMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookingButtonMVP.swift; sourceTree = ""; }; + 5CBA2A6A24F5D8CC0091D783 /* KarhooBookingButtonMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooBookingButtonMVP.swift; sourceTree = ""; }; 5CBA2A6B24F5D8CC0091D783 /* KarhooBookingButtonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooBookingButtonView.swift; sourceTree = ""; }; - 5CBA2A6C24F5D8CC0091D783 /* KarhooBookingRequestPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooBookingRequestPresenter.swift; sourceTree = ""; }; - 5CBA2A6E24F5D8CC0091D783 /* SupplierView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SupplierView.swift; sourceTree = ""; }; - 5CBA2A6F24F5D8CC0091D783 /* KarhooBookingRequestViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooBookingRequestViewController.swift; sourceTree = ""; }; 5CBA2A7124F5D8CC0091D783 /* KarhooTimePriceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooTimePriceView.swift; sourceTree = ""; }; - 5CBA2A7224F5D8CC0091D783 /* TimePriceMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePriceMVP.swift; sourceTree = ""; }; + 5CBA2A7224F5D8CC0091D783 /* KarhooTimePriceMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooTimePriceMVP.swift; sourceTree = ""; }; 5CBA2A7324F5D8CC0091D783 /* KarhooTimePriceView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KarhooTimePriceView.xib; sourceTree = ""; }; - 5CC253702441FD4000603D84 /* PaymentMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethod.swift; sourceTree = ""; }; 5CD9CFA922DCAB580086E7A0 /* RatingViewMVP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingViewMVP.swift; sourceTree = ""; }; 5CDACF2D23CCAC8700FD4F56 /* KarhooMKMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooMKMapView.swift; sourceTree = ""; }; 5CDACF2F23CCB8DC00FD4F56 /* MapAnnotationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapAnnotationViewModel.swift; sourceTree = ""; }; 5CED9267227F1CFB00E0C960 /* ScreenBuilders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBuilders.swift; sourceTree = ""; }; + 6B2633D226FCD0930027BCF5 /* CountryFlags.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CountryFlags.xcassets; sourceTree = ""; }; + 6B4C15A82731881A00C10EAE /* QuoteCategory+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "QuoteCategory+Extensions.swift"; sourceTree = ""; }; + 6B5B035226D7B8010001B2DB /* KarhooAddPassengerDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooAddPassengerDetailsView.swift; sourceTree = ""; }; + 6B5B035426D7B81F0001B2DB /* KarhooAddPassengerDetailsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooAddPassengerDetailsPresenter.swift; sourceTree = ""; }; + 6B5B035626D7B83F0001B2DB /* KarhooAddPassengerDetailsMVP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooAddPassengerDetailsMVP.swift; sourceTree = ""; }; + 6B5B035826D7C2D90001B2DB /* KarhooCheckoutViewController+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KarhooCheckoutViewController+Extensions.swift"; sourceTree = ""; }; + 6B5D607C26E8E45900163EFE /* MockPassengerDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPassengerDetailsViewController.swift; sourceTree = ""; }; + 6B5D607E26E8E60C00163EFE /* PassengerDetailsPresenterSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassengerDetailsPresenterSpec.swift; sourceTree = ""; }; + 6B5E25F226D672090017BFB3 /* PassengerDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassengerDetailsViewController.swift; sourceTree = ""; }; + 6B5E25F426D67DCA0017BFB3 /* PassengerDetailsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassengerDetailsPresenter.swift; sourceTree = ""; }; + 6B7BE3F2271968A600682AA1 /* PassengerDetails+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PassengerDetails+Extensions.swift"; sourceTree = ""; }; + 6BA3544E27304E400003B888 /* QuoteVehicle+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "QuoteVehicle+Extensions.swift"; sourceTree = ""; }; + 6BE3695126EB34D000F0FE86 /* CountryCodeSelectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountryCodeSelectionViewController.swift; sourceTree = ""; }; + 6BE3695326EB34E000F0FE86 /* CountryCodeSelectionPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountryCodeSelectionPresenter.swift; sourceTree = ""; }; + 6BE3695526EB352700F0FE86 /* CountryCodeSelectionMVP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountryCodeSelectionMVP.swift; sourceTree = ""; }; + 6BE36B5626EBB1F300F0FE86 /* CountryCodeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountryCodeTableViewCell.swift; sourceTree = ""; }; + 6BE36B5826EBB24400F0FE86 /* CountryCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountryCodeView.swift; sourceTree = ""; }; + 6BE36B5A26EBB37E00F0FE86 /* CountryCodeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountryCodeViewModel.swift; sourceTree = ""; }; + 6BE36B5C26EF8A3400F0FE86 /* Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = ""; }; + 6BE36B5E26EF8DFD00F0FE86 /* KarhooCountryParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooCountryParser.swift; sourceTree = ""; }; + 6BE36B6026EF8E3B00F0FE86 /* KarhooFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooFileManager.swift; sourceTree = ""; }; 6F4235BE2391800C00233C02 /* AddressGoogleLogoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressGoogleLogoView.swift; sourceTree = ""; }; 6F89EA0C248E5CA300F47C1B /* KarhooAddressDisplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooAddressDisplayView.swift; sourceTree = ""; }; + 74CD3B9E97F3F71C70E70B9A /* Pods_KarhooUISDKTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KarhooUISDKTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 791A9CDD26C4EC2A00B52DA1 /* KarhooAddPassengerDetailsAndPaymentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooAddPassengerDetailsAndPaymentView.swift; sourceTree = ""; }; + 79793ED7270F2E2200944896 /* UIViewController+extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+extensions.swift"; sourceTree = ""; }; 799DC591268F66EC00A48589 /* MapAnnotationViewModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapAnnotationViewModelSpec.swift; sourceTree = ""; }; + 79ACDCE326CCB3A9008820B5 /* KarhooLearnMoreButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooLearnMoreButton.swift; sourceTree = ""; }; + 79ACDCE526CCB5FB008820B5 /* KarhooFleetCapabilitiesDetailsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooFleetCapabilitiesDetailsView.swift; sourceTree = ""; }; + 79ACDCE726CCBAA9008820B5 /* KarhooRideInfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooRideInfoView.swift; sourceTree = ""; }; + 79ACDCEC26CFC3E7008820B5 /* KarhooFareInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooFareInfoView.swift; sourceTree = ""; }; + 7EBD72D5A33685C761A23874 /* Pods-KarhooUISDKTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDKTests.debug.xcconfig"; path = "Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests.debug.xcconfig"; sourceTree = ""; }; 986573E003E549DB4C06EA7A /* RidesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RidesViewController.xib; sourceTree = ""; }; - 9BA7A827B91FEFCA386D1C4A /* Pods-KarhooUISDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDK.debug.xcconfig"; path = "Target Support Files/Pods-KarhooUISDK/Pods-KarhooUISDK.debug.xcconfig"; sourceTree = ""; }; - 9FF975DAE636DFA8CA47C6F2 /* Pods_Client.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Client.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A1A0312526171A4E00B01E1F /* KarhooQuoteListPresenterSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KarhooQuoteListPresenterSpec.swift; sourceTree = ""; }; - A9F928AAF8C70E5FFDE416BC /* Pods_KarhooUISDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KarhooUISDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - AA979AB3B77F9708C97C2E84 /* Pods_KarhooUISDKTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KarhooUISDKTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AC8D4F24E607275C42382EA5 /* Pods_Client.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Client.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + ACEF9B513CE84FCE3A9D112B /* Pods-KarhooUISDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDK.debug.xcconfig"; path = "Target Support Files/Pods-KarhooUISDK/Pods-KarhooUISDK.debug.xcconfig"; sourceTree = ""; }; AE4AC8A325F12C28000F9E57 /* AdyenThreeDSecureUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdyenThreeDSecureUtils.swift; sourceTree = ""; }; - D58D9119291DD6B42DC25E25 /* Pods-Client.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Client.debug.xcconfig"; path = "Target Support Files/Pods-Client/Pods-Client.debug.xcconfig"; sourceTree = ""; }; + AE6E39E5271DADE500EE92C9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + AE6E39E6271DADE500EE92C9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = de; path = de.lproj/Localizable.stringsdict; sourceTree = ""; }; + AE6E39E7271DAE0E00EE92C9 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + AE6E39E8271DAE0E00EE92C9 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = it; path = it.lproj/Localizable.stringsdict; sourceTree = ""; }; + AE6E39E9271DAE2100EE92C9 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + AE6E39EA271DAE2100EE92C9 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = nl; path = nl.lproj/Localizable.stringsdict; sourceTree = ""; }; D8263F4D262096C30042F259 /* TimeFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeFormatter.swift; sourceTree = ""; }; D88BC2852620C51C00F1EA60 /* TimeFormatterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeFormatterSpec.swift; sourceTree = ""; }; D8D8ED2C261F1FDA0061066D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; D8D8ED31261F1FE00061066D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fr; path = fr.lproj/Localizable.stringsdict; sourceTree = ""; }; D8D8ED32261F1FE10061066D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = es; path = es.lproj/Localizable.stringsdict; sourceTree = ""; }; + E0FC889910C10F74B4D3774E /* Pods_KarhooUISDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KarhooUISDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E15EBC42388B5BC1A3C392A8 /* Pods-KarhooUISDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KarhooUISDK.release.xcconfig"; path = "Target Support Files/Pods-KarhooUISDK/Pods-KarhooUISDK.release.xcconfig"; sourceTree = ""; }; FC046594221484E2004E76FE /* RideDetailsScreenBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RideDetailsScreenBuilder.swift; sourceTree = ""; }; FC04659722148912004E76FE /* PopupDialogPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopupDialogPresenterSpec.swift; sourceTree = ""; }; FC04659E2215A6AD004E76FE /* Navigation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Navigation.swift; sourceTree = ""; }; @@ -930,8 +955,8 @@ FC13583E21D64E18005054AE /* BookingDetailsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookingDetailsSpec.swift; sourceTree = ""; }; FC13584121D64E8C005054AE /* ResizingSwitcherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResizingSwitcherTests.swift; sourceTree = ""; }; FC13584221D64E8C005054AE /* DefaultConstraintSwitcherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultConstraintSwitcherTests.swift; sourceTree = ""; }; - FC13584621D64F66005054AE /* KarhooBookingRequestPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooBookingRequestPresenterSpec.swift; sourceTree = ""; }; - FC13584A21D6752F005054AE /* MockBookingRequestView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockBookingRequestView.swift; sourceTree = ""; }; + FC13584621D64F66005054AE /* KarhooCheckoutPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooCheckoutPresenterSpec.swift; sourceTree = ""; }; + FC13584A21D6752F005054AE /* MockCheckoutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockCheckoutView.swift; sourceTree = ""; }; FC13585121D67971005054AE /* MockTripService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockTripService.swift; sourceTree = ""; }; FC435EE52211B33B00FB6BB5 /* KarhooRidesPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooRidesPresenter.swift; sourceTree = ""; }; FC435EE72211B33B00FB6BB5 /* RidesMVP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RidesMVP.swift; sourceTree = ""; }; @@ -986,9 +1011,8 @@ FC435F8D2211E3FA00FB6BB5 /* MockTimeScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockTimeScheduler.swift; sourceTree = ""; }; FC4B92EC222E982400FE33B4 /* MockRideDetailsScreenBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRideDetailsScreenBuilder.swift; sourceTree = ""; }; FC658F422216D0BB006C48F2 /* MockDatePickerScreenBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockDatePickerScreenBuilder.swift; sourceTree = ""; }; - FC658F432216D0BB006C48F2 /* MockFlightDetailsScreenBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockFlightDetailsScreenBuilder.swift; sourceTree = ""; }; FC658F452216D0BB006C48F2 /* MockPrebookConfirmationScreenBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockPrebookConfirmationScreenBuilder.swift; sourceTree = ""; }; - FC658F462216D0BB006C48F2 /* MockBookingRequestScreenBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockBookingRequestScreenBuilder.swift; sourceTree = ""; }; + FC658F462216D0BB006C48F2 /* MockCheckoutScreenBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockCheckoutScreenBuilder.swift; sourceTree = ""; }; FC658F472216D0BB006C48F2 /* MockAddressScreenBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockAddressScreenBuilder.swift; sourceTree = ""; }; FC658F532216D307006C48F2 /* KarhooCardRegistrationFlowSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KarhooCardRegistrationFlowSpec.swift; sourceTree = ""; }; FC658F562216D4FC006C48F2 /* MockNavigationItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockNavigationItem.swift; sourceTree = ""; }; @@ -1077,7 +1101,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2A9BC10FB50E39DBB73C43FF /* Pods_Client.framework in Frameworks */, + 7311338799B6FA2263683FE5 /* Pods_Client.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1085,7 +1109,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 11835BEF4BCC4A95D6F37450 /* Pods_KarhooUISDK.framework in Frameworks */, + D0FC00230C27E6227EBAC4AD /* Pods_KarhooUISDK.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1093,7 +1117,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FC45D6D817F54C9C62E8B7A0 /* Pods_KarhooUISDKTests.framework in Frameworks */, + A2F57788B9E24B8BCDB8AC3E /* Pods_KarhooUISDKTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1246,18 +1270,18 @@ 0949545121FF6FBB00D930C0 /* Common */ = { isa = PBXGroup; children = ( + 14A5B99B25C1BB3500986616 /* MockAddressBarView.swift */, 5C9D9917242CEBC3004F1DBD /* MockAnalytics.swift */, - 5C3C671024603B5700C736E9 /* MockURLOpener.swift */, - 5C20976F244475660097BA3A /* MockKarhooPaymentView.swift */, - 09B30F682253986B007768CF /* mockImage.png */, - FC435F6F2211D7AF00FB6BB5 /* MockStackButtonView.swift */, - 09022B232239133700C4A7EE /* MockViewController.swift */, 09F12DC622313E300024D6E9 /* MockBaseViewController.swift */, - 0949545D2201C3E900D930C0 /* MockUserLocationProvider.swift */, + 0949545B2201C2BA00D930C0 /* MockDataFormatterType.swift */, + 09B30F682253986B007768CF /* mockImage.png */, 0949545421FF7CDB00D930C0 /* MockKarhooMapView.swift */, + 5C20976F244475660097BA3A /* MockKarhooPaymentView.swift */, 094954562201C13E00D930C0 /* MockPhoneNumberCaller.swift */, - 0949545B2201C2BA00D930C0 /* MockDataFormatterType.swift */, - 14A5B99B25C1BB3500986616 /* MockAddressBarView.swift */, + FC435F6F2211D7AF00FB6BB5 /* MockStackButtonView.swift */, + 5C3C671024603B5700C736E9 /* MockURLOpener.swift */, + 0949545D2201C3E900D930C0 /* MockUserLocationProvider.swift */, + 09022B232239133700C4A7EE /* MockViewController.swift */, ); path = Common; sourceTree = ""; @@ -1344,16 +1368,15 @@ 0968F0E321BE7FF100745370 /* Screen */ = { isa = PBXGroup; children = ( - 0968D82622F8648200047FCF /* TripFeedback */, + 0968F0E421BE7FF100745370 /* Address */, + 09E35D4721E5117C003E840C /* BookingScreen */, + 090F08DB21C934EB000C7E50 /* DatePickerScreen */, 093D2E6C2224345700D5F031 /* PopupDialog */, + FCAD1C0C220884B900C3AD1D /* PrebookConfirmation */, + FC435F522211D34400FB6BB5 /* Rides */, FC83E2E0221EED43008FE26D /* Trip */, + 0968D82622F8648200047FCF /* TripFeedback */, FC83E2EC221EEDA3008FE26D /* TripSummary */, - FC435F522211D34400FB6BB5 /* Rides */, - FCAD1C0C220884B900C3AD1D /* PrebookConfirmation */, - 09E35D4721E5117C003E840C /* BookingScreen */, - 090F08DB21C934EB000C7E50 /* DatePickerScreen */, - 09E1475321C7ED06003BB30B /* FlightDetails */, - 0968F0E421BE7FF100745370 /* Address */, FC658F7F221726C8006C48F2 /* UINavigationSpec.swift */, ); path = Screen; @@ -1397,24 +1420,24 @@ 0968F10321BE859400745370 /* Classes */ = { isa = PBXGroup; children = ( - 092F282022B25C7800AF8E0E /* MockPaymentNonceProvider.swift */, - 094B764522CE734D00326CE1 /* MockThreeDSecureProvider.swift */, - 095D7455231825C7002253C0 /* MockTripRatingCache.swift */, + 14A5B97225C1AC7C00986616 /* MockAlertHandler.swift */, + 09F86F83222D84A8008C86DE /* MockAppStateNotifier.swift */, 09F86F85222D8553008C86DE /* MockBookingDetailsObserver.swift */, + 097050A421FF0AF300E53AD2 /* MockBookingStatus.swift */, + FC435F692211D67200FB6BB5 /* MockCancelRideBehaviour.swift */, + FC435F712211D7F500FB6BB5 /* MockFeedbackMailComposter.swift */, 097800A9226F4886008772E4 /* MockLocationService.swift */, - 09F86F83222D84A8008C86DE /* MockAppStateNotifier.swift */, - 09F86F7F222D60AB008C86DE /* TestBroadcaster.swift */, - FC83E302221EF0B9008FE26D /* MockTimeFetcher.swift */, FC658F562216D4FC006C48F2 /* MockNavigationItem.swift */, + 092F282022B25C7800AF8E0E /* MockPaymentNonceProvider.swift */, + 094B764522CE734D00326CE1 /* MockThreeDSecureProvider.swift */, + FC83E302221EF0B9008FE26D /* MockTimeFetcher.swift */, FC435F8D2211E3FA00FB6BB5 /* MockTimeScheduler.swift */, - FC435F712211D7F500FB6BB5 /* MockFeedbackMailComposter.swift */, + 095D7455231825C7002253C0 /* MockTripRatingCache.swift */, FC435F6C2211D76100FB6BB5 /* MockTripsProvider.swift */, FC435F6B2211D76100FB6BB5 /* MockTripsSorter.swift */, - FC435F692211D67200FB6BB5 /* MockCancelRideBehaviour.swift */, - 097050A421FF0AF300E53AD2 /* MockBookingStatus.swift */, 09BDD18721C2C20A0074421C /* MockUserDefaults.swift */, 09AAEF9721C4283200A04EEC /* MockValidator.swift */, - 14A5B97225C1AC7C00986616 /* MockAlertHandler.swift */, + 09F86F7F222D60AB008C86DE /* TestBroadcaster.swift */, ); path = Classes; sourceTree = ""; @@ -1454,21 +1477,21 @@ 0991065C21B8291900BD7E6F /* Screens */ = { isa = PBXGroup; children = ( - 403E907722C527EE00F39B91 /* PaymentView */, - FC0465A02215A962004E76FE /* UINavigation.swift */, - 092005D5225B91C1001038ED /* SideMenu */, - FC83E24B221DB4C9008FE26D /* TripScreen */, - FC83E282221DB549008FE26D /* TripSummaryScreen */, - 09DE8D44221C658B00451B3C /* PaymentScreen */, - 5CBA2A5F24F5D8CC0091D783 /* BookingRequestScreen */, - 09C7655F21DE688000CD81AB /* BookingScreen */, 0991066021B8291900BD7E6F /* AddressScreen */, + 09C7655F21DE688000CD81AB /* BookingScreen */, + 5CBA2A5F24F5D8CC0091D783 /* CheckoutScreen */, + 6BE3695026EB34AD00F0FE86 /* CountryCodeSelectionScreen */, 094AE85521C9145D0046EC3C /* DatePickerScreen */, - 09BDD18921C2CAD00074421C /* FlightDetailsScreen */, + 5CBA2A6524F5D8CC0091D783 /* PassengerDetails */, + 09DE8D44221C658B00451B3C /* PaymentScreen */, FC705B16221322220001036E /* PopupDialog */, FCAD1BE922087B9100C3AD1D /* PrebookConfirmationScreen */, FC435EE42211B30F00FB6BB5 /* Rides */, + 092005D5225B91C1001038ED /* SideMenu */, 403F448522F1EC97008147FC /* TripFeedbackScreen */, + FC83E24B221DB4C9008FE26D /* TripScreen */, + FC83E282221DB549008FE26D /* TripSummaryScreen */, + FC0465A02215A962004E76FE /* UINavigation.swift */, ); path = Screens; sourceTree = ""; @@ -1523,6 +1546,7 @@ isa = PBXGroup; children = ( 099106BC21B82D5200BD7E6F /* Address.swift */, + 6BE36B5C26EF8A3400F0FE86 /* Country.swift */, ); path = Model; sourceTree = ""; @@ -1551,6 +1575,9 @@ 0991070521B83AF700BD7E6F /* LocationDetailsExt.swift */, 4070213B23D9E19400F82B6A /* UIView+Extensions.swift */, 4030C8F5241B980E0034A944 /* UIColor+extension.swift */, + 6B7BE3F2271968A600682AA1 /* PassengerDetails+Extensions.swift */, + 6BA3544E27304E400003B888 /* QuoteVehicle+Extensions.swift */, + 6B4C15A82731881A00C10EAE /* QuoteCategory+Extensions.swift */, ); path = KarhooSDKExtensions; sourceTree = ""; @@ -1559,21 +1586,20 @@ isa = PBXGroup; children = ( 0991071121B8486300BD7E6F /* AddressScreenBuilder.swift */, - 09D8B29322F3491F00569C55 /* TripFeedbackScreenBuilder.swift */, - 0946CB5C21CBDF0400DBDD42 /* BookingRequestScreenBuilder.swift */, 09C7649221DE665000CD81AB /* BookingScreenBuilder.swift */, + 0946CB5C21CBDF0400DBDD42 /* CheckoutScreenBuilder.swift */, 094AE85321C913020046EC3C /* DatePickerScreenBuilder.swift */, - 09E0249A21C2D7D40071E367 /* FlightDetailsScreenBuilder.swift */, - FC83E283221DB6B8008FE26D /* TripScreenBuilder.swift */, - FC83E287221DBA1B008FE26D /* TripSummaryScreenBuilder.swift */, FC997268221C0C8900D476E1 /* PaymentScreenBuilder.swift */, FC705B14221321650001036E /* PopupDialogScreenBuilder.swift */, FCAD1C0A2208816000C3AD1D /* PrebookConfirmationScreenBuilder.swift */, FC046594221484E2004E76FE /* RideDetailsScreenBuilder.swift */, FC705B0E22130B990001036E /* RidesListScreenBuilder.swift */, FC705B0C2212DE6E0001036E /* RidesScreenBuilder.swift */, - 092005E1225B9216001038ED /* SideMenuBuilder.swift */, 0991071021B8486300BD7E6F /* Screen.swift */, + 092005E1225B9216001038ED /* SideMenuBuilder.swift */, + 09D8B29322F3491F00569C55 /* TripFeedbackScreenBuilder.swift */, + FC83E283221DB6B8008FE26D /* TripScreenBuilder.swift */, + FC83E287221DBA1B008FE26D /* TripSummaryScreenBuilder.swift */, ); path = Builders; sourceTree = ""; @@ -1582,47 +1608,11 @@ isa = PBXGroup; children = ( 0991530021BFDB6400B46D9F /* Assets.xcassets */, + 6B2633D226FCD0930027BCF5 /* CountryFlags.xcassets */, ); path = Assets; sourceTree = ""; }; - 09BDD18921C2CAD00074421C /* FlightDetailsScreen */ = { - isa = PBXGroup; - children = ( - 09BDD18A21C2CAD00074421C /* FlightDetailsMVP.swift */, - 09E0249E21C2D9FD0071E367 /* Domain */, - 09BDD18B21C2CAD00074421C /* Presenter */, - 09BDD18D21C2CAD00074421C /* View */, - ); - path = FlightDetailsScreen; - sourceTree = ""; - }; - 09BDD18B21C2CAD00074421C /* Presenter */ = { - isa = PBXGroup; - children = ( - 09BDD18C21C2CAD00074421C /* KarhooFlightDetailsPresenter.swift */, - ); - path = Presenter; - sourceTree = ""; - }; - 09BDD18D21C2CAD00074421C /* View */ = { - isa = PBXGroup; - children = ( - 09BDD18E21C2CAD00074421C /* FlightDetailsViewController.xib */, - 09BDD18F21C2CAD00074421C /* FlightDetailsViewController.swift */, - ); - path = View; - sourceTree = ""; - }; - 09BDD19621C2CBCF0074421C /* FlightDetails */ = { - isa = PBXGroup; - children = ( - 09BDD19721C2CBCF0074421C /* FlightDetailsPresenterSpec.swift */, - 09AAEF9521C4270800A04EEC /* FlightNumberValidatorSpec.swift */, - ); - path = FlightDetails; - sourceTree = ""; - }; 09C7655F21DE688000CD81AB /* BookingScreen */ = { isa = PBXGroup; children = ( @@ -1776,18 +1766,18 @@ 09DCC7ED21BE7CE000DF02B9 /* Screens */ = { isa = PBXGroup; children = ( - 0968D82322F82F7C00047FCF /* TripFeedbackScreen */, - FC83E2E1221EED4F008FE26D /* TripSummaryScreen */, - FC83E2B5221EEBE2008FE26D /* TripScreen */, - FC435F452211D30700FB6BB5 /* Rides */, + 09DCC7EE21BE7CE000DF02B9 /* AddressScreen */, 09E35D5F21E5118A003E840C /* BookingScreen */, - FC13584521D64F2D005054AE /* BookingRequestScreen */, + FC13584521D64F2D005054AE /* CheckoutScreen */, 090F08E221C93591000C7E50 /* DatePickerScreen */, - 09BDD19621C2CBCF0074421C /* FlightDetails */, - 09DCC7EE21BE7CE000DF02B9 /* AddressScreen */, + 4038DF452446179D0014539B /* GuestCheckoutScreen */, + 6B5D607B26E8E43400163EFE /* PassengerDetails */, FC046596221488D8004E76FE /* PopupDialogScreen */, FCAD1BFE22087C4700C3AD1D /* PrebookConfirmationScreen */, - 4038DF452446179D0014539B /* GuestBookingRequestScreen */, + FC435F452211D30700FB6BB5 /* Rides */, + 0968D82322F82F7C00047FCF /* TripFeedbackScreen */, + FC83E2B5221EEBE2008FE26D /* TripScreen */, + FC83E2E1221EED4F008FE26D /* TripSummaryScreen */, ); path = Screens; sourceTree = ""; @@ -1824,28 +1814,10 @@ isa = PBXGroup; children = ( 09DE8D45221C658B00451B3C /* BraintreePaymentScreensBuilder.swift */, - 5CC253702441FD4000603D84 /* PaymentMethod.swift */, ); path = PaymentScreen; sourceTree = ""; }; - 09E0249E21C2D9FD0071E367 /* Domain */ = { - isa = PBXGroup; - children = ( - 09BDD19021C2CAD00074421C /* FlightDetails.swift */, - 09E0249F21C2D9FD0071E367 /* FlightNumberValidator.swift */, - ); - path = Domain; - sourceTree = ""; - }; - 09E1475321C7ED06003BB30B /* FlightDetails */ = { - isa = PBXGroup; - children = ( - 09E1475421C7ED06003BB30B /* MockFlightDetailsView.swift */, - ); - path = FlightDetails; - sourceTree = ""; - }; 09E35D4721E5117C003E840C /* BookingScreen */ = { isa = PBXGroup; children = ( @@ -1998,7 +1970,7 @@ isa = PBXGroup; children = ( 4010B0D92458847500E7B0F1 /* KarhooTextInputView.swift */, - 4038DF402445D5180014539B /* KarhooPhoneInputView */, + 4038DF3C2444C6E00014539B /* KarhooPhoneInputView.swift */, 4038DF3E2444D6810014539B /* KarhooInputView.swift */, 4010B0DB245C5DD900E7B0F1 /* KarhooInputViewState.swift */, 4010B0DF245C5E1F00E7B0F1 /* KarhooTextInputViewErrorFeedbackType.swift */, @@ -2007,32 +1979,22 @@ path = KarhooTextInputView; sourceTree = ""; }; - 4038DF402445D5180014539B /* KarhooPhoneInputView */ = { - isa = PBXGroup; - children = ( - 4038DF3C2444C6E00014539B /* KarhooPhoneInputView.swift */, - 4038DF412445D5340014539B /* KarhooPhoneInputViewDataSource.swift */, - ); - path = KarhooPhoneInputView; - sourceTree = ""; - }; - 4038DF452446179D0014539B /* GuestBookingRequestScreen */ = { + 4038DF452446179D0014539B /* GuestCheckoutScreen */ = { isa = PBXGroup; children = ( - 4038DF43244617960014539B /* KarhooGuestBookingRequestPresenterSpec.swift */, + 4038DF43244617960014539B /* KarhooGuestCheckoutPresenterSpec.swift */, ); - path = GuestBookingRequestScreen; + path = GuestCheckoutScreen; sourceTree = ""; }; - 403E907722C527EE00F39B91 /* PaymentView */ = { + 403E907722C527EE00F39B91 /* AddPaymentView */ = { isa = PBXGroup; children = ( - 5C3C66B624468B7800C736E9 /* KarhooPaymentMVP.swift */, - 403E907822C5287F00F39B91 /* KarhooPaymentView.swift */, - 40E54AC32460DF9D00D13E10 /* KarhooAddCardView.swift */, - 400BE99122CF4D27002942CC /* KarhooPaymentPresenter.swift */, + 5C3C66B624468B7800C736E9 /* KarhooAddPaymentMVP.swift */, + 40E54AC32460DF9D00D13E10 /* KarhooAddPaymentView.swift */, + 400BE99122CF4D27002942CC /* KarhooAddPaymentPresenter.swift */, ); - path = PaymentView; + path = AddPaymentView; sourceTree = ""; }; 403F448522F1EC97008147FC /* TripFeedbackScreen */ = { @@ -2427,74 +2389,66 @@ path = Error; sourceTree = ""; }; - 5CBA2A5F24F5D8CC0091D783 /* BookingRequestScreen */ = { + 5CBA2A5F24F5D8CC0091D783 /* CheckoutScreen */ = { isa = PBXGroup; children = ( - 5CBA2A6024F5D8CC0091D783 /* BookingRequestMVP.swift */, - 5CBA2A6124F5D8CC0091D783 /* FormBookingRequestScreen */, - 5CBA2A6824F5D8CC0091D783 /* BookingRequest */, + 5CBA2A6124F5D8CC0091D783 /* Checkout */, + 5CBA2A6824F5D8CC0091D783 /* Components */, ); - name = BookingRequestScreen; - path = KarhooUISDK/Screens/BookingRequestScreen; + name = CheckoutScreen; + path = KarhooUISDK/Screens/CheckoutScreen; sourceTree = SOURCE_ROOT; }; - 5CBA2A6124F5D8CC0091D783 /* FormBookingRequestScreen */ = { + 5CBA2A6124F5D8CC0091D783 /* Checkout */ = { isa = PBXGroup; children = ( - 5CBA2A6224F5D8CC0091D783 /* FormBookingRequestViewController.swift */, - 5CBA2A6324F5D8CC0091D783 /* FormBookingRequestPresenter.swift */, - 5CBA2A6424F5D8CC0091D783 /* FormCheckoutHeaderView.swift */, - 5CBA2A6524F5D8CC0091D783 /* PassengerDetails */, + 5CBA2A6024F5D8CC0091D783 /* KarhooCheckoutMVP.swift */, + 5CBA2A6224F5D8CC0091D783 /* KarhooCheckoutViewController.swift */, + 6B5B035826D7C2D90001B2DB /* KarhooCheckoutViewController+Extensions.swift */, + 5CBA2A6324F5D8CC0091D783 /* KarhooCheckoutPresenter.swift */, ); - path = FormBookingRequestScreen; + path = Checkout; sourceTree = ""; }; 5CBA2A6524F5D8CC0091D783 /* PassengerDetails */ = { isa = PBXGroup; children = ( 5CBA2A6624F5D8CC0091D783 /* PassengerDetailsMVP.swift */, - 5CBA2A6724F5D8CC0091D783 /* PassengerDetailsView.swift */, + 6B5E25F226D672090017BFB3 /* PassengerDetailsViewController.swift */, + 6B5E25F426D67DCA0017BFB3 /* PassengerDetailsPresenter.swift */, ); path = PassengerDetails; sourceTree = ""; }; - 5CBA2A6824F5D8CC0091D783 /* BookingRequest */ = { + 5CBA2A6824F5D8CC0091D783 /* Components */ = { isa = PBXGroup; children = ( - 5CBA2A6C24F5D8CC0091D783 /* KarhooBookingRequestPresenter.swift */, - 5CBA2A6F24F5D8CC0091D783 /* KarhooBookingRequestViewController.swift */, - 5CBA2A6924F5D8CC0091D783 /* BookingButtonMVP */, - 5CBA2A6D24F5D8CC0091D783 /* SupplierView */, - 5CBA2A7024F5D8CC0091D783 /* TimePriceMVP */, + 6B5B035126D7B7DC0001B2DB /* AddPassengerDetailsView */, + 403E907722C527EE00F39B91 /* AddPaymentView */, + 79ACDCE926CD2F45008820B5 /* CheckoutViews */, + 5CBA2A6924F5D8CC0091D783 /* BookingButton */, + 5CBA2A7024F5D8CC0091D783 /* TimePrice */, ); - path = BookingRequest; + path = Components; sourceTree = ""; }; - 5CBA2A6924F5D8CC0091D783 /* BookingButtonMVP */ = { + 5CBA2A6924F5D8CC0091D783 /* BookingButton */ = { isa = PBXGroup; children = ( - 5CBA2A6A24F5D8CC0091D783 /* BookingButtonMVP.swift */, + 5CBA2A6A24F5D8CC0091D783 /* KarhooBookingButtonMVP.swift */, 5CBA2A6B24F5D8CC0091D783 /* KarhooBookingButtonView.swift */, ); - path = BookingButtonMVP; - sourceTree = ""; - }; - 5CBA2A6D24F5D8CC0091D783 /* SupplierView */ = { - isa = PBXGroup; - children = ( - 5CBA2A6E24F5D8CC0091D783 /* SupplierView.swift */, - ); - path = SupplierView; + path = BookingButton; sourceTree = ""; }; - 5CBA2A7024F5D8CC0091D783 /* TimePriceMVP */ = { + 5CBA2A7024F5D8CC0091D783 /* TimePrice */ = { isa = PBXGroup; children = ( 5CBA2A7124F5D8CC0091D783 /* KarhooTimePriceView.swift */, - 5CBA2A7224F5D8CC0091D783 /* TimePriceMVP.swift */, + 5CBA2A7224F5D8CC0091D783 /* KarhooTimePriceMVP.swift */, 5CBA2A7324F5D8CC0091D783 /* KarhooTimePriceView.xib */, ); - path = TimePriceMVP; + path = TimePrice; sourceTree = ""; }; 5CDACF3123CCB8E300FD4F56 /* AppleMapKit */ = { @@ -2506,15 +2460,68 @@ path = AppleMapKit; sourceTree = ""; }; + 6B5B035126D7B7DC0001B2DB /* AddPassengerDetailsView */ = { + isa = PBXGroup; + children = ( + 6B5B035226D7B8010001B2DB /* KarhooAddPassengerDetailsView.swift */, + 6B5B035426D7B81F0001B2DB /* KarhooAddPassengerDetailsPresenter.swift */, + 6B5B035626D7B83F0001B2DB /* KarhooAddPassengerDetailsMVP.swift */, + ); + path = AddPassengerDetailsView; + sourceTree = ""; + }; + 6B5D607B26E8E43400163EFE /* PassengerDetails */ = { + isa = PBXGroup; + children = ( + 6B5D607C26E8E45900163EFE /* MockPassengerDetailsViewController.swift */, + 6B5D607E26E8E60C00163EFE /* PassengerDetailsPresenterSpec.swift */, + ); + path = PassengerDetails; + sourceTree = ""; + }; + 6BE3695026EB34AD00F0FE86 /* CountryCodeSelectionScreen */ = { + isa = PBXGroup; + children = ( + 6BE36B6226F07F4700F0FE86 /* CountryCell */, + 6BE3695126EB34D000F0FE86 /* CountryCodeSelectionViewController.swift */, + 6BE3695326EB34E000F0FE86 /* CountryCodeSelectionPresenter.swift */, + 6BE3695526EB352700F0FE86 /* CountryCodeSelectionMVP.swift */, + ); + path = CountryCodeSelectionScreen; + sourceTree = ""; + }; + 6BE36B6226F07F4700F0FE86 /* CountryCell */ = { + isa = PBXGroup; + children = ( + 6BE36B5626EBB1F300F0FE86 /* CountryCodeTableViewCell.swift */, + 6BE36B5826EBB24400F0FE86 /* CountryCodeView.swift */, + 6BE36B5A26EBB37E00F0FE86 /* CountryCodeViewModel.swift */, + ); + path = CountryCell; + sourceTree = ""; + }; + 79ACDCE926CD2F45008820B5 /* CheckoutViews */ = { + isa = PBXGroup; + children = ( + 5CBA2A6424F5D8CC0091D783 /* KarhooCheckoutHeaderView.swift */, + 791A9CDD26C4EC2A00B52DA1 /* KarhooAddPassengerDetailsAndPaymentView.swift */, + 79ACDCE326CCB3A9008820B5 /* KarhooLearnMoreButton.swift */, + 79ACDCE726CCBAA9008820B5 /* KarhooRideInfoView.swift */, + 79ACDCEC26CFC3E7008820B5 /* KarhooFareInfoView.swift */, + 79ACDCE526CCB5FB008820B5 /* KarhooFleetCapabilitiesDetailsView.swift */, + ); + path = CheckoutViews; + sourceTree = ""; + }; 79C4CC0320274ACDA240783A /* Pods */ = { isa = PBXGroup; children = ( - D58D9119291DD6B42DC25E25 /* Pods-Client.debug.xcconfig */, - 5A6218A52CFEDECA5CD3884E /* Pods-Client.release.xcconfig */, - 9BA7A827B91FEFCA386D1C4A /* Pods-KarhooUISDK.debug.xcconfig */, - 424F848C513A1D30E2DC8308 /* Pods-KarhooUISDK.release.xcconfig */, - 2372675E70509D3779F8061D /* Pods-KarhooUISDKTests.debug.xcconfig */, - 1061B90ED3BAE79634610DAC /* Pods-KarhooUISDKTests.release.xcconfig */, + 3CDC92F5EF4385593DC9E7C1 /* Pods-Client.debug.xcconfig */, + 31B3B4A018455D19516D4105 /* Pods-Client.release.xcconfig */, + ACEF9B513CE84FCE3A9D112B /* Pods-KarhooUISDK.debug.xcconfig */, + E15EBC42388B5BC1A3C392A8 /* Pods-KarhooUISDK.release.xcconfig */, + 7EBD72D5A33685C761A23874 /* Pods-KarhooUISDKTests.debug.xcconfig */, + 4AEFE9B70C37266D3CDE762F /* Pods-KarhooUISDKTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -2526,9 +2533,9 @@ 094DAF9D2400503F00035F9F /* KarhooSDK.framework */, 094DAF952400418000035F9F /* KarhooSDK.framework */, 09EBC66922D612C600F1177E /* KarhooSDK.framework */, - 9FF975DAE636DFA8CA47C6F2 /* Pods_Client.framework */, - A9F928AAF8C70E5FFDE416BC /* Pods_KarhooUISDK.framework */, - AA979AB3B77F9708C97C2E84 /* Pods_KarhooUISDKTests.framework */, + AC8D4F24E607275C42382EA5 /* Pods_Client.framework */, + E0FC889910C10F74B4D3774E /* Pods_KarhooUISDK.framework */, + 74CD3B9E97F3F71C70E70B9A /* Pods_KarhooUISDKTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -2544,23 +2551,23 @@ FC13583821D64CFB005054AE /* Common */ = { isa = PBXGroup; children = ( - 094B764322CE731200326CE1 /* TripStatesGetterSpec.swift */, - 094B763F22CE729400326CE1 /* BraintreeThreeDSecureProviderSpec.swift */, - 095D7457231827B4002253C0 /* KarhooTripRatingCacheSpec.swift */, + 09C169BF2281B7C700CF7E66 /* BaseViewControllerSpec.swift */, 094B763D22CE729300326CE1 /* BraintreePaymentNonceProviderSpec.swift */, - 09D293C422C651C10051C455 /* KarhooDateFormatterSpec.swift */, - 09D293C322C651C10051C455 /* QtaStringFormatterSpec.swift */, + 094B763F22CE729400326CE1 /* BraintreeThreeDSecureProviderSpec.swift */, 09B30F5A224CE8BF007768CF /* CancelRideBehaviourSpec.swift */, - 09C169BF2281B7C700CF7E66 /* BaseViewControllerSpec.swift */, - 09B30F5B224CE8BF007768CF /* TripsListSorterSpec.swift */, + FC13584021D64E63005054AE /* ConstraintSwitcher */, + 14A5B96A25C19BEE00986616 /* CurrencyCodeConverterSpec.swift */, FCF7E68E2226A76B00EEBF98 /* KarhooBookingStatusSpec.swift */, + 09D293C422C651C10051C455 /* KarhooDateFormatterSpec.swift */, + 095D7457231827B4002253C0 /* KarhooTripRatingCacheSpec.swift */, FC435F852211E26400FB6BB5 /* KarhooTripsProviderSpec.swift */, + 09D293C322C651C10051C455 /* QtaStringFormatterSpec.swift */, FC435F7B2211DE2A00FB6BB5 /* StackButtonViewSpec.swift */, + D88BC2852620C51C00F1EA60 /* TimeFormatterSpec.swift */, FC13583B21D64D52005054AE /* TripInfoUtilitySpec.swift */, + 09B30F5B224CE8BF007768CF /* TripsListSorterSpec.swift */, + 094B764322CE731200326CE1 /* TripStatesGetterSpec.swift */, FC435F762211DC3B00FB6BB5 /* ViewModel */, - FC13584021D64E63005054AE /* ConstraintSwitcher */, - 14A5B96A25C19BEE00986616 /* CurrencyCodeConverterSpec.swift */, - D88BC2852620C51C00F1EA60 /* TimeFormatterSpec.swift */, ); path = Common; sourceTree = ""; @@ -2582,13 +2589,13 @@ path = ConstraintSwitcher; sourceTree = ""; }; - FC13584521D64F2D005054AE /* BookingRequestScreen */ = { + FC13584521D64F2D005054AE /* CheckoutScreen */ = { isa = PBXGroup; children = ( - FC13584A21D6752F005054AE /* MockBookingRequestView.swift */, - FC13584621D64F66005054AE /* KarhooBookingRequestPresenterSpec.swift */, + FC13584A21D6752F005054AE /* MockCheckoutView.swift */, + FC13584621D64F66005054AE /* KarhooCheckoutPresenterSpec.swift */, ); - path = BookingRequestScreen; + path = CheckoutScreen; sourceTree = ""; }; FC13584C21D67823005054AE /* Service */ = { @@ -2596,10 +2603,10 @@ children = ( 5C9D9919242CED15004F1DBD /* MockAddressService.swift */, 407EC7EF22CF93DC00F24CFC /* MockAnalyticsService.swift */, - FC658F612216D9C1006C48F2 /* MockPaymentService.swift */, - FC13585121D67971005054AE /* MockTripService.swift */, FC83E300221EF042008FE26D /* MockDriverTrackingService.swift */, 408AB682234F418B00B351B2 /* MockFareService.swift */, + FC658F612216D9C1006C48F2 /* MockPaymentService.swift */, + FC13585121D67971005054AE /* MockTripService.swift */, 14A5B97A25C1AD4600986616 /* MockUserService.swift */, ); path = Service; @@ -2773,17 +2780,16 @@ isa = PBXGroup; children = ( FC658F472216D0BB006C48F2 /* MockAddressScreenBuilder.swift */, - FC658F462216D0BB006C48F2 /* MockBookingRequestScreenBuilder.swift */, + FC658F462216D0BB006C48F2 /* MockCheckoutScreenBuilder.swift */, FC658F422216D0BB006C48F2 /* MockDatePickerScreenBuilder.swift */, - FC658F432216D0BB006C48F2 /* MockFlightDetailsScreenBuilder.swift */, - 09F12DC82232ABD30024D6E9 /* MockPopupDialogScreenBuilder.swift */, 09D8B29522F444AA00569C55 /* MockFeedbackScreenBuilder.swift */, - FC658F452216D0BB006C48F2 /* MockPrebookConfirmationScreenBuilder.swift */, FC658F702216F8B7006C48F2 /* MockPaymentScreenBuilder.swift */, - FC83E30A221F1839008FE26D /* MockTripScreenBuilder.swift */, - FC83E30C221F18F3008FE26D /* MockTripSummaryScreenBuilder.swift */, + 09F12DC82232ABD30024D6E9 /* MockPopupDialogScreenBuilder.swift */, + FC658F452216D0BB006C48F2 /* MockPrebookConfirmationScreenBuilder.swift */, FC4B92EC222E982400FE33B4 /* MockRideDetailsScreenBuilder.swift */, 5C4397CF22615F37006BC6C4 /* MockRidesScreenBuilder.swift */, + FC83E30A221F1839008FE26D /* MockTripScreenBuilder.swift */, + FC83E30C221F18F3008FE26D /* MockTripSummaryScreenBuilder.swift */, ); path = Builders; sourceTree = ""; @@ -3084,6 +3090,7 @@ 099106FE21B83AF700BD7E6F /* KarhooSDKExtensions */, 0973872121DE77B3004BD5F9 /* NSAttributedString+Utils.swift */, FC8F474C2153E770007841FB /* Bundle+Utils.swift */, + 79793ED7270F2E2200944896 /* UIViewController+extensions.swift */, ); path = Extensions; sourceTree = ""; @@ -3157,6 +3164,8 @@ FC435F382211B8B400FB6BB5 /* Trips */, FC435F362211B88800FB6BB5 /* CancelRideBehaviour.swift */, FCAD1C1222088A4200C3AD1D /* Formatters */, + 6BE36B5E26EF8DFD00F0FE86 /* KarhooCountryParser.swift */, + 6BE36B6026EF8E3B00F0FE86 /* KarhooFileManager.swift */, ); path = Classes; sourceTree = ""; @@ -3187,11 +3196,11 @@ isa = PBXNativeTarget; buildConfigurationList = 5C2E261E2420F8AD00B1FF0C /* Build configuration list for PBXNativeTarget "Client" */; buildPhases = ( - 36DC943EF7B0FE910F0A9064 /* [CP] Check Pods Manifest.lock */, + E9317C2821462424F4EB2C80 /* [CP] Check Pods Manifest.lock */, 5C2E26092420F8AC00B1FF0C /* Sources */, 5C2E260A2420F8AC00B1FF0C /* Frameworks */, 5C2E260B2420F8AC00B1FF0C /* Resources */, - A00B58814AB207EE82EF9E2B /* [CP] Embed Pods Frameworks */, + 8AA42DB8D4D56B3A14AC0854 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -3206,7 +3215,7 @@ isa = PBXNativeTarget; buildConfigurationList = FC8F472821539E24007841FB /* Build configuration list for PBXNativeTarget "KarhooUISDK" */; buildPhases = ( - C51FB46235E9C063CF38FF2C /* [CP] Check Pods Manifest.lock */, + 91D35E6ED133994C36121217 /* [CP] Check Pods Manifest.lock */, FC8F470F21539E24007841FB /* Sources */, FC8F471021539E24007841FB /* Frameworks */, FC8F471121539E24007841FB /* Headers */, @@ -3226,11 +3235,11 @@ isa = PBXNativeTarget; buildConfigurationList = FC8F472B21539E24007841FB /* Build configuration list for PBXNativeTarget "KarhooUISDKTests" */; buildPhases = ( - 2A6956228AD4561359A37221 /* [CP] Check Pods Manifest.lock */, + 86ADB78CACF3A692FAA0567F /* [CP] Check Pods Manifest.lock */, FC8F471921539E24007841FB /* Sources */, FC8F471A21539E24007841FB /* Frameworks */, FC8F471B21539E24007841FB /* Resources */, - 7DB439AD72189E18EBA41011 /* [CP] Embed Pods Frameworks */, + 235EC0082CF7B4ED1A8AF231 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -3274,6 +3283,9 @@ Base, es, fr, + de, + it, + nl, ); mainGroup = FC8F470A21539E24007841FB; productRefGroup = FC8F471521539E24007841FB /* Products */; @@ -3308,10 +3320,10 @@ FC83E2AB221ECC52008FE26D /* KarhooTripSummaryInfoView.xib in Resources */, 09C765B321DE688100CD81AB /* PrebookField.xib in Resources */, 5CBA2A8124F5D8CC0091D783 /* KarhooTimePriceView.xib in Resources */, + 6B2633D326FCD0930027BCF5 /* CountryFlags.xcassets in Resources */, 0991530221BFDC3000B46D9F /* Assets.xcassets in Resources */, FCAD1BF922087BD800C3AD1D /* KarhooPrebookConfirmationViewController.xib in Resources */, FC705B1B221322550001036E /* PopupDialogViewController.xib in Resources */, - 5C7B191C2534B2120001CFE6 /* FlightDetailsViewController.xib in Resources */, 094AE85F21C9145D0046EC3C /* DatePickerViewController.xib in Resources */, FC83E2A6221ECC52008FE26D /* TripSummaryHeaderView.xib in Resources */, 092005E0225B91C1001038ED /* SideMenuViewController.xib in Resources */, @@ -3336,29 +3348,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 2A6956228AD4561359A37221 /* [CP] Check Pods Manifest.lock */ = { + 235EC0082CF7B4ED1A8AF231 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-KarhooUISDKTests-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 36DC943EF7B0FE910F0A9064 /* [CP] Check Pods Manifest.lock */ = { + 5C8316B92469FCB200BAA926 /* SwiftLint Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3366,21 +3373,17 @@ inputFileListPaths = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Check Pods Manifest.lock"; + name = "SwiftLint Script"; outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Client-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; }; - 5C8316B92469FCB200BAA926 /* SwiftLint Script */ = { + 86ADB78CACF3A692FAA0567F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3388,51 +3391,60 @@ inputFileListPaths = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "SwiftLint Script"; + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-KarhooUISDKTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 7DB439AD72189E18EBA41011 /* [CP] Embed Pods Frameworks */ = { + 8AA42DB8D4D56B3A14AC0854 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-Client/Pods-Client-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-Client/Pods-Client-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-KarhooUISDKTests/Pods-KarhooUISDKTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Client/Pods-Client-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - A00B58814AB207EE82EF9E2B /* [CP] Embed Pods Frameworks */ = { + 91D35E6ED133994C36121217 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Client/Pods-Client-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Client/Pods-Client-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-KarhooUISDK-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Client/Pods-Client-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - C51FB46235E9C063CF38FF2C /* [CP] Check Pods Manifest.lock */ = { + E9317C2821462424F4EB2C80 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3447,7 +3459,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-KarhooUISDK-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Client-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -3494,9 +3506,10 @@ 09C765B021DE688100CD81AB /* DestinationSetStrategy.swift in Sources */, 5C1CD0B9241A5D88004AFF7D /* TripInfoView.swift in Sources */, 5C6267EA252CC24500AB6CD2 /* PaymentFactory.swift in Sources */, + 79ACDCE426CCB3A9008820B5 /* KarhooLearnMoreButton.swift in Sources */, 407EC7BC22CF564E00F24CFC /* ResizingSwitcher.swift in Sources */, 407EC7B622CF564E00F24CFC /* KarhooFeedbackEmailComposer.swift in Sources */, - 5CBA2A7624F5D8CC0091D783 /* FormBookingRequestPresenter.swift in Sources */, + 5CBA2A7624F5D8CC0091D783 /* KarhooCheckoutPresenter.swift in Sources */, 09C765B721DE688100CD81AB /* KarhooBookingViewController.swift in Sources */, FC0465A12215A962004E76FE /* UINavigation.swift in Sources */, FC83E29C221ECC0D008FE26D /* KarhooOriginEtaPresenter.swift in Sources */, @@ -3504,6 +3517,7 @@ 407EC7EA22CF564E00F24CFC /* TableDataSource.swift in Sources */, 09C765A821DE688100CD81AB /* QuoteListEmptyDataSetView.swift in Sources */, FC435F062211B3B900FB6BB5 /* RideCellStackButtonPresenter.swift in Sources */, + 79ACDCE826CCBAA9008820B5 /* KarhooRideInfoView.swift in Sources */, FC83E29B221ECC0B008FE26D /* KarhooOriginEtaView.swift in Sources */, 6F4235BF2391800C00233C02 /* AddressGoogleLogoView.swift in Sources */, FC83E250221DB4F5008FE26D /* KarhooTripViewController.swift in Sources */, @@ -3515,8 +3529,6 @@ FC705B1D221322550001036E /* KarhooPopupDialogPresenter.swift in Sources */, 407EC7B222CF564E00F24CFC /* TermsConditionsView.swift in Sources */, 5C626861252DFC0A00AB6CD2 /* AdyenResponseHandler.swift in Sources */, - 5CBA2A7E24F5D8CC0091D783 /* KarhooBookingRequestViewController.swift in Sources */, - 5CC253712441FD4000603D84 /* PaymentMethod.swift in Sources */, 407EC7A722CF564E00F24CFC /* KarhooColors.swift in Sources */, 407EC79B22CF564E00F24CFC /* QtaStringFormatter.swift in Sources */, 40FE0CEA22D7D28B003F65B5 /* RateButton.swift in Sources */, @@ -3533,7 +3545,9 @@ 407EC7B022CF564E00F24CFC /* KarhooGradients.swift in Sources */, 407EC7CC22CF564E00F24CFC /* KarhooAddressBarFieldView.swift in Sources */, 407EC7EC22CF564E00F24CFC /* TableData.swift in Sources */, + 79793ED8270F2E2200944896 /* UIViewController+extensions.swift in Sources */, 407EC7BD22CF564E00F24CFC /* ConstraintSwitcher.swift in Sources */, + 79ACDCE626CCB5FB008820B5 /* KarhooFleetCapabilitiesDetailsView.swift in Sources */, 407EC79E22CF564E00F24CFC /* NotificationMVP.swift in Sources */, FC705B0D2212DE6E0001036E /* RidesScreenBuilder.swift in Sources */, 0991067721B8291A00BD7E6F /* AddressSearchBarMVP.swift in Sources */, @@ -3547,19 +3561,19 @@ FC83E29F221ECC1C008FE26D /* KarhooDestinationEtaPresenter.swift in Sources */, FC435EFA2211B37A00FB6BB5 /* RidesListPresenter.swift in Sources */, 092005DD225B91C1001038ED /* MenuContentPresenter.swift in Sources */, - 5CBA2A7524F5D8CC0091D783 /* FormBookingRequestViewController.swift in Sources */, + 5CBA2A7524F5D8CC0091D783 /* KarhooCheckoutViewController.swift in Sources */, 09C765BF21DE688100CD81AB /* KarhooBookingAllocationSpinner.swift in Sources */, 4010B0E2245C67F300E7B0F1 /* ErrorBannerView.swift in Sources */, FC83E2AA221ECC52008FE26D /* KarhooTripSummaryInfoView.swift in Sources */, FC83E284221DB6B8008FE26D /* TripScreenBuilder.swift in Sources */, 40E6693523D5B99E00DE63BA /* RideDetailsViewContainer.swift in Sources */, 095B20D622649CEC00119D11 /* ScreenResult.swift in Sources */, - 5CBA2A7D24F5D8CC0091D783 /* SupplierView.swift in Sources */, 407EC7AF22CF564E00F24CFC /* Layout.swift in Sources */, FC435F242211B49100FB6BB5 /* RideDetailsMVP.swift in Sources */, 5CD9CFAA22DCAB580086E7A0 /* RatingViewMVP.swift in Sources */, 407EC7A522CF564E00F24CFC /* Constraints.swift in Sources */, - 5CBA2A7724F5D8CC0091D783 /* FormCheckoutHeaderView.swift in Sources */, + 5CBA2A7724F5D8CC0091D783 /* KarhooCheckoutHeaderView.swift in Sources */, + 6BE36B6126EF8E3B00F0FE86 /* KarhooFileManager.swift in Sources */, 407EC7C122CF564E00F24CFC /* KarhooNavigationBarView.swift in Sources */, 09C765B121DE688100CD81AB /* BookingMapStrategy.swift in Sources */, 407EC7C422CF564E00F24CFC /* URLOpener.swift in Sources */, @@ -3573,13 +3587,14 @@ 407EC7C922CF564E00F24CFC /* PrebookFieldMVP.swift in Sources */, 097800A8226F4434008772E4 /* KarhooLocationService.swift in Sources */, FC435F1B2211B3FA00FB6BB5 /* TripMetaDataViewModel.swift in Sources */, - 5CBA2A7A24F5D8CC0091D783 /* BookingButtonMVP.swift in Sources */, + 5CBA2A7A24F5D8CC0091D783 /* KarhooBookingButtonMVP.swift in Sources */, 407EC7D222CF564E00F24CFC /* CurrencyCodeConverter.swift in Sources */, 4010B0DA2458847500E7B0F1 /* KarhooTextInputView.swift in Sources */, 407EC7C322CF564E00F24CFC /* TripInfoUtility.swift in Sources */, FC83E251221DB4F5008FE26D /* TripMVP.swift in Sources */, 095D745323182313002253C0 /* TripRatingCache.swift in Sources */, 092005E2225B9216001038ED /* SideMenuBuilder.swift in Sources */, + 6BE36B5D26EF8A3400F0FE86 /* Country.swift in Sources */, 094AE86021C9145D0046EC3C /* TimeSinceNowProvider.swift in Sources */, FC83E2A3221ECC48008FE26D /* KarhooTripSummaryPresenter.swift in Sources */, 40A2851F22B2476F0020D78F /* QuoteViewModel.swift in Sources */, @@ -3597,16 +3612,19 @@ 0991071321B8486300BD7E6F /* AddressScreenBuilder.swift in Sources */, FC435F1A2211B3FA00FB6BB5 /* KarhooTripMetaDataView.swift in Sources */, 407EC79622CF564E00F24CFC /* LoadingView.swift in Sources */, - 5CBA2A7424F5D8CC0091D783 /* BookingRequestMVP.swift in Sources */, + 5CBA2A7424F5D8CC0091D783 /* KarhooCheckoutMVP.swift in Sources */, 09C765A021DE688100CD81AB /* QuoteListMVP.swift in Sources */, FC8F474D2153E770007841FB /* Bundle+Utils.swift in Sources */, FC435EF82211B37A00FB6BB5 /* RidesListMVP.swift in Sources */, 09C765C521DE688100CD81AB /* BookingMVP.swift in Sources */, 4056598422F2ED8D00EF4AFF /* RatingType.swift in Sources */, + 6BE36B5926EBB24400F0FE86 /* CountryCodeView.swift in Sources */, 09C765C421DE688100CD81AB /* KarhooQuoteSorter.swift in Sources */, 407EC7C822CF564E00F24CFC /* PhoneNumberCaller.swift in Sources */, 403F448222F19A38008147FC /* BaseStackView.swift in Sources */, 09C765B821DE688100CD81AB /* CancelButtonMVP.swift in Sources */, + 6B4C15A92731881A00C10EAE /* QuoteCategory+Extensions.swift in Sources */, + 6BE36B5B26EBB37E00F0FE86 /* CountryCodeViewModel.swift in Sources */, 407EC7D322CF564E00F24CFC /* MapMVP.swift in Sources */, 094AE86121C9145D0046EC3C /* KarhooDatePickerPresenter.swift in Sources */, 09DA1A3322F1A8F4004C6B20 /* FeedbackButtonMVP.swift in Sources */, @@ -3624,31 +3642,27 @@ FC83E288221DBA1B008FE26D /* TripSummaryScreenBuilder.swift in Sources */, 09F60CDF226623A200023C74 /* SideMenu.swift in Sources */, 407EC7DB22CF564E00F24CFC /* PinView.swift in Sources */, + 6B5B035326D7B8010001B2DB /* KarhooAddPassengerDetailsView.swift in Sources */, 097800A6226F427D008772E4 /* LocationService.swift in Sources */, 5C1B298725247E4F00E3CEEF /* AdyenPaymentNonceProvider.swift in Sources */, FC83E2A0221ECC1C008FE26D /* KarhooDestinationEtaView.swift in Sources */, - 09BDD19521C2CAD00074421C /* FlightDetails.swift in Sources */, - 09BDD19221C2CAD00074421C /* KarhooFlightDetailsPresenter.swift in Sources */, 5CBA2A7B24F5D8CC0091D783 /* KarhooBookingButtonView.swift in Sources */, - 09E0249B21C2D7D40071E367 /* FlightDetailsScreenBuilder.swift in Sources */, - 09E024A021C2D9FD0071E367 /* FlightNumberValidator.swift in Sources */, FC435F252211B49100FB6BB5 /* RideDetailsViewController.swift in Sources */, 407EC7A322CF564E00F24CFC /* LoadingImageView.swift in Sources */, FCAD1BFA22087BD800C3AD1D /* PrebookConfirmationViewModel.swift in Sources */, FC83E2A4221ECC48008FE26D /* TripSummaryViewController.swift in Sources */, 0991070921B83AF700BD7E6F /* TripLocationDetailsExt.swift in Sources */, 099106C321B8304900BD7E6F /* RecentAddressProvider.swift in Sources */, - 0946CB5D21CBDF0400DBDD42 /* BookingRequestScreenBuilder.swift in Sources */, + 0946CB5D21CBDF0400DBDD42 /* CheckoutScreenBuilder.swift in Sources */, FC435F3D2211BA1700FB6BB5 /* KarhooTripsProvider.swift in Sources */, 407EC7D022CF564E00F24CFC /* AddressBarMVP.swift in Sources */, - 09BDD19121C2CAD00074421C /* FlightDetailsMVP.swift in Sources */, 091EA9D421AC4AA700849112 /* AccessibilityIdentifier.swift in Sources */, 09C7659F21DE688100CD81AB /* QuoteSortMVP.swift in Sources */, 099106ED21B8362C00BD7E6F /* KarhooBookingStatus.swift in Sources */, 407EC7A922CF564E00F24CFC /* AccessibilityIdentifiers.swift in Sources */, FC83E2AD221EE890008FE26D /* TimeFetcher.swift in Sources */, 407EC7E222CF564E00F24CFC /* BookingStatusViewModel.swift in Sources */, - 5C3C66B724468B7800C736E9 /* KarhooPaymentMVP.swift in Sources */, + 5C3C66B724468B7800C736E9 /* KarhooAddPaymentMVP.swift in Sources */, 407FC5F622F0A46800F74D0A /* HintTextView.swift in Sources */, 407EC7B922CF564E00F24CFC /* KarhooTextField.swift in Sources */, FC83E299221ECC02008FE26D /* KarhooTripAddressBarPresenter.swift in Sources */, @@ -3659,6 +3673,7 @@ FC435F1E2211B40B00FB6BB5 /* RideDetailsStackButtonActions.swift in Sources */, 5C1CD0BB241A5D88004AFF7D /* TripScreenDetailsViewModel.swift in Sources */, 09E683232374522900BFF5B9 /* KarhooAddressMapPresenter.swift in Sources */, + 6B5B035526D7B81F0001B2DB /* KarhooAddPassengerDetailsPresenter.swift in Sources */, 5C089DF82507A2E100B3D4CA /* AdyenCardRegistrationFlow.swift in Sources */, 094AE85421C913020046EC3C /* DatePickerScreenBuilder.swift in Sources */, 407EC7E122CF564E00F24CFC /* TripDetailsViewModel.swift in Sources */, @@ -3667,6 +3682,7 @@ FC83E29A221ECC06008FE26D /* OriginEtaMVP.swift in Sources */, FC997269221C0C8900D476E1 /* PaymentScreenBuilder.swift in Sources */, 407EC7A022CF564E00F24CFC /* AlertFactory.swift in Sources */, + 6BE3695626EB352700F0FE86 /* CountryCodeSelectionMVP.swift in Sources */, 5CED9268227F1CFB00E0C960 /* ScreenBuilders.swift in Sources */, 407EC79C22CF564E00F24CFC /* LinkLabel.swift in Sources */, 09C765B421DE688100CD81AB /* PrebookField.swift in Sources */, @@ -3680,33 +3696,38 @@ FC435F442211BB8B00FB6BB5 /* KarhooTimeScheduler.swift in Sources */, FC83E2A7221ECC52008FE26D /* TripSummaryHeaderView.swift in Sources */, 5C1CD0BF241A8DB8004AFF7D /* KarhooTripDetailsView.swift in Sources */, + 791A9CDE26C4EC2A00B52DA1 /* KarhooAddPassengerDetailsAndPaymentView.swift in Sources */, FC435F012211B39A00FB6BB5 /* RideCellViewModel.swift in Sources */, 5C1CD0B5241A5D88004AFF7D /* DriverDetailsMVP.swift in Sources */, 408AB68523507DF600B351B2 /* FareExt.swift in Sources */, 09F60CE9226756AF00023C74 /* SideMenuHandler.swift in Sources */, + 79ACDCED26CFC3E7008820B5 /* KarhooFareInfoView.swift in Sources */, 099106BD21B82D5200BD7E6F /* Address.swift in Sources */, 407EC7A122CF564E00F24CFC /* AlertHandler.swift in Sources */, D8263F4E262096C30042F259 /* TimeFormatter.swift in Sources */, 407EC7CA22CF564E00F24CFC /* KarhooPrebookFieldView.swift in Sources */, - 40E54AC42460DF9D00D13E10 /* KarhooAddCardView.swift in Sources */, + 40E54AC42460DF9D00D13E10 /* KarhooAddPaymentView.swift in Sources */, 094AE85D21C9145D0046EC3C /* DatePickerMVP.swift in Sources */, 5C1CD0B2241A5D88004AFF7D /* TripOptionsMVP.swift in Sources */, 092F281C22B25B0700AF8E0E /* ThreeDSecureProvider.swift in Sources */, 097BF283234F2A3E00BBE418 /* VehicleCapacityView.swift in Sources */, - 5CBA2A7C24F5D8CC0091D783 /* KarhooBookingRequestPresenter.swift in Sources */, + 6B5B035926D7C2D90001B2DB /* KarhooCheckoutViewController+Extensions.swift in Sources */, 0991070C21B83AF700BD7E6F /* LocationDetailsExt.swift in Sources */, FC83E29E221ECC1C008FE26D /* DestinationEtaMVP.swift in Sources */, FC0465A52215AA05004E76FE /* NavigationControllerDelegate.swift in Sources */, 4017C46A23CCB0230081834B /* EmptyStateView.swift in Sources */, + 6B5B035726D7B83F0001B2DB /* KarhooAddPassengerDetailsMVP.swift in Sources */, 407EC7E722CF564E00F24CFC /* KarhooEmptyDataSetView.swift in Sources */, 407EC79922CF564E00F24CFC /* KarhooStackButtonView.swift in Sources */, FCAD1BFC22087BD800C3AD1D /* KarhooPrebookConfirmationViewController.swift in Sources */, 407EC7E922CF564E00F24CFC /* EmptyDataSetMVP.swift in Sources */, + 6BE3695226EB34D000F0FE86 /* CountryCodeSelectionViewController.swift in Sources */, 09C765C021DE688100CD81AB /* BookingAllocationSpinnerMVP.swift in Sources */, FC435EFF2211B39A00FB6BB5 /* RideCell.swift in Sources */, - 5CBA2A8024F5D8CC0091D783 /* TimePriceMVP.swift in Sources */, + 5CBA2A8024F5D8CC0091D783 /* KarhooTimePriceMVP.swift in Sources */, 4010B0DC245C5DD900E7B0F1 /* KarhooInputViewState.swift in Sources */, FC435F372211B88900FB6BB5 /* CancelRideBehaviour.swift in Sources */, + 6B7BE3F3271968A600682AA1 /* PassengerDetails+Extensions.swift in Sources */, 407EC7A822CF564E00F24CFC /* NibStrings.swift in Sources */, 0991068121B8291A00BD7E6F /* AddressSearchProvider.swift in Sources */, FC705B15221321650001036E /* PopupDialogScreenBuilder.swift in Sources */, @@ -3717,18 +3738,20 @@ 09C765AB21DE688100CD81AB /* KarhooQuoteCategoryBarView.swift in Sources */, 092A6D4F2265EDBA00A8DA5D /* KarhooUISDKErrorType.swift in Sources */, 09C765A521DE688100CD81AB /* KarhooGrabberHandleView.swift in Sources */, + 6B5E25F326D672090017BFB3 /* PassengerDetailsViewController.swift in Sources */, 407EC7A622CF564E00F24CFC /* Attributes.swift in Sources */, 4038DF3A2444BAC40014539B /* Utils.swift in Sources */, 407EC7E022CF564E00F24CFC /* TripDetailsView.swift in Sources */, - 09BDD19421C2CAD00074421C /* FlightDetailsViewController.swift in Sources */, 407EC7C222CF564E00F24CFC /* KeyboardSizeProvider.swift in Sources */, FCAD1BFB22087BD800C3AD1D /* PrebookConfirmationMVP.swift in Sources */, FC83E2B2221EE920008FE26D /* Logger.swift in Sources */, 4010B0DE245C5DFE00E7B0F1 /* KarhooTextInputViewContentType.swift in Sources */, 5C1CD0BA241A5D88004AFF7D /* KarhooTripDetailsPresenter.swift in Sources */, + 6BA3544F27304E400003B888 /* QuoteVehicle+Extensions.swift in Sources */, FC435EEA2211B33B00FB6BB5 /* KarhooRidesPresenter.swift in Sources */, 09C765A621DE688100CD81AB /* KarhooQuoteListViewController.swift in Sources */, 09D8B29422F3491F00569C55 /* TripFeedbackScreenBuilder.swift in Sources */, + 6BE36B5726EBB1F300F0FE86 /* CountryCodeTableViewCell.swift in Sources */, 5C1CD0B1241A5D88004AFF7D /* KarhooTripOptionsPresenter.swift in Sources */, 407EC7DD22CF564E00F24CFC /* GradientView.swift in Sources */, 09C765C321DE688100CD81AB /* TripAllocationMVP.swift in Sources */, @@ -3738,13 +3761,11 @@ 09C765BE21DE688100CD81AB /* KarhooTripAllocationPresenter.swift in Sources */, 404E9C4B23C8BB2B00289F43 /* LineView.swift in Sources */, 092F281D22B25B0700AF8E0E /* BraintreeThreeDSecureProvider.swift in Sources */, - 5CBA2A7924F5D8CC0091D783 /* PassengerDetailsView.swift in Sources */, 4070213723D9E11300F82B6A /* DropDownButton.swift in Sources */, 5C8316BB246A0B6200BAA926 /* EmptyMapBookingStrategy.swift in Sources */, 5C1CD0B0241A5D88004AFF7D /* TripOptionsViewModel.swift in Sources */, FC8F47392153DBDE007841FB /* KarhooUI.swift in Sources */, 0999CBB0220DDA0300A93AF9 /* KarhooUIScreenRouting.swift in Sources */, - 4038DF422445D5340014539B /* KarhooPhoneInputViewDataSource.swift in Sources */, 2396A2AB255566DC007BD9E1 /* JourneyInfo.swift in Sources */, 0991067F21B8291A00BD7E6F /* AddressTableViewCell.swift in Sources */, 4038DF3F2444D6810014539B /* KarhooInputView.swift in Sources */, @@ -3755,9 +3776,10 @@ FC435F3E2211BA1700FB6BB5 /* KarhooTripsSorter.swift in Sources */, 407EC79422CF564E00F24CFC /* Analytics.swift in Sources */, 092F281B22B25B0700AF8E0E /* PaymentNonceProvider.swift in Sources */, - 403E907922C5287F00F39B91 /* KarhooPaymentView.swift in Sources */, 0991067821B8291A00BD7E6F /* KarhooAddressSearchBar.swift in Sources */, 09C765B921DE688100CD81AB /* KarhooCancelButtonView.swift in Sources */, + 6BE3695426EB34E000F0FE86 /* CountryCodeSelectionPresenter.swift in Sources */, + 6B5E25F526D67DCA0017BFB3 /* PassengerDetailsPresenter.swift in Sources */, 40C7DC5B23D0A13500975AD3 /* MetaDataView.swift in Sources */, 0991070A21B83AF700BD7E6F /* TripExt.swift in Sources */, 4010B0E0245C5E1F00E7B0F1 /* KarhooTextInputViewErrorFeedbackType.swift in Sources */, @@ -3771,6 +3793,7 @@ 09C765B621DE688100CD81AB /* KarhooBookingPresenter.swift in Sources */, 09C765AD21DE688100CD81AB /* KarhooBookingMapPresenter.swift in Sources */, 4070213C23D9E19400F82B6A /* UIView+Extensions.swift in Sources */, + 6BE36B5F26EF8DFD00F0FE86 /* KarhooCountryParser.swift in Sources */, 5C1CD0B8241A5D88004AFF7D /* TripDetailsMVP.swift in Sources */, FC83E2A2221ECC48008FE26D /* TripSummaryMVP.swift in Sources */, 0991070821B83AF700BD7E6F /* Observable+Utils.swift in Sources */, @@ -3779,7 +3802,7 @@ 5C7233C0226510B9001078B6 /* KarhooUISDKError.swift in Sources */, 407EC7BE22CF564E00F24CFC /* CloseBarButton.swift in Sources */, 0991070621B83AF700BD7E6F /* QuoteType+Description.swift in Sources */, - 400BE99222CF4D27002942CC /* KarhooPaymentPresenter.swift in Sources */, + 400BE99222CF4D27002942CC /* KarhooAddPaymentPresenter.swift in Sources */, 407EC7DE22CF564E00F24CFC /* RoundedLabel.swift in Sources */, 0989E631220313740062474A /* BookingStatus.swift in Sources */, 40FE0CF222D7D333003F65B5 /* KarhooRatingPresenter.swift in Sources */, @@ -3801,7 +3824,7 @@ 14707C7525D54C2100CAD083 /* KarhooTripSummaryPresenterSpec.swift in Sources */, 14707CB225D54C2200CAD083 /* KarhooBookingPresenterSpec.swift in Sources */, 14707C5D25D54C2100CAD083 /* DatePickerPresenterSpec.swift in Sources */, - 14707C6325D54C2100CAD083 /* MockBookingRequestView.swift in Sources */, + 14707C6325D54C2100CAD083 /* MockCheckoutView.swift in Sources */, 14707C8A25D54C2200CAD083 /* MockKarhooMapView.swift in Sources */, 14707C8925D54C2200CAD083 /* MockDestinationEtaView.swift in Sources */, 14707C4F25D54C2100CAD083 /* MockPrebookConfirmationScreenBuilder.swift in Sources */, @@ -3811,10 +3834,10 @@ 14707CC725D54C2200CAD083 /* KarhooTripAllocationPresenterSpec.swift in Sources */, 14707C7625D54C2100CAD083 /* MockUserDefaults.swift in Sources */, 14707CC825D54C2200CAD083 /* MockError.swift in Sources */, - 14707C7C25D54C2100CAD083 /* KarhooBookingRequestPresenterSpec.swift in Sources */, + 14707C7C25D54C2100CAD083 /* KarhooCheckoutPresenterSpec.swift in Sources */, 14707CAD25D54C2200CAD083 /* MockRidesListView.swift in Sources */, 14707C3C25D54C2100CAD083 /* BookingAllocationSpinnerPresenterSpec.swift in Sources */, - 14707C6A25D54C2100CAD083 /* MockBookingRequestScreenBuilder.swift in Sources */, + 14707C6A25D54C2100CAD083 /* MockCheckoutScreenBuilder.swift in Sources */, 14707CD725D54C2200CAD083 /* MockSideMenuHandler.swift in Sources */, 14707C7F25D54C2100CAD083 /* BookingMapPresenterSpec.swift in Sources */, 14707C8E25D54C2200CAD083 /* BaseViewControllerSpec.swift in Sources */, @@ -3839,12 +3862,11 @@ 14707C7725D54C2100CAD083 /* BookingDetailsSpec.swift in Sources */, 14707C6225D54C2100CAD083 /* KarhooPrebookConfirmationPresenterSpec.swift in Sources */, 14707CCD25D54C2200CAD083 /* MockTripView.swift in Sources */, - 14707CBC25D54C2200CAD083 /* MockFlightDetailsScreenBuilder.swift in Sources */, 14707C9F25D54C2200CAD083 /* MockRecentAddressProvider.swift in Sources */, 14707C9825D54C2200CAD083 /* MockTripAllocationView.swift in Sources */, 14707C4B25D54C2100CAD083 /* PopupDialogView.swift in Sources */, 14707CD225D54C2200CAD083 /* MockQuoteSorter.swift in Sources */, - 14707CC125D54C2200CAD083 /* KarhooGuestBookingRequestPresenterSpec.swift in Sources */, + 14707CC125D54C2200CAD083 /* KarhooGuestCheckoutPresenterSpec.swift in Sources */, 14707C5625D54C2100CAD083 /* MockTimeScheduler.swift in Sources */, 14707C6025D54C2100CAD083 /* BookingAddressBarPresenterSpec.swift in Sources */, 14707CC925D54C2200CAD083 /* MockTripSummaryView.swift in Sources */, @@ -3872,6 +3894,7 @@ 14707C7125D54C2100CAD083 /* MockDataFormatterType.swift in Sources */, 14707C3A25D54C2100CAD083 /* DestinationSetStrategySpec.swift in Sources */, 14707CA025D54C2200CAD083 /* KarhooTripRatingCacheSpec.swift in Sources */, + 6B5D607D26E8E45900163EFE /* MockPassengerDetailsViewController.swift in Sources */, 14707C6525D54C2100CAD083 /* MockFareService.swift in Sources */, 14707C7A25D54C2100CAD083 /* MockAddressScreenBuilder.swift in Sources */, 14707C9A25D54C2200CAD083 /* EmptyBookingMapStrategySpec.swift in Sources */, @@ -3879,7 +3902,6 @@ 14707C6825D54C2100CAD083 /* MockCall.swift in Sources */, 14707C4625D54C2100CAD083 /* MockValidator.swift in Sources */, 14707C3E25D54C2100CAD083 /* MockNavigationItem.swift in Sources */, - 14707CDD25D54C2200CAD083 /* FlightDetailsPresenterSpec.swift in Sources */, 14707C5925D54C2100CAD083 /* QuoteCellViewModelSpec.swift in Sources */, 14707C4C25D54C2100CAD083 /* MockPollCall.swift in Sources */, 14707C8125D54C2100CAD083 /* KarhooBookingStatusSpec.swift in Sources */, @@ -3902,6 +3924,7 @@ 14707C7225D54C2100CAD083 /* MockTripRatingCache.swift in Sources */, 14707CD925D54C2200CAD083 /* MockPhoneNumberCaller.swift in Sources */, 14707C6425D54C2100CAD083 /* MockTripScreenBuilder.swift in Sources */, + 6B5D607F26E8E60C00163EFE /* PassengerDetailsPresenterSpec.swift in Sources */, 14707C3F25D54C2100CAD083 /* MockAddressSearchProvider.swift in Sources */, 14707C5225D54C2100CAD083 /* TripScreenDetailsViewModelSpec.swift in Sources */, 14707CCE25D54C2200CAD083 /* TripsListSorterSpec.swift in Sources */, @@ -3943,11 +3966,9 @@ FC435F7A2211DDB400FB6BB5 /* RideCellViewModelSpec.swift in Sources */, 14707CA325D54C2200CAD083 /* KarhooTripMetaDataPresenterSpec.swift in Sources */, 14707CC625D54C2200CAD083 /* TripAddressBarPresenterSpec.swift in Sources */, - 14707C7325D54C2100CAD083 /* MockFlightDetailsView.swift in Sources */, 14707C5825D54C2100CAD083 /* MockBookingView.swift in Sources */, 14707C4325D54C2100CAD083 /* MockStackButtonView.swift in Sources */, 14707CC025D54C2200CAD083 /* MockFeedbackMailComposter.swift in Sources */, - 14707CA625D54C2200CAD083 /* FlightNumberValidatorSpec.swift in Sources */, 14707C9B25D54C2200CAD083 /* PickupOnlyStrategySpec.swift in Sources */, 14707C5F25D54C2100CAD083 /* KarhooTripsProviderSpec.swift in Sources */, A1A0312626171A4E00B01E1F /* KarhooQuoteListPresenterSpec.swift in Sources */, @@ -3981,6 +4002,9 @@ 090F08E921C94BB6000C7E50 /* es */, 090F08EA21C94BB6000C7E50 /* Base */, 090F08EB21C94BB6000C7E50 /* fr */, + AE6E39E5271DADE500EE92C9 /* de */, + AE6E39E7271DAE0E00EE92C9 /* it */, + AE6E39E9271DAE2100EE92C9 /* nl */, ); name = Localizable.strings; sourceTree = ""; @@ -3999,6 +4023,9 @@ D8D8ED2C261F1FDA0061066D /* en */, D8D8ED31261F1FE00061066D /* fr */, D8D8ED32261F1FE10061066D /* es */, + AE6E39E6271DADE500EE92C9 /* de */, + AE6E39E8271DAE0E00EE92C9 /* it */, + AE6E39EA271DAE2100EE92C9 /* nl */, ); name = Localizable.stringsdict; sourceTree = ""; @@ -4008,7 +4035,7 @@ /* Begin XCBuildConfiguration section */ 5C2E261F2420F8AD00B1FF0C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D58D9119291DD6B42DC25E25 /* Pods-Client.debug.xcconfig */; + baseConfigurationReference = 3CDC92F5EF4385593DC9E7C1 /* Pods-Client.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; @@ -4031,7 +4058,7 @@ }; 5C2E26202420F8AD00B1FF0C /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5A6218A52CFEDECA5CD3884E /* Pods-Client.release.xcconfig */; + baseConfigurationReference = 31B3B4A018455D19516D4105 /* Pods-Client.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; @@ -4044,7 +4071,7 @@ "@executable_path/Frameworks", ); MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.karhooUISDK.Client; + PRODUCT_BUNDLE_IDENTIFIER = com.karhooUISDK.DropIn; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -4182,7 +4209,7 @@ }; FC8F472921539E24007841FB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9BA7A827B91FEFCA386D1C4A /* Pods-KarhooUISDK.debug.xcconfig */; + baseConfigurationReference = ACEF9B513CE84FCE3A9D112B /* Pods-KarhooUISDK.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUILD_LIBRARY_FOR_DISTRIBUTION = YES; @@ -4190,7 +4217,7 @@ CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 9; + CURRENT_PROJECT_VERSION = 10; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = U7U4Q7YGDH; DYLIB_COMPATIBILITY_VERSION = 1; @@ -4209,7 +4236,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 1.6.4; + MARKETING_VERSION = 1.7.0; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.karhoo.KarhooUISDK; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; @@ -4224,7 +4251,7 @@ }; FC8F472A21539E24007841FB /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 424F848C513A1D30E2DC8308 /* Pods-KarhooUISDK.release.xcconfig */; + baseConfigurationReference = E15EBC42388B5BC1A3C392A8 /* Pods-KarhooUISDK.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUILD_LIBRARY_FOR_DISTRIBUTION = YES; @@ -4232,7 +4259,7 @@ CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 9; + CURRENT_PROJECT_VERSION = 10; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = U7U4Q7YGDH; DYLIB_COMPATIBILITY_VERSION = 1; @@ -4251,7 +4278,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 1.6.4; + MARKETING_VERSION = 1.7.0; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.karhoo.KarhooUISDK; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; @@ -4265,7 +4292,7 @@ }; FC8F472C21539E24007841FB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2372675E70509D3779F8061D /* Pods-KarhooUISDKTests.debug.xcconfig */; + baseConfigurationReference = 7EBD72D5A33685C761A23874 /* Pods-KarhooUISDKTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUILD_LIBRARY_FOR_DISTRIBUTION = NO; @@ -4290,9 +4317,9 @@ }; FC8F472D21539E24007841FB /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1061B90ED3BAE79634610DAC /* Pods-KarhooUISDKTests.release.xcconfig */; + baseConfigurationReference = 4AEFE9B70C37266D3CDE762F /* Pods-KarhooUISDKTests.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = U7U4Q7YGDH; diff --git a/KarhooUISDK/API/KarhooUIScreenRouting.swift b/KarhooUISDK/API/KarhooUIScreenRouting.swift index eb8c45ceb..8ccf5a95f 100644 --- a/KarhooUISDK/API/KarhooUIScreenRouting.swift +++ b/KarhooUISDK/API/KarhooUIScreenRouting.swift @@ -14,9 +14,8 @@ public protocol Routing { func ridesList() -> RidesListScreenBuilder func rideDetails() -> RideDetailsScreenBuilder func booking() -> BookingScreenBuilder - func flightDetails() -> FlightDetailsScreenBuilder func tripScreen() -> TripScreenBuilder - func bookingRequest() -> BookingRequestScreenBuilder + func checkout() -> CheckoutScreenBuilder } public final class UISDKScreenRouting: Routing { @@ -51,16 +50,12 @@ public final class UISDKScreenRouting: Routing { return routing.bookingScreenBuilder } - public func flightDetails() -> FlightDetailsScreenBuilder { - return routing.flightDetailsScreenBuilder - } - public func tripScreen() -> TripScreenBuilder { return routing.tripScreenBuilder } - public func bookingRequest() -> BookingRequestScreenBuilder { - return routing.bookingRequestScreenBuilder + public func checkout() -> CheckoutScreenBuilder { + return routing.checkoutScreenBuilder } public func paymentScreen() -> PaymentScreenBuilder { diff --git a/KarhooUISDK/API/ScreenBuilders.swift b/KarhooUISDK/API/ScreenBuilders.swift index 3c92b47f0..780ee4738 100644 --- a/KarhooUISDK/API/ScreenBuilders.swift +++ b/KarhooUISDK/API/ScreenBuilders.swift @@ -15,9 +15,8 @@ public protocol ScreenBuilders { var ridesScreenBuilder: RidesListScreenBuilder { get } var rideDetailsScreenBuilder: RideDetailsScreenBuilder { get } var bookingScreenBuilder: BookingScreenBuilder { get } - var flightDetailsScreenBuilder: FlightDetailsScreenBuilder { get } var tripScreenBuilder: TripScreenBuilder { get } - var bookingRequestScreenBuilder: BookingRequestScreenBuilder { get } + var checkoutScreenBuilder: CheckoutScreenBuilder { get } } internal protocol InternalScreenBuilders { @@ -40,8 +39,8 @@ final class KarhooScreenBuilders: ScreenBuilders, InternalScreenBuilders { return KarhooBookingScreenBuilder() } - var bookingRequestScreenBuilder: BookingRequestScreenBuilder { - return bookingRequestBuilder() + var checkoutScreenBuilder: CheckoutScreenBuilder { + return checkoutBuilder() } var datePickerScreenBuilder: DatePickerScreenBuilder { @@ -92,22 +91,15 @@ public extension ScreenBuilders { return RidesListViewController.KarhooRidesListScreenBuilder() } - var flightDetailsScreenBuilder: FlightDetailsScreenBuilder { - return FlightDetailsViewController.KarhooFlightDetailsScreenBuilder() - } - var tripScreenBuilder: TripScreenBuilder { return KarhooTripViewController.KarhooTripScreenBuilder() } - var bookingRequestScreenBuilder: BookingRequestScreenBuilder { - return bookingRequestBuilder() + var checkoutScreenBuilder: CheckoutScreenBuilder { + return checkoutBuilder() } - func bookingRequestBuilder() -> BookingRequestScreenBuilder { - switch Karhoo.configuration.authenticationMethod() { - case .guest(settings: _), .tokenExchange: return FormBookingRequestViewController.Builder() - case .karhooUser: return KarhooBookingRequestViewController.KarhooBookingRequestScreenBuilder() - } + func checkoutBuilder() -> CheckoutScreenBuilder { + return KarhooCheckoutViewController.Builder() } } diff --git a/KarhooUISDK/Assets/Assets.xcassets/backIcon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/backIcon.imageset/Contents.json new file mode 100644 index 000000000..562531fa2 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/backIcon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "fi_chevron-left.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/backIcon.imageset/fi_chevron-left.pdf b/KarhooUISDK/Assets/Assets.xcassets/backIcon.imageset/fi_chevron-left.pdf new file mode 100644 index 000000000..431832ffe Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/backIcon.imageset/fi_chevron-left.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/childseat.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/childseat.imageset/Contents.json new file mode 100644 index 000000000..c65a44487 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/childseat.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "u_baby-carriage.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/childseat.imageset/u_baby-carriage.pdf b/KarhooUISDK/Assets/Assets.xcassets/childseat.imageset/u_baby-carriage.pdf new file mode 100644 index 000000000..14995ed93 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/childseat.imageset/u_baby-carriage.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/circle.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/circle.imageset/Contents.json new file mode 100644 index 000000000..2844f9954 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/circle.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "fi_circle.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/circle.imageset/fi_circle.pdf b/KarhooUISDK/Assets/Assets.xcassets/circle.imageset/fi_circle.pdf new file mode 100644 index 000000000..0aae9b95c Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/circle.imageset/fi_circle.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/dropdownIcon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/dropdownIcon.imageset/Contents.json new file mode 100644 index 000000000..85edf2de8 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/dropdownIcon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "fi_chevron-down.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/dropdownIcon.imageset/fi_chevron-down.pdf b/KarhooUISDK/Assets/Assets.xcassets/dropdownIcon.imageset/fi_chevron-down.pdf new file mode 100644 index 000000000..56d8571a4 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/dropdownIcon.imageset/fi_chevron-down.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/dropupIcon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/dropupIcon.imageset/Contents.json new file mode 100644 index 000000000..87ed725d2 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/dropupIcon.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "fi_chevron-up.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/dropupIcon.imageset/fi_chevron-up.pdf b/KarhooUISDK/Assets/Assets.xcassets/dropupIcon.imageset/fi_chevron-up.pdf new file mode 100644 index 000000000..85f11e13b Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/dropupIcon.imageset/fi_chevron-up.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/electric.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/electric.imageset/Contents.json new file mode 100644 index 000000000..4bdc4947b --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/electric.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "Vector.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/electric.imageset/Vector.pdf b/KarhooUISDK/Assets/Assets.xcassets/electric.imageset/Vector.pdf new file mode 100644 index 000000000..c6d60cd87 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/electric.imageset/Vector.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/flightTrackingIcon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/flightTrackingIcon.imageset/Contents.json new file mode 100644 index 000000000..f99ecb018 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/flightTrackingIcon.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "u_plane.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/flightTrackingIcon.imageset/u_plane.pdf b/KarhooUISDK/Assets/Assets.xcassets/flightTrackingIcon.imageset/u_plane.pdf new file mode 100644 index 000000000..fc7685910 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/flightTrackingIcon.imageset/u_plane.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/gpsTrackingIcon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/gpsTrackingIcon.imageset/Contents.json new file mode 100644 index 000000000..0ebd5162f --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/gpsTrackingIcon.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "fi_map.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/gpsTrackingIcon.imageset/fi_map.pdf b/KarhooUISDK/Assets/Assets.xcassets/gpsTrackingIcon.imageset/fi_map.pdf new file mode 100644 index 000000000..ed1a27e3d Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/gpsTrackingIcon.imageset/fi_map.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/info_icon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/info_icon.imageset/Contents.json new file mode 100644 index 000000000..d410039e5 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/info_icon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "fi_alert-circle.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/info_icon.imageset/fi_alert-circle.pdf b/KarhooUISDK/Assets/Assets.xcassets/info_icon.imageset/fi_alert-circle.pdf new file mode 100644 index 000000000..1b90532d7 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/info_icon.imageset/fi_alert-circle.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/Contents.json index 9658e29dc..ecf4ff766 100644 --- a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/Contents.json +++ b/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/Contents.json @@ -1,23 +1,15 @@ { "images" : [ { - "filename" : "luggage_icon.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "luggage_icon@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "luggage_icon@3x.png", - "idiom" : "universal", - "scale" : "3x" + "filename" : "fi_briefcase.pdf", + "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true } } diff --git a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/fi_briefcase.pdf b/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/fi_briefcase.pdf new file mode 100644 index 000000000..56d9ddd94 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/fi_briefcase.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon.png b/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon.png deleted file mode 100644 index 2457abafd..000000000 Binary files a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon.png and /dev/null differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon@2x.png b/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon@2x.png deleted file mode 100644 index bdcad5ea6..000000000 Binary files a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon@2x.png and /dev/null differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon@3x.png b/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon@3x.png deleted file mode 100644 index 31111210d..000000000 Binary files a/KarhooUISDK/Assets/Assets.xcassets/luggage_icon.imageset/luggage_icon@3x.png and /dev/null differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/Contents.json index a550affe0..68cd18dd8 100644 --- a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/Contents.json +++ b/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/Contents.json @@ -1,19 +1,8 @@ { "images" : [ { - "filename" : "profile.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "profile@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "profile@3x.png", - "idiom" : "universal", - "scale" : "3x" + "filename" : "fi_users.pdf", + "idiom" : "universal" } ], "info" : { diff --git a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/fi_users.pdf b/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/fi_users.pdf new file mode 100644 index 000000000..1d17e6b95 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/fi_users.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile.png b/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile.png deleted file mode 100644 index 6c1f4e3c8..000000000 Binary files a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile.png and /dev/null differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile@2x.png b/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile@2x.png deleted file mode 100644 index 44e462b96..000000000 Binary files a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile@2x.png and /dev/null differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile@3x.png b/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile@3x.png deleted file mode 100644 index fd6f027d4..000000000 Binary files a/KarhooUISDK/Assets/Assets.xcassets/passenger_capacity_icon.imageset/profile@3x.png and /dev/null differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/plus_icon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/plus_icon.imageset/Contents.json new file mode 100644 index 000000000..accb07355 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/plus_icon.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "u_plus-circle.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/plus_icon.imageset/u_plus-circle.pdf b/KarhooUISDK/Assets/Assets.xcassets/plus_icon.imageset/u_plus-circle.pdf new file mode 100644 index 000000000..c0f18e47c Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/plus_icon.imageset/u_plus-circle.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/search.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/search.imageset/Contents.json new file mode 100644 index 000000000..4a3f4dab2 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/search.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "search.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/search.imageset/search.svg b/KarhooUISDK/Assets/Assets.xcassets/search.imageset/search.svg new file mode 100644 index 000000000..0f80b3925 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/search.imageset/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/KarhooUISDK/Assets/Assets.xcassets/star.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/star.imageset/Contents.json new file mode 100644 index 000000000..d5a2b09dc --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/star.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Vector (1).pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/star.imageset/Vector (1).pdf b/KarhooUISDK/Assets/Assets.xcassets/star.imageset/Vector (1).pdf new file mode 100644 index 000000000..838aa4413 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/star.imageset/Vector (1).pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/taxi.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/taxi.imageset/Contents.json new file mode 100644 index 000000000..f4c225d75 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/taxi.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "taxi.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/taxi.imageset/taxi.pdf b/KarhooUISDK/Assets/Assets.xcassets/taxi.imageset/taxi.pdf new file mode 100644 index 000000000..fe9db3762 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/taxi.imageset/taxi.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/trainTrackingIcon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/trainTrackingIcon.imageset/Contents.json new file mode 100644 index 000000000..ad1ef2816 --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/trainTrackingIcon.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "u_metro.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/trainTrackingIcon.imageset/u_metro.pdf b/KarhooUISDK/Assets/Assets.xcassets/trainTrackingIcon.imageset/u_metro.pdf new file mode 100644 index 000000000..ad10f71b9 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/trainTrackingIcon.imageset/u_metro.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/user_icon.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/user_icon.imageset/Contents.json new file mode 100644 index 000000000..40def4e3f --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/user_icon.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "fi_user.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/user_icon.imageset/fi_user.pdf b/KarhooUISDK/Assets/Assets.xcassets/user_icon.imageset/fi_user.pdf new file mode 100644 index 000000000..c8d2b30b3 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/user_icon.imageset/fi_user.pdf differ diff --git a/KarhooUISDK/Assets/Assets.xcassets/wheelchair.imageset/Contents.json b/KarhooUISDK/Assets/Assets.xcassets/wheelchair.imageset/Contents.json new file mode 100644 index 000000000..b21f8f93a --- /dev/null +++ b/KarhooUISDK/Assets/Assets.xcassets/wheelchair.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "u_wheelchair.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/KarhooUISDK/Assets/Assets.xcassets/wheelchair.imageset/u_wheelchair.pdf b/KarhooUISDK/Assets/Assets.xcassets/wheelchair.imageset/u_wheelchair.pdf new file mode 100644 index 000000000..0ef80ca37 Binary files /dev/null and b/KarhooUISDK/Assets/Assets.xcassets/wheelchair.imageset/u_wheelchair.pdf differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AC.imageset/AC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AC.imageset/AC.png new file mode 100644 index 000000000..d76832cc7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AC.imageset/AC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AC.imageset/Contents.json new file mode 100644 index 000000000..294bf6380 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AD.imageset/AD.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AD.imageset/AD.png new file mode 100644 index 000000000..4d238e346 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AD.imageset/AD.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AD.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AD.imageset/Contents.json new file mode 100644 index 000000000..4717029a8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AD.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AD.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AE.imageset/AE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AE.imageset/AE.png new file mode 100644 index 000000000..f40f4b4a0 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AE.imageset/AE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AE.imageset/Contents.json new file mode 100644 index 000000000..9f2fdcced --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AF.imageset/AF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AF.imageset/AF.png new file mode 100644 index 000000000..e3584665f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AF.imageset/AF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AF.imageset/Contents.json new file mode 100644 index 000000000..a86469317 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AG.imageset/AG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AG.imageset/AG.png new file mode 100644 index 000000000..681554ce5 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AG.imageset/AG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AG.imageset/Contents.json new file mode 100644 index 000000000..d5a776a94 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AI.imageset/AI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AI.imageset/AI.png new file mode 100644 index 000000000..c55608a2b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AI.imageset/AI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AI.imageset/Contents.json new file mode 100644 index 000000000..12eba120d --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AL.imageset/AL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AL.imageset/AL.png new file mode 100644 index 000000000..5d114d401 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AL.imageset/AL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AL.imageset/Contents.json new file mode 100644 index 000000000..199d323da --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AM.imageset/AM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AM.imageset/AM.png new file mode 100644 index 000000000..7636fc670 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AM.imageset/AM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AM.imageset/Contents.json new file mode 100644 index 000000000..c68b84fb5 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AN.imageset/AN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AN.imageset/AN.png new file mode 100644 index 000000000..f8e11600a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AN.imageset/AN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AN.imageset/Contents.json new file mode 100644 index 000000000..5b24b9832 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AO.imageset/AO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AO.imageset/AO.png new file mode 100644 index 000000000..89f1fbd44 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AO.imageset/AO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AO.imageset/Contents.json new file mode 100644 index 000000000..5db1415b9 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AQ.imageset/AQ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AQ.imageset/AQ.png new file mode 100644 index 000000000..a47d1d22d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AQ.imageset/AQ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AQ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AQ.imageset/Contents.json new file mode 100644 index 000000000..4e412993f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AQ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AQ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AR.imageset/AR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AR.imageset/AR.png new file mode 100644 index 000000000..c0c2dfb22 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AR.imageset/AR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AR.imageset/Contents.json new file mode 100644 index 000000000..fd8b601b7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AS.imageset/AS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AS.imageset/AS.png new file mode 100644 index 000000000..ef1b1c3b7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AS.imageset/AS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AS.imageset/Contents.json new file mode 100644 index 000000000..84ecb3a8b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AT.imageset/AT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AT.imageset/AT.png new file mode 100644 index 000000000..7eae9edb8 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AT.imageset/AT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AT.imageset/Contents.json new file mode 100644 index 000000000..b66b7e623 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AU.imageset/AU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AU.imageset/AU.png new file mode 100644 index 000000000..56e1e4b11 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AU.imageset/AU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AU.imageset/Contents.json new file mode 100644 index 000000000..f83a68398 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AW.imageset/AW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AW.imageset/AW.png new file mode 100644 index 000000000..65d832c0c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AW.imageset/AW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AW.imageset/Contents.json new file mode 100644 index 000000000..1ad61b0ca --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AX.imageset/AX.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AX.imageset/AX.png new file mode 100644 index 000000000..46dcdd932 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AX.imageset/AX.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AX.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AX.imageset/Contents.json new file mode 100644 index 000000000..70944ec56 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AX.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AX.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AZ.imageset/AZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/AZ.imageset/AZ.png new file mode 100644 index 000000000..4551706ac Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/AZ.imageset/AZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/AZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/AZ.imageset/Contents.json new file mode 100644 index 000000000..6a8dad9c7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/AZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "AZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BA.imageset/BA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BA.imageset/BA.png new file mode 100644 index 000000000..5f6039b37 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BA.imageset/BA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BA.imageset/Contents.json new file mode 100644 index 000000000..781d3c727 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BB.imageset/BB.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BB.imageset/BB.png new file mode 100644 index 000000000..0b2ecc188 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BB.imageset/BB.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BB.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BB.imageset/Contents.json new file mode 100644 index 000000000..7665ea7f6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BB.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BB.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BD.imageset/BD.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BD.imageset/BD.png new file mode 100644 index 000000000..bec62d9ad Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BD.imageset/BD.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BD.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BD.imageset/Contents.json new file mode 100644 index 000000000..bea390fc1 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BD.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BD.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BE.imageset/BE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BE.imageset/BE.png new file mode 100644 index 000000000..6311d10a8 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BE.imageset/BE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BE.imageset/Contents.json new file mode 100644 index 000000000..ab9c258dd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BF.imageset/BF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BF.imageset/BF.png new file mode 100644 index 000000000..1e7c69c1d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BF.imageset/BF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BF.imageset/Contents.json new file mode 100644 index 000000000..0c7c636c8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BG.imageset/BG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BG.imageset/BG.png new file mode 100644 index 000000000..53e35fcef Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BG.imageset/BG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BG.imageset/Contents.json new file mode 100644 index 000000000..67e0599aa --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BH.imageset/BH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BH.imageset/BH.png new file mode 100644 index 000000000..15f69490e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BH.imageset/BH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BH.imageset/Contents.json new file mode 100644 index 000000000..a24320756 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BI.imageset/BI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BI.imageset/BI.png new file mode 100644 index 000000000..20d6b448d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BI.imageset/BI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BI.imageset/Contents.json new file mode 100644 index 000000000..adc217f0c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BJ.imageset/BJ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BJ.imageset/BJ.png new file mode 100644 index 000000000..582a56656 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BJ.imageset/BJ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BJ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BJ.imageset/Contents.json new file mode 100644 index 000000000..7b45f8a88 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BJ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BJ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BL.imageset/BL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BL.imageset/BL.png new file mode 100644 index 000000000..6421f045c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BL.imageset/BL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BL.imageset/Contents.json new file mode 100644 index 000000000..ed4ab8ee8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BM.imageset/BM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BM.imageset/BM.png new file mode 100644 index 000000000..172057f63 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BM.imageset/BM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BM.imageset/Contents.json new file mode 100644 index 000000000..26e1a3e74 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BN.imageset/BN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BN.imageset/BN.png new file mode 100644 index 000000000..be511ff4b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BN.imageset/BN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BN.imageset/Contents.json new file mode 100644 index 000000000..34cbe6f97 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BO.imageset/BO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BO.imageset/BO.png new file mode 100644 index 000000000..24f8988ed Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BO.imageset/BO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BO.imageset/Contents.json new file mode 100644 index 000000000..3e7312b5a --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BQ.imageset/BQ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BQ.imageset/BQ.png new file mode 100644 index 000000000..03a8b9014 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BQ.imageset/BQ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BQ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BQ.imageset/Contents.json new file mode 100644 index 000000000..d2992bae4 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BQ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BQ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BR.imageset/BR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BR.imageset/BR.png new file mode 100644 index 000000000..b6c7378a5 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BR.imageset/BR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BR.imageset/Contents.json new file mode 100644 index 000000000..2ae37df19 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BS.imageset/BS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BS.imageset/BS.png new file mode 100644 index 000000000..20c7b2cfd Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BS.imageset/BS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BS.imageset/Contents.json new file mode 100644 index 000000000..212c5ae25 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BT.imageset/BT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BT.imageset/BT.png new file mode 100644 index 000000000..cff987097 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BT.imageset/BT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BT.imageset/Contents.json new file mode 100644 index 000000000..094f2689b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BV.imageset/BV.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BV.imageset/BV.png new file mode 100644 index 000000000..3e2e2574d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BV.imageset/BV.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BV.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BV.imageset/Contents.json new file mode 100644 index 000000000..fbcd6059f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BV.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BV.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BW.imageset/BW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BW.imageset/BW.png new file mode 100644 index 000000000..8f9f01aa1 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BW.imageset/BW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BW.imageset/Contents.json new file mode 100644 index 000000000..438b202e6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BY.imageset/BY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BY.imageset/BY.png new file mode 100644 index 000000000..48395ccba Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BY.imageset/BY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BY.imageset/Contents.json new file mode 100644 index 000000000..4b01b65d9 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BZ.imageset/BZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/BZ.imageset/BZ.png new file mode 100644 index 000000000..71cc58c12 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/BZ.imageset/BZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/BZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/BZ.imageset/Contents.json new file mode 100644 index 000000000..2e67ff7e9 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/BZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "BZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CA.imageset/CA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CA.imageset/CA.png new file mode 100644 index 000000000..23a2d2c56 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CA.imageset/CA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CA.imageset/Contents.json new file mode 100644 index 000000000..1522805e6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CC.imageset/CC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CC.imageset/CC.png new file mode 100644 index 000000000..df42ca84d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CC.imageset/CC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CC.imageset/Contents.json new file mode 100644 index 000000000..385fc9fab --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CD.imageset/CD.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CD.imageset/CD.png new file mode 100644 index 000000000..f84c03d52 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CD.imageset/CD.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CD.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CD.imageset/Contents.json new file mode 100644 index 000000000..fa0d592ba --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CD.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CD.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CF.imageset/CF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CF.imageset/CF.png new file mode 100644 index 000000000..4a31ca751 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CF.imageset/CF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CF.imageset/Contents.json new file mode 100644 index 000000000..a455584af --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CG.imageset/CG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CG.imageset/CG.png new file mode 100644 index 000000000..26eda5957 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CG.imageset/CG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CG.imageset/Contents.json new file mode 100644 index 000000000..5b7d64107 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CH.imageset/CH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CH.imageset/CH.png new file mode 100644 index 000000000..17e8be20a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CH.imageset/CH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CH.imageset/Contents.json new file mode 100644 index 000000000..d1aa73aee --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CI.imageset/CI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CI.imageset/CI.png new file mode 100644 index 000000000..07c142a8f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CI.imageset/CI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CI.imageset/Contents.json new file mode 100644 index 000000000..ede8dd5ee --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CK.imageset/CK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CK.imageset/CK.png new file mode 100644 index 000000000..3b76baa02 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CK.imageset/CK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CK.imageset/Contents.json new file mode 100644 index 000000000..04f1311e4 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CL.imageset/CL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CL.imageset/CL.png new file mode 100644 index 000000000..013ada3bf Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CL.imageset/CL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CL.imageset/Contents.json new file mode 100644 index 000000000..271bb9447 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CM.imageset/CM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CM.imageset/CM.png new file mode 100644 index 000000000..0f7e7bdca Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CM.imageset/CM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CM.imageset/Contents.json new file mode 100644 index 000000000..300fa18d5 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CN.imageset/CN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CN.imageset/CN.png new file mode 100644 index 000000000..52e7bd215 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CN.imageset/CN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CN.imageset/Contents.json new file mode 100644 index 000000000..e0db21fe0 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CO.imageset/CO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CO.imageset/CO.png new file mode 100644 index 000000000..98150fa4c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CO.imageset/CO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CO.imageset/Contents.json new file mode 100644 index 000000000..10deaf273 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CR.imageset/CR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CR.imageset/CR.png new file mode 100644 index 000000000..ef20aa65e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CR.imageset/CR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CR.imageset/Contents.json new file mode 100644 index 000000000..f0155203e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CU.imageset/CU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CU.imageset/CU.png new file mode 100644 index 000000000..d6a4245bb Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CU.imageset/CU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CU.imageset/Contents.json new file mode 100644 index 000000000..e3221df44 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CV.imageset/CV.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CV.imageset/CV.png new file mode 100644 index 000000000..c0284c3c9 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CV.imageset/CV.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CV.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CV.imageset/Contents.json new file mode 100644 index 000000000..ff3fdce88 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CV.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CV.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CW.imageset/CW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CW.imageset/CW.png new file mode 100644 index 000000000..eb7dc2a09 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CW.imageset/CW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CW.imageset/Contents.json new file mode 100644 index 000000000..57b7fc3e1 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CX.imageset/CX.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CX.imageset/CX.png new file mode 100644 index 000000000..b65aaf2fa Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CX.imageset/CX.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CX.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CX.imageset/Contents.json new file mode 100644 index 000000000..7bfb325d1 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CX.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CX.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CY.imageset/CY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CY.imageset/CY.png new file mode 100644 index 000000000..3a23ac32f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CY.imageset/CY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CY.imageset/Contents.json new file mode 100644 index 000000000..f20814099 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CZ.imageset/CZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/CZ.imageset/CZ.png new file mode 100644 index 000000000..5e2312b9f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/CZ.imageset/CZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/CZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/CZ.imageset/Contents.json new file mode 100644 index 000000000..e283737ac --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/CZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "CZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/DE.imageset/Contents.json new file mode 100644 index 000000000..d254161c1 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/DE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "DE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DE.imageset/DE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/DE.imageset/DE.png new file mode 100644 index 000000000..dbd6c6f57 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/DE.imageset/DE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DJ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/DJ.imageset/Contents.json new file mode 100644 index 000000000..fce51167c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/DJ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "DJ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DJ.imageset/DJ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/DJ.imageset/DJ.png new file mode 100644 index 000000000..04b240cfa Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/DJ.imageset/DJ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/DK.imageset/Contents.json new file mode 100644 index 000000000..7e0272c59 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/DK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "DK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DK.imageset/DK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/DK.imageset/DK.png new file mode 100644 index 000000000..91eb5f0aa Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/DK.imageset/DK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/DM.imageset/Contents.json new file mode 100644 index 000000000..10110d484 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/DM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "DM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DM.imageset/DM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/DM.imageset/DM.png new file mode 100644 index 000000000..c314089ad Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/DM.imageset/DM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/DO.imageset/Contents.json new file mode 100644 index 000000000..c3887c593 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/DO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "DO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DO.imageset/DO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/DO.imageset/DO.png new file mode 100644 index 000000000..64a34ad78 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/DO.imageset/DO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/DZ.imageset/Contents.json new file mode 100644 index 000000000..dd8ce28f7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/DZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "DZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/DZ.imageset/DZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/DZ.imageset/DZ.png new file mode 100644 index 000000000..66903fbb7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/DZ.imageset/DZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/EC.imageset/Contents.json new file mode 100644 index 000000000..fae81869d --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/EC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "EC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EC.imageset/EC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/EC.imageset/EC.png new file mode 100644 index 000000000..dbb3b64e7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/EC.imageset/EC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/EE.imageset/Contents.json new file mode 100644 index 000000000..394429b61 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/EE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "EE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EE.imageset/EE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/EE.imageset/EE.png new file mode 100644 index 000000000..08b58af9c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/EE.imageset/EE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/EG.imageset/Contents.json new file mode 100644 index 000000000..6d5416d9f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/EG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "EG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EG.imageset/EG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/EG.imageset/EG.png new file mode 100644 index 000000000..af45a3d91 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/EG.imageset/EG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/EH.imageset/Contents.json new file mode 100644 index 000000000..f5be23f09 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/EH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "EH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/EH.imageset/EH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/EH.imageset/EH.png new file mode 100644 index 000000000..51b5865a5 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/EH.imageset/EH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ER.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ER.imageset/Contents.json new file mode 100644 index 000000000..1a056cec7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ER.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ER.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ER.imageset/ER.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ER.imageset/ER.png new file mode 100644 index 000000000..251c85275 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ER.imageset/ER.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ES.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ES.imageset/Contents.json new file mode 100644 index 000000000..7b4b640c8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ES.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ES.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ES.imageset/ES.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ES.imageset/ES.png new file mode 100644 index 000000000..252a1a2a7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ES.imageset/ES.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ET.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ET.imageset/Contents.json new file mode 100644 index 000000000..d7713eeec --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ET.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ET.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ET.imageset/ET.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ET.imageset/ET.png new file mode 100644 index 000000000..2e14448ac Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ET.imageset/ET.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/FI.imageset/Contents.json new file mode 100644 index 000000000..309808a8c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/FI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "FI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FI.imageset/FI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/FI.imageset/FI.png new file mode 100644 index 000000000..6d873cc2e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/FI.imageset/FI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FJ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/FJ.imageset/Contents.json new file mode 100644 index 000000000..0fbd61e16 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/FJ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "FJ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FJ.imageset/FJ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/FJ.imageset/FJ.png new file mode 100644 index 000000000..cf68e4c47 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/FJ.imageset/FJ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/FK.imageset/Contents.json new file mode 100644 index 000000000..e8ff444d0 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/FK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "FK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FK.imageset/FK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/FK.imageset/FK.png new file mode 100644 index 000000000..dfc3842d5 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/FK.imageset/FK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/FM.imageset/Contents.json new file mode 100644 index 000000000..61225e893 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/FM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "FM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FM.imageset/FM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/FM.imageset/FM.png new file mode 100644 index 000000000..ea395b42c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/FM.imageset/FM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/FO.imageset/Contents.json new file mode 100644 index 000000000..da24b0116 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/FO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "FO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FO.imageset/FO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/FO.imageset/FO.png new file mode 100644 index 000000000..0854ce563 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/FO.imageset/FO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/FR.imageset/Contents.json new file mode 100644 index 000000000..ff2855b4f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/FR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "FR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FR.imageset/FR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/FR.imageset/FR.png new file mode 100644 index 000000000..a1b465e7e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/FR.imageset/FR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FX.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/FX.imageset/Contents.json new file mode 100644 index 000000000..01ea61d3c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/FX.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "FX.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/FX.imageset/FX.png b/KarhooUISDK/Assets/CountryFlags.xcassets/FX.imageset/FX.png new file mode 100644 index 000000000..a1b465e7e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/FX.imageset/FX.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GA.imageset/Contents.json new file mode 100644 index 000000000..8a998926a --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GA.imageset/GA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GA.imageset/GA.png new file mode 100644 index 000000000..05fd0b1d9 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GA.imageset/GA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GB.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GB.imageset/Contents.json new file mode 100644 index 000000000..301823e8e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GB.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GB.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GB.imageset/GB.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GB.imageset/GB.png new file mode 100644 index 000000000..d76832cc7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GB.imageset/GB.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GD.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GD.imageset/Contents.json new file mode 100644 index 000000000..03f040878 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GD.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GD.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GD.imageset/GD.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GD.imageset/GD.png new file mode 100644 index 000000000..c9077a85e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GD.imageset/GD.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GE.imageset/Contents.json new file mode 100644 index 000000000..97a5ee8ec --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GE.imageset/GE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GE.imageset/GE.png new file mode 100644 index 000000000..8d8680c8f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GE.imageset/GE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GF.imageset/Contents.json new file mode 100644 index 000000000..f19939cf4 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GF.imageset/GF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GF.imageset/GF.png new file mode 100644 index 000000000..45d00a255 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GF.imageset/GF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GG.imageset/Contents.json new file mode 100644 index 000000000..e401e0ca3 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GG.imageset/GG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GG.imageset/GG.png new file mode 100644 index 000000000..06192d355 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GG.imageset/GG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GH.imageset/Contents.json new file mode 100644 index 000000000..2416cd801 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GH.imageset/GH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GH.imageset/GH.png new file mode 100644 index 000000000..486a61562 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GH.imageset/GH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GI.imageset/Contents.json new file mode 100644 index 000000000..214d5f0da --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GI.imageset/GI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GI.imageset/GI.png new file mode 100644 index 000000000..b2300cce4 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GI.imageset/GI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GL.imageset/Contents.json new file mode 100644 index 000000000..c44dddc51 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GL.imageset/GL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GL.imageset/GL.png new file mode 100644 index 000000000..4088cbca7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GL.imageset/GL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GM.imageset/Contents.json new file mode 100644 index 000000000..5a2c7dc67 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GM.imageset/GM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GM.imageset/GM.png new file mode 100644 index 000000000..ab693d1f1 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GM.imageset/GM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GN.imageset/Contents.json new file mode 100644 index 000000000..c46e0e47b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GN.imageset/GN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GN.imageset/GN.png new file mode 100644 index 000000000..d49ef4f46 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GN.imageset/GN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GP.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GP.imageset/Contents.json new file mode 100644 index 000000000..04e83287e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GP.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GP.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GP.imageset/GP.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GP.imageset/GP.png new file mode 100644 index 000000000..a1b465e7e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GP.imageset/GP.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GQ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GQ.imageset/Contents.json new file mode 100644 index 000000000..f3d80e6ca --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GQ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GQ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GQ.imageset/GQ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GQ.imageset/GQ.png new file mode 100644 index 000000000..fd35eb4b2 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GQ.imageset/GQ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GR.imageset/Contents.json new file mode 100644 index 000000000..26cf09d82 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GR.imageset/GR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GR.imageset/GR.png new file mode 100644 index 000000000..c79b2aafa Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GR.imageset/GR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GS.imageset/Contents.json new file mode 100644 index 000000000..dd1615c9c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GS.imageset/GS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GS.imageset/GS.png new file mode 100644 index 000000000..3b0380438 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GS.imageset/GS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GT.imageset/Contents.json new file mode 100644 index 000000000..d57deaa1c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GT.imageset/GT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GT.imageset/GT.png new file mode 100644 index 000000000..07d19b7f8 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GT.imageset/GT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GU.imageset/Contents.json new file mode 100644 index 000000000..c65b7bb5d --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GU.imageset/GU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GU.imageset/GU.png new file mode 100644 index 000000000..81dfbbd8d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GU.imageset/GU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GW.imageset/Contents.json new file mode 100644 index 000000000..3e6d5243f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GW.imageset/GW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GW.imageset/GW.png new file mode 100644 index 000000000..204314c1a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GW.imageset/GW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/GY.imageset/Contents.json new file mode 100644 index 000000000..9b14d4132 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/GY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "GY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/GY.imageset/GY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/GY.imageset/GY.png new file mode 100644 index 000000000..e0af75032 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/GY.imageset/GY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/HK.imageset/Contents.json new file mode 100644 index 000000000..de372de2c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/HK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "HK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HK.imageset/HK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/HK.imageset/HK.png new file mode 100644 index 000000000..fb259993e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/HK.imageset/HK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/HM.imageset/Contents.json new file mode 100644 index 000000000..043b59055 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/HM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "HM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HM.imageset/HM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/HM.imageset/HM.png new file mode 100644 index 000000000..bc5801a5b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/HM.imageset/HM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/HN.imageset/Contents.json new file mode 100644 index 000000000..70f5e8dcd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/HN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "HN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HN.imageset/HN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/HN.imageset/HN.png new file mode 100644 index 000000000..3d969014b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/HN.imageset/HN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/HR.imageset/Contents.json new file mode 100644 index 000000000..844a05db8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/HR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "HR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HR.imageset/HR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/HR.imageset/HR.png new file mode 100644 index 000000000..89f8f339e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/HR.imageset/HR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/HT.imageset/Contents.json new file mode 100644 index 000000000..9e4445e2e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/HT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "HT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HT.imageset/HT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/HT.imageset/HT.png new file mode 100644 index 000000000..ef823a4c5 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/HT.imageset/HT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/HU.imageset/Contents.json new file mode 100644 index 000000000..f3be8f8c9 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/HU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "HU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/HU.imageset/HU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/HU.imageset/HU.png new file mode 100644 index 000000000..099832a55 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/HU.imageset/HU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ID.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ID.imageset/Contents.json new file mode 100644 index 000000000..186c4f8bc --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ID.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ID.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ID.imageset/ID.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ID.imageset/ID.png new file mode 100644 index 000000000..cdcd1ee80 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ID.imageset/ID.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IE.imageset/Contents.json new file mode 100644 index 000000000..e2c4dd53b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IE.imageset/IE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IE.imageset/IE.png new file mode 100644 index 000000000..60d547c1f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IE.imageset/IE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IL.imageset/Contents.json new file mode 100644 index 000000000..8819b34b8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IL.imageset/IL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IL.imageset/IL.png new file mode 100644 index 000000000..46b44d1d0 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IL.imageset/IL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IM.imageset/Contents.json new file mode 100644 index 000000000..39f01c287 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IM.imageset/IM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IM.imageset/IM.png new file mode 100644 index 000000000..212501841 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IM.imageset/IM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IN.imageset/Contents.json new file mode 100644 index 000000000..27baccfa6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IN.imageset/IN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IN.imageset/IN.png new file mode 100644 index 000000000..e6b44fd1f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IN.imageset/IN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IO.imageset/Contents.json new file mode 100644 index 000000000..b424be271 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IO.imageset/IO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IO.imageset/IO.png new file mode 100644 index 000000000..a04fcd1fd Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IO.imageset/IO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IQ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IQ.imageset/Contents.json new file mode 100644 index 000000000..4b7755c9c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IQ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IQ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IQ.imageset/IQ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IQ.imageset/IQ.png new file mode 100644 index 000000000..2b26888e5 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IQ.imageset/IQ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IR.imageset/Contents.json new file mode 100644 index 000000000..9e4b31415 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IR.imageset/IR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IR.imageset/IR.png new file mode 100644 index 000000000..15a176326 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IR.imageset/IR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IS.imageset/Contents.json new file mode 100644 index 000000000..50ba17f7b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IS.imageset/IS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IS.imageset/IS.png new file mode 100644 index 000000000..cf8252814 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IS.imageset/IS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/IT.imageset/Contents.json new file mode 100644 index 000000000..b79fad20b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/IT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/IT.imageset/IT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/IT.imageset/IT.png new file mode 100644 index 000000000..b96a113c7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/IT.imageset/IT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/JE.imageset/Contents.json new file mode 100644 index 000000000..d28bbb30d --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/JE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "JE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JE.imageset/JE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/JE.imageset/JE.png new file mode 100644 index 000000000..d6072444e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/JE.imageset/JE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/JM.imageset/Contents.json new file mode 100644 index 000000000..a050d3300 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/JM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "JM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JM.imageset/JM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/JM.imageset/JM.png new file mode 100644 index 000000000..404f1847a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/JM.imageset/JM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/JO.imageset/Contents.json new file mode 100644 index 000000000..180e5d20b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/JO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "JO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JO.imageset/JO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/JO.imageset/JO.png new file mode 100644 index 000000000..7b59be816 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/JO.imageset/JO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JP.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/JP.imageset/Contents.json new file mode 100644 index 000000000..5c7ecb4bd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/JP.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "JP.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/JP.imageset/JP.png b/KarhooUISDK/Assets/CountryFlags.xcassets/JP.imageset/JP.png new file mode 100644 index 000000000..f193e2a7e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/JP.imageset/JP.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KE.imageset/Contents.json new file mode 100644 index 000000000..a8efc277b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KE.imageset/KE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KE.imageset/KE.png new file mode 100644 index 000000000..0db6cbb23 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KE.imageset/KE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KG.imageset/Contents.json new file mode 100644 index 000000000..de29a2adf --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KG.imageset/KG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KG.imageset/KG.png new file mode 100644 index 000000000..7c6a1b571 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KG.imageset/KG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KH.imageset/Contents.json new file mode 100644 index 000000000..24f97ede6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KH.imageset/KH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KH.imageset/KH.png new file mode 100644 index 000000000..50bfdf502 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KH.imageset/KH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KI.imageset/Contents.json new file mode 100644 index 000000000..c6de91e95 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KI.imageset/KI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KI.imageset/KI.png new file mode 100644 index 000000000..0d4c4d3cf Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KI.imageset/KI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KM.imageset/Contents.json new file mode 100644 index 000000000..a202a746f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KM.imageset/KM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KM.imageset/KM.png new file mode 100644 index 000000000..3ad3741df Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KM.imageset/KM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KN.imageset/Contents.json new file mode 100644 index 000000000..c4856cc9f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KN.imageset/KN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KN.imageset/KN.png new file mode 100644 index 000000000..2c4bf7919 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KN.imageset/KN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KP.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KP.imageset/Contents.json new file mode 100644 index 000000000..f67545bb5 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KP.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KP.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KP.imageset/KP.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KP.imageset/KP.png new file mode 100644 index 000000000..1cd8b1143 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KP.imageset/KP.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KR.imageset/Contents.json new file mode 100644 index 000000000..1fb47d035 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KR.imageset/KR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KR.imageset/KR.png new file mode 100644 index 000000000..290c26af9 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KR.imageset/KR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KW.imageset/Contents.json new file mode 100644 index 000000000..d2ae65c54 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KW.imageset/KW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KW.imageset/KW.png new file mode 100644 index 000000000..030ba5d1b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KW.imageset/KW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KY.imageset/Contents.json new file mode 100644 index 000000000..b706e8f43 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KY.imageset/KY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KY.imageset/KY.png new file mode 100644 index 000000000..a6fda222a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KY.imageset/KY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/KZ.imageset/Contents.json new file mode 100644 index 000000000..13ad4d9a2 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/KZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "KZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/KZ.imageset/KZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/KZ.imageset/KZ.png new file mode 100644 index 000000000..ea0419b8a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/KZ.imageset/KZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LA.imageset/Contents.json new file mode 100644 index 000000000..0ae52c412 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LA.imageset/LA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LA.imageset/LA.png new file mode 100644 index 000000000..d6d06532b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LA.imageset/LA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LB.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LB.imageset/Contents.json new file mode 100644 index 000000000..764e567ef --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LB.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LB.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LB.imageset/LB.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LB.imageset/LB.png new file mode 100644 index 000000000..c78aa2a41 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LB.imageset/LB.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LC.imageset/Contents.json new file mode 100644 index 000000000..fa23a5e88 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LC.imageset/LC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LC.imageset/LC.png new file mode 100644 index 000000000..5b1e65d07 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LC.imageset/LC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LI.imageset/Contents.json new file mode 100644 index 000000000..4b63398a4 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LI.imageset/LI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LI.imageset/LI.png new file mode 100644 index 000000000..3c25cd460 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LI.imageset/LI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LK.imageset/Contents.json new file mode 100644 index 000000000..cb9829125 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LK.imageset/LK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LK.imageset/LK.png new file mode 100644 index 000000000..7e64f3774 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LK.imageset/LK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LR.imageset/Contents.json new file mode 100644 index 000000000..018354b60 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LR.imageset/LR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LR.imageset/LR.png new file mode 100644 index 000000000..9fff081da Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LR.imageset/LR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LS.imageset/Contents.json new file mode 100644 index 000000000..64b5f9ef3 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LS.imageset/LS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LS.imageset/LS.png new file mode 100644 index 000000000..29d1f8ec2 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LS.imageset/LS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LT.imageset/Contents.json new file mode 100644 index 000000000..3a8e32368 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LT.imageset/LT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LT.imageset/LT.png new file mode 100644 index 000000000..17b24e8e8 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LT.imageset/LT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LU.imageset/Contents.json new file mode 100644 index 000000000..b3e82ac32 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LU.imageset/LU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LU.imageset/LU.png new file mode 100644 index 000000000..f65afc446 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LU.imageset/LU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LV.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LV.imageset/Contents.json new file mode 100644 index 000000000..0e8011ca9 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LV.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LV.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LV.imageset/LV.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LV.imageset/LV.png new file mode 100644 index 000000000..ae1ef3155 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LV.imageset/LV.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/LY.imageset/Contents.json new file mode 100644 index 000000000..2959217f8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/LY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/LY.imageset/LY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/LY.imageset/LY.png new file mode 100644 index 000000000..d10c50802 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/LY.imageset/LY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MA.imageset/Contents.json new file mode 100644 index 000000000..a7ba53747 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MA.imageset/MA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MA.imageset/MA.png new file mode 100644 index 000000000..9a84993b8 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MA.imageset/MA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MC.imageset/Contents.json new file mode 100644 index 000000000..c63cc2408 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MC.imageset/MC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MC.imageset/MC.png new file mode 100644 index 000000000..b0d8ce049 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MC.imageset/MC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MD.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MD.imageset/Contents.json new file mode 100644 index 000000000..e0fa1f36c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MD.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MD.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MD.imageset/MD.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MD.imageset/MD.png new file mode 100644 index 000000000..01a670ab7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MD.imageset/MD.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ME.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ME.imageset/Contents.json new file mode 100644 index 000000000..945066faf --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ME.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ME.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ME.imageset/ME.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ME.imageset/ME.png new file mode 100644 index 000000000..68471a26b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ME.imageset/ME.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MF.imageset/Contents.json new file mode 100644 index 000000000..0b69d1d51 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MF.imageset/MF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MF.imageset/MF.png new file mode 100644 index 000000000..a623b52cd Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MF.imageset/MF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MG.imageset/Contents.json new file mode 100644 index 000000000..fad6fa1d7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MG.imageset/MG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MG.imageset/MG.png new file mode 100644 index 000000000..5949eb7d6 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MG.imageset/MG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MH.imageset/Contents.json new file mode 100644 index 000000000..c8f013a4a --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MH.imageset/MH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MH.imageset/MH.png new file mode 100644 index 000000000..e90e5d4cb Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MH.imageset/MH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MK.imageset/Contents.json new file mode 100644 index 000000000..1ea0ed472 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MK.imageset/MK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MK.imageset/MK.png new file mode 100644 index 000000000..f40eb914e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MK.imageset/MK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ML.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ML.imageset/Contents.json new file mode 100644 index 000000000..b12a8c0b3 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ML.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ML.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ML.imageset/ML.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ML.imageset/ML.png new file mode 100644 index 000000000..fb1008e17 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ML.imageset/ML.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MM.imageset/Contents.json new file mode 100644 index 000000000..7b3463e23 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MM.imageset/MM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MM.imageset/MM.png new file mode 100644 index 000000000..b8e68c40c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MM.imageset/MM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MN.imageset/Contents.json new file mode 100644 index 000000000..facf254b7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MN.imageset/MN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MN.imageset/MN.png new file mode 100644 index 000000000..033e171a4 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MN.imageset/MN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MO.imageset/Contents.json new file mode 100644 index 000000000..382086fc8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MO.imageset/MO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MO.imageset/MO.png new file mode 100644 index 000000000..dc9884eff Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MO.imageset/MO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MP.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MP.imageset/Contents.json new file mode 100644 index 000000000..3baded746 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MP.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MP.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MP.imageset/MP.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MP.imageset/MP.png new file mode 100644 index 000000000..7fd0c1c78 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MP.imageset/MP.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MQ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MQ.imageset/Contents.json new file mode 100644 index 000000000..963ca38b0 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MQ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MQ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MQ.imageset/MQ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MQ.imageset/MQ.png new file mode 100644 index 000000000..3b2d0e443 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MQ.imageset/MQ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MR.imageset/Contents.json new file mode 100644 index 000000000..6ea52995c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MR.imageset/MR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MR.imageset/MR.png new file mode 100644 index 000000000..87dbda79a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MR.imageset/MR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MS.imageset/Contents.json new file mode 100644 index 000000000..77a8aa64e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MS.imageset/MS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MS.imageset/MS.png new file mode 100644 index 000000000..cb79c7c2d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MS.imageset/MS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MT.imageset/Contents.json new file mode 100644 index 000000000..49e0c8531 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MT.imageset/MT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MT.imageset/MT.png new file mode 100644 index 000000000..e83ad8be1 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MT.imageset/MT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MU.imageset/Contents.json new file mode 100644 index 000000000..ea63118d8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MU.imageset/MU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MU.imageset/MU.png new file mode 100644 index 000000000..c52a00c0e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MU.imageset/MU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MV.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MV.imageset/Contents.json new file mode 100644 index 000000000..5a4fe2447 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MV.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MV.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MV.imageset/MV.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MV.imageset/MV.png new file mode 100644 index 000000000..2b64dd88d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MV.imageset/MV.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MW.imageset/Contents.json new file mode 100644 index 000000000..26f057baf --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MW.imageset/MW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MW.imageset/MW.png new file mode 100644 index 000000000..b18b8add6 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MW.imageset/MW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MX.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MX.imageset/Contents.json new file mode 100644 index 000000000..f2b4949a8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MX.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MX.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MX.imageset/MX.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MX.imageset/MX.png new file mode 100644 index 000000000..a03ce2e72 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MX.imageset/MX.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MY.imageset/Contents.json new file mode 100644 index 000000000..c8bd28695 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MY.imageset/MY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MY.imageset/MY.png new file mode 100644 index 000000000..1e118db09 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MY.imageset/MY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/MZ.imageset/Contents.json new file mode 100644 index 000000000..9da831c9f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/MZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "MZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/MZ.imageset/MZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/MZ.imageset/MZ.png new file mode 100644 index 000000000..fad9bd047 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/MZ.imageset/MZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NA.imageset/Contents.json new file mode 100644 index 000000000..5ef71b1ad --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NA.imageset/NA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NA.imageset/NA.png new file mode 100644 index 000000000..19adad0b0 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NA.imageset/NA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NC.imageset/Contents.json new file mode 100644 index 000000000..0225219c0 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NC.imageset/NC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NC.imageset/NC.png new file mode 100644 index 000000000..3058c521b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NC.imageset/NC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NE.imageset/Contents.json new file mode 100644 index 000000000..c8bd0018a --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NE.imageset/NE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NE.imageset/NE.png new file mode 100644 index 000000000..26607c2f0 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NE.imageset/NE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NF.imageset/Contents.json new file mode 100644 index 000000000..ac35807ed --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NF.imageset/NF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NF.imageset/NF.png new file mode 100644 index 000000000..89e37a3c4 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NF.imageset/NF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NG.imageset/Contents.json new file mode 100644 index 000000000..9dfeb45f7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NG.imageset/NG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NG.imageset/NG.png new file mode 100644 index 000000000..6f8b3acf2 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NG.imageset/NG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NI.imageset/Contents.json new file mode 100644 index 000000000..7b7b34f23 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NI.imageset/NI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NI.imageset/NI.png new file mode 100644 index 000000000..ab3034741 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NI.imageset/NI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NL.imageset/Contents.json new file mode 100644 index 000000000..a41e91fff --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NL.imageset/NL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NL.imageset/NL.png new file mode 100644 index 000000000..bf0b5d0ff Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NL.imageset/NL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NO.imageset/Contents.json new file mode 100644 index 000000000..323a25248 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NO.imageset/NO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NO.imageset/NO.png new file mode 100644 index 000000000..f05434843 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NO.imageset/NO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NP.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NP.imageset/Contents.json new file mode 100644 index 000000000..5dc595fe5 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NP.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NP.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NP.imageset/NP.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NP.imageset/NP.png new file mode 100644 index 000000000..4ef7f643f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NP.imageset/NP.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NR.imageset/Contents.json new file mode 100644 index 000000000..c8fbb3473 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NR.imageset/NR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NR.imageset/NR.png new file mode 100644 index 000000000..b2e1495cc Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NR.imageset/NR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NU.imageset/Contents.json new file mode 100644 index 000000000..e45f0dc2e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NU.imageset/NU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NU.imageset/NU.png new file mode 100644 index 000000000..8ce9bc3e9 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NU.imageset/NU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/NZ.imageset/Contents.json new file mode 100644 index 000000000..2948582bf --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/NZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "NZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/NZ.imageset/NZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/NZ.imageset/NZ.png new file mode 100644 index 000000000..af1f796de Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/NZ.imageset/NZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/OM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/OM.imageset/Contents.json new file mode 100644 index 000000000..f4960144b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/OM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "OM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/OM.imageset/OM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/OM.imageset/OM.png new file mode 100644 index 000000000..cab806a84 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/OM.imageset/OM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PA.imageset/Contents.json new file mode 100644 index 000000000..fed864864 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PA.imageset/PA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PA.imageset/PA.png new file mode 100644 index 000000000..e227ef37b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PA.imageset/PA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PE.imageset/Contents.json new file mode 100644 index 000000000..634b85e81 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PE.imageset/PE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PE.imageset/PE.png new file mode 100644 index 000000000..4bf87bc23 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PE.imageset/PE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PF.imageset/Contents.json new file mode 100644 index 000000000..1f0d77666 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PF.imageset/PF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PF.imageset/PF.png new file mode 100644 index 000000000..5712da507 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PF.imageset/PF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PG.imageset/Contents.json new file mode 100644 index 000000000..910c1f1ce --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PG.imageset/PG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PG.imageset/PG.png new file mode 100644 index 000000000..6cd9b229f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PG.imageset/PG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PH.imageset/Contents.json new file mode 100644 index 000000000..9f6243a5f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PH.imageset/PH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PH.imageset/PH.png new file mode 100644 index 000000000..56ed130ef Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PH.imageset/PH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PK.imageset/Contents.json new file mode 100644 index 000000000..eb2030553 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PK.imageset/PK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PK.imageset/PK.png new file mode 100644 index 000000000..ab7fcf2ed Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PK.imageset/PK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PL.imageset/Contents.json new file mode 100644 index 000000000..50fb11d61 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PL.imageset/PL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PL.imageset/PL.png new file mode 100644 index 000000000..524f9fb29 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PL.imageset/PL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PM.imageset/Contents.json new file mode 100644 index 000000000..4b3b2c500 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PM.imageset/PM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PM.imageset/PM.png new file mode 100644 index 000000000..99e92140e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PM.imageset/PM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PN.imageset/Contents.json new file mode 100644 index 000000000..f330452b2 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PN.imageset/PN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PN.imageset/PN.png new file mode 100644 index 000000000..d8dc46bea Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PN.imageset/PN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PR.imageset/Contents.json new file mode 100644 index 000000000..208fd7cc1 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PR.imageset/PR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PR.imageset/PR.png new file mode 100644 index 000000000..2ede5086c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PR.imageset/PR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PS.imageset/Contents.json new file mode 100644 index 000000000..881aff162 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PS.imageset/PS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PS.imageset/PS.png new file mode 100644 index 000000000..0aef52ce3 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PS.imageset/PS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PT.imageset/Contents.json new file mode 100644 index 000000000..a165d4948 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PT.imageset/PT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PT.imageset/PT.png new file mode 100644 index 000000000..8af7a7bf7 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PT.imageset/PT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PW.imageset/Contents.json new file mode 100644 index 000000000..9d2fcfb9e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PW.imageset/PW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PW.imageset/PW.png new file mode 100644 index 000000000..8b0cfe22e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PW.imageset/PW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/PY.imageset/Contents.json new file mode 100644 index 000000000..645030185 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/PY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "PY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/PY.imageset/PY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/PY.imageset/PY.png new file mode 100644 index 000000000..c42b41f08 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/PY.imageset/PY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/QA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/QA.imageset/Contents.json new file mode 100644 index 000000000..bfb3c0cd6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/QA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "QA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/QA.imageset/QA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/QA.imageset/QA.png new file mode 100644 index 000000000..406f6a2cb Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/QA.imageset/QA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/RE.imageset/Contents.json new file mode 100644 index 000000000..d87fc416e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/RE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "RE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RE.imageset/RE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/RE.imageset/RE.png new file mode 100644 index 000000000..ae052412d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/RE.imageset/RE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/RO.imageset/Contents.json new file mode 100644 index 000000000..2df768d29 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/RO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "RO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RO.imageset/RO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/RO.imageset/RO.png new file mode 100644 index 000000000..8f6d4e418 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/RO.imageset/RO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/RS.imageset/Contents.json new file mode 100644 index 000000000..3c5a742ab --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/RS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "RS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RS.imageset/RS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/RS.imageset/RS.png new file mode 100644 index 000000000..c57193237 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/RS.imageset/RS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/RU.imageset/Contents.json new file mode 100644 index 000000000..548b04fd5 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/RU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "RU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RU.imageset/RU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/RU.imageset/RU.png new file mode 100644 index 000000000..77f218530 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/RU.imageset/RU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/RW.imageset/Contents.json new file mode 100644 index 000000000..dd63a9219 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/RW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "RW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/RW.imageset/RW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/RW.imageset/RW.png new file mode 100644 index 000000000..5d78fde99 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/RW.imageset/RW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SA.imageset/Contents.json new file mode 100644 index 000000000..4c37672a2 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SA.imageset/SA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SA.imageset/SA.png new file mode 100644 index 000000000..f3ad3a14a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SA.imageset/SA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SB.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SB.imageset/Contents.json new file mode 100644 index 000000000..f59f4650a --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SB.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SB.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SB.imageset/SB.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SB.imageset/SB.png new file mode 100644 index 000000000..7152c215c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SB.imageset/SB.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SC.imageset/Contents.json new file mode 100644 index 000000000..95c0f418e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SC.imageset/SC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SC.imageset/SC.png new file mode 100644 index 000000000..f8d876d2a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SC.imageset/SC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SD.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SD.imageset/Contents.json new file mode 100644 index 000000000..2488fd446 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SD.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SD.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SD.imageset/SD.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SD.imageset/SD.png new file mode 100644 index 000000000..1a6e1638e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SD.imageset/SD.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SE.imageset/Contents.json new file mode 100644 index 000000000..f67d07cfd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SE.imageset/SE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SE.imageset/SE.png new file mode 100644 index 000000000..96d92623a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SE.imageset/SE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SG.imageset/Contents.json new file mode 100644 index 000000000..193ab1e2f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SG.imageset/SG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SG.imageset/SG.png new file mode 100644 index 000000000..89f71a7e8 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SG.imageset/SG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SH.imageset/Contents.json new file mode 100644 index 000000000..66fd7f9fa --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SH.imageset/SH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SH.imageset/SH.png new file mode 100644 index 000000000..49131de92 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SH.imageset/SH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SI.imageset/Contents.json new file mode 100644 index 000000000..3a9985dbd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SI.imageset/SI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SI.imageset/SI.png new file mode 100644 index 000000000..4e33a9ddc Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SI.imageset/SI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SJ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SJ.imageset/Contents.json new file mode 100644 index 000000000..501850703 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SJ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SJ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SJ.imageset/SJ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SJ.imageset/SJ.png new file mode 100644 index 000000000..1272aed32 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SJ.imageset/SJ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SK.imageset/Contents.json new file mode 100644 index 000000000..81ca433fd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SK.imageset/SK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SK.imageset/SK.png new file mode 100644 index 000000000..f651cfd99 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SK.imageset/SK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SL.imageset/Contents.json new file mode 100644 index 000000000..b61ac0d5c --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SL.imageset/SL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SL.imageset/SL.png new file mode 100644 index 000000000..bf5f98c1a Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SL.imageset/SL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SM.imageset/Contents.json new file mode 100644 index 000000000..e369fd0dd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SM.imageset/SM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SM.imageset/SM.png new file mode 100644 index 000000000..87aadb014 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SM.imageset/SM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SN.imageset/Contents.json new file mode 100644 index 000000000..fdb19ca5b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SN.imageset/SN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SN.imageset/SN.png new file mode 100644 index 000000000..a8ffca6b9 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SN.imageset/SN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SO.imageset/Contents.json new file mode 100644 index 000000000..932f9c468 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SO.imageset/SO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SO.imageset/SO.png new file mode 100644 index 000000000..5fd24408c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SO.imageset/SO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SR.imageset/Contents.json new file mode 100644 index 000000000..3a311de18 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SR.imageset/SR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SR.imageset/SR.png new file mode 100644 index 000000000..93c941e70 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SR.imageset/SR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SS.imageset/Contents.json new file mode 100644 index 000000000..b3d2464ce --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SS.imageset/SS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SS.imageset/SS.png new file mode 100644 index 000000000..1b5c0ba9c Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SS.imageset/SS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ST.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ST.imageset/Contents.json new file mode 100644 index 000000000..6b471b35f --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ST.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ST.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ST.imageset/ST.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ST.imageset/ST.png new file mode 100644 index 000000000..2bb71e759 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ST.imageset/ST.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SV.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SV.imageset/Contents.json new file mode 100644 index 000000000..437428a56 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SV.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SV.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SV.imageset/SV.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SV.imageset/SV.png new file mode 100644 index 000000000..8579b9639 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SV.imageset/SV.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SX.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SX.imageset/Contents.json new file mode 100644 index 000000000..746ba0894 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SX.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SX.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SX.imageset/SX.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SX.imageset/SX.png new file mode 100644 index 000000000..5a680e936 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SX.imageset/SX.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SY.imageset/Contents.json new file mode 100644 index 000000000..2d4eb9f24 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SY.imageset/SY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SY.imageset/SY.png new file mode 100644 index 000000000..1373cfb31 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SY.imageset/SY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/SZ.imageset/Contents.json new file mode 100644 index 000000000..ad6c083af --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/SZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "SZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/SZ.imageset/SZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/SZ.imageset/SZ.png new file mode 100644 index 000000000..9ee14e85f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/SZ.imageset/SZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TC.imageset/Contents.json new file mode 100644 index 000000000..47ebe62a6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TC.imageset/TC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TC.imageset/TC.png new file mode 100644 index 000000000..d9df358a1 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TC.imageset/TC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TD.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TD.imageset/Contents.json new file mode 100644 index 000000000..67554ba4d --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TD.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TD.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TD.imageset/TD.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TD.imageset/TD.png new file mode 100644 index 000000000..3b32e7937 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TD.imageset/TD.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TF.imageset/Contents.json new file mode 100644 index 000000000..b4aa5f209 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TF.imageset/TF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TF.imageset/TF.png new file mode 100644 index 000000000..5b274bb8d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TF.imageset/TF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TG.imageset/Contents.json new file mode 100644 index 000000000..7a06a1785 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TG.imageset/TG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TG.imageset/TG.png new file mode 100644 index 000000000..709afeb91 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TG.imageset/TG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TH.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TH.imageset/Contents.json new file mode 100644 index 000000000..b1a74ade7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TH.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TH.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TH.imageset/TH.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TH.imageset/TH.png new file mode 100644 index 000000000..6caf126ca Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TH.imageset/TH.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TJ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TJ.imageset/Contents.json new file mode 100644 index 000000000..0612ca250 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TJ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TJ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TJ.imageset/TJ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TJ.imageset/TJ.png new file mode 100644 index 000000000..968f5d44b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TJ.imageset/TJ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TK.imageset/Contents.json new file mode 100644 index 000000000..8f4ea13a6 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TK.imageset/TK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TK.imageset/TK.png new file mode 100644 index 000000000..3f2c0541b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TK.imageset/TK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TL.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TL.imageset/Contents.json new file mode 100644 index 000000000..cfb4574ad --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TL.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TL.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TL.imageset/TL.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TL.imageset/TL.png new file mode 100644 index 000000000..8dbb1c739 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TL.imageset/TL.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TM.imageset/Contents.json new file mode 100644 index 000000000..bdee49569 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TM.imageset/TM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TM.imageset/TM.png new file mode 100644 index 000000000..770c30a8d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TM.imageset/TM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TN.imageset/Contents.json new file mode 100644 index 000000000..4535827d4 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TN.imageset/TN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TN.imageset/TN.png new file mode 100644 index 000000000..1a5008808 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TN.imageset/TN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TO.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TO.imageset/Contents.json new file mode 100644 index 000000000..354c368f7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TO.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TO.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TO.imageset/TO.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TO.imageset/TO.png new file mode 100644 index 000000000..2b40e54fb Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TO.imageset/TO.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TR.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TR.imageset/Contents.json new file mode 100644 index 000000000..0052cbc6a --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TR.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TR.imageset/TR.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TR.imageset/TR.png new file mode 100644 index 000000000..6216d1d3e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TR.imageset/TR.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TT.imageset/Contents.json new file mode 100644 index 000000000..299ae90a4 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TT.imageset/TT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TT.imageset/TT.png new file mode 100644 index 000000000..0c9a40d7f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TT.imageset/TT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TV.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TV.imageset/Contents.json new file mode 100644 index 000000000..69d991784 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TV.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TV.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TV.imageset/TV.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TV.imageset/TV.png new file mode 100644 index 000000000..4c0e6f057 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TV.imageset/TV.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TW.imageset/Contents.json new file mode 100644 index 000000000..fda724cba --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TW.imageset/TW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TW.imageset/TW.png new file mode 100644 index 000000000..799a4a0b9 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TW.imageset/TW.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/TZ.imageset/Contents.json new file mode 100644 index 000000000..ca79f4ce3 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/TZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "TZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/TZ.imageset/TZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/TZ.imageset/TZ.png new file mode 100644 index 000000000..1fe02149f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/TZ.imageset/TZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/UA.imageset/Contents.json new file mode 100644 index 000000000..9a03d3e92 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/UA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "UA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UA.imageset/UA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/UA.imageset/UA.png new file mode 100644 index 000000000..16f917d81 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/UA.imageset/UA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/UG.imageset/Contents.json new file mode 100644 index 000000000..2cfb91d57 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/UG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "UG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UG.imageset/UG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/UG.imageset/UG.png new file mode 100644 index 000000000..a1d295171 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/UG.imageset/UG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/UM.imageset/Contents.json new file mode 100644 index 000000000..87d458310 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/UM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "UM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UM.imageset/UM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/UM.imageset/UM.png new file mode 100644 index 000000000..4a2e2940d Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/UM.imageset/UM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/US.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/US.imageset/Contents.json new file mode 100644 index 000000000..f9a3986eb --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/US.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "US.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/US.imageset/US.png b/KarhooUISDK/Assets/CountryFlags.xcassets/US.imageset/US.png new file mode 100644 index 000000000..9521fe9db Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/US.imageset/US.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UY.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/UY.imageset/Contents.json new file mode 100644 index 000000000..825978e74 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/UY.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "UY.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UY.imageset/UY.png b/KarhooUISDK/Assets/CountryFlags.xcassets/UY.imageset/UY.png new file mode 100644 index 000000000..400502d8b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/UY.imageset/UY.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UZ.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/UZ.imageset/Contents.json new file mode 100644 index 000000000..eaa16cea9 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/UZ.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "UZ.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/UZ.imageset/UZ.png b/KarhooUISDK/Assets/CountryFlags.xcassets/UZ.imageset/UZ.png new file mode 100644 index 000000000..a3390e05f Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/UZ.imageset/UZ.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/VA.imageset/Contents.json new file mode 100644 index 000000000..4e78bdcca --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/VA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "VA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VA.imageset/VA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/VA.imageset/VA.png new file mode 100644 index 000000000..5b6184707 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/VA.imageset/VA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VC.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/VC.imageset/Contents.json new file mode 100644 index 000000000..e1d09718b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/VC.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "VC.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VC.imageset/VC.png b/KarhooUISDK/Assets/CountryFlags.xcassets/VC.imageset/VC.png new file mode 100644 index 000000000..ad20ec659 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/VC.imageset/VC.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/VE.imageset/Contents.json new file mode 100644 index 000000000..d64057b5e --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/VE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "VE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VE.imageset/VE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/VE.imageset/VE.png new file mode 100644 index 000000000..9d0327a36 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/VE.imageset/VE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VG.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/VG.imageset/Contents.json new file mode 100644 index 000000000..55e910f4b --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/VG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "VG.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VG.imageset/VG.png b/KarhooUISDK/Assets/CountryFlags.xcassets/VG.imageset/VG.png new file mode 100644 index 000000000..978741aab Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/VG.imageset/VG.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VI.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/VI.imageset/Contents.json new file mode 100644 index 000000000..26d39dd94 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/VI.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "VI.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VI.imageset/VI.png b/KarhooUISDK/Assets/CountryFlags.xcassets/VI.imageset/VI.png new file mode 100644 index 000000000..d7dee5fc1 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/VI.imageset/VI.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VN.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/VN.imageset/Contents.json new file mode 100644 index 000000000..307cef973 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/VN.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "VN.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VN.imageset/VN.png b/KarhooUISDK/Assets/CountryFlags.xcassets/VN.imageset/VN.png new file mode 100644 index 000000000..6785f5763 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/VN.imageset/VN.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/VU.imageset/Contents.json new file mode 100644 index 000000000..df37be285 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/VU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "VU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/VU.imageset/VU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/VU.imageset/VU.png new file mode 100644 index 000000000..cd81d79b3 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/VU.imageset/VU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/WF.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/WF.imageset/Contents.json new file mode 100644 index 000000000..5fef44cb8 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/WF.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "WF.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/WF.imageset/WF.png b/KarhooUISDK/Assets/CountryFlags.xcassets/WF.imageset/WF.png new file mode 100644 index 000000000..5ffc0ba5e Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/WF.imageset/WF.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/WS.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/WS.imageset/Contents.json new file mode 100644 index 000000000..9b9f5ddd3 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/WS.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "WS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/WS.imageset/WS.png b/KarhooUISDK/Assets/CountryFlags.xcassets/WS.imageset/WS.png new file mode 100644 index 000000000..af3917055 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/WS.imageset/WS.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/XK.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/XK.imageset/Contents.json new file mode 100644 index 000000000..79dab3ff7 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/XK.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "XK.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/XK.imageset/XK.png b/KarhooUISDK/Assets/CountryFlags.xcassets/XK.imageset/XK.png new file mode 100644 index 000000000..3a48fe2b6 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/XK.imageset/XK.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/YE.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/YE.imageset/Contents.json new file mode 100644 index 000000000..791d379ec --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/YE.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "YE.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/YE.imageset/YE.png b/KarhooUISDK/Assets/CountryFlags.xcassets/YE.imageset/YE.png new file mode 100644 index 000000000..30d49b106 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/YE.imageset/YE.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/YT.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/YT.imageset/Contents.json new file mode 100644 index 000000000..bfd2d6183 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/YT.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "YT.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/YT.imageset/YT.png b/KarhooUISDK/Assets/CountryFlags.xcassets/YT.imageset/YT.png new file mode 100644 index 000000000..6d5a32497 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/YT.imageset/YT.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/YU.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/YU.imageset/Contents.json new file mode 100644 index 000000000..a93885f52 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/YU.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "YU.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/YU.imageset/YU.png b/KarhooUISDK/Assets/CountryFlags.xcassets/YU.imageset/YU.png new file mode 100644 index 000000000..953dd6d7b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/YU.imageset/YU.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ZA.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ZA.imageset/Contents.json new file mode 100644 index 000000000..9731ab8cd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ZA.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ZA.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ZA.imageset/ZA.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ZA.imageset/ZA.png new file mode 100644 index 000000000..76b6a945b Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ZA.imageset/ZA.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ZM.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ZM.imageset/Contents.json new file mode 100644 index 000000000..e3b867ee1 --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ZM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ZM.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ZM.imageset/ZM.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ZM.imageset/ZM.png new file mode 100644 index 000000000..11917ed92 Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ZM.imageset/ZM.png differ diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ZW.imageset/Contents.json b/KarhooUISDK/Assets/CountryFlags.xcassets/ZW.imageset/Contents.json new file mode 100644 index 000000000..a222987bd --- /dev/null +++ b/KarhooUISDK/Assets/CountryFlags.xcassets/ZW.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ZW.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/KarhooUISDK/Assets/CountryFlags.xcassets/ZW.imageset/ZW.png b/KarhooUISDK/Assets/CountryFlags.xcassets/ZW.imageset/ZW.png new file mode 100644 index 000000000..1093d6bda Binary files /dev/null and b/KarhooUISDK/Assets/CountryFlags.xcassets/ZW.imageset/ZW.png differ diff --git a/KarhooUISDK/Builders/CheckoutScreenBuilder.swift b/KarhooUISDK/Builders/CheckoutScreenBuilder.swift new file mode 100644 index 000000000..59ed2e628 --- /dev/null +++ b/KarhooUISDK/Builders/CheckoutScreenBuilder.swift @@ -0,0 +1,18 @@ +// +// CheckoutScreenBuilder.swift +// KarhooUISDK +// +// +// Copyright © 2020 Karhoo. All rights reserved. +// + +import Foundation +import KarhooSDK + +public protocol CheckoutScreenBuilder { + + func buildCheckoutScreen(quote: Quote, + bookingDetails: BookingDetails, + bookingMetadata: [String: Any]?, + callback: @escaping ScreenResultCallback) -> Screen +} diff --git a/KarhooUISDK/Builders/FlightDetailsScreenBuilder.swift b/KarhooUISDK/Builders/FlightDetailsScreenBuilder.swift deleted file mode 100644 index 78045ab0e..000000000 --- a/KarhooUISDK/Builders/FlightDetailsScreenBuilder.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// FlightDetailsScreenBuilder.swift -// KarhooUISDK -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -import Foundation - -public protocol FlightDetailsScreenBuilder { - func buildFlightDetailsScreen(completion: @escaping ScreenResultCallback) -> Screen -} diff --git a/KarhooUISDK/Builders/PaymentScreenBuilder.swift b/KarhooUISDK/Builders/PaymentScreenBuilder.swift index ae23fb22a..252c7a4d6 100644 --- a/KarhooUISDK/Builders/PaymentScreenBuilder.swift +++ b/KarhooUISDK/Builders/PaymentScreenBuilder.swift @@ -11,6 +11,6 @@ import KarhooSDK public protocol PaymentScreenBuilder { func buildAddCardScreen(paymentsToken: PaymentSDKToken, - paymentMethodAdded: ScreenResultCallback?, + paymentMethodAdded: ScreenResultCallback?, flowItemCallback: ScreenResultCallback?) } diff --git a/KarhooUISDK/Classes/KarhooCountryParser.swift b/KarhooUISDK/Classes/KarhooCountryParser.swift new file mode 100644 index 000000000..58f0af9a0 --- /dev/null +++ b/KarhooUISDK/Classes/KarhooCountryParser.swift @@ -0,0 +1,67 @@ +// +// KarhooCountryParser.swift +// KarhooUISDK +// +// Created by Diana Petrea on 13.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit +import CoreTelephony + +final class KarhooCountryParser { + + private static var _defaultCountry: Country? + static var defaultCountry: Country { + get { + guard let def = _defaultCountry + else { + let all = getCountries() + guard all.count > 0 + else { + return Country(name: "United Kingdom", phoneCode: "+44", code: "GB") + } + + let networkInfo = CTTelephonyNetworkInfo().subscriberCellularProvider + + guard let regionCode = networkInfo?.isoCountryCode?.uppercased() ?? NSLocale.current.regionCode else { + return all.first(where: { $0.code == "GB" })! + } + + _defaultCountry = all.first(where: { $0.code == regionCode }) ?? all.first(where: { $0.code == "GB" })! + return _defaultCountry! + } + + return def + } + } + + static func getCountries() -> [Country] { + let c = NSLocale.isoCountryCodes + let availableLocales = Bundle.main.localizations + let deviceLocale = Locale.current.languageCode ?? "en" + let locale = availableLocales.contains(deviceLocale) ? deviceLocale : "en" + + var prefixCodes = ["AF": "93", "AE": "971", "AL": "355", "AN": "599", "AS":"1", "AD": "376", "AO": "244", "AI": "1", "AG":"1", "AR": "54","AM": "374", "AW": "297", "AU":"61", "AT": "43","AZ": "994", "BS": "1", "BH":"973", "BF": "226","BI": "257", "BD": "880", "BB": "1", "BY": "375", "BE":"32","BZ": "501", "BJ": "229", "BM": "1", "BT":"975", "BA": "387", "BW": "267", "BR": "55", "BG": "359", "BO": "591", "BL": "590", "BN": "673", "CC": "61", "CD":"243","CI": "225", "KH":"855", "CM": "237", "CA": "1", "CV": "238", "KY":"345", "CF":"236", "CH": "41", "CL": "56", "CN":"86","CX": "61", "CO": "57", "KM": "269", "CG":"242", "CK": "682", "CR": "506", "CU":"53", "CY":"537","CZ": "420", "DE": "49", "DK": "45", "DJ":"253", "DM": "1", "DO": "1", "DZ": "213", "EC": "593", "EG":"20", "ER": "291", "EE":"372","ES": "34", "ET": "251", "FM": "691", "FK": "500", "FO": "298", "FJ": "679", "FI":"358", "FR": "33", "GB":"44", "GF": "594", "GA":"241", "GS": "500", "GM":"220", "GE":"995","GH":"233", "GI": "350", "GQ": "240", "GR": "30", "GG": "44", "GL": "299", "GD":"1", "GP": "590", "GU": "1", "GT": "502", "GN":"224","GW": "245", "GY": "595", "HT": "509", "HR": "385", "HN":"504", "HU": "36", "HK": "852", "IR": "98", "IM": "44", "IL": "972", "IO":"246", "IS": "354", "IN": "91", "ID":"62", "IQ":"964", "IE": "353","IT":"39", "JM":"1", "JP": "81", "JO": "962", "JE":"44", "KP": "850", "KR": "82","KZ":"77", "KE": "254", "KI": "686", "KW": "965", "KG":"996","KN":"1", "LC": "1", "LV": "371", "LB": "961", "LK":"94", "LS": "266", "LR":"231", "LI": "423", "LT": "370", "LU": "352", "LA": "856", "LY":"218", "MO": "853", "MK": "389", "MG":"261", "MW": "265", "MY": "60","MV": "960", "ML":"223", "MT": "356", "MH": "692", "MQ": "596", "MR":"222", "MU": "230", "MX": "52","MC": "377", "MN": "976", "ME": "382", "MP": "1", "MS": "1", "MA":"212", "MM": "95", "MF": "590", "MD":"373", "MZ": "258", "NA":"264", "NR":"674", "NP":"977", "NL": "31","NC": "687", "NZ":"64", "NI": "505", "NE": "227", "NG": "234", "NU":"683", "NF": "672", "NO": "47","OM": "968", "PK": "92", "PM": "508", "PW": "680", "PF": "689", "PA": "507", "PG":"675", "PY": "595", "PE": "51", "PH": "63", "PL":"48", "PN": "872","PT": "351", "PR": "1","PS": "970", "QA": "974", "RO":"40", "RE":"262", "RS": "381", "RU": "7", "RW": "250", "SM": "378", "SA":"966", "SN": "221", "SC": "248", "SL":"232","SG": "65", "SK": "421", "SI": "386", "SB":"677", "SH": "290", "SD": "249", "SR": "597","SZ": "268", "SE":"46", "SV": "503", "ST": "239","SO": "252", "SJ": "47", "SY":"963", "TW": "886", "TZ": "255", "TL": "670", "TD": "235", "TJ": "992", "TH": "66", "TG":"228", "TK": "690", "TO": "676", "TT": "1", "TN":"216","TR": "90", "TM": "993", "TC": "1", "TV":"688", "UG": "256", "UA": "380", "US": "1", "UY": "598","UZ": "998", "VA":"379", "VE":"58", "VN": "84", "VG": "1", "VI": "1","VC":"1", "VU":"678", "WS": "685", "WF": "681", "YE": "967", "YT": "262","ZA": "27" , "ZM": "260", "ZW":"263", "AC":"247", "AQ":"672", "AX":"358", "BQ":"599", "BV":"47", "CP":"1", "CW":"599", "DG":"246", "EA":"34", "EH":"212", "HM":"1", "IC":"828", "SS":"211", "SX":"599", "TA":"290", "TF":"262", "UM":"246", "XK":"383" ] + + for (k, v) in prefixCodes { + prefixCodes[k] = "+\(v)" + } + + var countries = [Country]() + + for code in c { + let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code]) + let name = NSLocale(localeIdentifier: locale).displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)" + countries.append(Country(name: name, phoneCode: prefixCodes[code] ?? "", code: code)) + } + + countries = countries.sorted(by: { $0.name < $1.name }) + return countries + } + + static func getCountry(countryCode: String) -> Country? { + let all = getCountries() + return all.first(where: { $0.code == countryCode }) + } +} diff --git a/KarhooUISDK/Classes/KarhooFileManager.swift b/KarhooUISDK/Classes/KarhooFileManager.swift new file mode 100644 index 000000000..bf12b20bd --- /dev/null +++ b/KarhooUISDK/Classes/KarhooFileManager.swift @@ -0,0 +1,43 @@ +// +// KarhooFileManager.swift +// KarhooUISDK +// +// Created by Diana Petrea on 13.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit + +final class KarhooFileManager { + + static func getFromFile(_ fileName: String) -> T? { + guard let data = readLocalFile(forName: fileName) + else { + return nil + } + + do { + let decodedData = try JSONDecoder().decode(T.self, from: data) + return decodedData + } + catch { + print(error) + } + + return nil + } + + static private func readLocalFile(forName name: String) -> Data? { + do { + if let bundlePath = Bundle.current.path(forResource: name, ofType: "json"), + let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8) { + return jsonData + } + } + catch { + print(error) + } + + return nil + } +} diff --git a/KarhooUISDK/Classes/Payment/AddCard/AdyenCardRegistrationFlow.swift b/KarhooUISDK/Classes/Payment/AddCard/AdyenCardRegistrationFlow.swift index 328fab472..22bf48481 100644 --- a/KarhooUISDK/Classes/Payment/AddCard/AdyenCardRegistrationFlow.swift +++ b/KarhooUISDK/Classes/Payment/AddCard/AdyenCardRegistrationFlow.swift @@ -100,7 +100,7 @@ final class AdyenCardRegistrationFlow: CardRegistrationFlow { adyenDropIn = DropInComponent(paymentMethods: methods, paymentMethodsConfiguration: configuration, - style: DropInComponent.Style(tintColor: KarhooUI.colors.primary)) + style: DropInComponent.Style(tintColor: KarhooUI.colors.secondary)) adyenDropIn?.delegate = self adyenDropIn?.environment = paymentFactory.adyenEnvironment() adyenDropIn?.payment = Payment(amount: Payment.Amount(value: self.amount, @@ -228,8 +228,8 @@ extension AdyenCardRegistrationFlow: DropInComponentDelegate { switch event { case .failure: finish(result: .completed(value: .didFailWithError(nil))) - case .paymentAuthorised(let method): - finish(result: .completed(value: .didAddPaymentMethod(method: method))) + case .paymentAuthorised(let nonce): + finish(result: .completed(value: .didAddPaymentMethod(nonce: nonce))) case .requiresAction(let action): adyenDropIn?.handle(action) case .refused(let reason, let code): diff --git a/KarhooUISDK/Classes/Payment/AddCard/AdyenResponseHandler.swift b/KarhooUISDK/Classes/Payment/AddCard/AdyenResponseHandler.swift index 73eb9216c..cd9813a6c 100644 --- a/KarhooUISDK/Classes/Payment/AddCard/AdyenResponseHandler.swift +++ b/KarhooUISDK/Classes/Payment/AddCard/AdyenResponseHandler.swift @@ -9,6 +9,7 @@ // import Adyen +import KarhooSDK struct AdyenResponseHandler { @@ -23,7 +24,7 @@ struct AdyenResponseHandler { enum AdyenEvent { case requiresAction(_ action: Action) - case paymentAuthorised(_ method: PaymentMethod) + case paymentAuthorised(_ method: Nonce) case refused(reason: String, code: String) case handleResult(code: String?) case failure @@ -53,10 +54,8 @@ struct AdyenResponseHandler { let lastFour = paymentData?[cardSummary] as? String ?? "" let icon = paymentIcon(adyenDescription: paymentData?[paymentMethod] as? String) - let method = PaymentMethod(nonce: tripId, - nonceType: icon, - paymentDescription: lastFour) - return .paymentAuthorised(method) + let nonce = Nonce(nonce: tripId, cardType: icon, lastFour: lastFour) + return .paymentAuthorised(nonce) } if result == refused { diff --git a/KarhooUISDK/Classes/Payment/AddCard/BraintreeCardRegistrationFlow.swift b/KarhooUISDK/Classes/Payment/AddCard/BraintreeCardRegistrationFlow.swift index 4bc02e006..d89abb656 100644 --- a/KarhooUISDK/Classes/Payment/AddCard/BraintreeCardRegistrationFlow.swift +++ b/KarhooUISDK/Classes/Payment/AddCard/BraintreeCardRegistrationFlow.swift @@ -97,7 +97,7 @@ public final class BraintreeCardRegistrationFlow: CardRegistrationFlow { baseViewController?.present(item, animated: true, completion: nil) } - private func handleBraintreeUICompletion(_ result: ScreenResult) { + private func handleBraintreeUICompletion(_ result: ScreenResult) { switch result { case .cancelled: dismissBraintreeUI() @@ -106,20 +106,20 @@ public final class BraintreeCardRegistrationFlow: CardRegistrationFlow { dismissBraintreeUI() analyticsService.send(eventName: .userCardRegistrationFailed) self.callback?(.completed(value: .didFailWithError(error))) - case .completed(let braintreePaymentMethod): + case .completed(let braintreePaymentNonce): dismissBraintreeUI() baseViewController?.showLoadingOverlay(true) if Karhoo.configuration.authenticationMethod().guestSettings != nil { - registerGuestPayer(method: braintreePaymentMethod) + registerGuestPayer(nonce: braintreePaymentNonce) } else { - registerKarhooPayer(method: braintreePaymentMethod) + registerKarhooPayer(nonce: braintreePaymentNonce) } } } - private func registerKarhooPayer(method: PaymentMethod) { + private func registerKarhooPayer(nonce: Nonce) { guard let currentUser = userService.getCurrentUser() else { return } @@ -133,7 +133,7 @@ public final class BraintreeCardRegistrationFlow: CardRegistrationFlow { return } - let addPaymentPayload = AddPaymentDetailsPayload(nonce: method.nonce, + let addPaymentPayload = AddPaymentDetailsPayload(nonce: nonce.nonce, payer: payer, organisationId: payerOrg.id) @@ -150,15 +150,15 @@ public final class BraintreeCardRegistrationFlow: CardRegistrationFlow { self?.analyticsService.send(eventName: .userCardRegistered) self?.callback?(OperationResult.completed( - value: .didAddPaymentMethod(method: PaymentMethod(nonce: nonce.nonce)))) + value: .didAddPaymentMethod(nonce: nonce))) }) } - private func registerGuestPayer(method: PaymentMethod) { + private func registerGuestPayer(nonce: Nonce) { analyticsService.send(eventName: .userCardRegistered) self.baseViewController?.showLoadingOverlay(false) - self.callback?(OperationResult.completed(value: .didAddPaymentMethod(method: method))) + self.callback?(OperationResult.completed(value: .didAddPaymentMethod(nonce: nonce))) } private func dismissBraintreeUI() { diff --git a/KarhooUISDK/Classes/Payment/AddCard/CardRegistrationFlow.swift b/KarhooUISDK/Classes/Payment/AddCard/CardRegistrationFlow.swift index 05bb74286..dccc38041 100644 --- a/KarhooUISDK/Classes/Payment/AddCard/CardRegistrationFlow.swift +++ b/KarhooUISDK/Classes/Payment/AddCard/CardRegistrationFlow.swift @@ -19,7 +19,7 @@ public protocol CardRegistrationFlow { } public enum CardFlowResult { - case didAddPaymentMethod(method: PaymentMethod) + case didAddPaymentMethod(nonce: Nonce) case didFailWithError(_ error: KarhooError?) case cancelledByUser } diff --git a/KarhooUISDK/Classes/Payment/NonceProvider/AdyenPaymentNonceProvider.swift b/KarhooUISDK/Classes/Payment/NonceProvider/AdyenPaymentNonceProvider.swift index 89ad34905..5a2e7010a 100644 --- a/KarhooUISDK/Classes/Payment/NonceProvider/AdyenPaymentNonceProvider.swift +++ b/KarhooUISDK/Classes/Payment/NonceProvider/AdyenPaymentNonceProvider.swift @@ -19,7 +19,7 @@ final class AdyenPaymentNonceProvider: PaymentNonceProvider { } func getPaymentNonce(user: UserInfo, - organisation: Organisation, + organisationId: String, quote: Quote, result: @escaping (OperationResult) -> Void) { cardFlow.start(cardCurrency: quote.price.currencyCode, @@ -41,8 +41,7 @@ final class AdyenPaymentNonceProvider: PaymentNonceProvider { private func handleAddCardFlow(result: CardFlowResult, callback: @escaping (OperationResult) -> Void) { switch result { - case .didAddPaymentMethod(let method): - let nonce = Nonce(nonce: method.nonce, cardType: method.nonceType) + case .didAddPaymentMethod(let nonce): callback(.completed(value: .nonce(nonce: nonce))) case .didFailWithError(let error): callback(.completed(value: .failedToAddCard(error: error))) case .cancelledByUser: callback(.completed(value: .cancelledByUser)) diff --git a/KarhooUISDK/Classes/Payment/NonceProvider/BraintreePaymentNonceProvider.swift b/KarhooUISDK/Classes/Payment/NonceProvider/BraintreePaymentNonceProvider.swift index 60faee963..10c9281dd 100644 --- a/KarhooUISDK/Classes/Payment/NonceProvider/BraintreePaymentNonceProvider.swift +++ b/KarhooUISDK/Classes/Payment/NonceProvider/BraintreePaymentNonceProvider.swift @@ -34,13 +34,13 @@ final class BraintreePaymentNonceProvider: PaymentNonceProvider { } func getPaymentNonce(user: UserInfo, - organisation: Organisation, + organisationId: String, quote: Quote, result: @escaping (OperationResult) -> Void) { self.callbackResult = result self.quoteToBook = quote - let sdkTokenRequest = PaymentSDKTokenPayload(organisationId: organisation.id, + let sdkTokenRequest = PaymentSDKTokenPayload(organisationId: organisationId, currency: quote.price.currencyCode) paymentService.initialisePaymentSDK(paymentSDKTokenPayload: sdkTokenRequest).execute {[weak self] result in @@ -58,7 +58,7 @@ final class BraintreePaymentNonceProvider: PaymentNonceProvider { lastName: user.lastName, email: user.email) let nonceRequestPayload = NonceRequestPayload(payer: payer, - organisationId: organisation.id) + organisationId: organisationId) getNonce(payload: nonceRequestPayload, currencyCode: quote.price.currencyCode) } @@ -87,7 +87,7 @@ final class BraintreePaymentNonceProvider: PaymentNonceProvider { private func handleAddCardResult(_ result: CardFlowResult) { switch result { - case .didAddPaymentMethod(let method): execute3dSecureCheckOnNonce(Nonce(nonce: method.nonce)) + case .didAddPaymentMethod(let nonce): execute3dSecureCheckOnNonce(nonce) case .didFailWithError(let error): callbackResult?(.completed(value: .failedToAddCard(error: error))) case .cancelledByUser: self.callbackResult?(.cancelledByUser) } diff --git a/KarhooUISDK/Classes/Payment/NonceProvider/PaymentNonceProvider.swift b/KarhooUISDK/Classes/Payment/NonceProvider/PaymentNonceProvider.swift index 8fd57e9f6..8f8a5c80e 100644 --- a/KarhooUISDK/Classes/Payment/NonceProvider/PaymentNonceProvider.swift +++ b/KarhooUISDK/Classes/Payment/NonceProvider/PaymentNonceProvider.swift @@ -19,7 +19,7 @@ enum PaymentNonceProviderResult { protocol PaymentNonceProvider { func getPaymentNonce(user: UserInfo, - organisation: Organisation, + organisationId: String, quote: Quote, result: @escaping (OperationResult) -> Void) diff --git a/KarhooUISDK/Common/Alert/AlertHandler.swift b/KarhooUISDK/Common/Alert/AlertHandler.swift index 13e100334..d8df28bec 100644 --- a/KarhooUISDK/Common/Alert/AlertHandler.swift +++ b/KarhooUISDK/Common/Alert/AlertHandler.swift @@ -63,7 +63,7 @@ public final class AlertHandler: AlertHandlerProtocol { } public func show(title: String?, message: String?, actions: [AlertAction]) -> UIAlertController { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) + let alert = UIAlertController.create(title: title, message: message, preferredStyle: .alert) actions.forEach { alert.addAction($0.action) } alert.view.tintColor = KarhooUI.colors.darkGrey @@ -74,9 +74,8 @@ public final class AlertHandler: AlertHandlerProtocol { public func show(error: KarhooError?) -> UIAlertController { let message = error?.localizedMessage ?? UITexts.Errors.noDetailsAvailable - let alert = UIAlertController(title: UITexts.Errors.somethingWentWrong, - message: message, - preferredStyle: .alert) + let alert = UIAlertController.create(title: UITexts.Errors.somethingWentWrong, message: message, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: UITexts.Generic.ok, style: .default)) alert.view.tintColor = KarhooUI.colors.darkGrey diff --git a/KarhooUISDK/Common/BaseStackView.swift b/KarhooUISDK/Common/BaseStackView.swift index 0c8fd1de4..7cce83d45 100644 --- a/KarhooUISDK/Common/BaseStackView.swift +++ b/KarhooUISDK/Common/BaseStackView.swift @@ -51,16 +51,15 @@ class BaseStackView: UIView { bottomInset = safeAreaInsets.bottom } - _ = [scrollView.topAnchor.constraint(equalTo: self.topAnchor), - scrollView.leadingAnchor.constraint(equalTo: self.leadingAnchor), - scrollView.trailingAnchor.constraint(equalTo: self.trailingAnchor), - scrollView.bottomAnchor.constraint(equalTo: self.bottomAnchor, - constant: -bottomInset)].map { $0.isActive = true } + scrollView.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor, + paddingBottom: bottomInset) - _ = [stackContainer.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor), - stackContainer.topAnchor.constraint(equalTo: scrollView.topAnchor), - stackContainer.bottomAnchor.constraint(greaterThanOrEqualTo: scrollView.bottomAnchor)] - .map { $0.isActive = true } + stackContainer.centerX(inView: scrollView) + stackContainer.anchor(top: scrollView.topAnchor, + bottom: scrollView.bottomAnchor) didSetupConstraints = true } diff --git a/KarhooUISDK/Common/KarhooTextInputView/KarhooInputView.swift b/KarhooUISDK/Common/KarhooTextInputView/KarhooInputView.swift index 500cd6e34..34ec65342 100644 --- a/KarhooUISDK/Common/KarhooTextInputView/KarhooInputView.swift +++ b/KarhooUISDK/Common/KarhooTextInputView/KarhooInputView.swift @@ -13,9 +13,19 @@ protocol KarhooInputView: UIView { func setInactive() func showIcon(_ show: Bool) func showError() - func getIntput() -> String + func getInput() -> String func isValid() -> Bool func isFirstResponder() -> Bool func set(text: String?) func dismissKeyboard() } + +protocol KarhooPhoneInputViewProtocol: KarhooInputView { + func getFullPhoneNumber() -> String + func getCountryCode() -> String + func getPhoneNumberNoCountryCode() -> String + + // NOTE: When using KarhooPhoneInputView set the country before the text for best results + // This is not mandatory, as the usage may vary from component to component + func set(country: Country) +} diff --git a/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView.swift b/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView.swift new file mode 100644 index 000000000..43afd53f6 --- /dev/null +++ b/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView.swift @@ -0,0 +1,382 @@ +// +// KarhooPhoneInputView.swift +// KarhooUISDK +// +// Copyright © 2020 Karhoo All rights reserved. +// + +import UIKit +import PhoneNumberKit + +struct KHPhoneInputViewIdentifiers { + static let containerStackView = "container_stack_view" + static let contentStackView = "content_stack_view" + static let iconContainerView = "icon_container_view" + static let iconImageView = "icon_image_view" + static let titleLabel = "title_label" + static let textView = "text_view" + static let countryCodeButton = "country_code_button" + static let errorLabel = "error_label" +} + +class KarhooPhoneInputView: UIView { + + // MARK: - Variables and Controls + public weak var delegate: KarhooInputViewDelegate? + + private var didSetUpConstraints: Bool = false + private var iconImage: UIImage? + private var errorFeedbackType: KarhooTextInputViewErrorFeedbackType = .icon + + private var country: Country = KarhooCountryParser.defaultCountry { + didSet { + countryCodeButton.setTitle(country.phoneCode, for: .normal) + countryCodeButton.setImage(UIImage.uisdkImage(country.code), for: .normal) + } + } + + private let contentType: KarhooTextInputViewContentType = .phone + private let countryCodeButtonWidth: CGFloat = 120.0 + private let iconSize: CGFloat = 30.0 + private let padding: CGFloat = 15.0 + private let innerSpacing: CGFloat = 5.0 + + private lazy var containerStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.accessibilityIdentifier = KHPhoneInputViewIdentifiers.containerStackView + stackView.axis = .vertical + stackView.distribution = .fill + stackView.alignment = .fill + stackView.spacing = innerSpacing + return stackView + }() + + private lazy var contentStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.accessibilityIdentifier = KHPhoneInputViewIdentifiers.contentStackView + stackView.axis = .horizontal + stackView.distribution = .fill + stackView.alignment = .center + stackView.spacing = innerSpacing + return stackView + }() + + private lazy var iconImageView: UIImageView = { + let imageView = UIImageView(image: iconImage?.withRenderingMode(.alwaysTemplate)) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.accessibilityIdentifier = KHPhoneInputViewIdentifiers.iconImageView + imageView.tintColor = KarhooTextInputViewState.inactive.color + imageView.contentMode = .scaleAspectFit + imageView.anchor(width: iconSize, height: iconSize) + return imageView + }() + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHPhoneInputViewIdentifiers.titleLabel + label.text = contentType.titleText + label.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) + label.tintColor = KarhooUI.colors.primaryTextColor + return label + }() + + private lazy var countryCodeButton: UIButton = { + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityIdentifier = KHPhoneInputViewIdentifiers.countryCodeButton + button.layer.borderColor = KarhooTextInputViewState.inactive.color.cgColor + button.layer.borderWidth = 1.0 + button.layer.cornerRadius = 3.0 + button.setTitle(KarhooCountryParser.defaultCountry.phoneCode, for: .normal) + button.titleLabel?.font = KarhooUI.fonts.getRegularFont(withSize: 14.0) + button.setTitleColor(KarhooUI.colors.primaryTextColor, for: .normal) + button.titleEdgeInsets = UIEdgeInsets(top: padding, left: 0, bottom: padding, right: innerSpacing) + button.setImage(UIImage.uisdkImage(KarhooCountryParser.defaultCountry.code), for: .normal) + button.imageEdgeInsets = UIEdgeInsets(top: padding, left: -padding, bottom: padding, right: innerSpacing) + button.imageView?.contentMode = .scaleAspectFit + button.addTarget(self, action: #selector(countryCodeSelected), for: .touchUpInside) + button.anchor(width: countryCodeButtonWidth) + return button + }() + + private lazy var textView: UITextView = { + let textView = UITextView() + textView.translatesAutoresizingMaskIntoConstraints = false + textView.accessibilityIdentifier = KHPhoneInputViewIdentifiers.textView + textView.text = contentType.placeholderText + textView.font = KarhooUI.fonts.getRegularFont(withSize: 14.0) + textView.returnKeyType = .done + textView.textColor = KarhooTextInputViewState.inactive.color + textView.layer.borderWidth = 1.0 + textView.layer.cornerRadius = 3.0 + textView.textContainerInset = UIEdgeInsets(top: padding, left: innerSpacing, bottom: padding, right: innerSpacing) + textView.layer.borderColor = KarhooTextInputViewState.inactive.color.cgColor + textView.autocorrectionType = .no + textView.keyboardType = .phonePad + textView.delegate = self + textView.isScrollEnabled = false + return textView + }() + + private lazy var errorLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHPhoneInputViewIdentifiers.errorLabel + label.text = UITexts.Errors.missingPhoneNumber + label.textColor = UIColor.red + label.font = KarhooUI.fonts.captionRegular() + return label + }() + + // MARK: - Init + init(iconImage: UIImage? = nil, + errorFeedbackType: KarhooTextInputViewErrorFeedbackType = .text, + accessibilityIdentifier: String) { + super.init(frame: .zero) + self.accessibilityIdentifier = accessibilityIdentifier + self.iconImage = iconImage + self.errorFeedbackType = errorFeedbackType + self.setUpView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setUpView() { + addSubview(containerStackView) + containerStackView.addArrangedSubview(titleLabel) + containerStackView.addArrangedSubview(contentStackView) + containerStackView.addArrangedSubview(errorLabel) + + errorLabel.isHidden = true + + contentStackView.addArrangedSubview(iconImageView) + contentStackView.addArrangedSubview(countryCodeButton) + contentStackView.addArrangedSubview(textView) + + iconImageView.isHidden = iconImage == nil + } + + override func updateConstraints() { + if !didSetUpConstraints { + containerStackView.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor) + + countryCodeButton.topAnchor.constraint(equalTo: textView.topAnchor).isActive = true + countryCodeButton.bottomAnchor.constraint(equalTo: textView.bottomAnchor).isActive = true + + + + didSetUpConstraints = true + } + + super.updateConstraints() + } + + // MARK: - Actions + @objc private func countryCodeSelected() { + tintView(.active) + + let presenter = CountryCodeSelectionPresenter(preSelectedCountry: country) { [weak self] result in + guard let value = result.completedValue() + else { + return + } + + self?.country = value + self?.runValidation() + } + + let vc = CountryCodeSelectionViewController(presenter: presenter) + if let topController = ViewControllerUtils.topBaseViewController { + topController.showAsOverlay(item: vc, animated: true) + } + } + + //MARK: - Utils + private func tintView(_ state: KarhooTextInputViewState) { + UIView.animate(withDuration: state == .error ? 0.1 : 0.3) { [weak self] in + self?.textView.layer.borderColor = state.color.cgColor + self?.iconImageView.tintColor = state.color + } + } + + private func validatePhoneNumber() -> Bool { + let phoneNumber = country.phoneCode + textView.text + let phoneNumberKit = PhoneNumberKit() + do { + _ = try phoneNumberKit.parse(phoneNumber) + return true + } catch { +// print("Generic parser error") + return false + } + } + + private func runValidation() { + if !Utils.isValidPhoneNumber(number: getInput()) { + showError() + } else { + errorLabel.isHidden = true + textView.resignFirstResponder() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } + } +} + +extension KarhooPhoneInputView: KarhooPhoneInputViewProtocol { + public func resetView() { + tintView(.inactive) + textView.text = nil + } + + public func setActive() { + textView.becomeFirstResponder() + } + + public func setInactive() { + textView.resignFirstResponder() + } + + public func showIcon(_ show: Bool) { + iconImageView.isHidden = !show + } + + public func showError() { + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.error) + + switch errorFeedbackType { + case .full: + shakeView() + case .text: + textView.shakeView() + case .icon: + iconImageView.shakeView() + default: + return + } + tintView(.error) + + if textView.text == nil || (textView.text?.isEmpty ?? true) { + errorLabel.text = UITexts.Errors.missingPhoneNumber + } + else { + errorLabel.text = UITexts.Errors.invalidPhoneNumber + } + errorLabel.isHidden = false + } + + public func getInput() -> String { + _ = validatePhoneNumber() + return country.phoneCode + textView.text + } + + public func isValid() -> Bool { + return validatePhoneNumber() + } + + public func isFirstResponder() -> Bool { + return textView.isFirstResponder + } + + func set(text: String? = nil) { + guard var value = text else { + return + } + + if value.hasPrefix("+") { + // The phone code in the phone number coincides with the provided country's phone code + if value.hasPrefix(country.phoneCode) { + value = value.removePrefix(country.phoneCode) + } + // The phone number provided has a different phone code than the provided country's phone code + else { + let allCountries = KarhooCountryParser.getCountries().sorted(by: { $0.code < $1.code }) + if let newCountry = allCountries.first(where: { value.starts(with: $0.phoneCode) }) { + country = newCountry + value = value.removePrefix(country.phoneCode) + } + } + } + + textView.text = value + textView.textColor = KarhooUI.colors.primaryTextColor + } + + func dismissKeyboard() { + textView.resignFirstResponder() + } + + public func getFullPhoneNumber() -> String { + return getInput() + } + + public func getPhoneNumberNoCountryCode() -> String { + return textView.text + } + + public func getCountryCode() -> String { + return country.code + } + + public func set(country: Country) { + self.country = country + } +} + +extension KarhooPhoneInputView: UITextViewDelegate { + + func textViewDidBeginEditing(_ textView: UITextView) { + + tintView(.active) + if textView.textColor == KarhooTextInputViewState.inactive.color { + textView.textColor = KarhooUI.colors.primaryTextColor + textView.text = nil + } + + delegate?.didBecomeActive(identifier: accessibilityIdentifier!) + } + + func textViewDidEndEditing(_ textView: UITextView) { + tintView(.inactive) + + if textView.text.contains(" ") && contentType.whitespaceAllowed == false { + textView.text = textView.text.trimmingCharacters(in: .whitespaces) + } + + if textView.text.isEmpty { + textView.textColor = KarhooTextInputViewState.inactive.color + textView.text = contentType.placeholderText + } + + runValidation() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } + + func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { + if text == "\n" { + if !validatePhoneNumber() { + showError() + } else { + textView.resignFirstResponder() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } + return false + } + + return true + } + + func textViewDidChange(_ textView: UITextView) { + let size = CGSize(width: frame.width, height: .infinity) + textView.sizeThatFits(size) + delegate?.didChangeCharacterInSet(identifier: accessibilityIdentifier!) + } +} diff --git a/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView/KarhooPhoneInputView.swift b/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView/KarhooPhoneInputView.swift deleted file mode 100644 index d0187638b..000000000 --- a/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView/KarhooPhoneInputView.swift +++ /dev/null @@ -1,357 +0,0 @@ -// -// KarhooPhoneInputView.swift -// KarhooUISDK -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import UIKit -import PhoneNumberKit - -class KarhooPhoneInputView: UIView, KarhooInputView { - - private var didSetUpConstraints: Bool = false - - private var stackContainer: UIStackView! - private var icon: UIImageView! - private var iconContainer: UIView! - private var placeholder: UILabel! - private var placeholderTopConstraint: NSLayoutConstraint! - private var textField: UITextView! - private var countryCode: UIButton! - private var separatorLine: LineView! - private var lineView: LineView! - - private var iconImage: UIImage? - private var placeholderText: String = "Phone Number" - private var errorFeedbackType: KarhooTextInputViewErrorFeedbackType = .icon - private var phoneNumber: String = "" - public weak var delegate: KarhooInputViewDelegate? - - private var dataSource: PhoneCountryCodeDataSource! - - init(iconImage: UIImage? = nil, - errorFeedbackType: KarhooTextInputViewErrorFeedbackType = .text, - accessibilityIdentifier: String, - dataSource: PhoneCountryCodeDataSource = KarhooPhoneCountryCodeDataSource()) { - super.init(frame: .zero) - self.accessibilityIdentifier = accessibilityIdentifier - self.iconImage = iconImage - self.errorFeedbackType = errorFeedbackType - self.dataSource = dataSource - self.setUpView() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func setUpView() { - translatesAutoresizingMaskIntoConstraints = false - - stackContainer = UIStackView() - stackContainer.translatesAutoresizingMaskIntoConstraints = false - stackContainer.accessibilityIdentifier = "stack_container" - stackContainer.axis = .horizontal - stackContainer.spacing = 5.0 - addSubview(stackContainer) - - iconContainer = UIView() - iconContainer.translatesAutoresizingMaskIntoConstraints = false - iconContainer.accessibilityIdentifier = "icon_container_view" - iconContainer.isHidden = iconImage != nil ? false : true - stackContainer.addArrangedSubview(iconContainer) - - icon = UIImageView(image: iconImage?.withRenderingMode(.alwaysTemplate)) - icon.translatesAutoresizingMaskIntoConstraints = false - icon.accessibilityIdentifier = "icon_image" - icon.tintColor = KarhooTextInputViewState.inactive.color - icon.contentMode = .scaleAspectFit - iconContainer.addSubview(icon) - - countryCode = UIButton(type: .custom) - countryCode.translatesAutoresizingMaskIntoConstraints = false - countryCode.accessibilityIdentifier = "country_code_label" - countryCode.setTitle("+00", for: .normal) - countryCode.setTitleColor(KarhooTextInputViewState.inactive.color, for: .normal) - countryCode.titleEdgeInsets = UIEdgeInsets(top: 4, left: 0, bottom: 0, right: 0) - countryCode.titleLabel?.font = KarhooUI.fonts.bodyRegular() - countryCode.addTarget(self, action: #selector(countryCodeTapped), for: .touchUpInside) - stackContainer.addArrangedSubview(countryCode) - - separatorLine = LineView(color: KarhooTextInputViewState.inactive.color, - width: 1.0, - accessibilityIdentifier: "line_view") - stackContainer.addArrangedSubview(separatorLine) - - textField = UITextView() - textField.translatesAutoresizingMaskIntoConstraints = false - textField.accessibilityIdentifier = "text_field" - textField.text = placeholderText - textField.font = KarhooUI.fonts.bodyRegular() - textField.returnKeyType = .done - textField.textColor = KarhooTextInputViewState.inactive.color - textField.delegate = self - textField.isScrollEnabled = false - stackContainer.addArrangedSubview(textField) - - placeholder = UILabel() - placeholder.translatesAutoresizingMaskIntoConstraints = false - placeholder.accessibilityIdentifier = "placeholder_label" - placeholder.text = textField.text - placeholder.font = textField.font?.withSize(textField.font!.pointSize / 2) - placeholder.textColor = KarhooTextInputViewState.inactive.color - placeholder.alpha = 0 - addSubview(placeholder) - - lineView = LineView(color: KarhooTextInputViewState.inactive.color, - accessibilityIdentifier: "line_view") - addSubview(lineView) - - updateConstraints() - } - - override func updateConstraints() { - if !didSetUpConstraints { - - _ = [icon.widthAnchor.constraint(equalToConstant: 30.0), - icon.heightAnchor.constraint(equalToConstant: 30.0), - icon.leadingAnchor.constraint(equalTo: iconContainer.leadingAnchor), - icon.topAnchor.constraint(equalTo: iconContainer.topAnchor), - icon.trailingAnchor.constraint(equalTo: iconContainer.trailingAnchor)].map { $0.isActive = true } - - _ = [stackContainer.leadingAnchor.constraint(equalTo: leadingAnchor), - stackContainer.topAnchor.constraint(equalTo: topAnchor, constant: 13.0), - stackContainer.trailingAnchor.constraint(equalTo: trailingAnchor, - constant: -10.0)].map { $0.isActive = true } - - _ = [countryCode.heightAnchor.constraint(equalToConstant: 30.0), - countryCode.widthAnchor.constraint(equalToConstant: 50.0)].map { $0.isActive = true } - - _ = [separatorLine.topAnchor.constraint(equalTo: stackContainer.topAnchor), - separatorLine.bottomAnchor.constraint(equalTo: stackContainer.bottomAnchor)].map { $0.isActive = true } - - textField.heightAnchor.constraint(equalToConstant: 30.0).isActive = true - - placeholder.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0.0).isActive = true - placeholderTopConstraint = placeholder.topAnchor.constraint(equalTo: topAnchor, constant: 15.0) - placeholderTopConstraint.isActive = true - - _ = [lineView.topAnchor.constraint(equalTo: stackContainer.bottomAnchor), - lineView.leadingAnchor.constraint(equalTo: leadingAnchor), - lineView.trailingAnchor.constraint(equalTo: trailingAnchor), - lineView.bottomAnchor.constraint(equalTo: bottomAnchor), - lineView.heightAnchor.constraint(equalToConstant: 1.0)].map { $0.isActive = true } - - didSetUpConstraints = true - } - - super.updateConstraints() - } - - private func tintView(_ state: KarhooTextInputViewState) { - UIView.animate(withDuration: state == .error ? 0.1 : 0.3) { [weak self] in - self?.lineView.backgroundColor = state.color - self?.icon.tintColor = state.color - self?.placeholder.textColor = state.color - self?.separatorLine.backgroundColor = state.color - } - } - - private func animatePlaceHoder(show: Bool) { - placeholderTopConstraint.constant = show ? 0.0 : 15.0 - UIView.animate(withDuration: 0.5) { [weak self] in - self?.layoutIfNeeded() - self?.placeholder.alpha = show ? 1.0 : 0.0 - } - } - - func set(text: String? = nil) { - guard let value = text else { - return - } - textField.text = value - } - - func dismissKeyboard() { - textField.resignFirstResponder() - } - - @objc - private func countryCodeTapped() { - tintView(.active) - showCountryPicker() - } - - public func resetView() { - animatePlaceHoder(show: false) - tintView(.inactive) - textField.text = placeholderText - } - - public func setActive() { - textField.becomeFirstResponder() - } - - public func setInactive() { - textField.resignFirstResponder() - } - - public func showIcon(_ show: Bool) { - iconContainer.isHidden = !show - } - - public func showError() { - let generator = UINotificationFeedbackGenerator() - generator.notificationOccurred(.error) - - switch errorFeedbackType { - case .full: - shakeView() - case .text: - textField.shakeView() - case .icon: - icon.shakeView() - default: - return - } - tintView(.error) - } - - public func getIntput() -> String { - _ = validatePhoneNumber() - return phoneNumber - } - - private func showCountryPicker() { - let alertView = UIAlertController( - title: UITexts.User.countryCode, - message: "\n\n\n\n\n\n\n\n\n", - preferredStyle: .alert) - - let pickerView = UIPickerView(frame: - CGRect(x: 0, y: 50, width: 260, height: 162)) - pickerView.dataSource = self - pickerView.delegate = self - - alertView.view.addSubview(pickerView) - - let action = UIAlertAction(title: "OK", style: .default, handler: nil) - - alertView.addAction(action) - - if var topController = UIApplication.shared.keyWindow?.rootViewController { - while let presentedViewController = topController.presentedViewController { - topController = presentedViewController - } - - topController.present(alertView, animated: true) { - pickerView.frame.size.width = alertView.view.frame.size.width - } - } - } - - private func validatePhoneNumber() -> Bool { - phoneNumber = (countryCode.titleLabel?.text)! + textField.text - let phoneNumberKit = PhoneNumberKit() - do { - _ = try phoneNumberKit.parse(phoneNumber) - return true - } catch { - print("Generic parser error") - return false - } - } - - public func isValid() -> Bool { - return countryCode.titleLabel?.text != "+00" && (textField.text != placeholderText || textField.text != "") - } - - public func isFirstResponder() -> Bool { - return textField.isFirstResponder - } -} - -extension KarhooPhoneInputView: UITextViewDelegate { - - func textViewDidBeginEditing(_ textView: UITextView) { - let newPosition = textField.beginningOfDocument - textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition) - tintView(.active) - if textView.textColor == KarhooUI.colors.lightGrey { - textView.textColor = KarhooUI.colors.darkGrey - } - } - - func textViewDidEndEditing(_ textView: UITextView) { - tintView(.inactive) - } - - func textView(_ textView: UITextView, - shouldChangeTextIn range: NSRange, - replacementText text: String) -> Bool { - if text == "\n" { - if !validatePhoneNumber() { - showError() - } else { - textView.resignFirstResponder() - delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) - } - return false - } - return true - } - - internal func textViewDidChange(_ textView: UITextView) { - tintView(.active) - if textView.text.contains(placeholderText) { - animatePlaceHoder(show: true) - textView.text = textView.text.replacingOccurrences(of: placeholderText, with: "") - textView.textColor = KarhooUI.colors.darkGrey - } - - if textView.text?.count == 0 { - textView.text = placeholderText - textView.textColor = KarhooUI.colors.lightGrey - animatePlaceHoder(show: false) - } - - let size = CGSize(width: frame.width, height: .infinity) - textView.sizeThatFits(size) - } -} - -extension KarhooPhoneInputView: UIPickerViewDataSource { - func numberOfComponents(in pickerView: UIPickerView) -> Int { - return 1 - } - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - return dataSource.rowCount - } -} - -extension KarhooPhoneInputView: UIPickerViewDelegate { - func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { - countryCode.setTitle(dataSource.countryCode(at: row), for: .normal) - countryCode.setTitleColor(KarhooUI.colors.darkGrey, for: .normal) - } - - func pickerView(_ pickerView: UIPickerView, - viewForRow row: Int, - forComponent component: Int, - reusing view: UIView?) -> UIView { - - pickerView.backgroundColor = .groupTableViewBackground - var label = view as? UILabel - if label == nil { - label = UILabel() - label?.font = UIFont.systemFont(ofSize: 15) - label?.textAlignment = .center - } - - label?.text = dataSource?.titleForRow(at: row) - - return label! - } -} diff --git a/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView/KarhooPhoneInputViewDataSource.swift b/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView/KarhooPhoneInputViewDataSource.swift deleted file mode 100644 index 20db21d13..000000000 --- a/KarhooUISDK/Common/KarhooTextInputView/KarhooPhoneInputView/KarhooPhoneInputViewDataSource.swift +++ /dev/null @@ -1,337 +0,0 @@ -// -// KarhooPhoneInputViewDataSource.swift -// KarhooUISDK -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import Foundation -import CoreTelephony - -typealias PhoneCountryCodeMenuItem = (phoneCountryCode: String, title: String) - -protocol PhoneCountryCodeDataSource: class { - - var rowCount: Int { get } - - func titleForRow(at index: Int) -> String - - func countryCode(at index: Int) -> String - - func defautCountryCodeIndex() -> Int - - func defaultPhoneCountryCode() -> String? -} - -final class KarhooPhoneCountryCodeDataSource: PhoneCountryCodeDataSource { - - private let items = KarhooPhoneCountryCodeDataSource.telephoneCodesByRegionCode - - var rowCount: Int { - return items.count - } - - func titleForRow(at index: Int) -> String { - return phoneCountryCodeMenuItems()[index].title - } - - func countryCode(at index: Int) -> String { - return phoneCountryCodeMenuItems()[index].phoneCountryCode - } - - func map(_ transform: (String, String) -> T) -> [T] { - return type(of: self).telephoneCodesByRegionCode.flatMap { element in - element.1.map { transform(element.0, "+" + $0) } - } - } - - func phoneCountryCodeMenuItems() -> [PhoneCountryCodeMenuItem] { - let menuItems: [PhoneCountryCodeMenuItem] = map { (menuItemCode, menuItemTitle) in - let localizedRegionName = NSLocale.current.localizedString(forRegionCode: menuItemCode) - let regionName = localizedRegionName ?? "Unknown region" - let displayTitle = "\(regionName) (\(menuItemTitle))" - return PhoneCountryCodeMenuItem(menuItemTitle, displayTitle) - }.sorted { - return $0.title < $1.title - } - - return menuItems - } - - func defaultPhoneCountryCode() -> String? { - let networkInfo = CTTelephonyNetworkInfo().subscriberCellularProvider - - guard let regionCode = networkInfo?.isoCountryCode?.uppercased() ?? NSLocale.current.regionCode else { - return nil - } - - return telephoneCodes(forRegionCode: regionCode).first - } - - func defautCountryCodeIndex() -> Int { - guard let defaultCode = defaultPhoneCountryCode() else { - return 0 - } - - guard let defaultIndex = phoneCountryCodeMenuItems().firstIndex(where: { $0.phoneCountryCode == defaultCode - }) else { return 0 } - - return defaultIndex - } - - private func telephoneCodes(forRegionCode code: String) -> [String] { - guard let telephoneCodes = type(of: self).telephoneCodesByRegionCode[code.uppercased()] else { - return [] - } - - return telephoneCodes.map { "+" + $0 } - } - - private static let telephoneCodesByRegionCode = [ - "BD": ["880"], - "BE": ["32"], - "BF": ["226"], - "BG": ["359"], - "BA": ["387"], - "BB": ["1-246"], - "WF": ["681"], - "BL": ["590"], - "BM": ["1-441"], - "BN": ["673"], - "BO": ["591"], - "BH": ["973"], - "BI": ["257"], - "BJ": ["229"], - "BT": ["975"], - "JM": ["1-876"], - "BW": ["267"], - "WS": ["685"], - "BQ": ["599"], - "BR": ["55"], - "BS": ["1-242"], - "JE": ["44-1534"], - "BY": ["375"], - "BZ": ["501"], - "RU": ["7"], - "RW": ["250"], - "RS": ["381"], - "TL": ["670"], - "RE": ["262"], - "TM": ["993"], - "TJ": ["992"], - "RO": ["40"], - "TK": ["690"], - "GW": ["245"], - "GU": ["1-671"], - "GT": ["502"], - "GR": ["30"], - "GQ": ["240"], - "GP": ["590"], - "JP": ["81"], - "GY": ["592"], - "GG": ["44-1481"], - "GF": ["594"], - "GE": ["995"], - "GD": ["1-473"], - "GB": ["44"], - "GA": ["241"], - "SV": ["503"], - "GN": ["224"], - "GM": ["220"], - "GL": ["299"], - "GI": ["350"], - "GH": ["233"], - "OM": ["968"], - "TN": ["216"], - "JO": ["962"], - "HR": ["385"], - "HT": ["509"], - "HU": ["36"], - "HK": ["852"], - "HN": ["504"], - "VE": ["58"], - "PR": ["1-787", "1-939"], - "PS": ["970"], - "PW": ["680"], - "PT": ["351"], - "SJ": ["47"], - "PY": ["595"], - "IQ": ["964"], - "PA": ["507"], - "PF": ["689"], - "PG": ["675"], - "PE": ["51"], - "PK": ["92"], - "PH": ["63"], - "PN": ["870"], - "PL": ["48"], - "PM": ["508"], - "ZM": ["260"], - "EH": ["212"], - "EE": ["372"], - "EG": ["20"], - "ZA": ["27"], - "EC": ["593"], - "IT": ["39"], - "VN": ["84"], - "SB": ["677"], - "ET": ["251"], - "SO": ["252"], - "ZW": ["263"], - "SA": ["966"], - "ES": ["34"], - "ER": ["291"], - "ME": ["382"], - "MD": ["373"], - "MG": ["261"], - "MF": ["590"], - "MA": ["212"], - "MC": ["377"], - "UZ": ["998"], - "MM": ["95"], - "ML": ["223"], - "MO": ["853"], - "MN": ["976"], - "MH": ["692"], - "MK": ["389"], - "MU": ["230"], - "MT": ["356"], - "MW": ["265"], - "MV": ["960"], - "MQ": ["596"], - "MP": ["1-670"], - "MS": ["1-664"], - "MR": ["222"], - "IM": ["44-1624"], - "UG": ["256"], - "TZ": ["255"], - "MY": ["60"], - "MX": ["52"], - "IL": ["972"], - "FR": ["33"], - "IO": ["246"], - "SH": ["290"], - "FI": ["358"], - "FJ": ["679"], - "FK": ["500"], - "FM": ["691"], - "FO": ["298"], - "NI": ["505"], - "NL": ["31"], - "NO": ["47"], - "NA": ["264"], - "VU": ["678"], - "NC": ["687"], - "NE": ["227"], - "NF": ["672"], - "NG": ["234"], - "NZ": ["64"], - "NP": ["977"], - "NR": ["674"], - "NU": ["683"], - "CK": ["682"], - "XK": ["383"], - "CI": ["225"], - "CH": ["41"], - "CO": ["57"], - "CN": ["86"], - "CM": ["237"], - "CL": ["56"], - "CC": ["61"], - "CA": ["1"], - "CG": ["242"], - "CF": ["236"], - "CD": ["243"], - "CZ": ["420"], - "CY": ["357"], - "CX": ["61"], - "CR": ["506"], - "CW": ["599"], - "CV": ["238"], - "CU": ["53"], - "SZ": ["268"], - "SY": ["963"], - "SX": ["599"], - "KG": ["996"], - "KE": ["254"], - "SS": ["211"], - "SR": ["597"], - "KI": ["686"], - "KH": ["855"], - "KN": ["1-869"], - "KM": ["269"], - "ST": ["239"], - "SK": ["421"], - "KR": ["82"], - "SI": ["386"], - "KP": ["850"], - "KW": ["965"], - "SN": ["221"], - "SM": ["378"], - "SL": ["232"], - "SC": ["248"], - "KZ": ["7"], - "KY": ["1-345"], - "SG": ["65"], - "SE": ["46"], - "SD": ["249"], - "DO": ["1-809", "1-829"], - "DM": ["1-767"], - "DJ": ["253"], - "DK": ["45"], - "VG": ["1-284"], - "DE": ["49"], - "YE": ["967"], - "DZ": ["213"], - "US": ["1"], - "UY": ["598"], - "YT": ["262"], - "UM": ["1"], - "LB": ["961"], - "LC": ["1-758"], - "LA": ["856"], - "TV": ["688"], - "TW": ["886"], - "TT": ["1-868"], - "TR": ["90"], - "LK": ["94"], - "LI": ["423"], - "LV": ["371"], - "TO": ["676"], - "LT": ["370"], - "LU": ["352"], - "LR": ["231"], - "LS": ["266"], - "TH": ["66"], - "TG": ["228"], - "TD": ["235"], - "TC": ["1-649"], - "LY": ["218"], - "VA": ["379"], - "VC": ["1-784"], - "AE": ["971"], - "AD": ["376"], - "AG": ["1-268"], - "AF": ["93"], - "AI": ["1-264"], - "VI": ["1-340"], - "IS": ["354"], - "IR": ["98"], - "AM": ["374"], - "AL": ["355"], - "AO": ["244"], - "AS": ["1-684"], - "AR": ["54"], - "AU": ["61"], - "AT": ["43"], - "AW": ["297"], - "IN": ["91"], - "AX": ["358-18"], - "AZ": ["994"], - "IE": ["353"], - "ID": ["62"], - "UA": ["380"], - "QA": ["974"], - "MZ": ["258"] - ] -} diff --git a/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputView.swift b/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputView.swift index 615852ee6..bdce620a3 100644 --- a/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputView.swift +++ b/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputView.swift @@ -7,8 +7,10 @@ import UIKit -public protocol KarhooInputViewDelegate: class { +public protocol KarhooInputViewDelegate: AnyObject { func didBecomeInactive(identifier: String) + func didBecomeActive(identifier: String) + func didChangeCharacterInSet(identifier: String) } class KarhooTextInputView: UIView, KarhooInputView { @@ -79,7 +81,7 @@ class KarhooTextInputView: UIView, KarhooInputView { textView.layer.cornerRadius = 3.0 textView.textContainerInset = UIEdgeInsets(top: 15, left: 5, bottom: 15, right: 5) textView.layer.borderColor = KarhooTextInputViewState.inactive.color.cgColor - textView.autocorrectionType = .no + textView.autocorrectionType = .no switch contentType { case .firstname: @@ -87,9 +89,9 @@ class KarhooTextInputView: UIView, KarhooInputView { case .surname: textView.textContentType = .familyName case .email: - textView.keyboardType = .emailAddress + textView.keyboardType = .emailAddress textView.textContentType = .emailAddress - textView.autocapitalizationType = .none + textView.autocapitalizationType = .none case .phone: textView.keyboardType = .phonePad case .poiDetails: @@ -106,7 +108,7 @@ class KarhooTextInputView: UIView, KarhooInputView { titleLabel.accessibilityIdentifier = "title_label" titleLabel.text = contentType.titleText titleLabel.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) - titleLabel.tintColor = KarhooUI.colors.infoColor + titleLabel.tintColor = KarhooUI.colors.primaryTextColor addSubview(titleLabel) updateConstraints() @@ -149,6 +151,7 @@ class KarhooTextInputView: UIView, KarhooInputView { public func setActive() { textView.becomeFirstResponder() + delegate?.didBecomeActive(identifier: accessibilityIdentifier!) } public func setInactive() { @@ -195,7 +198,7 @@ class KarhooTextInputView: UIView, KarhooInputView { } textView.text = value - textView.textColor = KarhooUI.colors.infoColor + textView.textColor = KarhooUI.colors.primaryTextColor } private func validateField() -> Bool { @@ -204,92 +207,99 @@ class KarhooTextInputView: UIView, KarhooInputView { return Utils.isValidEmail(email: textView.text!) case .phone: return Utils.isValidPhoneNumber(number: textView.text!) + case .firstname, .surname: + return textView.text != contentType.placeholderText && Utils.isValidName(name: textView.text) default: return textView.text != contentType.placeholderText && textView.text != "" } } - public func getIntput() -> String { - if textView.text == contentType.placeholderText { - return "" - } - - return isValid() ? textView.text : "" - } - public func isFirstResponder() -> Bool { return textView.isFirstResponder } - private func runValidation() { - switch contentType { - case .email: - if !Utils.isValidEmail(email: textView.text!) { - showError() - } else { - textView.resignFirstResponder() - delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) - } - case .phone: - if !Utils.isValidPhoneNumber(number: textView.text!) { - showError() - } else { - textView.resignFirstResponder() - delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) - } - case .firstname, .surname: - if validateField() { - textView.resignFirstResponder() - delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) - } else { - showError() - } - default: - textView.resignFirstResponder() - delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) - } - } + private func runValidation() { + switch contentType { + case .email: + if !Utils.isValidEmail(email: textView.text!) { + showError() + } else { + textView.resignFirstResponder() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } + case .phone: + if !Utils.isValidPhoneNumber(number: textView.text!) { + showError() + } else { + textView.resignFirstResponder() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } + case .firstname, .surname: + if validateField() { + textView.resignFirstResponder() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } else { + showError() + } + default: + textView.resignFirstResponder() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } + } } extension KarhooTextInputView: UITextViewDelegate { func textViewDidBeginEditing(_ textView: UITextView) { - tintView(.active) + tintView(.active) if textView.textColor == KarhooTextInputViewState.inactive.color { - textView.textColor = KarhooUI.colors.infoColor - textView.text = nil + textView.textColor = KarhooUI.colors.primaryTextColor + textView.text = nil } + + delegate?.didBecomeActive(identifier: accessibilityIdentifier!) } func textViewDidEndEditing(_ textView: UITextView) { - tintView(.inactive) + tintView(.inactive) if textView.text.contains(" ") && contentType.whitespaceAllowed == false { textView.text = textView.text.trimmingCharacters(in: .whitespaces) } - if textView.text.isEmpty { - textView.textColor = KarhooTextInputViewState.inactive.color - textView.text = contentType.placeholderText - } else { - runValidation() - delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) - } + + if textView.text.isEmpty { + textView.textColor = KarhooTextInputViewState.inactive.color + textView.text = contentType.placeholderText + } + + runValidation() + delegate?.didBecomeInactive(identifier: accessibilityIdentifier!) + } + + public func getInput() -> String { + if textView.text == contentType.placeholderText { + return "" + } + + return isValid() ? textView.text : "" } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if text == "\n" { - runValidation() + runValidation() return false } + return true } internal func textViewDidChange(_ textView: UITextView) { let size = CGSize(width: frame.width, height: .infinity) textView.sizeThatFits(size) + delegate?.didChangeCharacterInSet(identifier: accessibilityIdentifier!) } } diff --git a/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputViewContentType.swift b/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputViewContentType.swift index fea4ca458..3f7d431db 100644 --- a/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputViewContentType.swift +++ b/KarhooUISDK/Common/KarhooTextInputView/KarhooTextInputViewContentType.swift @@ -18,15 +18,15 @@ enum KarhooTextInputViewContentType { var placeholderText: String { switch self { case .firstname: - return "e.g. Fatima" + return UITexts.Generic.name // "e.g. Fatima" case .surname: - return "e.g. Mangani" + return UITexts.Generic.surname // "e.g. Mangani" case .email: - return "e.g. thomamangani@mail.com" + return UITexts.Generic.email // "e.g. thomamangani@mail.com" case .phone: - return "e.g. +447891011123" + return UITexts.Generic.phone // "e.g. +447891011123" case .comment: - return UITexts.Generic.optional + return UITexts.Generic.commentOptional case .poiDetails: return UITexts.Booking.guestCheckoutFlightNumberPlaceholder } diff --git a/KarhooUISDK/Common/Layout/KarhooColors.swift b/KarhooUISDK/Common/Layout/KarhooColors.swift index 96e3871d9..9c0df44bc 100644 --- a/KarhooUISDK/Common/Layout/KarhooColors.swift +++ b/KarhooUISDK/Common/Layout/KarhooColors.swift @@ -22,9 +22,12 @@ public protocol KarhooColors { /// The accent color is used for secondary category actions (links, filters) var accent: UIColor { get } - /// Black is used for text or icons associated with informational texts (titles, body, captions, some icons) + /// InfoColor is used for text or icons associated with informational texts (titles, body, captions, some icons) var infoColor: UIColor { get } + /// PrimaryTextColor is used for informational texts + var primaryTextColor: UIColor { get } + var medGrey: UIColor { get } /// The light grey is used for text backgrounds @@ -71,6 +74,9 @@ public extension KarhooColors { var infoColor: UIColor { return .darkGray } + var primaryTextColor: UIColor { + return .darkGray + } var medGrey: UIColor { return UIColor(white: 153.0 / 255.0, alpha: 1.0) } @@ -114,11 +120,8 @@ public extension KarhooColors { var darkBlue: UIColor { return #colorLiteral(red: 0.09411764706, green: 0.1019607843, blue: 0.2784313725, alpha: 1) // #181A47 } - var paymentLightGrey: UIColor { - return #colorLiteral(red: 0.5176470588, green: 0.5960784314, blue: 0.6784313725, alpha: 1) - } - var brightGreen: UIColor { - return #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1) + var infoBackgroundColor: UIColor { + return #colorLiteral(red: 0.9607843137, green: 0.9607843137, blue: 0.9607843137, alpha: 1) } } diff --git a/KarhooUISDK/Common/TermsConditionsView/TermsConditionsStringBuilder.swift b/KarhooUISDK/Common/TermsConditionsView/TermsConditionsStringBuilder.swift index 6d61fd012..7a020a0bb 100644 --- a/KarhooUISDK/Common/TermsConditionsView/TermsConditionsStringBuilder.swift +++ b/KarhooUISDK/Common/TermsConditionsView/TermsConditionsStringBuilder.swift @@ -10,45 +10,27 @@ import Foundation import UIKit public struct TermsConditionsStringBuilder { - - public static var karhooTermsURLString: String { - #if PRODUCTION - return "https://cdn.karhoo.com/d/terms/KarhooAppTerms/Karhoo_terms_and_conditions.html" - #else - return "https://cdn.karhoo.com/d/terms/KarhooAppTerms/Karhoo_terms_and_conditions.html" - #endif - } - - public static var karhooPrivacyPolicyURLString: String { - #if PRODUCTION - return "https://cdn.karhoo.com/d/terms/KarhooAppTerms/Karhoo_privacy.html" - #else - return "https://cdn.karhoo.com/d/terms/KarhooAppTerms/Karhoo_privacy.html" - #endif - } - + public static func karhooTermsURL() -> URL { - return URL(string: karhooTermsURLString)! + return URL(string: UITexts.TermsConditions.karhooTermsLink)! } public static func karhooPrivacyPolicy() -> URL { - return URL(string: karhooPrivacyPolicyURLString)! + return URL(string: UITexts.TermsConditions.karhooPolicyLink)! } func registrationTermsCopy() -> NSAttributedString { return attributedTermsString(context: "Karhoo", action: UITexts.Generic.registeringAccountAction, - policyType: UITexts.Generic.privacyPolicy, + policyType: UITexts.Generic.cancellationPolicy, termsURL: TermsConditionsStringBuilder.karhooTermsURL(), policyURL: TermsConditionsStringBuilder.karhooPrivacyPolicy()) } func bookingTermsCopy(supplierName: String?, termsURL: URL) -> NSAttributedString { - return attributedTermsString(context: supplierName, - action: UITexts.Generic.makingABookingAction, - policyType: UITexts.Generic.cancellationPolicy, - termsURL: termsURL, - policyURL: termsURL) // future proof for fleet cancellation policy urls + return bookingAttributedTermsString(fleetName: supplierName, + termsURL: termsURL, + policyURL: termsURL) // future proof for fleet cancellation policy urls } private func attributedTermsString(context: String?, @@ -71,10 +53,14 @@ public struct TermsConditionsStringBuilder { let policyAttributes: [NSAttributedString.Key: Any] = [.font: KarhooUI.fonts.captionRegular(), .link: policyURL, - .foregroundColor: KarhooUI.colors.primary] + .foregroundColor: KarhooUI.colors.primary, + .underlineColor: KarhooUI.colors.accent, + .underlineStyle: NSUnderlineStyle.single.rawValue] let termsAttributes: [NSAttributedString.Key: Any] = [.font: KarhooUI.fonts.captionRegular(), .foregroundColor: KarhooUI.colors.primary, + .underlineStyle: NSUnderlineStyle.single.rawValue, + .underlineColor: KarhooUI.colors.accent, .link: termsURL] let termsText = NSMutableAttributedString() @@ -92,5 +78,78 @@ public struct TermsConditionsStringBuilder { return termsText } + + private func bookingAttributedTermsString(fleetName: String?, + termsURL: URL, + policyURL: URL) -> NSAttributedString { + guard let fleetName = fleetName + else { + return NSAttributedString(string: "") + } + + // dp stands for Demand Partner. Karhoo provides the default links, but they may be updated by our demand partners + let dpTermsLink = URL(string: UITexts.TermsConditions.termsLink) ?? TermsConditionsStringBuilder.karhooTermsURL() + let dpPolicyLink = URL(string: UITexts.TermsConditions.policyLink) ?? TermsConditionsStringBuilder.karhooPrivacyPolicy() + + let dpTermsText: String = UITexts.Generic.termsOfUse + let dpPolicyText: String = UITexts.Generic.privacyPolicy + let fleetTermsText: String = UITexts.Generic.termsAndConditions + let fleetPolicyText: String = UITexts.Generic.cancellationPolicy + + let paragraphStyle = NSMutableParagraphStyle() + paragraphStyle.alignment = .center + paragraphStyle.lineSpacing = 8 + + let regularAttributes: [NSAttributedString.Key: Any] = [.font: KarhooUI.fonts.captionRegular(), + .foregroundColor: KarhooUI.colors.medGrey, + .paragraphStyle: paragraphStyle] + + let dpPolicyAttributes: [NSAttributedString.Key: Any] = [.font: KarhooUI.fonts.captionRegular(), + .link: dpPolicyLink, + .foregroundColor: KarhooUI.colors.primary, + .underlineColor: KarhooUI.colors.accent, + .underlineStyle: NSUnderlineStyle.single.rawValue, + .paragraphStyle: paragraphStyle] + + let dpTermsAttributes: [NSAttributedString.Key: Any] = [.font: KarhooUI.fonts.captionRegular(), + .foregroundColor: KarhooUI.colors.primary, + .underlineStyle: NSUnderlineStyle.single.rawValue, + .underlineColor: KarhooUI.colors.accent, + .link: dpTermsLink, + .paragraphStyle: paragraphStyle] + + let fleetPolicyAttributes: [NSAttributedString.Key: Any] = [.font: KarhooUI.fonts.captionRegular(), + .link: policyURL, + .foregroundColor: KarhooUI.colors.primary, + .underlineColor: KarhooUI.colors.accent, + .underlineStyle: NSUnderlineStyle.single.rawValue, + .paragraphStyle: paragraphStyle] + + let fleetTermsAttributes: [NSAttributedString.Key: Any] = [.font: KarhooUI.fonts.captionRegular(), + .foregroundColor: KarhooUI.colors.primary, + .underlineStyle: NSUnderlineStyle.single.rawValue, + .underlineColor: KarhooUI.colors.accent, + .link: termsURL, + .paragraphStyle: paragraphStyle] + + let termsText = NSMutableAttributedString() + + let fullText = String(format: NSLocalizedString(UITexts.TermsConditions.bookingTermAndConditionsFullText, + comment: ""), dpTermsText, dpPolicyText, fleetName, fleetTermsText, fleetPolicyText) + + termsText.append(NSAttributedString(string: fullText, attributes: regularAttributes)) + + let dpTermsRange = (termsText.string as NSString).range(of: dpTermsText) + let dpPolicyRange = (termsText.string as NSString).range(of: dpPolicyText) + let fleetTermsRange = (termsText.string as NSString).range(of: fleetTermsText) + let fleetPolicyRange = (termsText.string as NSString).range(of: fleetPolicyText) + + termsText.addAttributes(dpTermsAttributes, range: dpTermsRange) + termsText.addAttributes(dpPolicyAttributes, range: dpPolicyRange) + termsText.addAttributes(fleetTermsAttributes, range: fleetTermsRange) + termsText.addAttributes(fleetPolicyAttributes, range: fleetPolicyRange) + + return termsText + } } diff --git a/KarhooUISDK/Common/TermsConditionsView/TermsConditionsView.swift b/KarhooUISDK/Common/TermsConditionsView/TermsConditionsView.swift index 52b301964..cd0c2d967 100644 --- a/KarhooUISDK/Common/TermsConditionsView/TermsConditionsView.swift +++ b/KarhooUISDK/Common/TermsConditionsView/TermsConditionsView.swift @@ -9,7 +9,7 @@ import UIKit import KarhooSDK -public protocol TermsConditionsViewDelegate: class { +public protocol TermsConditionsViewDelegate: AnyObject { func selectedRegistrationTermsConditions() } @@ -63,10 +63,7 @@ public final class TermsConditionsView: UIView, UITextViewDelegate { public override func updateConstraints() { if !didSetupConstraints { - _ = [termsTextView.topAnchor.constraint(equalTo: topAnchor), - termsTextView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8.0), - termsTextView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8.0), - termsTextView.bottomAnchor.constraint(equalTo: bottomAnchor)].map { $0.isActive = true } + termsTextView.anchor(top: topAnchor, leading: leadingAnchor, bottom: bottomAnchor, trailing: trailingAnchor, paddingLeft: 8.0, paddingRight: 8.0) } super.updateConstraints() diff --git a/KarhooUISDK/Common/UITexts.swift b/KarhooUISDK/Common/UITexts.swift index 44f0fca5e..3fb5502a1 100644 --- a/KarhooUISDK/Common/UITexts.swift +++ b/KarhooUISDK/Common/UITexts.swift @@ -35,6 +35,7 @@ public enum UITexts { public static let registeringAccountAction = "Text.Generic.RegisterAccountAction".localized public static let makingABookingAction = "Text.Generic.MakingBookingAction".localized public static let termsAndConditions = "Text.Generic.TermsConditions".localized + public static let termsOfUse = "Text.Generic.TermsOfUse".localized public static let privacyPolicy = "Text.Generic.PrivacyPolicy".localized public static let cancellationPolicy = "Text.Generic.CancellationPolicy".localized public static let minutes = "Text.Generic.Minutes".localized @@ -61,12 +62,14 @@ public enum UITexts { public static let change = "Text.Generic.Change".localized public static let submit = "Text.Generic.Submit".localized public static let etaLong = "Text.Generic.ETALong".localized + public static let meetGreet = "Text.Generic.MeetGreet".localized public static let estimatedPrice = "Text.Generic.EPrice".localized public static let name = "Text.Generic.Name".localized public static let surname = "Text.Generic.Surname".localized public static let email = "Text.Generic.Email".localized public static let phone = "Text.Generic.PhoneNumber".localized public static let comment = "Text.Generic.Comment".localized + public static let commentOptional = "Text.Generic.Comment.Optional".localized public static let optional = "Text.Generic.Optional".localized public static let errorMessage = "Text.Generic.ErrorMessage".localized } @@ -127,6 +130,8 @@ public enum UITexts { public static let prebookingWithinTheHour = "Text.Error.PrebookingWithinTheHour".localized public static let missingPaymentSDKToken = "Text.Errors.failedToInitialisePaymentSetup".localized public static let noResultsFound = "Text.Errors.NoResultsFound".localized + public static let missingPhoneNumber = "Text.Errors.MissingPhoneNumber".localized + public static let invalidPhoneNumber = "Text.Errors.InvalidPhoneNumber".localized } /* Payment Error */ @@ -140,6 +145,14 @@ public enum UITexts { public enum TermsConditions { // 1: action 2: Supplier name, 2: "Terms and Conditions", 3: "Cancellation/Privacy Policy" public static let termsConditionFullString = "Text.TermsConditions.FullString".localized + // 1: "Terms and Conditions", 2: "Privacy Policy", 3: Fleet Name, 4: "Terms and Conditions, 5: "Cancellation Policy" + public static let bookingTermAndConditionsFullText = "Text.TermsConditions.BookingFullString".localized + + public static let karhooTermsLink = "Text.TermsConditions.KarhooTermsLink".localized + public static let karhooPolicyLink = "Text.TermsConditions.KarhooPolicyLink".localized + + public static var termsLink = "Text.TermsConditions.TermsLink".localized + public static var policyLink = "Text.TermsConditions.PolicyLink".localized } /* Demand API (Karhoo specific) errors */ @@ -147,9 +160,15 @@ public enum UITexts { public static let K3002 = "Text.KarhooError.K3002".localized // no availability in requested area public static let Q0001 = "Text.KarhooError.Q0001".localized // origin } + + /* Help */ + public enum Help { + public static var faqLink = "Text.Help.FAQ.Link".localized + public static var contactUsLink = "Text.Help.ContactUs.Link".localized + } /* Side menu */ - enum SideMenu { + public enum SideMenu { public static let signIn = "Text.SideMenu.SignIn".localized public static let profile = "Text.SideMenu.Profile".localized public static let register = "Text.SideMenu.Register".localized @@ -190,6 +209,7 @@ public enum UITexts { public enum Booking { public static let requestCar = "Text.Booking.RequestCar".localized public static let requestingCar = "Text.Booking.RequestingCar".localized + public static let next = "Text.Booking.Next".localized public static let requestReceived = "Text.Booking.RequestReceived".localized public static let enterDestination = "Text.Booking.EnterDestination".localized public static let baseFareExplanation = "Text.Booking.BaseFareExplanation".localized @@ -203,6 +223,16 @@ public enum UITexts { public static let guestCheckoutPassengerDetailsTitle = "Text.Booking.GuestCheckoutPassengerDetailsTitle".localized public static let guestCheckoutPaymentDetailsTitle = "Text.Booking.GuestCheckoutPaymentDetailsTitle".localized public static let guestCheckoutFlightNumberPlaceholder = "Text.Booking.GuestCheckoutFlightNumberPlaceholder".localized + public static let estimatedInfoBox = "Text.Booking.EstimatedInfoBox".localized + public static let meteredInfoBox = "Text.Booking.MeteredInfoBox".localized + public static let fixedInfoBox = "Text.Booking.FixedInfoBox".localized + public static let learnMore = "Text.Booking.LearnMore".localized + public static let passenger = "Text.Booking.Passenger".localized + public static let maximumPassengers = "Text.Booking.MaximumPassengers".localized + public static let maximumLuggages = "Text.Booking.MaximumLuggages".localized + public static let gpsTracking = "Text.Booking.GPSTracking".localized + public static let trainTracking = "Text.Booking.TrainTracking".localized + public static let flightTracking = "Text.Booking.FlightTracking".localized } public enum Availability { @@ -218,6 +248,60 @@ public enum UITexts { public static let cancelling = "Text.TripAllocation.Cancelling".localized public static let cancelInstruction = "Text.TripAllocation.CancelInstruction".localized } + + public enum PassengerDetails { + public static let title = "Text.Booking.PassengerDetails.Title".localized + public static let subtitle = "Text.Booking.PassengerDetails.Subtitle".localized + public static let firstName = "Text.Booking.PassengerDetails.FirstName".localized + public static let lastName = "Text.Booking.PassengerDetails.LastName".localized + public static let email = "Text.Booking.PassengerDetails.Email".localized + public static let mobilePhone = "Text.Booking.PassengerDetails.MobilePhone".localized + public static let saveAction = "Text.Booking.PassengerDetails.SaveAction".localized + public static let add = "Text.Booking.PassengerDetails.Add".localized + } + + public enum QuoteCategory { + public static let electric = "Text.QuoteCategory.Electric".localized + public static let mpv = "Text.QuoteCategory.MPV".localized + public static let saloon = "Text.QuoteCategory.Saloon".localized + public static let exec = "Text.QuoteCategory.Exec".localized + public static let executive = "Text.QuoteCategory.Executive".localized + public static let moto = "Text.QuoteCategory.Moto".localized + public static let motorcycle = "Text.QuoteCategory.Motorcycle".localized + public static let taxi = "Text.QuoteCategory.Taxi".localized + } + + public enum VehicleClass { + public static let saloon = "Text.VehicleClass.Saloon".localized + public static let taxi = "Text.VehicleClass.Taxi".localized + public static let mpv = "Text.VehicleClass.MPV".localized + public static let exec = "Text.VehicleClass.Exec".localized + public static let executive = "Text.VehicleClass.Executive".localized + public static let moto = "Text.VehicleClass.Moto".localized + public static let motorcycle = "Text.VehicleClass.Motorcycle".localized + public static let electric = "Text.VehicleClass.Electric".localized + } + + public enum VehicleType { + public static let moto = "Text.VehicleType.Moto".localized + public static let standard = "Text.VehicleType.Standard".localized + public static let mpv = "Text.VehicleType.MPV".localized + public static let bus = "Text.VehicleType.Bus".localized + } + + public enum VehicleTag { + public static let electric = "Text.VehicleTag.Electric".localized + public static let hybrid = "Text.VehicleTag.Hybrid".localized + public static let wheelchair = "Text.VehicleTag.Wheelchair".localized + public static let childseat = "Text.VehicleTag.Childseat".localized + public static let taxi = "Text.VehicleTag.Taxi".localized + public static let executive = "Text.VehicleTag.Executive".localized + } + + public enum CountryCodeSelection { + public static let title = "Text.Booking.CountryCodeSelection.Title".localized + public static let search = "Text.Booking.CountryCodeSelection.Search".localized + } /* Trip */ public enum Trip { @@ -349,4 +433,19 @@ public extension String { return NSLocalizedString(self, bundle: .current, comment: "") } } + + func firstLetterUppercased() -> String { + guard let firstLetter = self.first?.uppercased() else { + return self + } + return firstLetter + self.dropFirst() + } + + func removePrefix(_ prefix: String) -> String { + guard self.hasPrefix(prefix) + else { + return self + } + return String(self.dropFirst(prefix.count)) + } } diff --git a/KarhooUISDK/Common/VehicleCapacityView/VehicleCapacityView.swift b/KarhooUISDK/Common/VehicleCapacityView/VehicleCapacityView.swift index 1087f2ead..7104ff457 100644 --- a/KarhooUISDK/Common/VehicleCapacityView/VehicleCapacityView.swift +++ b/KarhooUISDK/Common/VehicleCapacityView/VehicleCapacityView.swift @@ -10,125 +10,243 @@ import UIKit import KarhooSDK public struct KHVehicleCapacityViewID { - public static let baggageInfoView = "baggage_info_view" - public static let baggageIcon = "baggage_image" - public static let baggageCapacityLabel = "baggage_capacity_label" - public static let capacityInfoView = "capacity_info_view" - public static let capacityIcon = "passenger_capacity_image" - public static let passengerCapacityLabel = "passenger_capacity_label" + public static let capacityView = "vehicle_capacity_view" + public static let baggageContentView = "baggage_content_view" + public static let passengerCapacityContentView = "passenger_capacity_content_view" + public static let baggageInfoView = "baggage_info_view" + public static let baggageIcon = "baggage_image" + public static let baggageCapacityLabel = "baggage_capacity_label" + public static let capacityInfoView = "capacity_info_view" + public static let capacityIcon = "passenger_capacity_image" + public static let passengerCapacityLabel = "passenger_capacity_label" + public static let additionalCapacityContentView = "additional_capabilities_content_view" + public static let additionalFleetCapabilitiesView = "additional_capabilities_view" + public static let additionalFleetCapabilitiesLabel = "additional_capabilities_label" } -final class VehicleCapacityView: UIView { - - private var stackContainer: UIStackView! - private var baggageInfoView: UIView! - private var capacityInfoView: UIView! +final class VehicleCapacityView: UIStackView { + + // MARK: - UI + private lazy var baggageContentView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHVehicleCapacityViewID.baggageContentView + view.backgroundColor = .clear + view.anchor(width: 33.0, height: 33.0) + return view + }() + + // Note: Needed to provide the background color for the baggageImageView + private lazy var baggageBackgroundView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHVehicleCapacityViewID.baggageInfoView + view.backgroundColor = KarhooUI.colors.infoBackgroundColor + view.layer.cornerRadius = 10.0 + view.layer.masksToBounds = true + view.anchor(width: 20.0, height: 20.0) + return view + }() + + private var baggageImageView: UIImageView = { + let imageView = UIImageView(image: UIImage.uisdkImage("luggage_icon")) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFill + imageView.accessibilityIdentifier = KHVehicleCapacityViewID.baggageIcon + imageView.anchor(width: 14.0, height: 14.0) + return imageView + }() + + private lazy var baggageCapacityNumberCircleView: UIView = { + let view = UIView() + view.backgroundColor = KarhooUI.colors.white + view.anchor(width: 14.0, height: 14.0) + view.layer.cornerRadius = 7.0 + return view + }() + + private lazy var baggageCapacityLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHVehicleCapacityViewID.baggageCapacityLabel + label.textColor = KarhooUI.colors.primaryTextColor + label.font = KarhooUI.fonts.footnoteBold() + return label + }() + + private lazy var passengerCapacityContentView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHVehicleCapacityViewID.passengerCapacityContentView + view.backgroundColor = .clear + view.anchor(width: 33.0, height: 33.0) + return view + }() + + // Note: Needed to provide the background color for the passengerCapacityImageView + private lazy var passengerCapacityBackgroundView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHVehicleCapacityViewID.capacityInfoView + view.backgroundColor = KarhooUI.colors.infoBackgroundColor + view.layer.cornerRadius = 10.0 + view.layer.masksToBounds = true + view.anchor(width: 20.0, height: 20.0) + return view + }() - private var baggageIcon: UIImageView! - private var baggageCapacityLabel: UILabel! - private var capacityIcon: UIImageView! - private var passengerCapacityLabel: UILabel! + private lazy var passengerCapacityImageView: UIImageView = { + let imageView = UIImageView(image: UIImage.uisdkImage("passenger_capacity_icon")) + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFill + imageView.accessibilityIdentifier = KHVehicleCapacityViewID.capacityIcon + imageView.anchor(width: 14.0, height: 14.0) + return imageView + }() + private lazy var passengerCapacityCircleView: UIView = { + let view = UIView() + view.backgroundColor = KarhooUI.colors.white + view.anchor(width: 14.0, height: 14.0) + view.layer.cornerRadius = 7.0 + view.layer.masksToBounds = true + return view + }() + + private lazy var passengerCapacityLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHVehicleCapacityViewID.passengerCapacityLabel + label.textColor = KarhooUI.colors.primaryTextColor + label.font = KarhooUI.fonts.footnoteBold() + return label + }() + + // Note: Added this view to preserve the size (and spacing respectably) between all 3 possible logical areas of the VehicleCapacityView + private lazy var additionalFleetCapabilitiesContentView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHVehicleCapacityViewID.additionalCapacityContentView + view.backgroundColor = .clear + view.anchor(width: 33.0, height: 33.0) + return view + }() + + private lazy var additionalFleetCapabilitiesBackgroundView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHVehicleCapacityViewID.additionalFleetCapabilitiesView + view.backgroundColor = KarhooUI.colors.infoBackgroundColor + view.layer.cornerRadius = 10.0 + view.anchor(width: 20.0, height: 20.0) + view.layer.masksToBounds = true + return view + }() + + private lazy var additionalFleetCapabiliesLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHVehicleCapacityViewID.additionalFleetCapabilitiesLabel + label.textColor = KarhooUI.colors.infoColor + label.font = KarhooUI.fonts.captionBold() + return label + }() + + // MARK: - Init init() { super.init(frame: .zero) self.setUpView() } - required init?(coder: NSCoder) { + required init(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + // MARK: - Setup private func setUpView() { translatesAutoresizingMaskIntoConstraints = false - accessibilityIdentifier = "vehicle_capacity_view" + accessibilityIdentifier = KHVehicleCapacityViewID.capacityView backgroundColor = .clear + axis = .horizontal + spacing = 5.0 + alignment = .center + distribution = .fillProportionally - stackContainer = UIStackView() - stackContainer.translatesAutoresizingMaskIntoConstraints = false - stackContainer.accessibilityIdentifier = "stack_container" - stackContainer.axis = .horizontal - stackContainer.spacing = 8.0 - stackContainer.alignment = .leading - stackContainer.distribution = .equalSpacing - addSubview(stackContainer) - - baggageInfoView = UIView() - baggageInfoView.translatesAutoresizingMaskIntoConstraints = false - baggageInfoView.accessibilityIdentifier = KHVehicleCapacityViewID.baggageInfoView - stackContainer.addArrangedSubview(baggageInfoView) + baggageContentView.addSubview(baggageBackgroundView) + baggageBackgroundView.addSubview(baggageImageView) + baggageContentView.addSubview(baggageCapacityNumberCircleView) + baggageCapacityNumberCircleView.addSubview(baggageCapacityLabel) + addArrangedSubview(baggageContentView) - baggageIcon = UIImageView(image: UIImage.uisdkImage("luggage_icon")) - baggageIcon.translatesAutoresizingMaskIntoConstraints = false - baggageIcon.contentMode = .scaleAspectFill - baggageIcon.accessibilityIdentifier = KHVehicleCapacityViewID.baggageIcon - baggageInfoView.addSubview(baggageIcon) - - baggageCapacityLabel = UILabel() - baggageCapacityLabel.translatesAutoresizingMaskIntoConstraints = false - baggageCapacityLabel.accessibilityIdentifier = KHVehicleCapacityViewID.baggageCapacityLabel - baggageCapacityLabel.textColor = KarhooUI.colors.guestCheckoutLightGrey - baggageCapacityLabel.font = UIFont.systemFont(ofSize: 13.0) - baggageCapacityLabel.text = "x0" - baggageInfoView.addSubview(baggageCapacityLabel) - - capacityInfoView = UIView() - capacityInfoView.translatesAutoresizingMaskIntoConstraints = false - capacityInfoView.accessibilityIdentifier = KHVehicleCapacityViewID.capacityInfoView - stackContainer.addArrangedSubview(capacityInfoView) - - capacityIcon = UIImageView(image: UIImage.uisdkImage("passenger_capacity_icon")) - capacityIcon.translatesAutoresizingMaskIntoConstraints = false - capacityIcon.contentMode = .scaleAspectFill - capacityIcon.accessibilityIdentifier = KHVehicleCapacityViewID.capacityIcon - capacityInfoView.addSubview(capacityIcon) - - passengerCapacityLabel = UILabel() - passengerCapacityLabel.translatesAutoresizingMaskIntoConstraints = false - passengerCapacityLabel.accessibilityIdentifier = KHVehicleCapacityViewID.passengerCapacityLabel - passengerCapacityLabel.textColor = KarhooUI.colors.guestCheckoutLightGrey - passengerCapacityLabel.font = UIFont.systemFont(ofSize: 13.0) - passengerCapacityLabel.text = "x0" - capacityInfoView.addSubview(passengerCapacityLabel) + passengerCapacityContentView.addSubview(passengerCapacityBackgroundView) + passengerCapacityBackgroundView.addSubview(passengerCapacityImageView) + passengerCapacityContentView.addSubview(passengerCapacityCircleView) + passengerCapacityCircleView.addSubview(passengerCapacityLabel) + addArrangedSubview(passengerCapacityContentView) setUpConstraints() + + layoutIfNeeded() } private func setUpConstraints() { - _ = [stackContainer.topAnchor.constraint(equalTo: topAnchor), - stackContainer.leadingAnchor.constraint(equalTo: leadingAnchor), - stackContainer.trailingAnchor.constraint(equalTo: trailingAnchor), - stackContainer.bottomAnchor.constraint(equalTo: bottomAnchor)].map { $0.isActive = true } - - _ = [baggageIcon.topAnchor.constraint(equalTo: baggageInfoView.topAnchor), - baggageIcon.leadingAnchor.constraint(equalTo: baggageInfoView.leadingAnchor), - baggageIcon.bottomAnchor.constraint(equalTo: baggageInfoView.bottomAnchor), - baggageIcon.widthAnchor.constraint(equalToConstant: 20.0), - baggageIcon.heightAnchor.constraint(equalToConstant: 14.0)].map { $0.isActive = true } + baggageBackgroundView.centerX(inView: baggageContentView) + baggageBackgroundView.centerY(inView: baggageContentView) + baggageImageView.centerX(inView: baggageBackgroundView) + baggageImageView.centerY(inView: baggageBackgroundView) + baggageCapacityNumberCircleView.anchor(top: baggageContentView.topAnchor, + trailing: baggageContentView.trailingAnchor) - _ = [baggageCapacityLabel.centerYAnchor.constraint(equalTo: baggageIcon.centerYAnchor), - baggageCapacityLabel.leadingAnchor.constraint(equalTo: baggageIcon.trailingAnchor, constant: 4.0), - baggageCapacityLabel.trailingAnchor.constraint(equalTo: baggageInfoView.trailingAnchor)] - .map { $0.isActive = true } + baggageCapacityLabel.centerX(inView: baggageCapacityNumberCircleView) + baggageCapacityLabel.centerY(inView: baggageCapacityNumberCircleView) baggageCapacityLabel.setContentCompressionResistancePriority(.required, for: .horizontal) - - _ = [capacityIcon.topAnchor.constraint(equalTo: capacityInfoView.topAnchor), - capacityIcon.leadingAnchor.constraint(equalTo: capacityInfoView.leadingAnchor), - capacityIcon.bottomAnchor.constraint(equalTo: capacityInfoView.bottomAnchor), - capacityIcon.widthAnchor.constraint(equalToConstant: 20.0), - capacityIcon.heightAnchor.constraint(equalToConstant: 14.0)].map { $0.isActive = true } - - _ = [passengerCapacityLabel.centerYAnchor.constraint(equalTo: capacityIcon.centerYAnchor), - passengerCapacityLabel.leadingAnchor.constraint(equalTo: capacityIcon.trailingAnchor, constant: 4.0), - passengerCapacityLabel.trailingAnchor.constraint(equalTo: capacityInfoView.trailingAnchor)] - .map { $0.isActive = true } + + passengerCapacityBackgroundView.centerX(inView: passengerCapacityContentView) + passengerCapacityBackgroundView.centerY(inView: passengerCapacityContentView) + passengerCapacityImageView.centerX(inView: passengerCapacityBackgroundView) + passengerCapacityImageView.centerY(inView: passengerCapacityBackgroundView) + passengerCapacityCircleView.anchor(top: passengerCapacityContentView.topAnchor, + trailing: passengerCapacityContentView.trailingAnchor) + + passengerCapacityLabel.centerX(inView: passengerCapacityCircleView) + passengerCapacityLabel.centerY(inView: passengerCapacityCircleView) passengerCapacityLabel.setContentCompressionResistancePriority(.required, for: .horizontal) } - public func setBaggageCapacity(_ value: String) { - baggageCapacityLabel.text = "x" + value + // MARK: - Public + public func setBaggageCapacity(_ value: Int) { + guard value > 0 else { + baggageContentView.removeFromSuperview() + return + } + baggageCapacityLabel.text = "\(value)" } - public func setPassengerCapacity(_ value: String) { - passengerCapacityLabel.text = "x" + value + public func setPassengerCapacity(_ value: Int) { + guard value > 0 else { + passengerCapacityContentView.removeFromSuperview() + return + } + passengerCapacityLabel.text = "\(value)" + } + + public func setAdditionalFleetCapabilities(_ value: Int) { + guard value > 0 else { return } + additionalFleetCapabiliesLabel.text = "+\(value)" + + addArrangedSubview(additionalFleetCapabilitiesContentView) + additionalFleetCapabilitiesContentView.addSubview(additionalFleetCapabilitiesBackgroundView) + additionalFleetCapabilitiesBackgroundView.addSubview(additionalFleetCapabiliesLabel) + setAdditionalConstraints() + + needsUpdateConstraints() + } + + private func setAdditionalConstraints() { + additionalFleetCapabilitiesBackgroundView.centerX(inView: additionalFleetCapabilitiesContentView) + additionalFleetCapabilitiesBackgroundView.centerY(inView: additionalFleetCapabilitiesContentView) + + additionalFleetCapabiliesLabel.centerX(inView: additionalFleetCapabilitiesBackgroundView) + additionalFleetCapabiliesLabel.centerY(inView: additionalFleetCapabilitiesBackgroundView) } } diff --git a/KarhooUISDK/Extensions/KarhooSDKExtensions/PassengerDetails+Extensions.swift b/KarhooUISDK/Extensions/KarhooSDKExtensions/PassengerDetails+Extensions.swift new file mode 100644 index 000000000..56d8b7923 --- /dev/null +++ b/KarhooUISDK/Extensions/KarhooSDKExtensions/PassengerDetails+Extensions.swift @@ -0,0 +1,27 @@ +// +// PassengerDetails+Extensions.swift +// KarhooUISDK +// +// Created by Diana Petrea on 15.10.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +extension PassengerDetails { + var areValid: Bool { + get { + guard Utils.isValidName(name: firstName), + Utils.isValidName(name: lastName), + Utils.isValidEmail(email: email), + Utils.isValidPhoneNumber(number: phoneNumber), + !locale.isEmpty + else { + return false + } + + return true + } + } +} diff --git a/KarhooUISDK/Extensions/KarhooSDKExtensions/QuoteCategory+Extensions.swift b/KarhooUISDK/Extensions/KarhooSDKExtensions/QuoteCategory+Extensions.swift new file mode 100644 index 000000000..758284275 --- /dev/null +++ b/KarhooUISDK/Extensions/KarhooSDKExtensions/QuoteCategory+Extensions.swift @@ -0,0 +1,57 @@ +// +// QuoteCategory+Extensions.swift +// KarhooUISDK +// +// Created by Diana Petrea on 02.11.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +extension QuoteCategory { + var localizedCategoryName: String { + get { + let value = categoryName.uppercased() + + guard let enumCase = QuoteCategoryName(rawValue: value) + else { + return categoryName + } + + return enumCase.title + } + } +} + +public enum QuoteCategoryName: String { + case electric = "ELECTRIC" + case mpv = "MPV" + case saloon = "SALOON" + case exec = "EXEC" + case executive = "EXECUTIVE" + case moto = "MOTO" + case motorcycle = "MOTORCYCLE" + case taxi = "TAXI" + + var title: String { + switch self { + case .electric: + return UITexts.QuoteCategory.electric + case .mpv: + return UITexts.QuoteCategory.mpv + case .saloon: + return UITexts.QuoteCategory.saloon + case .exec: + return UITexts.QuoteCategory.exec + case .executive: + return UITexts.QuoteCategory.executive + case .moto: + return UITexts.QuoteCategory.moto + case .motorcycle: + return UITexts.QuoteCategory.motorcycle + case .taxi: + return UITexts.QuoteCategory.taxi + } + } +} diff --git a/KarhooUISDK/Extensions/KarhooSDKExtensions/QuoteVehicle+Extensions.swift b/KarhooUISDK/Extensions/KarhooSDKExtensions/QuoteVehicle+Extensions.swift new file mode 100644 index 000000000..c519aeaf5 --- /dev/null +++ b/KarhooUISDK/Extensions/KarhooSDKExtensions/QuoteVehicle+Extensions.swift @@ -0,0 +1,89 @@ +// +// QuoteVehicle+Extensions.swift +// KarhooUISDK +// +// Created by Diana Petrea on 01.11.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +extension QuoteVehicle { + + var localizedVehicleClass: String { + get { + let value = vehicleClass.uppercased() + + guard let enumCase = VehicleClass(rawValue: value) + else { + return vehicleClass + } + + return enumCase.title + } + } + + var localizedCarType: String { + get { + let value = type.uppercased() + + guard let enumCase = VehicleType(rawValue: value) + else { + return type + } + + return enumCase.title + } + } +} + +public enum VehicleClass: String { + case saloon = "SALOON" + case taxi = "TAXI" + case mpv = "MPV" + case exec = "EXEC" + case moto = "MOTO" + case motorcycle = "MOTORCYCLE" + case electric = "ELECTRIC" + + var title: String { + switch self { + case .saloon: + return UITexts.VehicleClass.saloon + case .taxi: + return UITexts.VehicleClass.taxi + case .mpv: + return UITexts.VehicleClass.mpv + case .exec: + return UITexts.VehicleClass.exec + case .moto: + return UITexts.VehicleClass.moto + case .motorcycle: + return UITexts.VehicleClass.motorcycle + case .electric: + return UITexts.VehicleClass.electric + } + } +} + +public enum VehicleType: String { + case moto = "MOTO" + case standard = "STANDARD" + case mpv = "MPV" + case bus = "BUS" + + var title: String { + switch self { + case .moto: + return UITexts.VehicleType.moto + case .standard: + return UITexts.VehicleType.standard + case .mpv: + return UITexts.VehicleType.mpv + case .bus: + return UITexts.VehicleType.bus + } + } +} + diff --git a/KarhooUISDK/Extensions/UIViewController+Extensions.swift b/KarhooUISDK/Extensions/UIViewController+Extensions.swift new file mode 100644 index 000000000..f301a49b7 --- /dev/null +++ b/KarhooUISDK/Extensions/UIViewController+Extensions.swift @@ -0,0 +1,30 @@ +// +// UIViewController+Extensions.swift +// KarhooUISDK +// +// Created by Diana Petrea on 04.10.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation + +public extension UIViewController { + func forceLightMode() { + if #available(iOS 13.0, *) { + // Always adopt a light interface style. + overrideUserInterfaceStyle = .light + } + } +} + +public extension UIAlertController { + static func create(title: String?, message: String?, preferredStyle: UIAlertController.Style) -> UIAlertController + { + let alert = UIAlertController(title: title, message: message, preferredStyle: preferredStyle) + if #available(iOS 13.0, *) { + // Always adopt a light interface style. + alert.overrideUserInterfaceStyle = .light + } + return alert + } +} diff --git a/KarhooUISDK/Model/Country.swift b/KarhooUISDK/Model/Country.swift new file mode 100644 index 000000000..87377b663 --- /dev/null +++ b/KarhooUISDK/Model/Country.swift @@ -0,0 +1,42 @@ +// +// Country.swift +// KarhooUISDK +// +// Created by Diana Petrea on 13.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit +import KarhooSDK + +struct Country: KarhooCodableModel { + var name: String + var phoneCode: String + var code: String // The flags in Assets > CountryFlags have names corresponding to the the country code + + init(name: String, phoneCode: String, code: String) { + self.name = name + self.phoneCode = phoneCode + self.code = code + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.name = try container.decode(String.self, forKey: .name) + self.phoneCode = try container.decode(String.self, forKey: .phoneCode) + self.code = try container.decode(String.self, forKey: .code) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(name, forKey: .name) + try container.encode(phoneCode, forKey: .phoneCode) + try container.encode(code, forKey: .code) + } + + enum CodingKeys: String, CodingKey { + case name + case phoneCode = "phone_code" + case code + } +} diff --git a/KarhooUISDK/Routing/BaseViewController.swift b/KarhooUISDK/Routing/BaseViewController.swift index f0b0b522b..270b90946 100644 --- a/KarhooUISDK/Routing/BaseViewController.swift +++ b/KarhooUISDK/Routing/BaseViewController.swift @@ -59,8 +59,7 @@ public extension BaseViewController { if let error = error { messageToShow = "\(messageToShow) [\(error.code)]" } - let alert = UIAlertController(title: title, message: messageToShow, preferredStyle: .alert) - + let alert = UIAlertController.create(title: title, message: messageToShow, preferredStyle: .alert) actions.forEach { alert.addAction($0.action) } alert.view.tintColor = KarhooUI.colors.darkGrey @@ -74,7 +73,7 @@ public extension BaseViewController { } else { message = UITexts.Errors.noDetailsAvailable } - let alert = UIAlertController(title: UITexts.Errors.somethingWentWrong, + let alert = UIAlertController.create(title: UITexts.Errors.somethingWentWrong, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: UITexts.Generic.ok, style: .default)) @@ -96,7 +95,7 @@ public extension BaseViewController { cancelSelected?() }) - let alert = UIAlertController(title: UITexts.PaymentError.paymentAlertTitle, + let alert = UIAlertController.create(title: UITexts.PaymentError.paymentAlertTitle, message: UITexts.PaymentError.paymentAlertMessage, preferredStyle: .alert) diff --git a/KarhooUISDK/Screens/AddressScreen/AddressViewController.swift b/KarhooUISDK/Screens/AddressScreen/AddressViewController.swift index ec9f624d6..cc75d00b1 100644 --- a/KarhooUISDK/Screens/AddressScreen/AddressViewController.swift +++ b/KarhooUISDK/Screens/AddressScreen/AddressViewController.swift @@ -55,6 +55,7 @@ final class AddressViewController: UIViewController, AddressView { super.viewDidLoad() keyboardSizeProvider.register(listener: self) setupBackButton() + forceLightMode() } override func loadView() { diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/KarhooBookingRequestPresenter.swift b/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/KarhooBookingRequestPresenter.swift deleted file mode 100644 index f6b8a1676..000000000 --- a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/KarhooBookingRequestPresenter.swift +++ /dev/null @@ -1,266 +0,0 @@ -// -// KarhooBookingRequestPresenter.swift -// Karhoo -// -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import UIKit -import KarhooSDK - -final class KarhooBookingRequestPresenter: BookingRequestPresenter { - - private weak var view: BookingRequestView? - private let quote: Quote - private let bookingDetails: BookingDetails - private let userService: UserService - private let tripService: TripService - private let callback: ScreenResultCallback - private let analytics: Analytics - private let appStateNotifier: AppStateNotifierProtocol - private var trip: TripInfo? - private var flightNumber: String? - private var comments: String? - private var bookingRequestInProgress: Bool = false - private var flightDetailsScreenIsPresented: Bool = false - private let flightDetailsScreenBuilder: FlightDetailsScreenBuilder - private let baseFareDialogBuilder: PopupDialogScreenBuilder - private let paymentNonceProvider: PaymentNonceProvider - private let bookingMetadata: [String: Any]? - - init(quote: Quote, - bookingDetails: BookingDetails, - bookingMetadata: [String: Any]?, - userService: UserService = Karhoo.getUserService(), - tripService: TripService = Karhoo.getTripService(), - analytics: Analytics = KarhooAnalytics(), - appStateNotifier: AppStateNotifierProtocol = AppStateNotifier(), - flightDetailsScreenBuilder: FlightDetailsScreenBuilder = KarhooUI().screens().flightDetails(), - paymentNonceProvider: PaymentNonceProvider = PaymentFactory().nonceProvider(), - baseFarePopupDialogBuilder: PopupDialogScreenBuilder = UISDKScreenRouting.default.popUpDialog(), - callback: @escaping ScreenResultCallback) { - self.quote = quote - self.bookingDetails = bookingDetails - self.userService = userService - self.tripService = tripService - self.callback = callback - self.appStateNotifier = appStateNotifier - self.analytics = analytics - self.flightDetailsScreenBuilder = flightDetailsScreenBuilder - self.baseFareDialogBuilder = baseFarePopupDialogBuilder - self.paymentNonceProvider = paymentNonceProvider - self.bookingMetadata = bookingMetadata - appStateNotifier.register(listener: self) - } - - func load(view: BookingRequestView) { - self.view = view - setUpBookingButtonState() - view.set(quote: quote) - - if quote.source == .market { - view.set(price: CurrencyCodeConverter.quoteRangePrice(quote: quote)) - } else { - view.set(price: CurrencyCodeConverter.toPriceString(quote: quote)) - } - - view.set(quoteType: quote.quoteType.description) - view.set(baseFareExplanationHidden: quote.quoteType == .fixed) - paymentNonceProvider.set(baseViewController: view) - configureQuoteView() - view.paymentView(hidden: userService.getCurrentUser()?.paymentProvider?.provider.type == .adyen) - } - - func bookTripPressed() { - submitBooking() - } - - func didPressAddFlightDetails() { - var dismissCallback: (() -> Void)? - let flightDetailsScreen = flightDetailsScreenBuilder - .buildFlightDetailsScreen(completion: { [weak self] result in - dismissCallback?() - self?.flightDetailsScreenIsPresented = false - - guard let flightDetails = result.completedValue() else { - return - } - - self?.didAdd(flightDetails: flightDetails) - }) - - dismissCallback = { - flightDetailsScreen.dismiss(animated: true, completion: nil) - } - - view?.present(flightDetailsScreen, animated: true, completion: nil) - self.flightDetailsScreenIsPresented = true - } - - func didPressClose() { - view?.showBookingRequestView(false) - } - - func didPressFareExplanation() { - guard bookingRequestInProgress == false else { - return - } - - let popupDialog = baseFareDialogBuilder.buildPopupDialogScreen(callback: { [weak self] _ in - self?.view?.dismiss(animated: true, completion: nil) - }) - - popupDialog.modalTransitionStyle = .crossDissolve - view?.showAsOverlay(item: popupDialog, animated: true) - } - - func screenHasFadedOut() { - if let trip = self.trip { - callback(ScreenResult.completed(result: trip)) - } else { - callback(ScreenResult.cancelled(byUser: false)) - } - } - - private func didAdd(flightDetails: FlightDetails) { - self.flightDetailsScreenIsPresented = false - self.flightNumber = flightDetails.flightNumber - self.comments = flightDetails.comments - - submitBooking() - } - - private func configureQuoteView() { - if bookingDetails.isScheduled { - configurePrebookState() - return - } - configureForAsapState() - } - - private func configurePrebookState() { - guard let timeZone = bookingDetails.originLocationDetails?.timezone() else { - return - } - - let prebookFormatter = KarhooDateFormatter(timeZone: timeZone) - - view?.setPrebookState(timeString: prebookFormatter.display(shortStyleTime: bookingDetails.scheduledDate), - dateString: prebookFormatter.display(mediumStyleDate: bookingDetails.scheduledDate)) - } - - private func configureForAsapState() { - view?.setAsapState(qta: QtaStringFormatter().qtaString(min: quote.vehicle.qta.lowMinutes, - max: quote.vehicle.qta.highMinutes)) - } - - private func setUpBookingButtonState() { - if TripInfoUtility.isAirportBooking(bookingDetails) { - view?.setAddFlightDetailsState() - } else { - view?.setDefaultState() - } - } - - private func submitBooking() { - bookingRequestInProgress = true - view?.setRequestingState() - - guard let currentUser = userService.getCurrentUser(), - let currentOrg = userService.getCurrentUser()?.organisations.first else { - view?.showAlert(title: UITexts.Errors.somethingWentWrong, - message: UITexts.Errors.getUserFail, - error: nil) - return - } - - if let destination = bookingDetails.destinationLocationDetails { - analytics.bookingRequested(destination: destination, - dateScheduled: bookingDetails.scheduledDate, - quote: quote) - } - - if let nonce = view?.getPaymentNonce() { - bookTrip(withPaymentNonce: Nonce(nonce: nonce), user: currentUser) - } else { - paymentNonceProvider.getPaymentNonce(user: currentUser, - organisation: currentOrg, - quote: quote) { [weak self] result in - switch result { - case .completed(let result): handlePaymentNonceProviderResult(result) - case .cancelledByUser: self?.view?.setDefaultState() - } - } - } - - func handlePaymentNonceProviderResult(_ paymentNonceResult: PaymentNonceProviderResult) { - switch paymentNonceResult { - case .nonce(let nonce): bookTrip(withPaymentNonce: nonce, user: currentUser) - case .cancelledByUser: - self.view?.setDefaultState() - case .failedToAddCard(let error): - self.view?.setDefaultState() - self.view?.show(error: error) - default: - self.view?.showAlert(title: UITexts.Generic.error, message: UITexts.Errors.somethingWentWrong, - error: nil) - view?.setDefaultState() - } - } - } - - private func bookTrip(withPaymentNonce nonce: Nonce, user: UserInfo) { - var tripBooking = TripBooking(quoteId: quote.id, - passengers: Passengers(additionalPassengers: 0, - passengerDetails: [PassengerDetails(user: user)]), - flightNumber: flightNumber) - - tripBooking.paymentNonce = nonce.nonce - - var map: [String: Any] = [:] - if let metadata = bookingMetadata { - map = metadata - } - tripBooking.meta = map - if userService.getCurrentUser()?.paymentProvider?.provider.type == .adyen { - tripBooking.meta["trip_id"] = nonce.nonce - } - - tripService.book(tripBooking: tripBooking) - .execute(callback: { [weak self] (result: Result) in - self?.bookingRequestInProgress = false - self?.handleBookTrip(result: result) - }) - } - - private func handleBookTrip(result: Result) { - guard let trip = result.successValue() else { - view?.setDefaultState() - - if result.errorValue()?.type == .couldNotBookTripPaymentPreAuthFailed { - view?.retryAddPaymentMethod() - } else { - callback(ScreenResult.failed(error: result.errorValue())) - } - - return - } - - self.trip = trip - view?.showBookingRequestView(false) - } - - deinit { - appStateNotifier.remove(listener: self) - } -} - -extension KarhooBookingRequestPresenter: AppStateChangeDelegate { - func appDidEnterBackground() { - if bookingRequestInProgress == false, - flightDetailsScreenIsPresented == false { - self.didPressClose() - } - } -} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/KarhooBookingRequestViewController.swift b/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/KarhooBookingRequestViewController.swift deleted file mode 100644 index 1415c096a..000000000 --- a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/KarhooBookingRequestViewController.swift +++ /dev/null @@ -1,308 +0,0 @@ -// -// BookingRequestViewController.swift -// Karhoo -// -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import UIKit -import KarhooSDK - -public struct KHBookingRequestViewID { - public static let exitBackgroundButton = "exit_background_button" - public static let exitButton = "exit_button" -} - -final class KarhooBookingRequestViewController: UIViewController, BookingRequestView { - - private var didSetupConstraints = false - - private var exitBackgroundButton: UIView! - private var container: UIView! - private var containerBottomConstraint: NSLayoutConstraint! - private var mainStackContainer: UIStackView! - private var mainStackBottomPadding: NSLayoutConstraint! - - private var supplierStackContainer: UIStackView! - private var supplierView: SupplierView! - private var exitButton: UIButton! - - private var timePriceView: KarhooTimePriceView! - - private lazy var paymentView: PaymentView = { - let view = KarhooPaymentView() - return view - }() - - private var termsConditionsView: TermsConditionsView! - private var separatorLine: LineView! - private var bookingButton: KarhooBookingButtonView! - - private let presenter: BookingRequestPresenter - private let drawAnimationTime: Double = 0.45 - - init(presenter: BookingRequestPresenter) { - self.presenter = presenter - super.init(nibName: nil, bundle: nil) - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(code:) has not been implemented") - } - - override func viewDidLoad() { - super.viewDidLoad() - setUpView() - } - - private func setUpView() { - exitBackgroundButton = UIView() - exitBackgroundButton.translatesAutoresizingMaskIntoConstraints = false - exitBackgroundButton.accessibilityIdentifier = KHBookingRequestViewID.exitBackgroundButton - exitBackgroundButton.backgroundColor = .clear - view.addSubview(exitBackgroundButton) - - let closeTapGesture = UITapGestureRecognizer(target: self, action: #selector(closePressed)) - exitBackgroundButton.addGestureRecognizer(closeTapGesture) - - container = UIView() - container.translatesAutoresizingMaskIntoConstraints = false - container.accessibilityIdentifier = "container_view" - container.layer.cornerRadius = 10.0 - container.layer.masksToBounds = true - container.backgroundColor = .white - view.addSubview(container) - - mainStackContainer = UIStackView() - mainStackContainer.translatesAutoresizingMaskIntoConstraints = false - mainStackContainer.accessibilityIdentifier = "main_stack_view" - mainStackContainer.axis = .vertical - mainStackContainer.spacing = 10.0 - container.addSubview(mainStackContainer) - - supplierStackContainer = UIStackView() - supplierStackContainer.translatesAutoresizingMaskIntoConstraints = false - supplierStackContainer.accessibilityIdentifier = "supplier_stack_view" - supplierStackContainer.axis = .horizontal - supplierStackContainer.alignment = .fill - supplierStackContainer.distribution = .fill - mainStackContainer.addArrangedSubview(supplierStackContainer) - - supplierView = SupplierView() - supplierStackContainer.addArrangedSubview(supplierView) - - exitButton = UIButton(type: .custom) - exitButton.translatesAutoresizingMaskIntoConstraints = false - exitButton.accessibilityIdentifier = KHBookingRequestViewID.exitButton - exitButton.setImage(UIImage.uisdkImage("cross").withRenderingMode(.alwaysTemplate), for: .normal) - exitButton.tintColor = KarhooUI.colors.darkGrey - exitButton.addTarget(self, action: #selector(closePressed), for: .touchUpInside) - exitButton.imageEdgeInsets = UIEdgeInsets(top: 17, left: 17, bottom: 17, right: 17) - exitButton.imageView?.contentMode = .scaleAspectFit - supplierStackContainer.addArrangedSubview(exitButton) - - timePriceView = KarhooTimePriceView() - timePriceView.set(actions: self) - mainStackContainer.addArrangedSubview(timePriceView) - - mainStackContainer.addArrangedSubview(paymentView) - paymentView.baseViewController = self - - termsConditionsView = TermsConditionsView() - mainStackContainer.addArrangedSubview(termsConditionsView) - - separatorLine = LineView(color: KarhooUI.colors.lightGrey, - accessibilityIdentifier: "booking_request_separator_line") - mainStackContainer.addArrangedSubview(separatorLine) - - bookingButton = KarhooBookingButtonView() - bookingButton.set(actions: self) - mainStackContainer.addArrangedSubview(bookingButton) - - presenter.load(view: self) - } - - override func updateViewConstraints() { - - if !didSetupConstraints { - _ = [view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width), - view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height)].map { $0.isActive = true } - - _ = [exitBackgroundButton.topAnchor.constraint(equalTo: view.topAnchor), - exitBackgroundButton.trailingAnchor.constraint(equalTo: view.trailingAnchor), - exitBackgroundButton.bottomAnchor.constraint(equalTo: container.topAnchor)].map { $0.isActive = true } - - _ = [container.leadingAnchor.constraint(equalTo: view.leadingAnchor), - container.trailingAnchor.constraint(equalTo: view.trailingAnchor), - container.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width)] - .map { $0.isActive = true } - - containerBottomConstraint = container.bottomAnchor.constraint(equalTo: view.bottomAnchor, - constant: UIScreen.main.bounds.height / 2) - containerBottomConstraint.isActive = true - - _ = [supplierView.topAnchor.constraint(equalTo: supplierStackContainer.topAnchor), - supplierView.bottomAnchor.constraint(equalTo: supplierStackContainer.bottomAnchor), - supplierView.trailingAnchor.constraint(equalTo: exitButton.leadingAnchor, constant: 10)] - .map { $0.isActive = true } - - _ = [exitButton.widthAnchor.constraint(equalToConstant: 50.0)].map { $0.isActive = true } - - _ = [mainStackContainer.topAnchor.constraint(equalTo: container.topAnchor), - mainStackContainer.leadingAnchor.constraint(equalTo: container.leadingAnchor), - mainStackContainer.trailingAnchor.constraint(equalTo: container.trailingAnchor)] - .map { $0.isActive = true } - - mainStackBottomPadding = mainStackContainer.bottomAnchor.constraint(equalTo: container.bottomAnchor, - constant: -20.0) - mainStackBottomPadding.isActive = true - - _ = [termsConditionsView.leadingAnchor.constraint(equalTo: mainStackContainer.leadingAnchor), - termsConditionsView.trailingAnchor.constraint(equalTo: mainStackContainer.trailingAnchor)] - .map { $0.isActive = true } - - _ = [separatorLine.heightAnchor.constraint(equalToConstant: 1.0), - separatorLine.leadingAnchor.constraint(equalTo: mainStackContainer.leadingAnchor), - separatorLine.trailingAnchor.constraint(equalTo: mainStackContainer.trailingAnchor)] - .map { $0.isActive = true } - - didSetupConstraints = true - } - - super.updateViewConstraints() - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - showBookingRequestView(true) - } - - @objc - func closePressed() { - presenter.didPressClose() - } - - func showBookingRequestView(_ show: Bool) { - if show { - mainStackBottomPadding.constant = -20.0 - containerBottomConstraint.constant = 0.0 - if #available(iOS 11.0, *) { - mainStackBottomPadding.constant = -view.safeAreaInsets.bottom - 20 - } - } else { - containerBottomConstraint.constant = UIScreen.main.bounds.height / 2 - } - - UIView.animate(withDuration: drawAnimationTime, - animations: { [weak self] in - self?.view.layoutIfNeeded() - }, completion: { [weak self] completed in - if completed && !show { - self?.presenter.screenHasFadedOut() - self?.dismiss(animated: false, completion: nil) - } - }) - } - - func setRequestingState() { - disableUserInteraction() - bookingButton.setRequestingMode() - } - - func setDefaultState() { - enableUserInteraction() - bookingButton.setRequestMode() - } - - func setAddFlightDetailsState() { - enableUserInteraction() - bookingButton.setAddFlightDetailsMode() - } - - func set(quote: Quote) { - let viewModel = QuoteViewModel(quote: quote) - supplierView.set(viewModel: viewModel) - paymentView.quote = quote - termsConditionsView.setBookingTerms(supplier: quote.fleet.name, - termsStringURL: quote.fleet.termsConditionsUrl) - } - - func set(price: String?) { - timePriceView.set(price: price) - } - - func setAsapState(qta: String?) { - timePriceView.setAsapMode(qta: qta) - } - - func setPrebookState(timeString: String?, dateString: String?) { - timePriceView.setPrebookMode(timeString: timeString, dateString: dateString) - } - - func set(quoteType: String) { - timePriceView.set(quoteType: quoteType) - } - - func set(baseFareExplanationHidden: Bool) { - timePriceView.set(baseFareHidden: baseFareExplanationHidden) - } - - func retryAddPaymentMethod() { - paymentView.startRegisterCardFlow() - } - - func paymentView(hidden: Bool) { - paymentView.isHidden = hidden - } - - private func enableUserInteraction() { - exitButton.isUserInteractionEnabled = true - exitButton.tintColor = KarhooUI.colors.secondary - exitBackgroundButton?.isUserInteractionEnabled = true - - paymentView.isUserInteractionEnabled = true - } - - private func disableUserInteraction() { - exitButton.isUserInteractionEnabled = false - exitButton.tintColor = KarhooUI.colors.medGrey - exitBackgroundButton?.isUserInteractionEnabled = false - - paymentView.isUserInteractionEnabled = false - } - - final class KarhooBookingRequestScreenBuilder: BookingRequestScreenBuilder { - - func buildBookingRequestScreen(quote: Quote, - bookingDetails: BookingDetails, - bookingMetadata: [String: Any]?, - callback: @escaping ScreenResultCallback) -> Screen { - - let presenter = KarhooBookingRequestPresenter(quote: quote, - bookingDetails: bookingDetails, - bookingMetadata: bookingMetadata, - callback: callback) - - let item = KarhooBookingRequestViewController(presenter: presenter) - - return item - } - } -} - -extension KarhooBookingRequestViewController: TimePriceViewActions { - func didPressFareExplanation() { - presenter.didPressFareExplanation() - } -} - -extension KarhooBookingRequestViewController: BookingButtonActions { - func requestPressed() { - presenter.bookTripPressed() - } - - func addFlightDetailsPressed() { - presenter.didPressAddFlightDetails() - } -} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormBookingRequestPresenter.swift b/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormBookingRequestPresenter.swift deleted file mode 100644 index 2801341ea..000000000 --- a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormBookingRequestPresenter.swift +++ /dev/null @@ -1,149 +0,0 @@ -// -// PassengerFormBookingRequestPresenter.swift -// KarhooUISDK -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import Foundation -import KarhooSDK - -final class FormBookingRequestPresenter: BookingRequestPresenter { - - private let callback: ScreenResultCallback - private weak var view: BookingRequestView? - private let quote: Quote - private let bookingDetails: BookingDetails - internal var passengerDetails: PassengerDetails! - private let threeDSecureProvider: ThreeDSecureProvider - private let tripService: TripService - private let userService: UserService - private let bookingMetadata: [String: Any]? - - init(quote: Quote, - bookingDetails: BookingDetails, - bookingMetadata: [String: Any]?, - threeDSecureProvider: ThreeDSecureProvider = BraintreeThreeDSecureProvider(), - tripService: TripService = Karhoo.getTripService(), - userService: UserService = Karhoo.getUserService(), - callback: @escaping ScreenResultCallback) { - self.threeDSecureProvider = threeDSecureProvider - self.tripService = tripService - self.callback = callback - self.userService = userService - self.quote = quote - self.bookingDetails = bookingDetails - self.bookingMetadata = bookingMetadata - } - - func load(view: BookingRequestView) { - self.view = view - view.set(quote: quote) - setUpBookingButtonState() - threeDSecureProvider.set(baseViewController: view) - } - - func bookTripPressed() { - view?.setRequestingState() - - guard let passengerDetails = view?.getPassengerDetails(), let nonce = getPaymentNonceAccordingToAuthState() else { - view?.setDefaultState() - return - } - - if userService.getCurrentUser()?.paymentProvider?.provider.type == .braintree { - threeDSecureNonceThenBook(nonce: nonce, - passengerDetails: passengerDetails) - } else { - book(threeDSecureNonce: nonce, passenger: passengerDetails) - } - } - - private func getPaymentNonceAccordingToAuthState() -> String? { - switch Karhoo.configuration.authenticationMethod() { - case .tokenExchange(settings: _): return tokenExchangeNonce() - case .karhooUser: return userService.getCurrentUser()?.nonce?.nonce - default: return view?.getPaymentNonce() - } - } - - private func tokenExchangeNonce() -> String? { - if userService.getCurrentUser()?.paymentProvider?.provider.type == .braintree { - return userService.getCurrentUser()?.nonce?.nonce - } else { - return view?.getPaymentNonce() - } - } - - private func threeDSecureNonceThenBook(nonce: String, passengerDetails: PassengerDetails) { - threeDSecureProvider.threeDSecureCheck(nonce: nonce, - currencyCode: quote.price.currencyCode, - paymentAmout: NSDecimalNumber(value: quote.price.highPrice), - callback: { [weak self] result in - switch result { - case .completed(let result): handleThreeDSecureCheck(result) - case .cancelledByUser: self?.view?.setDefaultState() - } - }) - - func handleThreeDSecureCheck(_ result: ThreeDSecureCheckResult) { - switch result { - case .failedToInitialisePaymentService: - view?.setDefaultState() - case .threeDSecureAuthenticationFailed: - view?.retryAddPaymentMethod() - view?.setDefaultState() - case .success(let threeDSecureNonce): - book(threeDSecureNonce: threeDSecureNonce, passenger: passengerDetails) - } - } - } - - private func book(threeDSecureNonce: String, passenger: PassengerDetails) { - let flightNumber = view?.getFlightNumber()?.isEmpty == true ? nil : view?.getFlightNumber() - var tripBooking = TripBooking(quoteId: quote.id, - passengers: Passengers(additionalPassengers: 0, - passengerDetails: [passenger]), - flightNumber: flightNumber, - paymentNonce: threeDSecureNonce, - comments: view?.getComments()) - - var map: [String: Any] = [:] - if let metadata = bookingMetadata { - map = metadata - } - tripBooking.meta = map - if userService.getCurrentUser()?.paymentProvider?.provider.type == .adyen { - tripBooking.meta["trip_id"] = threeDSecureNonce - } - - tripService.book(tripBooking: tripBooking).execute(callback: { [weak self] result in - self?.view?.setDefaultState() - - if let trip = result.successValue() { - PassengerInfo.shared.passengerDetails = self?.view?.getPassengerDetails() - self?.callback(.completed(result: trip)) - } else if let error = result.errorValue() { - self?.view?.showAlert(title: UITexts.Generic.error, message: "\(error.localizedMessage)", error: result.errorValue()) - } - }) - } - - func didPressAddFlightDetails() {} - func didPressFareExplanation() {} - - func didPressClose() { - PassengerInfo.shared.passengerDetails = view?.getPassengerDetails() - view?.showBookingRequestView(false) - } - - func screenHasFadedOut() { - callback(ScreenResult.cancelled(byUser: true)) - } - - private func setUpBookingButtonState() { - if TripInfoUtility.isAirportBooking(bookingDetails) { - view?.setAddFlightDetailsState() - } - } -} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormBookingRequestViewController.swift b/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormBookingRequestViewController.swift deleted file mode 100644 index 8e22a905f..000000000 --- a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormBookingRequestViewController.swift +++ /dev/null @@ -1,415 +0,0 @@ -// -// FormBookingRequestViewController.swift -// KarhooUISDK -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import UIKit -import KarhooSDK - -final class FormBookingRequestViewController: UIViewController, BookingRequestView { - - private var didSetupConstraints = false - private var container: UIView! - private var exitButton: UIButton! - private var headerView: FormCheckoutHeaderView! - private var passengerDetailsTitle: UILabel! - private var paymentDetailsTitle: UILabel! - private var commentsInputText: KarhooTextInputView! - private var poiDetailsInputText: KarhooTextInputView! - private var passengerDetailsValid: Bool? - - private var addPaymentView: KarhooAddCardView! - private var termsConditionsView: TermsConditionsView! - private var baseStackView: BaseStackView! - private var footerView: UIView! - private var footerStack: UIStackView! - private var separatorLine: LineView! - private var bookingButton: KarhooBookingButtonView! - private var containerBottomConstraint: NSLayoutConstraint! - private var presenter: BookingRequestPresenter - private let drawAnimationTime: Double = 0.45 - - private lazy var passengerDetailsView: PassengerDetailsView = { - let passengerDetailsView = PassengerDetailsView() - passengerDetailsView.translatesAutoresizingMaskIntoConstraints = false - passengerDetailsView.accessibilityIdentifier = "passengerDetailsView" - passengerDetailsView.actions = self - return passengerDetailsView - }() - - var paymentNonce: String? - - init(presenter: BookingRequestPresenter) { - self.presenter = presenter - super.init(nibName: nil, bundle: nil) - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(code:) has not been implemented") - } - - override func loadView() { - setUpView() - } - - private func setUpView() { - view = UIView() - view.translatesAutoresizingMaskIntoConstraints = false - - container = UIView() - container.translatesAutoresizingMaskIntoConstraints = false - container.accessibilityIdentifier = "container_view" - container.backgroundColor = .white - view.addSubview(container) - - exitButton = UIButton(type: .custom) - exitButton.translatesAutoresizingMaskIntoConstraints = false - exitButton.accessibilityIdentifier = KHBookingRequestViewID.exitButton - exitButton.setImage(UIImage.uisdkImage("close_button"), for: .normal) - exitButton.addTarget(self, action: #selector(closePressed), for: .touchUpInside) - exitButton.imageView?.contentMode = .scaleAspectFit - container.addSubview(exitButton) - - baseStackView = BaseStackView() - baseStackView.accessibilityIdentifier = "base_stack_view" - baseStackView.viewSpacing(15.0) - container.addSubview(baseStackView) - - headerView = FormCheckoutHeaderView() - baseStackView.addViewToStack(view: headerView) - - passengerDetailsTitle = UILabel() - passengerDetailsTitle.translatesAutoresizingMaskIntoConstraints = false - passengerDetailsTitle.accessibilityIdentifier = "passenger_details_title_label" - passengerDetailsTitle.text = UITexts.Booking.guestCheckoutPassengerDetailsTitle - passengerDetailsTitle.textColor = KarhooUI.colors.infoColor - passengerDetailsTitle.font = KarhooUI.fonts.getBoldFont(withSize: 20.0) - baseStackView.addViewToStack(view: passengerDetailsTitle) - - baseStackView.addViewToStack(view: passengerDetailsView) - setUpFields() - - paymentDetailsTitle = UILabel() - paymentDetailsTitle.translatesAutoresizingMaskIntoConstraints = false - paymentDetailsTitle.accessibilityIdentifier = "payment_details_title_label" - paymentDetailsTitle.text = UITexts.Booking.guestCheckoutPaymentDetailsTitle - paymentDetailsTitle.textColor = KarhooUI.colors.infoColor - paymentDetailsTitle.font = KarhooUI.fonts.getBoldFont(withSize: 20.0) - baseStackView.addViewToStack(view: paymentDetailsTitle) - - addPaymentView = KarhooAddCardView() - addPaymentView.baseViewController = self - addPaymentView.actions = self - baseStackView.addViewToStack(view: addPaymentView) - - // Footer view - footerView = UIView() - footerView.translatesAutoresizingMaskIntoConstraints = false - footerView.accessibilityIdentifier = "footer_view" - footerView.backgroundColor = .white - baseStackView.addViewToStack(view: footerView) - - footerStack = UIStackView() - footerStack.translatesAutoresizingMaskIntoConstraints = false - footerStack.accessibilityIdentifier = "footer_stack_view" - footerStack.axis = .vertical - footerStack.spacing = 15.0 - footerView.addSubview(footerStack) - - separatorLine = LineView(color: KarhooUI.colors.lightGrey, - accessibilityIdentifier: "booking_request_separator_line") - footerStack.addArrangedSubview(separatorLine) - - bookingButton = KarhooBookingButtonView() - bookingButton.set(actions: self) - bookingButton.setDisabledMode() - footerStack.addArrangedSubview(bookingButton) - - termsConditionsView = TermsConditionsView() - baseStackView.addViewToStack(view: termsConditionsView) - - let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView)) - container.addGestureRecognizer(tapGesture) - - view.setNeedsUpdateConstraints() - - presenter.load(view: self) - } - - private func setUpFields() { - commentsInputText = KarhooTextInputView(contentType: .comment, - isOptional: true, - accessibilityIdentifier: "comment_input_view") - commentsInputText.delegate = self - baseStackView.addViewToStack(view: commentsInputText) - - poiDetailsInputText = KarhooTextInputView(contentType: .poiDetails, - isOptional: true, - accessibilityIdentifier: "poi_input_view") - poiDetailsInputText.delegate = self - poiDetailsInputText.isHidden = true - baseStackView.addViewToStack(view: poiDetailsInputText) - } - - override func updateViewConstraints() { - if !didSetupConstraints { - _ = [view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width), - view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height)].map { $0.isActive = true } - - _ = [container.leadingAnchor.constraint(equalTo: view.leadingAnchor), - container.trailingAnchor.constraint(equalTo: view.trailingAnchor), - container.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width), - container.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height)] - .map { $0.isActive = true } - - containerBottomConstraint = container.bottomAnchor.constraint(equalTo: view.bottomAnchor, - constant: UIScreen.main.bounds.height) - containerBottomConstraint.isActive = true - - _ = [exitButton.topAnchor.constraint(equalTo: container.topAnchor, constant: view.safeAreaInsets.top), - exitButton.trailingAnchor.constraint(equalTo: container.trailingAnchor), - exitButton.widthAnchor.constraint(equalToConstant: 50.0)].map { $0.isActive = true } - - _ = [baseStackView.topAnchor.constraint(equalTo: exitButton.bottomAnchor), - baseStackView.leadingAnchor.constraint(equalTo: container.leadingAnchor), - baseStackView.trailingAnchor.constraint(equalTo: container.trailingAnchor), - baseStackView.bottomAnchor.constraint(equalTo: container.bottomAnchor)].map { $0.isActive = true } - - let titleInset: CGFloat = 15.0 - - _ = [headerView.leadingAnchor.constraint(equalTo: baseStackView.leadingAnchor, constant: titleInset), - headerView.trailingAnchor.constraint(equalTo: baseStackView.trailingAnchor, - constant: -titleInset)].map { $0.isActive = true } - - _ = [passengerDetailsTitle.leadingAnchor.constraint(equalTo: baseStackView.leadingAnchor, - constant: titleInset), - passengerDetailsTitle.trailingAnchor.constraint(equalTo: baseStackView.trailingAnchor, - constant: -titleInset)].map { $0.isActive = true } - - passengerDetailsView.pinLeftRightEdegs(to: baseStackView) - - let textInputInset: CGFloat = 30.0 - - _ = [poiDetailsInputText.leadingAnchor.constraint(equalTo: baseStackView.leadingAnchor, - constant: textInputInset), - poiDetailsInputText.trailingAnchor.constraint(equalTo: baseStackView.trailingAnchor, - constant: -textInputInset)].map { $0.isActive = true } - - _ = [commentsInputText.leadingAnchor.constraint(equalTo: baseStackView.leadingAnchor, - constant: textInputInset), - commentsInputText.trailingAnchor.constraint(equalTo: baseStackView.trailingAnchor, - constant: -textInputInset)].map { $0.isActive = true } - - _ = [paymentDetailsTitle.leadingAnchor.constraint(equalTo: baseStackView.leadingAnchor, - constant: titleInset), - paymentDetailsTitle.trailingAnchor.constraint(equalTo: baseStackView.trailingAnchor, - constant: -titleInset)].map { $0.isActive = true } - - _ = [addPaymentView.leadingAnchor.constraint(equalTo: baseStackView.leadingAnchor, - constant: textInputInset), - addPaymentView.trailingAnchor.constraint(equalTo: baseStackView.trailingAnchor, - constant: -textInputInset)].map { $0.isActive = true } - - _ = [footerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10.0), - footerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, - constant: -10.0)].map { $0.isActive = true } - - _ = [footerStack.topAnchor.constraint(equalTo: footerView.topAnchor), - footerStack.leadingAnchor.constraint(equalTo: footerView.leadingAnchor), - footerStack.trailingAnchor.constraint(equalTo: footerView.trailingAnchor), - footerStack.bottomAnchor.constraint(equalTo: footerView.bottomAnchor)].map { $0.isActive = true } - - _ = [termsConditionsView.leadingAnchor.constraint(equalTo: footerStack.leadingAnchor), - termsConditionsView.trailingAnchor.constraint(equalTo: footerStack.trailingAnchor)] - .map { $0.isActive = true } - - _ = [separatorLine.heightAnchor.constraint(equalToConstant: 1.0), - separatorLine.leadingAnchor.constraint(equalTo: footerStack.leadingAnchor), - separatorLine.trailingAnchor.constraint(equalTo: footerStack.trailingAnchor)] - .map { $0.isActive = true } - - didSetupConstraints = true - } - - super.updateViewConstraints() - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - showBookingRequestView(true) - } - - override func viewDidLoad() { - super.viewDidLoad() - passengerDetailsView.details = initialisePassengerDetails() - } - - private func initialisePassengerDetails() -> PassengerDetails? { - if PassengerInfo.shared.passengerDetails == nil { - return PassengerInfo.shared.currentUserAsPassenger() - } else { - return PassengerInfo.shared.passengerDetails - } - } - - @objc - private func didTapView() { - view.endEditing(true) - } - - @objc - func closePressed() { - presenter.didPressClose() - } - - func showBookingRequestView(_ show: Bool) { - if show { - containerBottomConstraint.constant = 0.0 - } else { - containerBottomConstraint.constant = UIScreen.main.bounds.height - } - - UIView.animate(withDuration: drawAnimationTime, - animations: { [weak self] in - self?.view.layoutIfNeeded() - }, completion: { [weak self] completed in - if completed && !show { - self?.presenter.screenHasFadedOut() - self?.dismiss(animated: false, completion: nil) - } - }) - } - - func setRequestingState() { - disableUserInteraction() - bookingButton.setRequestingMode() - } - - func setDefaultState() { - enableUserInteraction() - bookingButton.setRequestMode() - } - - func setAddFlightDetailsState() { - enableUserInteraction() - poiDetailsInputText.isHidden = false - } - - func set(quote: Quote) { - let viewModel = QuoteViewModel(quote: quote) - headerView.set(viewModel: viewModel) - termsConditionsView.setBookingTerms(supplier: quote.fleet.name, - termsStringURL: quote.fleet.termsConditionsUrl) - addPaymentView.quote = quote - } - - func set(price: String?) {} - - func setPrebookState(timeString: String?, dateString: String?) {} - - func set(quoteType: String) {} - - func set(baseFareExplanationHidden: Bool) {} - - func retryAddPaymentMethod() { - addPaymentView.startRegisterCardFlow() - } - - func setAsapState(qta: String?) {} - - private func enableUserInteraction() { - exitButton.isUserInteractionEnabled = true - exitButton.tintColor = KarhooUI.colors.secondary - addPaymentView.isUserInteractionEnabled = true - } - - private func disableUserInteraction() { - exitButton.isUserInteractionEnabled = false - exitButton.tintColor = KarhooUI.colors.medGrey - addPaymentView.isUserInteractionEnabled = false - } - - final class Builder: BookingRequestScreenBuilder { - func buildBookingRequestScreen(quote: Quote, - bookingDetails: BookingDetails, - bookingMetadata: [String: Any]?, - callback: @escaping ScreenResultCallback) -> Screen { - let presenter = FormBookingRequestPresenter(quote: quote, - bookingDetails: bookingDetails, - bookingMetadata: bookingMetadata, - callback: callback) - return FormBookingRequestViewController(presenter: presenter) - } - } - - func getPassengerDetails() -> PassengerDetails? { - return passengerDetailsView.details - } - - func getPaymentNonce() -> String? { - return self.paymentNonce - } - - func getComments() -> String? { - return commentsInputText.getIntput() - } - - func getFlightNumber() -> String? { - return poiDetailsInputText.getIntput() - } - - func paymentView(hidden: Bool) { - addPaymentView.isHidden = hidden - } -} - -extension FormBookingRequestViewController: TimePriceViewActions { - func didPressFareExplanation() { - presenter.didPressFareExplanation() - } -} - -extension FormBookingRequestViewController: BookingButtonActions { - func requestPressed() { - presenter.bookTripPressed() - } - - func addFlightDetailsPressed() { - presenter.didPressAddFlightDetails() - } -} - -extension FormBookingRequestViewController: PassengerDetailsActions { - - func passengerDetailsValid(_ valid: Bool) { - passengerDetailsValid = valid - enableBookingButton() - } -} - -extension FormBookingRequestViewController: KarhooInputViewDelegate { - func didBecomeInactive(identifier: String) { - enableBookingButton() - } - - private func enableBookingButton() { - if passengerDetailsValid == true { - if addPaymentView.validPayment() { - bookingButton.setRequestMode() - } else { - addPaymentView.showError() - } - } else { - bookingButton.setDisabledMode() - } - } -} - -extension FormBookingRequestViewController: PaymentViewActions { - func didGetNonce(nonce: String) { - paymentNonce = nonce - didBecomeInactive(identifier: commentsInputText.accessibilityIdentifier!) - } -} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormCheckoutHeaderView.swift b/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormCheckoutHeaderView.swift deleted file mode 100644 index 2b90af577..000000000 --- a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/FormCheckoutHeaderView.swift +++ /dev/null @@ -1,212 +0,0 @@ -// -// GuestCheckoutHeaderView.swift -// KarhooUISDK -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import UIKit -import KarhooSDK - -public struct KHFormCheckoutHeaderViewID { - public static let topInfoContainer = "ride_top_info_container" - public static let view = "guest_checkout_header_view" - public static let logo = "logo_image" - public static let rideDetailsContainer = "ride_details_stack_view" - public static let name = "name_label" - public static let rideInfoView = "ride_info_view" - public static let etaTitle = "eta_title_label" - public static let etaText = "eta_text_label" - public static let estimatedPrice = "estimated_price_title_label" - public static let priceText = "price_text_label" - public static let carType = "car_type_label" - public static let cancellationInfo = "cancellationInfo_label" -} - -final class FormCheckoutHeaderView: UIView { - - private var didSetupConstraints: Bool = false - - private var topStackView: UIStackView! - private var logoLoadingImageView: LoadingImageView! - private var rideDetailStackView: UIStackView! - private var name: UILabel! - private var carType: UILabel! - private var cancellationInfo: UILabel! - private var vehicleCapacityView: VehicleCapacityView! - - private var rideInfoView: UIView! - private var scheduleCaption: UILabel! - private var scheduleMainValue: UILabel! - private var priceTitle: UILabel! - private var priceText: UILabel! - - init() { - super.init(frame: .zero) - self.setUpView() - } - - convenience init(viewModel: QuoteViewModel) { - self.init() - self.set(viewModel: viewModel) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func setUpView() { - translatesAutoresizingMaskIntoConstraints = false - accessibilityIdentifier = KHFormCheckoutHeaderViewID.view - - topStackView = UIStackView() - topStackView.accessibilityIdentifier = KHFormCheckoutHeaderViewID.topInfoContainer - topStackView.translatesAutoresizingMaskIntoConstraints = false - topStackView.alignment = .center - topStackView.distribution = .equalSpacing - topStackView.spacing = 10 - addSubview(topStackView) - - logoLoadingImageView = LoadingImageView() - logoLoadingImageView.accessibilityIdentifier = KHFormCheckoutHeaderViewID.logo - logoLoadingImageView.layer.cornerRadius = 5.0 - logoLoadingImageView.layer.borderColor = KarhooUI.colors.lightGrey.cgColor - logoLoadingImageView.layer.borderWidth = 0.5 - logoLoadingImageView.layer.masksToBounds = true - topStackView.addArrangedSubview(logoLoadingImageView) - - rideDetailStackView = UIStackView() - rideDetailStackView.translatesAutoresizingMaskIntoConstraints = false - rideDetailStackView.accessibilityIdentifier = KHFormCheckoutHeaderViewID.rideDetailsContainer - rideDetailStackView.axis = .vertical - rideDetailStackView.spacing = 8.0 - topStackView.addArrangedSubview(rideDetailStackView) - - name = UILabel() - name.translatesAutoresizingMaskIntoConstraints = false - name.accessibilityIdentifier = KHFormCheckoutHeaderViewID.name - name.textColor = KarhooUI.colors.infoColor - name.font = KarhooUI.fonts.getBoldFont(withSize: 16.0) - name.numberOfLines = 0 - rideDetailStackView.addArrangedSubview(name) - - carType = UILabel() - carType.translatesAutoresizingMaskIntoConstraints = false - carType.accessibilityIdentifier = KHFormCheckoutHeaderViewID.carType - carType.font = KarhooUI.fonts.getRegularFont(withSize: 14.0) - carType.textColor = KarhooUI.colors.guestCheckoutLightGrey - rideDetailStackView.addArrangedSubview(carType) - - cancellationInfo = UILabel() - cancellationInfo.translatesAutoresizingMaskIntoConstraints = false - cancellationInfo.accessibilityIdentifier = KHFormCheckoutHeaderViewID.cancellationInfo - cancellationInfo.font = KarhooUI.fonts.captionRegular() - cancellationInfo.textColor = KarhooUI.colors.accent - cancellationInfo.numberOfLines = 0 - rideDetailStackView.addArrangedSubview(cancellationInfo) - - vehicleCapacityView = VehicleCapacityView() - topStackView.addArrangedSubview(vehicleCapacityView) - - rideInfoView = UIView() - rideInfoView.translatesAutoresizingMaskIntoConstraints = false - rideInfoView.accessibilityIdentifier = KHFormCheckoutHeaderViewID.rideInfoView - rideInfoView.backgroundColor = KarhooUI.colors.guestCheckoutLightGrey - rideInfoView.layer.masksToBounds = true - rideInfoView.layer.cornerRadius = 8.0 - addSubview(rideInfoView) - - scheduleCaption = UILabel() - scheduleCaption.translatesAutoresizingMaskIntoConstraints = false - scheduleCaption.accessibilityIdentifier = KHFormCheckoutHeaderViewID.etaTitle - scheduleCaption.textColor = KarhooUI.colors.white - scheduleCaption.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) - scheduleCaption.text = UITexts.Generic.etaLong.uppercased() - rideInfoView.addSubview(scheduleCaption) - - scheduleMainValue = UILabel() - scheduleMainValue.translatesAutoresizingMaskIntoConstraints = false - scheduleMainValue.accessibilityIdentifier = KHFormCheckoutHeaderViewID.etaText - scheduleMainValue.textColor = KarhooUI.colors.white - scheduleMainValue.font = KarhooUI.fonts.getBoldFont(withSize: 24.0) - rideInfoView.addSubview(scheduleMainValue) - - priceTitle = UILabel() - priceTitle.translatesAutoresizingMaskIntoConstraints = false - priceTitle.accessibilityIdentifier = KHFormCheckoutHeaderViewID.estimatedPrice - priceTitle.textColor = KarhooUI.colors.white - priceTitle.textAlignment = .right - priceTitle.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) - priceTitle.text = UITexts.Generic.estimatedPrice.uppercased() - rideInfoView.addSubview(priceTitle) - - priceText = UILabel() - priceText.translatesAutoresizingMaskIntoConstraints = false - priceText.accessibilityIdentifier = KHFormCheckoutHeaderViewID.priceText - priceText.textColor = KarhooUI.colors.white - priceText.textAlignment = .right - priceText.font = KarhooUI.fonts.getBoldFont(withSize: 24.0) - rideInfoView.addSubview(priceText) - } - - override func updateConstraints() { - if !didSetupConstraints { - let logoSize: CGFloat = 60.0 - [logoLoadingImageView.widthAnchor.constraint(equalToConstant: logoSize), - logoLoadingImageView.heightAnchor.constraint(equalToConstant: logoSize)] - .forEach { $0.isActive = true } - - topStackView.topAnchor.constraint(equalTo: topAnchor, constant: 20.0).isActive = true - topStackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true - topStackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true - - vehicleCapacityView.setContentHuggingPriority(.required, for: .horizontal) - - [rideInfoView.topAnchor.constraint(equalTo: topStackView.bottomAnchor, constant: 15.0), - rideInfoView.leadingAnchor.constraint(equalTo: topStackView.leadingAnchor, constant: 10.0), - rideInfoView.trailingAnchor.constraint(equalTo: topStackView.trailingAnchor, constant: -10.0), - rideInfoView.bottomAnchor.constraint(equalTo: bottomAnchor)].forEach { $0.isActive = true } - - [scheduleCaption.leadingAnchor.constraint(equalTo: rideInfoView.leadingAnchor, constant: 10.0), - scheduleCaption.topAnchor.constraint(equalTo: rideInfoView.topAnchor, constant: 10.0), - scheduleCaption.trailingAnchor.constraint(lessThanOrEqualTo: priceTitle.leadingAnchor, - constant: 20.0)].forEach { $0.isActive = true } - - [scheduleMainValue.leadingAnchor.constraint(equalTo: scheduleCaption.leadingAnchor), - scheduleMainValue.topAnchor.constraint(equalTo: scheduleCaption.bottomAnchor, constant: 5.0), - scheduleMainValue.trailingAnchor.constraint(lessThanOrEqualTo: priceText.leadingAnchor, constant: 20.0), - scheduleMainValue.bottomAnchor.constraint(equalTo: rideInfoView.bottomAnchor, constant: -10.0)] - .forEach { $0.isActive = true } - - [priceTitle.trailingAnchor.constraint(equalTo: rideInfoView.trailingAnchor, constant: -10.0), - priceTitle.topAnchor.constraint(equalTo: rideInfoView.topAnchor, - constant: 10.0)].forEach { $0.isActive = true } - - [priceText.trailingAnchor.constraint(equalTo: priceTitle.trailingAnchor), - priceText.topAnchor.constraint(equalTo: priceTitle.bottomAnchor, constant: 5.0), - priceText.bottomAnchor.constraint(equalTo: rideInfoView.bottomAnchor, - constant: -10.0)].forEach { $0.isActive = true } - - didSetupConstraints = true - } - - super.updateConstraints() - } - - func set(viewModel: QuoteViewModel) { - name.text = viewModel.fleetName - scheduleCaption.text = viewModel.scheduleCaption - scheduleMainValue.text = viewModel.scheduleMainValue - carType.text = viewModel.carType - cancellationInfo.text = viewModel.freeCancellationMessage - cancellationInfo.isHidden = viewModel.freeCancellationMessage == nil - priceText.text = viewModel.fare - logoLoadingImageView.load(imageURL: viewModel.logoImageURL, - placeholderImageName: "supplier_logo_placeholder") - logoLoadingImageView.setStandardBorder() - vehicleCapacityView.setPassengerCapacity(viewModel.passengerCapacity) - vehicleCapacityView.setBaggageCapacity(viewModel.baggageCapacity) - - updateConstraints() - } -} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/PassengerDetails/PassengerDetailsMVP.swift b/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/PassengerDetails/PassengerDetailsMVP.swift deleted file mode 100644 index b691c6d93..000000000 --- a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/PassengerDetails/PassengerDetailsMVP.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// PassengerDetailsMVP.swift -// KarhooUISDK -// -// Created by Jeevan Thandi on 08/07/2020. -// Copyright © 2020 Flit Technologies Ltd. All rights reserved. -// - -import Foundation -import KarhooSDK - -protocol PassengerDetailsActions: class { - func passengerDetailsValid(_ : Bool) -} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/PassengerDetails/PassengerDetailsView.swift b/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/PassengerDetails/PassengerDetailsView.swift deleted file mode 100644 index d0cb459f6..000000000 --- a/KarhooUISDK/Screens/BookingRequestScreen/FormBookingRequestScreen/PassengerDetails/PassengerDetailsView.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// PassengerDetailsView.swift -// KarhooUISDK -// -// Created by Jeevan Thandi on 01/07/2020. -// Copyright © 2020 Flit Technologies Ltd. All rights reserved. -// - -import Foundation -import KarhooSDK - -final class PassengerDetailsView: UIView { - - private let textFieldInset: CGFloat = 30.0 - private var inputViews: [KarhooInputView] = [] - private var validSet = Set() - weak var actions: PassengerDetailsActions? - private var locale: String? - - var details: PassengerDetails? { - get { - return PassengerDetails(firstName: firstNameTextField.getIntput(), - lastName: surnameTextField.getIntput(), - email: emailTextField.getIntput(), - phoneNumber: phoneTextField.getIntput(), - locale: locale?.isEmpty == false ? locale! : currentLocale()) - } - set { - firstNameTextField.set(text: newValue?.firstName) - surnameTextField.set(text: newValue?.lastName) - emailTextField.set(text: newValue?.email) - phoneTextField.set(text: newValue?.phoneNumber) - locale = newValue?.locale ?? currentLocale() - - //When setting the text programmatically, the textField delegate methods are not invoked automatically - //This trigers the validation process as if the user had modified the infomation through the UI - textFieldValuesChanged() - } - } - - private lazy var firstNameTextField: KarhooTextInputView = { - let firstNameTextField = KarhooTextInputView(contentType: .firstname, - isOptional: false, - accessibilityIdentifier: "firstNameField") - firstNameTextField.delegate = self - self.inputViews.append(firstNameTextField) - return firstNameTextField - }() - - private lazy var surnameTextField: KarhooTextInputView = { - let surnameTextField = KarhooTextInputView(contentType: .surname, - isOptional: false, - accessibilityIdentifier: "surnameTextField") - - surnameTextField.delegate = self - inputViews.append(surnameTextField) - return surnameTextField - }() - - private lazy var emailTextField: KarhooTextInputView = { - let emailTextField = KarhooTextInputView(contentType: .email, - isOptional: false, - accessibilityIdentifier: "emailTextField") - - emailTextField.delegate = self - inputViews.append(emailTextField) - return emailTextField - }() - - private lazy var phoneTextField: KarhooTextInputView = { - let phoneTextField = KarhooTextInputView(contentType: .phone, - isOptional: false, - accessibilityIdentifier: "phoneTextField") - - phoneTextField.delegate = self - inputViews.append(phoneTextField) - return phoneTextField - }() - - private lazy var textFieldStackView: UIStackView = { - let textFieldStackView = UIStackView() - textFieldStackView.accessibilityIdentifier = "base_stack_view" - textFieldStackView.spacing = 15 - textFieldStackView.axis = .vertical - textFieldStackView.translatesAutoresizingMaskIntoConstraints = false - return textFieldStackView - }() - - private func currentLocale() -> String { - return NSLocale.current.identifier - } - - init() { - super.init(frame: .zero) - self.setUpView() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func setUpView() { - self.addSubview(textFieldStackView) - textFieldStackView.pinEdges(to: self) - - textFieldStackView.addArrangedSubview(firstNameTextField) - textFieldStackView.addArrangedSubview(surnameTextField) - textFieldStackView.addArrangedSubview(emailTextField) - textFieldStackView.addArrangedSubview(phoneTextField) - - layoutTextFields() - } - - private func layoutTextFields() { - [firstNameTextField, - surnameTextField, - emailTextField, - phoneTextField].forEach { view in - view.pinLeftRightEdegs(to: self, - leading: textFieldInset, - trailing: -textFieldInset) - } - } - - private func textFieldValuesChanged() - { - if let phoneNumberAccessibilityIdentifier = phoneTextField.accessibilityIdentifier { - //didBecomeInactive(:) checks all the mandatory fields, so calling it for every textField in particular isn't necessary - didBecomeInactive(identifier: phoneNumberAccessibilityIdentifier) - } - } -} - -extension PassengerDetailsView: KarhooInputViewDelegate { - func didBecomeInactive(identifier: String) { - for (index, inputView) in inputViews.enumerated() { - if inputView.isValid() { - validSet.insert(inputView.accessibilityIdentifier!) - } else { - validSet.remove(inputView.accessibilityIdentifier!) - } - if inputView.accessibilityIdentifier == identifier { - if index != inputViews.count - 1 { - inputViews[index + 1].setActive() - } - } - } - - actions?.passengerDetailsValid(validSet.count == inputViews.count) - } -} diff --git a/KarhooUISDK/Screens/BookingScreen/BookingMVP.swift b/KarhooUISDK/Screens/BookingScreen/BookingMVP.swift index 911af824e..2cd30d5c8 100644 --- a/KarhooUISDK/Screens/BookingScreen/BookingMVP.swift +++ b/KarhooUISDK/Screens/BookingScreen/BookingMVP.swift @@ -20,6 +20,8 @@ public protocol BookingScreen: BaseViewController { func openRidesList(presentationStyle: UIModalPresentationStyle?) func resetAndLocate() + + func openRideDetailsFor(_ trip: TripInfo) } /* internal interface for controlling booking screen */ @@ -75,6 +77,8 @@ protocol BookingPresenter { func exitPressed() func goToTripView(trip: TripInfo) + + func showRideDetailsView(trip: TripInfo) } public enum BookingScreenResult { diff --git a/KarhooUISDK/Screens/BookingScreen/KarhooBookingPresenter.swift b/KarhooUISDK/Screens/BookingScreen/KarhooBookingPresenter.swift index b1d31d5e7..e1afc6fc7 100644 --- a/KarhooUISDK/Screens/BookingScreen/KarhooBookingPresenter.swift +++ b/KarhooUISDK/Screens/BookingScreen/KarhooBookingPresenter.swift @@ -19,7 +19,7 @@ final class KarhooBookingPresenter { private let callback: ScreenResultCallback? private let tripScreenBuilder: TripScreenBuilder private let rideDetailsScreenBuilder: RideDetailsScreenBuilder - private let bookingRequestScreenBuilder: BookingRequestScreenBuilder + private let checkoutScreenBuilder: CheckoutScreenBuilder private let prebookConfirmationScreenBuilder: PrebookConfirmationScreenBuilder private let addressScreenBuilder: AddressScreenBuilder private let datePickerScreenBuilder: DatePickerScreenBuilder @@ -36,7 +36,7 @@ final class KarhooBookingPresenter { tripScreenBuilder: TripScreenBuilder = UISDKScreenRouting.default.tripScreen(), rideDetailsScreenBuilder: RideDetailsScreenBuilder = UISDKScreenRouting.default.rideDetails(), ridesScreenBuilder: RidesScreenBuilder = UISDKScreenRouting.default.rides(), - bookingRequestScreenBuilder: BookingRequestScreenBuilder = UISDKScreenRouting.default.bookingRequest(), + checkoutScreenBuilder: CheckoutScreenBuilder = UISDKScreenRouting.default.checkout(), prebookConfirmationScreenBuilder: PrebookConfirmationScreenBuilder = UISDKScreenRouting.default.prebookConfirmation(), addressScreenBuilder: AddressScreenBuilder = UISDKScreenRouting.default.address(), datePickerScreenBuilder: DatePickerScreenBuilder = UISDKScreenRouting.default.datePicker(), @@ -50,7 +50,7 @@ final class KarhooBookingPresenter { self.callback = callback self.tripScreenBuilder = tripScreenBuilder self.rideDetailsScreenBuilder = rideDetailsScreenBuilder - self.bookingRequestScreenBuilder = bookingRequestScreenBuilder + self.checkoutScreenBuilder = checkoutScreenBuilder self.prebookConfirmationScreenBuilder = prebookConfirmationScreenBuilder self.addressScreenBuilder = addressScreenBuilder self.datePickerScreenBuilder = datePickerScreenBuilder @@ -68,22 +68,22 @@ final class KarhooBookingPresenter { bookingStatus.remove(observer: self) } - private func showBookingRequestView(quote: Quote, - bookingDetails: BookingDetails, - bookingMetadata: [String: Any]? = KarhooUISDKConfigurationProvider.configuration.bookingMetadata) { - let bookingRequestView = bookingRequestScreenBuilder - .buildBookingRequestScreen(quote: quote, - bookingDetails: bookingDetails, - bookingMetadata: bookingMetadata, - callback: { [weak self] result in - self?.view?.presentedViewController?.dismiss(animated: false, completion: { - self?.bookingRequestCompleted(result: result, - quote: quote, - details: bookingDetails) - }) - }) + private func showCheckoutView(quote: Quote, + bookingDetails: BookingDetails, + bookingMetadata: [String: Any]? = KarhooUISDKConfigurationProvider.configuration.bookingMetadata) { + let checkoutView = checkoutScreenBuilder + .buildCheckoutScreen(quote: quote, + bookingDetails: bookingDetails, + bookingMetadata: bookingMetadata, + callback: { [weak self] result in + self?.view?.presentedViewController?.dismiss(animated: false, completion: { + self?.bookingRequestCompleted(result: result, + quote: quote, + details: bookingDetails) + }) + }) - view?.showAsOverlay(item: bookingRequestView, animated: false) + view?.showAsOverlay(item: checkoutView, animated: false) } private func bookingRequestCompleted(result: ScreenResult, quote: Quote, details: BookingDetails) { @@ -239,7 +239,7 @@ extension KarhooBookingPresenter: BookingPresenter { func tripWaitOnRideDetails(trip: TripInfo) { view?.resetAndLocate() view?.hideAllocationScreen() - showRideDetails(trip: trip) + showRideDetailsView(trip: trip) } func tripSuccessfullyCancelled() { @@ -257,7 +257,7 @@ extension KarhooBookingPresenter: BookingPresenter { return } - showBookingRequestView(quote: quote, bookingDetails: bookingDetails) + showCheckoutView(quote: quote, bookingDetails: bookingDetails) } func showRidesList(presentationStyle: UIModalPresentationStyle?) { @@ -351,7 +351,7 @@ extension KarhooBookingPresenter: BookingPresenter { goToTripView(trip: trip) case .prebookConfirmed(let trip, let action)?: if case .rideDetails = action { - showRideDetails(trip: trip) + showRideDetailsView(trip: trip) } default: break @@ -362,7 +362,7 @@ extension KarhooBookingPresenter: BookingPresenter { callback(result) } - func showRideDetails(trip: TripInfo) { + func showRideDetailsView(trip: TripInfo) { let rideDetailsViewController = rideDetailsScreenBuilder .buildOverlayRideDetailsScreen(trip: trip, callback: { [weak self] result in diff --git a/KarhooUISDK/Screens/BookingScreen/KarhooBookingViewController.swift b/KarhooUISDK/Screens/BookingScreen/KarhooBookingViewController.swift index 3bb4c8449..78439df55 100644 --- a/KarhooUISDK/Screens/BookingScreen/KarhooBookingViewController.swift +++ b/KarhooUISDK/Screens/BookingScreen/KarhooBookingViewController.swift @@ -115,6 +115,7 @@ final class KarhooBookingViewController: UIViewController, BookingView { override func viewDidLoad() { super.viewDidLoad() setupMapView(reverseGeolocate: journeyInfo == nil) + forceLightMode() } private func setupMapView(reverseGeolocate: Bool) { @@ -358,6 +359,10 @@ extension KarhooBookingViewController: BookingScreen { func openTrip(_ trip: TripInfo) { presenter.goToTripView(trip: trip) } + + func openRideDetailsFor(_ trip: TripInfo) { + presenter.showRideDetailsView(trip: trip) + } } // MARK: Builder @@ -372,7 +377,7 @@ public final class KarhooBookingScreenBuilder: BookingScreenBuilder { public func buildBookingScreen(journeyInfo: JourneyInfo? = nil, passengerDetails: PassengerDetails? = nil, callback: ScreenResultCallback?) -> Screen { - PassengerInfo.shared.passengerDetails = passengerDetails + PassengerInfo.shared.set(details: passengerDetails) var validatedJourneyInfo: JourneyInfo? diff --git a/KarhooUISDK/Screens/BookingScreen/QuoteCategoryBarMVP/KarhooQuoteCategoryBarView.swift b/KarhooUISDK/Screens/BookingScreen/QuoteCategoryBarMVP/KarhooQuoteCategoryBarView.swift index 203505ea0..8797c752d 100644 --- a/KarhooUISDK/Screens/BookingScreen/QuoteCategoryBarMVP/KarhooQuoteCategoryBarView.swift +++ b/KarhooUISDK/Screens/BookingScreen/QuoteCategoryBarMVP/KarhooQuoteCategoryBarView.swift @@ -202,7 +202,7 @@ final class KarhooQuoteCategoryBarView: UIView, QuoteCategoryBarView { private func addLabels(for categories: [QuoteCategory]) { categories.forEach { category in - let label = createLabel(category: category.categoryName) + let label = createLabel(category: category.localizedCategoryName) stackView.addArrangedSubview(label) _ = [label.centerYAnchor.constraint(equalTo: stackView.centerYAnchor)].map { $0.isActive = true } labels.append(label) diff --git a/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/KarhooQuoteListViewController.swift b/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/KarhooQuoteListViewController.swift index 62fd6710a..95bb36ec6 100644 --- a/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/KarhooQuoteListViewController.swift +++ b/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/KarhooQuoteListViewController.swift @@ -40,6 +40,11 @@ final class KarhooQuoteListViewController: UIViewController, QuoteListView { fatalError("init(coder:) has not been implemented") } + override func viewDidLoad() { + super.viewDidLoad() + forceLightMode() + } + override func loadView() { setUpView() } diff --git a/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/QuoteCell/QuoteViewModel.swift b/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/QuoteCell/QuoteViewModel.swift index 216e9a702..2ddd5bd44 100644 --- a/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/QuoteCell/QuoteViewModel.swift +++ b/KarhooUISDK/Screens/BookingScreen/QuoteListMVP/QuoteCell/QuoteViewModel.swift @@ -9,34 +9,129 @@ import UIKit import KarhooSDK +enum VehicleTag: String { + case electric, hybrid, wheelchair, childSeat, taxi, executive + + enum CodingKeys: String, CodingKey { + case childSeat = "child-seat" + } + + var title: String { + switch self { + case .electric: + return UITexts.VehicleTag.electric + case .hybrid: + return UITexts.VehicleTag.hybrid + case .wheelchair: + return UITexts.VehicleTag.wheelchair + case .childSeat: + return UITexts.VehicleTag.childseat + case .taxi: + return UITexts.VehicleTag.taxi + case .executive: + return UITexts.VehicleTag.executive + } + } + + var image: UIImage { + switch self { + case .electric: + return UIImage.uisdkImage("electric") + case .hybrid: + return UIImage.uisdkImage("circle") + case .wheelchair: + return UIImage.uisdkImage("wheelchair") + case .childSeat: + return UIImage.uisdkImage("childseat") + case .taxi: + return UIImage.uisdkImage("taxi") + case .executive: + return UIImage.uisdkImage("star") + } + } +} + +enum FleetCapabilities: String { + case gpsTracking, flightTracking, trainTracking + + enum CodingKeys: String, CodingKey { + case gpsTracking = "gps_tracking" + case flightTracking = "flight_tracking" + case trainTracking = "train_tracking" + } + + var title: String { + switch self { + case .gpsTracking: + return UITexts.Booking.gpsTracking + case .flightTracking: + return UITexts.Booking.flightTracking + case .trainTracking: + return UITexts.Booking.trainTracking + } + } + + var image: UIImage { + switch self { + case .gpsTracking: + return UIImage.uisdkImage("gpsTrackingIcon") + case .flightTracking: + return UIImage.uisdkImage("flightTrackingIcon") + case .trainTracking: + return UIImage.uisdkImage("trainTrackingIcon") + } + } + + init?(rawValue: String) { + guard let key = CodingKeys(rawValue: rawValue) else { + return nil + } + switch key { + case .gpsTracking: + self = .gpsTracking + case .flightTracking: + self = .flightTracking + case .trainTracking: + self = .trainTracking + } + } +} + final class QuoteViewModel { let fleetName: String + let fleetDescription: String let scheduleCaption: String let scheduleMainValue: String let carType: String + let vehicleTags: [VehicleTag] + let fleetCapabilities: [FleetCapabilities] let fare: String let logoImageURL: String let fareType: String let showPickUpLabel: Bool let pickUpType: String - let passengerCapacity: String - let baggageCapacity: String + let passengerCapacity: Int + let baggageCapacity: Int /// If this message is not `nil`, it should be displayed let freeCancellationMessage: String? init(quote: Quote, bookingStatus: BookingStatus = KarhooBookingStatus.shared) { - self.passengerCapacity = "\(quote.vehicle.passengerCapacity)" - self.baggageCapacity = "\(quote.vehicle.luggageCapacity)" + self.passengerCapacity = quote.vehicle.passengerCapacity + self.baggageCapacity = quote.vehicle.luggageCapacity self.fleetName = quote.fleet.name + self.fleetDescription = quote.fleet.description let bookingDetails = bookingStatus.getBookingDetails() let scheduleTexts = QuoteViewModel.scheduleTexts(quote: quote, bookingDetails: bookingDetails) self.scheduleCaption = scheduleTexts.caption self.scheduleMainValue = scheduleTexts.value - self.carType = quote.vehicle.vehicleClass + // TODO: to be reverted later to localized carType - vehicleClass is deprecated + self.carType = quote.vehicle.localizedVehicleClass + self.vehicleTags = quote.vehicle.tags.compactMap { VehicleTag(rawValue: $0) } + self.fleetCapabilities = quote.fleet.capability.compactMap { FleetCapabilities(rawValue: $0) } switch quote.serviceLevelAgreements?.serviceCancellation.type { case .timeBeforePickup: diff --git a/KarhooUISDK/Screens/BookingScreen/SharedPassengerDetails.swift b/KarhooUISDK/Screens/BookingScreen/SharedPassengerDetails.swift index 85a8128d4..78891ff8d 100644 --- a/KarhooUISDK/Screens/BookingScreen/SharedPassengerDetails.swift +++ b/KarhooUISDK/Screens/BookingScreen/SharedPassengerDetails.swift @@ -12,11 +12,39 @@ class PassengerInfo { static let shared = PassengerInfo() - var passengerDetails: PassengerDetails? + private var passengerDetails: PassengerDetails? + + // Note: Added it here to make it persistent without modifying the network SDK and affecting any backend logic + private var country: Country? + + func getDetails() -> PassengerDetails? { + return passengerDetails + } func set(details: PassengerDetails?) { passengerDetails = details } + + func getCountry() -> Country { + if let selectedCountry = country { + return selectedCountry + } + + guard let code = UserDefaults.standard.string(forKey: Keys.countryCode) + else { + set(country: KarhooCountryParser.defaultCountry) + return KarhooCountryParser.defaultCountry + } + + let country = KarhooCountryParser.getCountry(countryCode: code) ?? KarhooCountryParser.defaultCountry + set(country: country) + return country + } + + func set(country: Country) { + UserDefaults.standard.set(country.code, forKey: Keys.countryCode) + self.country = country + } func currentUserAsPassenger() -> PassengerDetails? { if Karhoo.configuration.authenticationMethod().isGuest() { @@ -29,4 +57,8 @@ class PassengerInfo { return PassengerDetails(user: currentUser) } + + private struct Keys { + static let countryCode = "PASSENGER_DETAILS_SELECTED_COUNTRY_CODE" + } } diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequestMVP.swift b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutMVP.swift similarity index 62% rename from KarhooUISDK/Screens/BookingRequestScreen/BookingRequestMVP.swift rename to KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutMVP.swift index 9c9a06b49..40f481789 100644 --- a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequestMVP.swift +++ b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutMVP.swift @@ -1,5 +1,5 @@ // -// BookingRequestMVP.swift +// CheckoutMVP.swift // Karhoo // // @@ -8,65 +8,40 @@ import KarhooSDK -protocol BookingRequestPresenter { - - func load(view: BookingRequestView) - +protocol CheckoutPresenter { + func load(view: CheckoutView) func bookTripPressed() - - func didPressAddFlightDetails() - + func addOrEditPassengerDetails() + func addMoreDetails() + func didAddPassengerDetails() func didPressFareExplanation() - func didPressClose() - func screenHasFadedOut() + func isKarhooUser() -> Bool } -protocol BookingRequestView: BaseViewController { - - func showBookingRequestView(_ show: Bool) - +protocol CheckoutView: BaseViewController { + func showCheckoutView(_ show: Bool) func setRequestingState() - func setAddFlightDetailsState() - + func setPassenger(details: PassengerDetails?) + func setMoreDetailsState() func setDefaultState() - + func resetPaymentNonce() func set(quote: Quote) - func set(price: String?) - func set(quoteType: String) - func set(baseFareExplanationHidden: Bool) - func setAsapState(qta: String?) - func setPrebookState(timeString: String?, dateString: String?) - - func retryAddPaymentMethod() - + func retryAddPaymentMethod(showRetryAlert: Bool) func getPaymentNonce() -> String? - func getPassengerDetails() -> PassengerDetails? - func getComments() -> String? - func getFlightNumber() -> String? - - func paymentView(hidden: Bool) } -extension BookingRequestView { - func getPassengerDetails() -> PassengerDetails? { - return nil - } - - func getPaymentNonce() -> String? { - return nil - } - +extension CheckoutView { func getComments() -> String? { return nil } diff --git a/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutPresenter.swift b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutPresenter.swift new file mode 100644 index 000000000..101cea7a1 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutPresenter.swift @@ -0,0 +1,422 @@ +// +// KarhooCheckoutPresenter.swift +// KarhooUISDK +// +// Copyright © 2020 Karhoo All rights reserved. +// + +import Foundation +import KarhooSDK + +final class KarhooCheckoutPresenter: CheckoutPresenter { + + private let callback: ScreenResultCallback + private weak var view: CheckoutView? + private let quote: Quote + private let bookingDetails: BookingDetails + internal var passengerDetails: PassengerDetails! + private let threeDSecureProvider: ThreeDSecureProvider + private let tripService: TripService + private let userService: UserService + private let bookingMetadata: [String: Any]? + private let paymentNonceProvider: PaymentNonceProvider + + private let analytics: Analytics + private let appStateNotifier: AppStateNotifierProtocol + private var trip: TripInfo? + private var comments: String? + private var bookingRequestInProgress: Bool = false + private var flightDetailsScreenIsPresented: Bool = false + private let baseFareDialogBuilder: PopupDialogScreenBuilder + + var karhooUser: Bool = false + + init(quote: Quote, + bookingDetails: BookingDetails, + bookingMetadata: [String: Any]?, + threeDSecureProvider: ThreeDSecureProvider = BraintreeThreeDSecureProvider(), + tripService: TripService = Karhoo.getTripService(), + userService: UserService = Karhoo.getUserService(), + analytics: Analytics = KarhooAnalytics(), + appStateNotifier: AppStateNotifierProtocol = AppStateNotifier(), + baseFarePopupDialogBuilder: PopupDialogScreenBuilder = UISDKScreenRouting.default.popUpDialog(), + paymentNonceProvider: PaymentNonceProvider = PaymentFactory().nonceProvider(), + callback: @escaping ScreenResultCallback) { + self.threeDSecureProvider = threeDSecureProvider + self.tripService = tripService + self.callback = callback + self.userService = userService + self.paymentNonceProvider = paymentNonceProvider + self.appStateNotifier = appStateNotifier + self.analytics = analytics + self.baseFareDialogBuilder = baseFarePopupDialogBuilder + self.quote = quote + self.bookingDetails = bookingDetails + self.bookingMetadata = bookingMetadata + } + + func load(view: CheckoutView) { + self.view = view + switch Karhoo.configuration.authenticationMethod() { + case .karhooUser: + self.karhooUser = true + default: + self.karhooUser = false + } + + if karhooUser { + completeLoadingViewForKarhooUser(view: view) + } + view.set(quote: quote) + setUpBookingButtonState() + threeDSecureProvider.set(baseViewController: view) + } + + private func completeLoadingViewForKarhooUser(view: CheckoutView) { + if quote.source == .market { + view.set(price: CurrencyCodeConverter.quoteRangePrice(quote: quote)) + } else { + view.set(price: CurrencyCodeConverter.toPriceString(quote: quote)) + } + + view.set(quoteType: quote.quoteType.description) + view.set(baseFareExplanationHidden: quote.quoteType == .fixed) + paymentNonceProvider.set(baseViewController: view) + configureQuoteView() + } + + private func configureQuoteView() { + if bookingDetails.isScheduled { + configurePrebookState() + return + } + configureForAsapState() + } + + private func configurePrebookState() { + guard let timeZone = bookingDetails.originLocationDetails?.timezone() else { + return + } + + let prebookFormatter = KarhooDateFormatter(timeZone: timeZone) + + view?.setPrebookState(timeString: prebookFormatter.display(shortStyleTime: bookingDetails.scheduledDate), + dateString: prebookFormatter.display(mediumStyleDate: bookingDetails.scheduledDate)) + } + + private func configureForAsapState() { + view?.setAsapState(qta: QtaStringFormatter().qtaString(min: quote.vehicle.qta.lowMinutes, + max: quote.vehicle.qta.highMinutes)) + } + + func isKarhooUser() -> Bool { + return karhooUser + } + + func addOrEditPassengerDetails() { + let details = view?.getPassengerDetails() + let presenter = PassengerDetailsPresenter(details: details) { [weak self] result in + guard let completedValue = result.completedValue() + else { + return + } + + self?.view?.setPassenger(details: completedValue.details) + PassengerInfo.shared.set(country: completedValue.country ?? KarhooCountryParser.defaultCountry) + } + let detailsViewController = PassengerDetailsViewController(presenter: presenter) + view?.showAsOverlay(item: detailsViewController, animated: true) + } + + func addMoreDetails() { + if !arePassengerDetailsValid() { + addOrEditPassengerDetails() + } else { + view?.retryAddPaymentMethod(showRetryAlert: false) + } + } + + func didAddPassengerDetails() { + if !arePassengerDetailsValid() || getPaymentNonceAccordingToAuthState() == nil { + view?.setMoreDetailsState() + } else { + view?.setDefaultState() + } + } + + private func arePassengerDetailsValid() -> Bool { + guard let details = view?.getPassengerDetails(), + details.areValid + else { + return false + } + + return true + } + + func bookTripPressed() { + view?.setRequestingState() + + if Karhoo.configuration.authenticationMethod().isGuest() { + submitGuestBooking() + } else { + submitAuthenticatedBooking() + } + } + + private func submitAuthenticatedBooking() { + bookingRequestInProgress = true + + guard let currentUser = userService.getCurrentUser(), + let passengerDetails = view?.getPassengerDetails(), + let currentOrg = userService.getCurrentUser()?.organisations.first?.id + else { + view?.showAlert(title: UITexts.Errors.somethingWentWrong, + message: UITexts.Errors.getUserFail, + error: nil) + view?.setDefaultState() + return + } + + if let destination = bookingDetails.destinationLocationDetails { + analytics.bookingRequested(destination: destination, + dateScheduled: bookingDetails.scheduledDate, + quote: quote) + } + + if let nonce = view?.getPaymentNonce() { + if userService.getCurrentUser()?.paymentProvider?.provider.type == .braintree { + self.getPaymentNonceThenBook(user: currentUser, + organisationId: currentOrg, + passengerDetails: passengerDetails) + } else { + book(paymentNonce: nonce, + passenger: passengerDetails, + flightNumber: view?.getFlightNumber()) + } + } else { + getPaymentNonceThenBook(user: currentUser, + organisationId: currentOrg, + passengerDetails: passengerDetails) + } + + } + + private func organisationId() -> String { + if let guestId = Karhoo.configuration.authenticationMethod().guestSettings?.organisationId { + return guestId + } else if let userOrg = userService.getCurrentUser()?.organisations.first?.id { + return userOrg + } + + return "" + } + + private func getPaymentNonceThenBook(user: UserInfo, + organisationId: String, + passengerDetails: PassengerDetails) { + + paymentNonceProvider.getPaymentNonce(user: user, + organisationId: organisationId, + quote: quote) { [weak self] result in + switch result { + case .completed(let result): + handlePaymentNonceProviderResult(result) + + case .cancelledByUser: + self?.view?.setDefaultState() + } + } + + func handlePaymentNonceProviderResult(_ paymentNonceResult: PaymentNonceProviderResult) { + switch paymentNonceResult { + case .nonce(let nonce): + self.book(paymentNonce: nonce.nonce, + passenger: passengerDetails, + flightNumber: view?.getFlightNumber()) + + case .cancelledByUser: + self.view?.setDefaultState() + + case .failedToAddCard(let error): + self.view?.setDefaultState() + self.view?.show(error: error) + + default: + self.view?.showAlert(title: UITexts.Generic.error, + message: UITexts.Errors.somethingWentWrong, + error: nil) + view?.setDefaultState() + } + } + } + + private func getPaymentNonceAccordingToAuthState() -> String? { + switch Karhoo.configuration.authenticationMethod() { + case .tokenExchange(settings: _), .karhooUser: return retrievePaymentNonce() + default: return view?.getPaymentNonce() + } + } + + private func retrievePaymentNonce() -> String? { + if userService.getCurrentUser()?.paymentProvider?.provider.type == .braintree { + return userService.getCurrentUser()?.nonce?.nonce + } else { + return view?.getPaymentNonce() + } + } + + private func submitGuestBooking() { + guard let passengerDetails = view?.getPassengerDetails() + else { + view?.setDefaultState() + return + } + guard let nonce = getPaymentNonceAccordingToAuthState() + else { + view?.retryAddPaymentMethod(showRetryAlert: false) + return + } + + if userService.getCurrentUser()?.paymentProvider?.provider.type == .braintree { + var organisation = organisationId() + guard let currentUser = userService.getCurrentUser() + else { + view?.showAlert(title: UITexts.Errors.somethingWentWrong, + message: UITexts.Errors.getUserFail, + error: nil) + view?.setDefaultState() + return + } + threeDSecureNonceThenBook(nonce: nonce, + passengerDetails: passengerDetails) + } else { + book(paymentNonce: nonce, passenger: passengerDetails, flightNumber: view?.getFlightNumber()) + } + } + + private func threeDSecureNonceThenBook(nonce: String, passengerDetails: PassengerDetails) { + threeDSecureProvider.threeDSecureCheck(nonce: nonce, + currencyCode: quote.price.currencyCode, + paymentAmout: NSDecimalNumber(value: quote.price.highPrice), + callback: { [weak self] result in + switch result { + case .completed(let result): handleThreeDSecureCheck(result) + case .cancelledByUser: + self?.view?.resetPaymentNonce() + self?.view?.setDefaultState() + } + }) + + func handleThreeDSecureCheck(_ result: ThreeDSecureCheckResult) { + switch result { + case .failedToInitialisePaymentService: + view?.setDefaultState() + + case .threeDSecureAuthenticationFailed: + view?.retryAddPaymentMethod(showRetryAlert: true) + view?.setDefaultState() + + case .success(let threeDSecureNonce): + book(paymentNonce: threeDSecureNonce, passenger: passengerDetails, flightNumber: view?.getFlightNumber()) + } + } + } + + private func book(paymentNonce: String, passenger: PassengerDetails, flightNumber: String?) { + var flight : String? = flightNumber + if let f = flight, (f.isEmpty || f == " ") { + flight = nil + } + + var tripBooking = TripBooking(quoteId: quote.id, + passengers: Passengers(additionalPassengers: 0, + passengerDetails: [passenger]), + flightNumber: flight, + paymentNonce: paymentNonce, + comments: view?.getComments()) + + var map: [String: Any] = [:] + if let metadata = bookingMetadata { + map = metadata + } + tripBooking.meta = map + if userService.getCurrentUser()?.paymentProvider?.provider.type == .adyen { + tripBooking.meta["trip_id"] = paymentNonce + } + + tripService.book(tripBooking: tripBooking).execute(callback: { [weak self] result in + self?.view?.setDefaultState() + + if self?.isKarhooUser() ?? false { + self?.handleKarhooUserBookTripResult(result) + } + else { + self?.handleGuestAndTokenBookTripResult(result) + } + }) + } + + private func handleKarhooUserBookTripResult(_ result: Result) { + bookingRequestInProgress = false + + guard let trip = result.successValue() else { + view?.setDefaultState() + + if result.errorValue()?.type == .couldNotBookTripPaymentPreAuthFailed { + view?.retryAddPaymentMethod(showRetryAlert: true) + } else { + callback(ScreenResult.failed(error: result.errorValue())) + } + + return + } + + self.trip = trip + view?.showCheckoutView(false) + } + + private func handleGuestAndTokenBookTripResult(_ result: Result) { + if let trip = result.successValue() { + callback(.completed(result: trip)) + } + else if let error = result.errorValue() { + view?.showAlert(title: UITexts.Generic.error, message: "\(error.localizedMessage)", error: result.errorValue()) + } + } + + func didPressFareExplanation() { + guard karhooUser, bookingRequestInProgress == false else { + return + } + + let popupDialog = baseFareDialogBuilder.buildPopupDialogScreen(callback: { [weak self] _ in + self?.view?.dismiss(animated: true, completion: nil) + }) + + popupDialog.modalTransitionStyle = .crossDissolve + view?.showAsOverlay(item: popupDialog, animated: true) + } + + func didPressClose() { + PassengerInfo.shared.set(details: view?.getPassengerDetails()) + view?.showCheckoutView(false) + } + + func screenHasFadedOut() { + if let trip = self.trip { + callback(ScreenResult.completed(result: trip)) + } else { + callback(ScreenResult.cancelled(byUser: false)) + } + } + + private func setUpBookingButtonState() { + if TripInfoUtility.isAirportBooking(bookingDetails) { + view?.setAddFlightDetailsState() + } else { + didAddPassengerDetails() + } + } +} + diff --git a/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutViewController+Extensions.swift b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutViewController+Extensions.swift new file mode 100644 index 000000000..b1d01162a --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutViewController+Extensions.swift @@ -0,0 +1,78 @@ +// +// KarhooCheckoutViewController+Extensions.swift +// KarhooUISDK +// +// Created by Diana Petrea on 26.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +extension KarhooCheckoutViewController: TimePriceViewDelegate { + func didPressFareExplanation() { + presenter.didPressFareExplanation() + } +} + +extension KarhooCheckoutViewController: BookingButtonDelegate { + func addMoreDetails() { + presenter.addMoreDetails() + } + + func requestPressed() { + presenter.bookTripPressed() + } +} + +extension KarhooCheckoutViewController: PassengerDetailsActions { + func passengerDetailsValid(_ valid: Bool) { + passengerDetailsValid = valid + enableBookingButton() + } +} + +extension KarhooCheckoutViewController: KarhooInputViewDelegate { + func didBecomeInactive(identifier: String) {} + + func didBecomeActive(identifier: String) {} + + func didChangeCharacterInSet(identifier: String) {} + + private func enableBookingButton() { + if passengerDetailsValid != true { + bookingButton.setDisabledMode() + } + } +} + +extension KarhooCheckoutViewController: AddPaymentViewDelegate { + func didGetNonce(nonce: String) { + paymentNonce = nonce + didBecomeInactive(identifier: commentsInputText.accessibilityIdentifier!) + presenter.didAddPassengerDetails() + } +} + +extension KarhooCheckoutViewController: AddPassengerDetailsViewDelegate { + func didUpdatePassengerDetails(details: PassengerDetails?) { + didBecomeInactive(identifier: commentsInputText.accessibilityIdentifier!) + presenter.didAddPassengerDetails() + } + + func willUpdatePassengerDetails() { + presenter.addOrEditPassengerDetails() + } +} + +extension KarhooCheckoutViewController: RideInfoViewDelegate { + func infoButtonPressed() { + if farePriceInfoView.isDescendant(of: rideInfoStackView) { + farePriceInfoView.isHidden.toggle() + } else { + rideInfoStackView.addArrangedSubview(farePriceInfoView) + farePriceInfoView.heightAnchor.constraint(greaterThanOrEqualToConstant: 50.0).isActive = true + } + } +} + diff --git a/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutViewController.swift b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutViewController.swift new file mode 100644 index 000000000..297d6f383 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Checkout/KarhooCheckoutViewController.swift @@ -0,0 +1,390 @@ +// +// KarhooCheckoutViewController.swift +// KarhooUISDK +// +// Copyright © 2020 Karhoo All rights reserved. +// + +import UIKit +import KarhooSDK + +final class KarhooCheckoutViewController: UIViewController, CheckoutView { + + private var didSetupConstraints = false + private var termsConditionsView: TermsConditionsView! + private var containerBottomConstraint: NSLayoutConstraint! + private let drawAnimationTime: Double = 0.45 + var presenter: CheckoutPresenter + var passengerDetailsValid: Bool? + var headerView: KarhooCheckoutHeaderView! + + private let extraSmallSpacing: CGFloat = 8.0 + private let standardButtonSize: CGFloat = 44.0 + + private lazy var footerStack: UIStackView = { + let footerStack = UIStackView() + footerStack.translatesAutoresizingMaskIntoConstraints = false + footerStack.accessibilityIdentifier = "footer_stack_view" + footerStack.axis = .vertical + footerStack.spacing = 15.0 + return footerStack + }() + + lazy var bookingButton: KarhooBookingButtonView = { + let bookingButton = KarhooBookingButtonView() + bookingButton.anchor(height: 55.0) + bookingButton.set(actions: self) + return bookingButton + }() + + private lazy var footerView: UIView = { + let footerView = UIView() + footerView.translatesAutoresizingMaskIntoConstraints = false + footerView.accessibilityIdentifier = "footer_view" + footerView.backgroundColor = .white + return footerView + }() + + lazy var commentsInputText: KarhooTextInputView = { + let commentsInputText = KarhooTextInputView(contentType: .comment, isOptional: true, accessibilityIdentifier: "comment_input_view") + commentsInputText.delegate = self + return commentsInputText + }() + + private lazy var poiDetailsInputText: KarhooTextInputView = { + let poiDetailsInputText = KarhooTextInputView(contentType: .poiDetails, isOptional: true, accessibilityIdentifier: "poi_input_view") + poiDetailsInputText.delegate = self + poiDetailsInputText.isHidden = true + return poiDetailsInputText + }() + + private lazy var passengerDetailsAndPaymentView: KarhooAddPassengerDetailsAndPaymentView = { + let passengerDetailsAndPaymentView = KarhooAddPassengerDetailsAndPaymentView(baseVC: self) + passengerDetailsAndPaymentView.accessibilityIdentifier = "passenger_details_payment_view" + passengerDetailsAndPaymentView.translatesAutoresizingMaskIntoConstraints = false + passengerDetailsAndPaymentView.setPaymentViewActions(actions: self) + passengerDetailsAndPaymentView.setPassengerViewActions(actions: self) + return passengerDetailsAndPaymentView + }() + + private lazy var backButton: UIButton = { + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityIdentifier = KHPassengerDetailsViewID.backButton + button.tintColor = KarhooUI.colors.darkGrey + button.setImage(UIImage.uisdkImage("backIcon").withRenderingMode(.alwaysTemplate), for: .normal) + button.imageView?.contentMode = .scaleAspectFit + button.setTitle(UITexts.Generic.back, for: .normal) + button.setTitleColor(KarhooUI.colors.darkGrey, for: .normal) + button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 12.0) + button.titleEdgeInsets = UIEdgeInsets(top: 0, left: extraSmallSpacing, bottom: 0, right: 0) + button.addTarget(self, action: #selector(backButtonPressed), for: .touchUpInside) + return button + }() + + private lazy var container: UIView = { + let container = UIView() + container.translatesAutoresizingMaskIntoConstraints = false + container.accessibilityIdentifier = "container_view" + container.layer.cornerRadius = 10.0 + container.layer.masksToBounds = true + container.backgroundColor = .white + return container + }() + + private lazy var baseStackView: BaseStackView = { + let baseStackView = BaseStackView() + baseStackView.translatesAutoresizingMaskIntoConstraints = false + baseStackView.accessibilityIdentifier = "base_stack_view" + baseStackView.viewSpacing(15.0) + return baseStackView + }() + + private var cancellationInfoLabel: UILabel = { + let cancellationInfo = UILabel() + cancellationInfo.translatesAutoresizingMaskIntoConstraints = false + cancellationInfo.accessibilityIdentifier = KHCheckoutHeaderViewID.cancellationInfo + cancellationInfo.font = KarhooUI.fonts.captionRegular() + cancellationInfo.textColor = KarhooUI.colors.primaryTextColor + cancellationInfo.text = "Free cancellation until arrival of the driver" + cancellationInfo.numberOfLines = 0 + return cancellationInfo + }() + + lazy var rideInfoStackView: UIStackView = { + let rideInfoStackView = UIStackView() + rideInfoStackView.accessibilityIdentifier = "ride_info_stack_view" + rideInfoStackView.translatesAutoresizingMaskIntoConstraints = false + rideInfoStackView.axis = .vertical + rideInfoStackView.spacing = 8 + rideInfoStackView.distribution = .fill + return rideInfoStackView + }() + + private lazy var rideInfoView: KarhooRideInfoView = { + let rideInfoView = KarhooRideInfoView() + rideInfoView.translatesAutoresizingMaskIntoConstraints = false + rideInfoView.accessibilityIdentifier = KHCheckoutHeaderViewID.rideInfoView + rideInfoView.backgroundColor = KarhooUI.colors.infoBackgroundColor + rideInfoView.layer.masksToBounds = true + rideInfoView.layer.cornerRadius = 8.0 + rideInfoView.setActions(self) + return rideInfoView + }() + + lazy var farePriceInfoView: KarhooFareInfoView = { + let farePriceInfoView = KarhooFareInfoView() + farePriceInfoView.translatesAutoresizingMaskIntoConstraints = false + farePriceInfoView.accessibilityIdentifier = "fare_price_info_view" + farePriceInfoView.backgroundColor = KarhooUI.colors.accent + farePriceInfoView.layer.masksToBounds = true + farePriceInfoView.layer.cornerRadius = 8.0 + return farePriceInfoView + }() + + private lazy var supplierStackContainer: UIStackView = { + let supplierStackContainer = UIStackView() + supplierStackContainer.translatesAutoresizingMaskIntoConstraints = false + supplierStackContainer.accessibilityIdentifier = "supplier_stack_view" + supplierStackContainer.axis = .horizontal + supplierStackContainer.alignment = .fill + supplierStackContainer.distribution = .fill + return supplierStackContainer + }() + + private lazy var timePriceView: KarhooTimePriceView = { + let timePriceView = KarhooTimePriceView() + timePriceView.set(actions: self) + return timePriceView + }() + + private var mainStackBottomPadding: NSLayoutConstraint! + + var paymentNonce: String? + + init(presenter: CheckoutPresenter) { + self.presenter = presenter + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(code:) has not been implemented") + } + + override func loadView() { + view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(container) + termsConditionsView = TermsConditionsView() + setUpView() + } + + private func setUpView() { + container.addSubview(backButton) + container.addSubview(baseStackView) + + headerView = KarhooCheckoutHeaderView() + baseStackView.addViewToStack(view: headerView) + baseStackView.addViewToStack(view: cancellationInfoLabel) + baseStackView.addViewToStack(view: rideInfoStackView) + rideInfoStackView.addArrangedSubview(rideInfoView) + baseStackView.addViewToStack(view: passengerDetailsAndPaymentView) + baseStackView.addViewToStack(view: poiDetailsInputText) + baseStackView.addViewToStack(view: commentsInputText) + baseStackView.addViewToStack(view: termsConditionsView) + + container.addSubview(footerView) + footerView.addSubview(footerStack) + footerStack.addArrangedSubview(bookingButton) + + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView)) + container.addGestureRecognizer(tapGesture) + view.setNeedsUpdateConstraints() + + presenter.load(view: self) + } + + override func updateViewConstraints() { + if didSetupConstraints == false { + setupConstraintsForDefault() + didSetupConstraints = true + } + super.updateViewConstraints() + } + + // TODO: Children of stack views shouldn't be anchored to their parent. + // Set the directionalLayoutMargins of the base stack view for insets + // and the spacing of the base stack view for distancing the children between each other + private func setupConstraintsForDefault() { + view.anchor(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + container.anchor(leading: view.leadingAnchor, trailing: view.trailingAnchor, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + + backButton.anchor(top: container.topAnchor, + leading: container.leadingAnchor, + paddingTop: view.safeAreaInsets.top + 15.0, + paddingBottom: 15.0, + width: standardButtonSize * 2) + + containerBottomConstraint = container.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: UIScreen.main.bounds.height) + containerBottomConstraint.isActive = true + baseStackView.anchor(top: backButton.bottomAnchor, leading: container.leadingAnchor, bottom: footerView.topAnchor, trailing: container.trailingAnchor) + + let titleInset: CGFloat = 15.0 + headerView.anchor(leading: baseStackView.leadingAnchor, trailing: baseStackView.trailingAnchor, paddingLeft: titleInset, paddingRight: titleInset) + headerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 90.0).isActive = true + + cancellationInfoLabel.anchor(top: headerView.bottomAnchor, leading: baseStackView.leadingAnchor, trailing: baseStackView.trailingAnchor, paddingTop: 20.0, paddingLeft: 20.0, paddingBottom: 20.0, paddingRight: 20.0) + + rideInfoStackView.anchor(top: cancellationInfoLabel.bottomAnchor, leading: baseStackView.leadingAnchor, trailing: baseStackView.trailingAnchor, paddingTop: 8.0, paddingLeft: titleInset, paddingRight: titleInset) + passengerDetailsAndPaymentView.anchor(top: rideInfoStackView.bottomAnchor, leading: baseStackView.leadingAnchor, trailing: baseStackView.trailingAnchor, paddingTop: titleInset, paddingLeft: titleInset, paddingRight: titleInset, height: 92.0) + + poiDetailsInputText.anchor(leading: baseStackView.leadingAnchor, trailing: baseStackView.trailingAnchor, paddingLeft: titleInset, paddingRight: titleInset) + commentsInputText.anchor(leading: baseStackView.leadingAnchor, trailing: baseStackView.trailingAnchor, paddingLeft: titleInset, paddingRight: titleInset) + + footerView.anchor(leading: view.leadingAnchor, bottom: container.bottomAnchor, trailing: view.trailingAnchor, paddingBottom: 20.0, paddingRight: 10.0) + footerStack.anchor(top: footerView.topAnchor, leading: footerView.leadingAnchor, bottom: footerView.bottomAnchor, trailing: footerView.trailingAnchor) + termsConditionsView.anchor(leading: baseStackView.leadingAnchor, trailing: baseStackView.trailingAnchor) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + showCheckoutView(true) + } + + override func viewDidLoad() { + super.viewDidLoad() + passengerDetailsAndPaymentView.details = initialisePassengerDetails() + forceLightMode() + } + + private func initialisePassengerDetails() -> PassengerDetails? { + if PassengerInfo.shared.getDetails() == nil { + return PassengerInfo.shared.currentUserAsPassenger() + } else { + return PassengerInfo.shared.getDetails() + } + } + + @objc private func didTapView() { + view.endEditing(true) + } + + @objc func backButtonPressed() { + presenter.didPressClose() + } + + func setPassenger(details: PassengerDetails?) { + passengerDetailsAndPaymentView.details = details + } + + func showCheckoutView(_ show: Bool) { + containerBottomConstraint.constant = show ? 0.0 : UIScreen.main.bounds.height + UIView.animate(withDuration: drawAnimationTime, + animations: { [weak self] in + self?.view.layoutIfNeeded() + }, completion: { [weak self] completed in + if completed && !show { + self?.presenter.screenHasFadedOut() + self?.dismiss(animated: false, completion: nil) + } + }) + } + + func setRequestingState() { + disableUserInteraction() + bookingButton.setRequestingMode() + } + + func setMoreDetailsState() { + bookingButton.setNextMode() + } + + func setDefaultState() { + enableUserInteraction() + bookingButton.setRequestMode() + } + + func resetPaymentNonce() { + self.paymentNonce = nil + passengerDetailsAndPaymentView.noPaymentMethod() + } + + func setAddFlightDetailsState() { + enableUserInteraction() + poiDetailsInputText.isHidden = false + } + + func set(quote: Quote) { + let viewModel = QuoteViewModel(quote: quote) + passengerDetailsAndPaymentView.quote = quote + headerView.set(viewModel: viewModel) + rideInfoView.setDetails(viewModel: viewModel) + termsConditionsView.setBookingTerms(supplier: quote.fleet.name, termsStringURL: quote.fleet.termsConditionsUrl) + cancellationInfoLabel.text = viewModel.freeCancellationMessage + farePriceInfoView.setInfoText(for: quote.quoteType) + } + + func set(price: String?) { + timePriceView.set(price: price) + } + + func setAsapState(qta: String?) { + timePriceView.setAsapMode(qta: qta) + } + + func setPrebookState(timeString: String?, dateString: String?) { + timePriceView.setPrebookMode(timeString: timeString, dateString: dateString) + } + + func set(quoteType: String) { + timePriceView.set(quoteType: quoteType) + } + + func set(baseFareExplanationHidden: Bool) { + timePriceView.set(baseFareHidden: baseFareExplanationHidden) + } + + func retryAddPaymentMethod(showRetryAlert: Bool = false) { + passengerDetailsAndPaymentView.startRegisterCardFlow(showRetryAlert: showRetryAlert) + } + + private func enableUserInteraction() { + backButton.isUserInteractionEnabled = true + backButton.tintColor = KarhooUI.colors.darkGrey + } + + private func disableUserInteraction() { + backButton.isUserInteractionEnabled = false + backButton.tintColor = KarhooUI.colors.medGrey + } + + final class Builder: CheckoutScreenBuilder { + func buildCheckoutScreen(quote: Quote, + bookingDetails: BookingDetails, + bookingMetadata: [String: Any]?, + callback: @escaping ScreenResultCallback) -> Screen { + + let presenter = KarhooCheckoutPresenter(quote: quote, + bookingDetails: bookingDetails, + bookingMetadata: bookingMetadata, + callback: callback) + return KarhooCheckoutViewController(presenter: presenter) + } + } + + func getPassengerDetails() -> PassengerDetails? { + return passengerDetailsAndPaymentView.details + } + + func getPaymentNonce() -> String? { + return self.paymentNonce + } + + func getComments() -> String? { + return commentsInputText.getInput() + } + + func getFlightNumber() -> String? { + return poiDetailsInputText.getInput() + } +} diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsMVP.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsMVP.swift new file mode 100644 index 000000000..598b17027 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsMVP.swift @@ -0,0 +1,31 @@ +// +// KarhooAddPassengerDetailsMVP.swift +// KarhooUISDK +// +// Created by Diana Petrea on 26.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +protocol AddPassengerDetailsViewDelegate { + func willUpdatePassengerDetails() + func didUpdatePassengerDetails(details: PassengerDetails?) +} + +protocol AddPassengerDetailsPresenter { + func set(details: PassengerDetails?) +} + +protocol AddPassengerView: BaseView { + var baseViewController: BaseViewController? { get set } + var actions: AddPassengerDetailsViewDelegate? { get set } + func set(details: PassengerDetails?) + func validDetails() -> Bool + func showError() + func updateViewState() + func resetViewState() + func resetViewBorder() + func updatePassengerSummary(details: PassengerDetails?) +} diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsPresenter.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsPresenter.swift new file mode 100644 index 000000000..8793f186b --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsPresenter.swift @@ -0,0 +1,44 @@ +// +// KarhooAddPassengerDetailsPresenter.swift +// KarhooUISDK +// +// Created by Diana Petrea on 26.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +class KarhooAddPassengerDetailsPresenter: AddPassengerDetailsPresenter { + + private let analyticsService: AnalyticsService + private let view: AddPassengerView + private var details: PassengerDetails? + + init(analyticsService: AnalyticsService = Karhoo.getAnalyticsService(), + view: AddPassengerView = KarhooAddPassengerDetailsView()) { + + self.analyticsService = analyticsService + self.view = view + displayAvailablePassengerDetails() + } + + func set(details: PassengerDetails?) { + self.details = details + displayAvailablePassengerDetails() + } + + private func displayAvailablePassengerDetails() { + view.updatePassengerSummary(details: details) + + if details == nil { + view.resetViewState() + } + else if let details = details, !details.areValid { + view.resetViewBorder() + } + else { + view.updateViewState() + } + } +} diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsView.swift new file mode 100644 index 000000000..8945cb0d3 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPassengerDetailsView/KarhooAddPassengerDetailsView.swift @@ -0,0 +1,219 @@ +// +// KarhooAddPassengerDetailsView.swift +// KarhooUISDK +// +// Created by Diana Petrea on 26.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit +import KarhooSDK + +public struct KHAddPassengerDetailsViewID { + public static let container = "container_view" + public static let stackView = "main_stack_view" + public static let image = "logo_image" + public static let title = "title_label" + public static let subtitle = "subtitle_label" +} + +final class KarhooAddPassengerDetailsView: UIView, AddPassengerView { + + var baseViewController: BaseViewController? + private var didSetupConstraints: Bool = false + private var presenter: KarhooAddPassengerDetailsPresenter? + var actions: AddPassengerDetailsViewDelegate? + private var dotBorderLayer: CAShapeLayer! + private var hasValidDetails: Bool = false + + private lazy var passengerDetailsContainer: UIView = { + let passengerDetailsView = UIView() + passengerDetailsView.accessibilityIdentifier = KHAddPassengerDetailsViewID.container + passengerDetailsView.layer.masksToBounds = true + + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(passengerDetailsViewTapped)) + passengerDetailsView.addGestureRecognizer(tapGesture) + + return passengerDetailsView + }() + + private lazy var passengerDetailsStackView: UIStackView = { + let passengerDetailsStackView = UIStackView() + passengerDetailsStackView.accessibilityIdentifier = KHAddPassengerDetailsViewID.stackView + passengerDetailsStackView.translatesAutoresizingMaskIntoConstraints = false + passengerDetailsStackView.alignment = .center + passengerDetailsStackView.axis = .vertical + passengerDetailsStackView.distribution = .equalSpacing + passengerDetailsStackView.spacing = 5.0 + + return passengerDetailsStackView + }() + + private lazy var passengerDetailsImage: UIImageView = { + let passengerDetailsIcon = UIImageView() + passengerDetailsIcon.accessibilityIdentifier = KHAddPassengerDetailsViewID.image + passengerDetailsIcon.translatesAutoresizingMaskIntoConstraints = false + passengerDetailsIcon.image = UIImage.uisdkImage("user_icon") + passengerDetailsIcon.tintColor = KarhooUI.colors.infoColor + passengerDetailsIcon.contentMode = .scaleAspectFit + + return passengerDetailsIcon + }() + + private lazy var passengerDetailsTitle: UILabel = { + let passengerDetailsTitleLabel = UILabel() + passengerDetailsTitleLabel.translatesAutoresizingMaskIntoConstraints = false + passengerDetailsTitleLabel.accessibilityIdentifier = KHAddPassengerDetailsViewID.title + passengerDetailsTitleLabel.textColor = KarhooUI.colors.primaryTextColor + passengerDetailsTitleLabel.textAlignment = .center + passengerDetailsTitleLabel.text = UITexts.Booking.passenger + passengerDetailsTitleLabel.font = KarhooUI.fonts.getBoldFont(withSize: 12.0) + + return passengerDetailsTitleLabel + }() + + private lazy var passengerDetailsSubtitle: UILabel = { + let passengerDetailsSubtitleLabel = UILabel() + passengerDetailsSubtitleLabel.translatesAutoresizingMaskIntoConstraints = false + passengerDetailsSubtitleLabel.accessibilityIdentifier = KHAddPassengerDetailsViewID.subtitle + passengerDetailsSubtitleLabel.textColor = KarhooUI.colors.accent + passengerDetailsSubtitleLabel.textAlignment = .center + passengerDetailsSubtitleLabel.text = UITexts.Booking.guestCheckoutPassengerDetailsTitle + passengerDetailsSubtitleLabel.font = KarhooUI.fonts.getRegularFont(withSize: 10.0) + + return passengerDetailsSubtitleLabel + }() + + init() { + super.init(frame: .zero) + self.setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func draw(_ rect: CGRect) { + super.draw(rect) + + if !hasValidDetails && dotBorderLayer == nil { + dotBorderLayer = CAShapeLayer() + dotBorderLayer.strokeColor = KarhooUI.colors.darkGrey.cgColor + dotBorderLayer.lineDashPattern = [4, 4] + dotBorderLayer.frame = bounds + dotBorderLayer.fillColor = nil + dotBorderLayer.path = UIBezierPath(rect: bounds).cgPath + layer.addSublayer(dotBorderLayer) + } + } + + private func setupView() { + backgroundColor = .clear + translatesAutoresizingMaskIntoConstraints = false + accessibilityIdentifier = KHAddPassengerDetailsAndPaymentViewID.container + layer.cornerRadius = 4.0 + layer.masksToBounds = true + + addSubview(passengerDetailsContainer) + + passengerDetailsStackView.addArrangedSubview(passengerDetailsImage) + passengerDetailsStackView.addArrangedSubview(passengerDetailsTitle) + passengerDetailsStackView.addArrangedSubview(passengerDetailsSubtitle) + + passengerDetailsContainer.addSubview(passengerDetailsStackView) + + presenter = KarhooAddPassengerDetailsPresenter(view: self) + } + + override func updateConstraints() { + if !didSetupConstraints { + passengerDetailsContainer.anchor(top: self.topAnchor, + leading: self.leadingAnchor, + bottom: self.bottomAnchor, + trailing: self.trailingAnchor) + + passengerDetailsStackView.anchor(top: passengerDetailsContainer.topAnchor, + leading: passengerDetailsContainer.leadingAnchor, + bottom: passengerDetailsContainer.bottomAnchor, + trailing: passengerDetailsContainer.trailingAnchor, + paddingTop: 12.0, + paddingBottom: 12.0) + + passengerDetailsImage.anchor(leading: passengerDetailsStackView.leadingAnchor, + trailing: passengerDetailsStackView.trailingAnchor, + paddingLeft: 56.0, + paddingRight: 56.0, + width: 24.0, + height: 24.0) + + didSetupConstraints = true + } + + super.updateConstraints() + } + + @objc private func passengerDetailsViewTapped() { + actions?.willUpdatePassengerDetails() + } + + func setBaseViewController(_ vc: BaseViewController) { + baseViewController = vc + } + + func set(details: PassengerDetails?) { + presenter?.set(details: details) + actions?.didUpdatePassengerDetails(details: details) + } + + func validDetails() -> Bool { + return hasValidDetails + } + + func showError() { + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.error) + shakeView() + + layer.borderWidth = 1.0 + layer.borderColor = UIColor.red.cgColor + } + + func updatePassengerSummary(details: PassengerDetails?) { + guard let details = details + else { + passengerDetailsTitle.text = UITexts.PassengerDetails.title + passengerDetailsSubtitle.text = UITexts.PassengerDetails.add + return + } + + passengerDetailsTitle.text = "\(details.firstName) \(details.lastName)" + passengerDetailsSubtitle.text = UITexts.Generic.edit + } + + func updateViewState() { + setFullBorder(true) + hasValidDetails = true + setNeedsDisplay() + } + + func resetViewState() { + setFullBorder(false) + hasValidDetails = false + passengerDetailsTitle.text = UITexts.PassengerDetails.title + passengerDetailsSubtitle.text = UITexts.PassengerDetails.add + passengerDetailsImage.image = UIImage.uisdkImage("user_icon") + + setNeedsDisplay() + } + + func resetViewBorder() { + setFullBorder(false) + hasValidDetails = false + setNeedsDisplay() + } + + private func setFullBorder(_ shouldSet: Bool) { + layer.borderWidth = shouldSet ? 1.0 : 0.0 + layer.borderColor = shouldSet ? KarhooUI.colors.guestCheckoutGrey.cgColor : UIColor.clear.cgColor + } +} diff --git a/KarhooUISDK/Screens/PaymentView/KarhooPaymentMVP.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentMVP.swift similarity index 60% rename from KarhooUISDK/Screens/PaymentView/KarhooPaymentMVP.swift rename to KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentMVP.swift index a77df9360..94cfb09ad 100644 --- a/KarhooUISDK/Screens/PaymentView/KarhooPaymentMVP.swift +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentMVP.swift @@ -7,20 +7,19 @@ import Foundation import KarhooSDK -protocol PaymentViewActions { +protocol AddPaymentViewDelegate { func didGetNonce(nonce: String) } -protocol PaymentPresenter { +protocol AddPaymentPresenter { func updateCardPressed(showRetryAlert: Bool) } -protocol PaymentView: BaseView { - func set(paymentMethod: PaymentMethod) +protocol AddPaymentView: BaseView { func set(nonce: Nonce) func noPaymentMethod() - func startRegisterCardFlow() + func startRegisterCardFlow(showRetryAlert: Bool) var baseViewController: BaseViewController? { get set } var quote: Quote? { get set } - var actions: PaymentViewActions? { get } + var actions: AddPaymentViewDelegate? { get set } } diff --git a/KarhooUISDK/Screens/PaymentView/KarhooPaymentPresenter.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentPresenter.swift similarity index 89% rename from KarhooUISDK/Screens/PaymentView/KarhooPaymentPresenter.swift rename to KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentPresenter.swift index d87922b5a..3f3fc5995 100644 --- a/KarhooUISDK/Screens/PaymentView/KarhooPaymentPresenter.swift +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentPresenter.swift @@ -9,17 +9,17 @@ import Foundation import KarhooSDK -final class KarhooPaymentPresenter: PaymentPresenter { +final class KarhooAddPaymentPresenter: AddPaymentPresenter { private let analyticsService: AnalyticsService private let userService: UserService - private let view: PaymentView + private let view: AddPaymentView private var cardRegistrationFlow: CardRegistrationFlow init(analyticsService: AnalyticsService = Karhoo.getAnalyticsService(), userService: UserService = Karhoo.getUserService(), cardRegistrationFlow: CardRegistrationFlow = PaymentFactory().getCardFlow(), - view: PaymentView = KarhooPaymentView()) { + view: AddPaymentView = KarhooAddPaymentView()) { self.cardRegistrationFlow = cardRegistrationFlow self.analyticsService = analyticsService self.userService = userService @@ -53,14 +53,13 @@ final class KarhooPaymentPresenter: PaymentPresenter { view.noPaymentMethod() return } - view.set(nonce: currentNonce) } private func handleAddCardFlow(result: CardFlowResult) { switch result { - case .didAddPaymentMethod(let method): - view.set(paymentMethod: method) + case .didAddPaymentMethod(let nonce): + view.set(nonce: nonce) case .didFailWithError(let error): (view.parentViewController as? BaseViewController)?.showAlert(title: UITexts.Errors.somethingWentWrong, message: error?.message ?? "", error: error) @@ -69,7 +68,7 @@ final class KarhooPaymentPresenter: PaymentPresenter { } } -extension KarhooPaymentPresenter: UserStateObserver { +extension KarhooAddPaymentPresenter: UserStateObserver { func userStateUpdated(user: UserInfo?) { displayAvailablePaymentMethod() diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentView.swift new file mode 100644 index 000000000..b2cbfcb90 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/AddPaymentView/KarhooAddPaymentView.swift @@ -0,0 +1,209 @@ +// +// KarhooAddCardView.swift +// KarhooUISDK +// +// Copyright © 2020 Karhoo All rights reserved. +// + +import UIKit +import KarhooSDK + +public struct KHAddCardViewID { + public static let view = "add_card_view" + public static let image = "logo_image" + public static let title = "title_label" + public static let subtitle = "subtitle_label" + public static let stackView = "stack_view_container" +} + +final public class KarhooAddPaymentView: UIView, AddPaymentView { + + public var baseViewController: BaseViewController? + + private var didSetupConstraints: Bool = false + + private lazy var passengerPaymentImage: UIImageView = { + let passengerPaymentIcon = UIImageView() + passengerPaymentIcon.accessibilityIdentifier = KHAddCardViewID.image + passengerPaymentIcon.translatesAutoresizingMaskIntoConstraints = false + passengerPaymentIcon.image = UIImage.uisdkImage("plus_icon") + passengerPaymentIcon.tintColor = KarhooUI.colors.infoColor + passengerPaymentIcon.contentMode = .scaleAspectFit + + return passengerPaymentIcon + }() + + private lazy var passengerPaymentTitle: UILabel = { + let passengerPaymentTitleLabel = UILabel() + passengerPaymentTitleLabel.translatesAutoresizingMaskIntoConstraints = false + passengerPaymentTitleLabel.accessibilityIdentifier = KHAddCardViewID.title + passengerPaymentTitleLabel.textColor = KarhooUI.colors.primaryTextColor + passengerPaymentTitleLabel.textAlignment = .center + passengerPaymentTitleLabel.text = UITexts.Booking.guestCheckoutPaymentDetailsTitle + passengerPaymentTitleLabel.font = KarhooUI.fonts.getBoldFont(withSize: 12.0) + passengerPaymentTitleLabel.numberOfLines = 0 + + return passengerPaymentTitleLabel + }() + + private lazy var passengerPaymentSubtitle: UILabel = { + let passengerPaymentSubtitleLabel = UILabel() + passengerPaymentSubtitleLabel.translatesAutoresizingMaskIntoConstraints = false + passengerPaymentSubtitleLabel.accessibilityIdentifier = KHAddCardViewID.subtitle + passengerPaymentSubtitleLabel.textColor = KarhooUI.colors.accent + passengerPaymentSubtitleLabel.textAlignment = .center + passengerPaymentSubtitleLabel.text = UITexts.Payment.addPaymentMethod + passengerPaymentSubtitleLabel.font = KarhooUI.fonts.getRegularFont(withSize: 10.0) + + return passengerPaymentSubtitleLabel + }() + + private lazy var stackContainer: UIStackView = { + + let passengerPaymentStackView = UIStackView() + passengerPaymentStackView.accessibilityIdentifier = KHAddCardViewID.stackView + passengerPaymentStackView.translatesAutoresizingMaskIntoConstraints = false + + passengerPaymentStackView.alignment = .center + passengerPaymentStackView.axis = .vertical + passengerPaymentStackView.distribution = .equalSpacing + passengerPaymentStackView.spacing = 5.0 + + return passengerPaymentStackView + }() + + private var dotBorderLayer: CAShapeLayer! + private var hasPayment: Bool = false + + var quote: Quote? + var actions: AddPaymentViewDelegate? { + didSet { + if presenter == nil { + presenter = KarhooAddPaymentPresenter(view: self) + } + } + } + private var presenter: AddPaymentPresenter? + + public init() { + super.init(frame: .zero) + self.setUpView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override public func draw(_ rect: CGRect) { + super.draw(rect) + + if !hasPayment && dotBorderLayer == nil { + dotBorderLayer = CAShapeLayer() + dotBorderLayer.strokeColor = KarhooUI.colors.darkGrey.cgColor + dotBorderLayer.lineDashPattern = [4, 4] + dotBorderLayer.frame = bounds + dotBorderLayer.fillColor = nil + dotBorderLayer.path = UIBezierPath(rect: bounds).cgPath + layer.addSublayer(dotBorderLayer) + } + } + + private func setUpView() { + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(paymentViewTapped)) + addGestureRecognizer(tapGesture) + + backgroundColor = .clear + translatesAutoresizingMaskIntoConstraints = false + accessibilityIdentifier = KHAddCardViewID.view + layer.cornerRadius = 4.0 + layer.masksToBounds = true + + addSubview(stackContainer) + + stackContainer.addArrangedSubview(passengerPaymentImage) + stackContainer.addArrangedSubview(passengerPaymentTitle) + stackContainer.addArrangedSubview(passengerPaymentSubtitle) + } + + override public func updateConstraints() { + if !didSetupConstraints { + + passengerPaymentImage.anchor(leading: leadingAnchor, + trailing: trailingAnchor, + paddingLeft: 56.0, + paddingRight: 56.0, + width: 24.0, + height: 24.0) + + let stackInset: CGFloat = 12.0 + stackContainer.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor, + paddingTop: stackInset, + paddingBottom: stackInset) + + didSetupConstraints = true + } + + super.updateConstraints() + } + + @objc + private func paymentViewTapped() { + presenter?.updateCardPressed(showRetryAlert: false) + } + + func setBaseViewController(_ vc: BaseViewController) { + baseViewController = vc + } + + func set(nonce: Nonce) { + passengerPaymentTitle.text = UITexts.Payment.paymentMethod + " **** " + nonce.lastFour + passengerPaymentSubtitle.text = UITexts.Generic.edit + passengerPaymentImage.image = UIImage.uisdkImage(nonce.cardType) + + updateViewState() + actions?.didGetNonce(nonce: nonce.nonce) + } + + func noPaymentMethod() { + resetViewState() + } + + func startRegisterCardFlow(showRetryAlert: Bool = true) { + presenter?.updateCardPressed(showRetryAlert: showRetryAlert) + } + + private func updateViewState() { + layer.borderWidth = 1.0 + layer.borderColor = KarhooUI.colors.guestCheckoutGrey.cgColor + hasPayment = true + + setNeedsDisplay() + } + + private func resetViewState() { + layer.borderWidth = 0.0 + layer.borderColor = UIColor.clear.cgColor + hasPayment = false + passengerPaymentTitle.text = UITexts.Booking.guestCheckoutPaymentDetailsTitle + passengerPaymentSubtitle.text = UITexts.Payment.addPaymentMethod + passengerPaymentImage.image = UIImage.uisdkImage("plus_icon") + + setNeedsDisplay() + } + + func validPayment() -> Bool { + return hasPayment + } + + func showError() { + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.error) + shakeView() + + layer.borderWidth = 1.0 + layer.borderColor = UIColor.red.cgColor + } +} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/BookingButtonMVP/BookingButtonMVP.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/BookingButton/KarhooBookingButtonMVP.swift similarity index 63% rename from KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/BookingButtonMVP/BookingButtonMVP.swift rename to KarhooUISDK/Screens/CheckoutScreen/Components/BookingButton/KarhooBookingButtonMVP.swift index 87b7983bf..3e59a5006 100644 --- a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/BookingButtonMVP/BookingButtonMVP.swift +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/BookingButton/KarhooBookingButtonMVP.swift @@ -9,23 +9,14 @@ import Foundation protocol BookingButtonView { - - func set(actions: BookingButtonActions) - + func set(actions: BookingButtonDelegate) func setDisabledMode() - func setRequestMode() - func setRequestingMode() - func setRequestedMode() - - func setAddFlightDetailsMode() } -protocol BookingButtonActions: AnyObject { - +protocol BookingButtonDelegate: AnyObject { func requestPressed() - - func addFlightDetailsPressed() + func addMoreDetails() } diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/BookingButtonMVP/KarhooBookingButtonView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/BookingButton/KarhooBookingButtonView.swift similarity index 67% rename from KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/BookingButtonMVP/KarhooBookingButtonView.swift rename to KarhooUISDK/Screens/CheckoutScreen/Components/BookingButton/KarhooBookingButtonView.swift index f1ad8875f..e74155e64 100644 --- a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/BookingButtonMVP/KarhooBookingButtonView.swift +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/BookingButton/KarhooBookingButtonView.swift @@ -10,10 +10,10 @@ import UIKit import KarhooSDK private enum ButtonMode { + case addDetails case requesting case requested case request - case addFlightDetails case disabled } @@ -28,7 +28,7 @@ public struct KHBookingButtonViewID { final class KarhooBookingButtonView: UIView, BookingButtonView { - private weak var actions: BookingButtonActions? + private weak var actions: BookingButtonDelegate? private var containerView: UIView! private var activityIndicator: UIActivityIndicatorView! private var button: UIButton! @@ -100,36 +100,38 @@ final class KarhooBookingButtonView: UIView, BookingButtonView { override func updateConstraints() { if !didSetupConstraints { - _ = [containerView.topAnchor.constraint(equalTo: topAnchor), - containerView.bottomAnchor.constraint(equalTo: bottomAnchor), - containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20.0), - containerView.trailingAnchor.constraint(equalTo: trailingAnchor, - constant: -20.0)].map { $0.isActive = true } - - _ = [buttonLabel.centerYAnchor.constraint(equalTo: centerYAnchor), - buttonLabel.centerXAnchor.constraint(equalTo: centerXAnchor), - buttonLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10), - buttonLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10)].map { $0.isActive = true } + containerView.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor, + paddingLeft: 20.0, + paddingRight: 20.0) + + buttonLabel.centerX(inView: self) + buttonLabel.centerY(inView: self) + buttonLabel.anchor(top: topAnchor, + bottom: bottomAnchor, + paddingTop: 10.0, + paddingBottom: 10.0) let activitySize: CGFloat = 20.0 - _ = [activityIndicator.widthAnchor.constraint(equalToConstant: activitySize), - activityIndicator.heightAnchor.constraint(equalToConstant: activitySize), - activityIndicator.centerYAnchor.constraint(equalTo: buttonLabel.centerYAnchor), - activityIndicator.trailingAnchor.constraint(equalTo: buttonLabel.leadingAnchor, - constant: -12.0)].map { $0.isActive = true } - + activityIndicator.anchor(trailing: buttonLabel.leadingAnchor, + paddingRight: 12.0, + width: activitySize, + height: activitySize) + activityIndicator.centerY(inView: buttonLabel) + let imageSize: CGFloat = 20.0 - _ = [tickImage.widthAnchor.constraint(equalToConstant: imageSize), - tickImage.heightAnchor.constraint(equalToConstant: imageSize), - tickImage.centerYAnchor.constraint(equalTo: activityIndicator.centerYAnchor), - tickImage.centerXAnchor.constraint(equalTo: activityIndicator.centerXAnchor)] - .map { $0.isActive = true } - - _ = [button.topAnchor.constraint(equalTo: topAnchor), - button.leadingAnchor.constraint(equalTo: leadingAnchor), - button.trailingAnchor.constraint(equalTo: trailingAnchor), - button.bottomAnchor.constraint(equalTo: bottomAnchor)].map { $0.isActive = true } - + tickImage.centerX(inView: activityIndicator) + tickImage.centerY(inView: activityIndicator) + tickImage.anchor(width: imageSize, + height: imageSize) + + button.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor) + didSetupConstraints = true } @@ -143,13 +145,13 @@ final class KarhooBookingButtonView: UIView, BookingButtonView { } switch mode { + case .addDetails: actions?.addMoreDetails() case .request: actions?.requestPressed() - case .addFlightDetails: actions?.addFlightDetailsPressed() default: return } } - func set(actions: BookingButtonActions) { + func set(actions: BookingButtonDelegate) { self.actions = actions } @@ -162,7 +164,7 @@ final class KarhooBookingButtonView: UIView, BookingButtonView { func setRequestMode() { setSelectedState() currentMode = .request - set(buttonTitle: UITexts.Booking.requestCar) + set(buttonTitle: UITexts.Booking.requestCar.uppercased()) tickImage.isHidden = true activityIndicator?.stopAnimating() } @@ -171,26 +173,27 @@ final class KarhooBookingButtonView: UIView, BookingButtonView { currentMode = .requesting button.isEnabled = false containerView.backgroundColor = KarhooUI.colors.secondary - set(buttonTitle: UITexts.Booking.requestingCar) + set(buttonTitle: UITexts.Booking.requestingCar.uppercased()) tickImage.isHidden = true activityIndicator?.startAnimating() } + + func setNextMode() { + currentMode = .addDetails + button.isEnabled = true + containerView.backgroundColor = KarhooUI.colors.secondary + set(buttonTitle: UITexts.Booking.next.uppercased()) + tickImage.isHidden = true + activityIndicator?.stopAnimating() + } func setRequestedMode() { setSelectedState() currentMode = .requested - set(buttonTitle: UITexts.Booking.requestReceived) + set(buttonTitle: UITexts.Booking.requestReceived.uppercased()) tickImage?.isHidden = false activityIndicator?.stopAnimating() } - - func setAddFlightDetailsMode() { - setSelectedState() - currentMode = .addFlightDetails - set(buttonTitle: UITexts.Airport.addFlightDetails) - tickImage.isHidden = true - activityIndicator?.stopAnimating() - } private func setSelectedState() { containerView.backgroundColor = KarhooUI.colors.secondary diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooAddPassengerDetailsAndPaymentView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooAddPassengerDetailsAndPaymentView.swift new file mode 100644 index 000000000..15817ad2e --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooAddPassengerDetailsAndPaymentView.swift @@ -0,0 +1,111 @@ +// +// KarhooAddPassengerDetailsAndPaymentView.swift +// KarhooUISDK +// +// Created by Anca Feurdean on 12.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit +import KarhooSDK + +public struct KHAddPassengerDetailsAndPaymentViewID { + public static let container = "passenger_details_payment_container" + public static let passengerDetailsPaymentStackView = "passenger_details_payment_stack_view" + public static let passengerDetailsContainer = "passenger_details_container" + public static let passengerPaymentContainer = "passenger_payment_container" +} + +final class KarhooAddPassengerDetailsAndPaymentView: UIView { + + private var didSetupConstraints: Bool = false + var baseViewController: BaseViewController! + var details: PassengerDetails? { + didSet { + passengerDetailsContainer.set(details: details) + } + } + var quote: Quote? { + didSet { + passengerPaymentContainer.quote = quote + } + } + + private lazy var stackView: UIStackView = { + let stackView = UIStackView() + stackView.accessibilityIdentifier = KHAddPassengerDetailsAndPaymentViewID.passengerDetailsPaymentStackView + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.distribution = .fillEqually + stackView.spacing = 16.0 + + return stackView + }() + + private lazy var passengerDetailsContainer: AddPassengerView = { + let passengerDetailsView = KarhooAddPassengerDetailsView() + passengerDetailsView.accessibilityIdentifier = KHAddPassengerDetailsAndPaymentViewID.passengerDetailsContainer + passengerDetailsView.setBaseViewController(baseViewController) + return passengerDetailsView + }() + + private lazy var passengerPaymentContainer: AddPaymentView = { + let passengerPaymentView = KarhooAddPaymentView() + passengerPaymentView.accessibilityIdentifier = KHAddPassengerDetailsAndPaymentViewID.passengerPaymentContainer + passengerPaymentView.setBaseViewController(baseViewController) + return passengerPaymentView + }() + + init(baseVC: BaseViewController) { + super.init(frame: .zero) + self.baseViewController = baseVC + self.setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupView() { + translatesAutoresizingMaskIntoConstraints = false + accessibilityIdentifier = KHAddPassengerDetailsAndPaymentViewID.container + + addSubview(stackView) + + stackView.addArrangedSubview(passengerDetailsContainer) + stackView.addArrangedSubview(passengerPaymentContainer) + } + + override func updateConstraints() { + if !didSetupConstraints { + stackView.anchor(top: topAnchor, + leading: leadingAnchor, + trailing: trailingAnchor, + height: 92.0) + + didSetupConstraints = true + } + + super.updateConstraints() + } + + func startRegisterCardFlow(showRetryAlert: Bool = false) { + passengerPaymentContainer.startRegisterCardFlow(showRetryAlert: showRetryAlert) + } + + func setPaymentViewActions(actions: AddPaymentViewDelegate) { + passengerPaymentContainer.actions = actions + } + + func setPassengerViewActions(actions: AddPassengerDetailsViewDelegate) { + passengerDetailsContainer.actions = actions + } + + func validPassengerDetails() -> Bool { + return passengerDetailsContainer.validDetails() + } + + func noPaymentMethod() { + passengerPaymentContainer.noPaymentMethod() + } +} diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooCheckoutHeaderView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooCheckoutHeaderView.swift new file mode 100644 index 000000000..5b2e1a969 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooCheckoutHeaderView.swift @@ -0,0 +1,277 @@ +// +// KarhooCheckoutHeaderView.swift +// KarhooUISDK +// +// Copyright © 2020 Karhoo All rights reserved. +// + +import UIKit +import KarhooSDK + +public struct KHCheckoutHeaderViewID { + public static let topContainer = "top_container" + public static let fleetInfoContainer = "fleet_info_container" + public static let logoContainer = "logo_container" + public static let logoImageView = "logo_image_view" + public static let rideDetailsContainer = "ride_details_stack_view" + public static let nameLabel = "name_label" + public static let rideInfoView = "ride_info_view" + public static let etaTitle = "eta_title_label" + public static let etaText = "eta_text_label" + public static let rideType = "ride_type_label" + public static let estimatedPrice = "estimated_price_title_label" + public static let priceText = "price_text_label" + public static let ridePriceType = "ride_price_type_label" + public static let ridePriceTypeIcon = "ride_price_type_icon" + public static let carType = "car_type_label" + public static let capabilitiesContentView = "capabilities_content_view" + public static let fleetCapabilities = "fleet_capabilties_stack_view" + public static let cancellationInfo = "cancellationInfo_label" + public static let learnMoreButton = "learn_more_button" + public static let capabilitiesDetailsView = "capabilities_details_view" + public static let vehicleCapacityView = "vehicle_capacity_view" +} + +final class KarhooCheckoutHeaderView: UIStackView { + // MARK: - UI + private lazy var fleetInfoStackView: UIStackView = { + let stackView = UIStackView() + stackView.accessibilityIdentifier = KHCheckoutHeaderViewID.fleetInfoContainer + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.alignment = .fill + stackView.distribution = .fill + stackView.spacing = 5 + return stackView + }() + + // Note: This view was added so thet the fleetInfoStackView could have it's children properly aligned on the vertical axis, yet not stretch the logoLoadingImageView to fit the height + // Because the image is loaded from a URL, and not from xcassets, it doesn't scale properly, so setting the content mode to .scaleAspectFit doesn't help + private lazy var logoContentView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHCheckoutHeaderViewID.logoContainer + return view + }() + + private lazy var logoLoadingImageView: LoadingImageView = { + let imageView = LoadingImageView() + imageView.accessibilityIdentifier = KHCheckoutHeaderViewID.logoImageView + imageView.layer.cornerRadius = 5.0 + imageView.layer.borderColor = KarhooUI.colors.lightGrey.cgColor + imageView.layer.borderWidth = 0.5 + imageView.layer.masksToBounds = true + imageView.contentMode = .scaleAspectFit + imageView.clipsToBounds = true + return imageView + }() + + private lazy var rideDetailStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.accessibilityIdentifier = KHCheckoutHeaderViewID.rideDetailsContainer + stackView.axis = .vertical + stackView.spacing = 4.0 + return stackView + }() + + private lazy var nameLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHCheckoutHeaderViewID.nameLabel + label.textColor = KarhooUI.colors.infoColor + label.font = KarhooUI.fonts.getBoldFont(withSize: 16.0) + label.numberOfLines = 0 + return label + }() + + private lazy var carTypeLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHCheckoutHeaderViewID.carType + label.font = KarhooUI.fonts.getBoldFont(withSize: 14.0) + label.textColor = KarhooUI.colors.guestCheckoutLightGrey + return label + }() + + private var capabilitiesStackView: UIStackView = { + let stackView = UIStackView() + stackView.accessibilityIdentifier = KHCheckoutHeaderViewID.fleetCapabilities + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.alignment = .center + stackView.distribution = .fill + stackView.spacing = 5 + return stackView + }() + + private lazy var capacityContentView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.accessibilityIdentifier = KHCheckoutHeaderViewID.capabilitiesContentView + return view + }() + + private lazy var vehicleCapacityView: VehicleCapacityView = { + let view = VehicleCapacityView() + view.accessibilityIdentifier = KHCheckoutHeaderViewID.vehicleCapacityView + return view + }() + + private lazy var learnMoreButton: KarhooLearnMoreButton = { + let button = KarhooLearnMoreButton() + button.set(actions: self) + button.accessibilityIdentifier = KHCheckoutHeaderViewID.learnMoreButton + button.anchor(height: 44.0) + return button + }() + + lazy var capacityDetailsView: KarhooFleetCapabilitiesDetailsView = { + let view = KarhooFleetCapabilitiesDetailsView() + view.accessibilityIdentifier = KHCheckoutHeaderViewID.capabilitiesDetailsView + return view + }() + + //MARK: - Variables + private var didSetupConstraints: Bool = false + + //MARK: - Init + init() { + super.init(frame: .zero) + self.setUpView() + } + + convenience init(viewModel: QuoteViewModel) { + self.init() + self.set(viewModel: viewModel) + } + + required init(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //MARK: - Setup + private func setUpView() { + accessibilityIdentifier = KHCheckoutHeaderViewID.topContainer + translatesAutoresizingMaskIntoConstraints = false + alignment = .fill + distribution = .fill + axis = .vertical + spacing = 10 + + // TODO: Move this line along with the directionalLayoutMargins line to CheckoutViewController + isLayoutMarginsRelativeArrangement = true + + addArrangedSubview(fleetInfoStackView) + fleetInfoStackView.addArrangedSubview(logoContentView) + fleetInfoStackView.addArrangedSubview(rideDetailStackView) + fleetInfoStackView.addArrangedSubview(capacityContentView) + + logoContentView.addSubview(logoLoadingImageView) + + rideDetailStackView.addArrangedSubview(nameLabel) + rideDetailStackView.addArrangedSubview(carTypeLabel) + rideDetailStackView.addArrangedSubview(capabilitiesStackView) + + capacityContentView.addSubview(vehicleCapacityView) + capacityContentView.addSubview(learnMoreButton) + + addArrangedSubview(capacityDetailsView) + learnLessPressed() + } + + override func updateConstraints() { + if !didSetupConstraints { + // TODO: move the padding to the CheckoutViewController when applying the standardization to the CheckoutViewController + // The controls inside the header view should be glued to the edges. The parent decides how much margin to add to it + // This is a good practice to make the header view reusable in other contexts that may not need the values set below. + directionalLayoutMargins = NSDirectionalEdgeInsets(top: 10, leading: 0, bottom: 0, trailing: 0) + + logoLoadingImageView.anchor(top: logoContentView.topAnchor, leading: logoContentView.leadingAnchor, trailing: logoContentView.trailingAnchor, width: 60.0, height: 60.0) + + + vehicleCapacityView.anchor(top: capacityContentView.topAnchor, + leading: capacityContentView.leadingAnchor, + trailing: capacityContentView.trailingAnchor) + + learnMoreButton.anchor(leading: capacityContentView.leadingAnchor, + bottom: capacityContentView.bottomAnchor, + trailing: capacityContentView.trailingAnchor) + + if capabilitiesStackView.subviews.count > 0 { + learnMoreButton.anchor(top: carTypeLabel.bottomAnchor) + } + else { + learnMoreButton.topAnchor.constraint(greaterThanOrEqualTo: vehicleCapacityView.bottomAnchor).isActive = true + } + + didSetupConstraints = true + } + + super.updateConstraints() + } + + func set(viewModel: QuoteViewModel) { + nameLabel.text = viewModel.fleetName + carTypeLabel.text = viewModel.carType + + logoLoadingImageView.load(imageURL: viewModel.logoImageURL, + placeholderImageName: "supplier_logo_placeholder") + logoLoadingImageView.setStandardBorder() + + vehicleCapacityView.setPassengerCapacity(viewModel.passengerCapacity) + vehicleCapacityView.setBaggageCapacity(viewModel.baggageCapacity) + vehicleCapacityView.setAdditionalFleetCapabilities(viewModel.fleetCapabilities.count) + setVehicleTags(viewModel: viewModel) + capacityDetailsView.set(viewModel: viewModel) + + updateConstraints() + } + + private func setVehicleTags(viewModel: QuoteViewModel) { + if viewModel.vehicleTags.count > 0 { + let firstTag = viewModel.vehicleTags[0] + setupView(for: firstTag) + + if viewModel.vehicleTags.count > 1 { + let label = UILabel() + label.text = "+\(viewModel.vehicleTags.count - 1)" + label.font = KarhooUI.fonts.getRegularFont(withSize: 9.0) + label.textColor = KarhooUI.colors.darkGrey + capabilitiesStackView.addArrangedSubview(label) + } + } + } + + private func setupView(for vehicleTag: VehicleTag) { + let imageView = UIImageView() + imageView.image = vehicleTag.image + imageView.contentMode = .scaleAspectFit + imageView.anchor(width: 12.0, height: 12.0) + imageView.tintColor = KarhooUI.colors.guestCheckoutLightGrey + + let label = UILabel() + label.text = vehicleTag.title + label.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) + label.textColor = KarhooUI.colors.guestCheckoutLightGrey + capabilitiesStackView.addArrangedSubview(imageView) + capabilitiesStackView.addArrangedSubview(label) + } +} + +// MARK: - RevealMoreButtonActions +extension KarhooCheckoutHeaderView: LearnMoreButtonDelegate { + func learnMorePressed() { + self.vehicleCapacityView.isHidden = true + self.capacityDetailsView.isHidden = false + UIView.animate(withDuration: 0.45) { [unowned self] in + self.capacityDetailsView.alpha = 1.0 + } + } + + func learnLessPressed() { + self.vehicleCapacityView.isHidden = false + UIView.animate(withDuration: 0.45) { + self.capacityDetailsView.alpha = 0.0 + self.capacityDetailsView.isHidden = true + } + } +} diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooFareInfoView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooFareInfoView.swift new file mode 100644 index 000000000..b22865848 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooFareInfoView.swift @@ -0,0 +1,84 @@ +// +// KarhooFareInfoView.swift +// KarhooUISDK +// +// Created by Anca Feurdean on 20.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit +import KarhooSDK + +final class KarhooFareInfoView: UIView { + private lazy var fareTypeInfoLabel: UILabel = { + let fareTypeInfo = UILabel() + fareTypeInfo.translatesAutoresizingMaskIntoConstraints = false + fareTypeInfo.accessibilityIdentifier = "fare_type_info_label" + fareTypeInfo.textColor = KarhooUI.colors.white + fareTypeInfo.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) + fareTypeInfo.text = "This fleet is a non-regulated taxi." + fareTypeInfo.numberOfLines = 0 + + return fareTypeInfo + }() + + private lazy var infoIcon: UIImageView = { + let iconImage = UIImageView() + iconImage.image = UIImage.uisdkImage("info_icon") + iconImage.tintColor = KarhooUI.colors.white + iconImage.contentMode = .scaleAspectFit + iconImage.setDimensions(height: 12.0, + width: 12.0) + + return iconImage + }() + + init() { + super.init(frame: .zero) + setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupView() { + addSubview(infoIcon) + addSubview(fareTypeInfoLabel) + } + + private func setupConstraints() { + infoIcon.centerY(inView: self) + infoIcon.anchor(leading: leadingAnchor, + trailing: fareTypeInfoLabel.leadingAnchor, + paddingLeft: 10.0, + paddingRight: 10.0) + fareTypeInfoLabel.centerY(inView: self) + fareTypeInfoLabel.anchor(top: topAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor, + paddingTop: 5.0, + paddingBottom: 5.0, + paddingRight: 10.0) + } + + private func retrieveTextBasedOn(fareType: QuoteType) -> String { + switch fareType { + case .estimated: + return UITexts.Booking.estimatedInfoBox + case .fixed: + return UITexts.Booking.fixedInfoBox + case .metered: + return UITexts.Booking.meteredInfoBox + @unknown default: + fatalError() + } + } + + func setInfoText(for fareType: QuoteType) { + fareTypeInfoLabel.text = retrieveTextBasedOn(fareType: fareType) + setupConstraints() + } + +} + diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooFleetCapabilitiesDetailsView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooFleetCapabilitiesDetailsView.swift new file mode 100644 index 000000000..0f4fcb900 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooFleetCapabilitiesDetailsView.swift @@ -0,0 +1,198 @@ +// +// KarhooFleetCapabilitiesDetailsView.swift +// KarhooUISDK +// +// Created by Anca Feurdean on 18.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit + +struct KHMoreDetailsViewID { + static let container = "more_details_container" + static let fleetCapabilitiesStackView = "fleet_capabilities_stack_view" + static let fleetDescriptionLabel = "fleet_description_label" +} + +final class KarhooFleetCapabilitiesDetailsView: UIView { + + private enum CapacityViewType { + case passenger, luggage + } + + private var didSetupConstraints: Bool = false + + private lazy var stackView: UIStackView = { + let stackView = UIStackView() + stackView.accessibilityIdentifier = KHMoreDetailsViewID.container + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.distribution = .fill + stackView.spacing = 10 + + return stackView + }() + + private lazy var fleetCapabilitiesStackView: UIStackView = { + let stackView = UIStackView() + stackView.accessibilityIdentifier = KHMoreDetailsViewID.fleetCapabilitiesStackView + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.distribution = .equalSpacing + stackView.spacing = 10.0 + + return stackView + }() + + private lazy var detailsLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHMoreDetailsViewID.fleetDescriptionLabel + label.textColor = KarhooUI.colors.infoColor + label.textAlignment = .left + label.numberOfLines = 0 + label.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) + + return label + }() + + init() { + super.init(frame: .zero) + self.setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupView() { + translatesAutoresizingMaskIntoConstraints = false + accessibilityIdentifier = KHMoreDetailsViewID.container + + addSubview(stackView) + stackView.addArrangedSubview(fleetCapabilitiesStackView) + } + + private func setupConstraints() { + if !didSetupConstraints { + + stackView.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor) + fleetCapabilitiesStackView.anchor(top: stackView.topAnchor, + leading: stackView.leadingAnchor, + trailing: stackView.trailingAnchor) + didSetupConstraints = true + } + + super.updateConstraints() + } + + func set(viewModel: QuoteViewModel) { + detailsLabel.text = viewModel.fleetDescription + + setupVehicleCapacityView(forViewModel: viewModel) + setupView(for: viewModel.fleetCapabilities) + fleetCapabilitiesStackView.addArrangedSubview(detailsLabel) + + setupConstraints() + } + + private func setupVehicleCapacityView(forViewModel viewModel: QuoteViewModel) { + if viewModel.fleetCapabilities.count > 0 { + let passengerBaggageStackView = UIStackView() + passengerBaggageStackView.accessibilityIdentifier = "container_passenger_baggage_stack" + passengerBaggageStackView.translatesAutoresizingMaskIntoConstraints = false + passengerBaggageStackView.axis = .horizontal + passengerBaggageStackView.distribution = .fillEqually + passengerBaggageStackView.alignment = .leading + passengerBaggageStackView.spacing = 5 + + if viewModel.passengerCapacity > 0 { + let passengerStackView = setupCapacityView(for: .passenger, maxNumber: viewModel.passengerCapacity) + passengerBaggageStackView.addArrangedSubview(passengerStackView) + } + + if viewModel.baggageCapacity > 0 { + let baggageStackView = setupCapacityView(for: .luggage, maxNumber: viewModel.baggageCapacity) + passengerBaggageStackView.addArrangedSubview(baggageStackView) + } + + fleetCapabilitiesStackView.addArrangedSubview(passengerBaggageStackView) + } else { + if viewModel.passengerCapacity > 0 { + let passengerStackView = setupCapacityView(for: .passenger, maxNumber: viewModel.passengerCapacity) + fleetCapabilitiesStackView.addArrangedSubview(passengerStackView) + } + + if viewModel.baggageCapacity > 0 { + let baggageStackView = setupCapacityView(for: .luggage, maxNumber: viewModel.baggageCapacity) + fleetCapabilitiesStackView.addArrangedSubview(baggageStackView) + } + } + } + + private func setupCapacityView(for capacityViewType: CapacityViewType, maxNumber: Int) -> UIStackView { + let title = String(format: (capacityViewType == .passenger ? UITexts.Booking.maximumPassengers : UITexts.Booking.maximumLuggages), "\(maxNumber)") + let image = capacityViewType == .passenger ? UIImage.uisdkImage("passenger_capacity_icon") : UIImage.uisdkImage("luggage_icon") + let accessibilityId = KHMoreDetailsViewID.fleetCapabilitiesStackView + "_\(capacityViewType == .passenger ? "passenger" : "baggage")" + return setupView(for: title, with: image, accessibilityId: accessibilityId) + } + + private func setupView(for title: String, with image: UIImage, accessibilityId: String) -> UIStackView { + let circleBackgroundView = UIView() + circleBackgroundView.backgroundColor = KarhooUI.colors.lightGrey + circleBackgroundView.setDimensions(height: 20.0, + width: 20.0) + circleBackgroundView.layer.cornerRadius = 10.0 + + let iconView = UIImageView() + iconView.image = image + iconView.setDimensions(height: 14.0, + width: 14.0) + iconView.tintColor = KarhooUI.colors.infoColor + circleBackgroundView.addSubview(iconView) + iconView.centerX(inView: circleBackgroundView) + iconView.centerY(inView: circleBackgroundView) + + let titleLabel = UILabel() + titleLabel.text = title + titleLabel.textColor = KarhooUI.colors.infoColor + titleLabel.font = KarhooUI.fonts.getBoldFont(withSize: 12.0) + + let stackView = UIStackView() + stackView.accessibilityIdentifier = accessibilityId + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.distribution = .fill + stackView.spacing = 5 + stackView.addArrangedSubview(circleBackgroundView) + stackView.addArrangedSubview(titleLabel) + + return stackView + } + + private func setupView(for capabilities: [FleetCapabilities]) { + var index = 0 + while index < capabilities.count { + let firstCap = capabilities[index] + let firstCapView = setupView(for: firstCap.title, with: firstCap.image, accessibilityId: firstCap.title) + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.distribution = .fillEqually + stackView.alignment = .leading + stackView.spacing = 5 + stackView.addArrangedSubview(firstCapView) + + if index + 1 < capabilities.count { + let secondCap = capabilities[index+1] + let secondView = setupView(for: secondCap.title, with: secondCap.image, accessibilityId: secondCap.title) + stackView.addArrangedSubview(secondView) + } + fleetCapabilitiesStackView.addArrangedSubview(stackView) + index += 2 + } + } +} diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooLearnMoreButton.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooLearnMoreButton.swift new file mode 100644 index 000000000..2def5fb28 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooLearnMoreButton.swift @@ -0,0 +1,164 @@ +// +// KarhooLearnMoreButton.swift +// KarhooUISDK +// +// Created by Anca Feurdean on 18.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit + +protocol LearnMoreButtonDelegate: AnyObject { + func learnMorePressed() + func learnLessPressed() +} + +private enum ButtonMode { + case learnMore + case learnLess + + var image: UIImage { + switch self { + case .learnLess: + return UIImage.uisdkImage("dropupIcon") + case .learnMore: + return UIImage.uisdkImage("dropdownIcon") + } + } + + var title: String { + return UITexts.Booking.learnMore + } +} + +public struct KHRevealMoreButtonViewID { + public static let container = "revealing_button_container" + public static let button = "revealing_button_view" + public static let buttonTitle = "title_label" + public static let image = "dropdown_up_icon" +} + +final class KarhooLearnMoreButton: UIButton { + private weak var actions: LearnMoreButtonDelegate? + private var currentMode: ButtonMode = .learnMore + private var didSetupConstraints = false + + private var containerView: UIView = { + let containerView = UIView() + containerView.translatesAutoresizingMaskIntoConstraints = false + containerView.accessibilityIdentifier = KHRevealMoreButtonViewID.container + containerView.backgroundColor = .clear + + return containerView + }() + + private lazy var button: UIButton = { + let button = UIButton(type: .custom) + button.accessibilityIdentifier = KHBookingButtonViewID.button + button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(learnMorePressed), for: .touchUpInside) + + return button + }() + + private lazy var buttonLabel: UILabel = { + let buttonLabel = UILabel() + buttonLabel.translatesAutoresizingMaskIntoConstraints = false + buttonLabel.accessibilityIdentifier = KHRevealMoreButtonViewID.buttonTitle + buttonLabel.font = UIFont.boldSystemFont(ofSize: 14.0) + buttonLabel.text = currentMode.title + buttonLabel.textColor = KarhooUI.colors.accent + buttonLabel.textAlignment = .center + + return buttonLabel + }() + + private lazy var dropdownImage: UIImageView = { + let imageView = UIImageView() + imageView.image = currentMode.image + imageView.accessibilityIdentifier = KHRevealMoreButtonViewID.image + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.tintColor = KarhooUI.colors.accent + imageView.contentMode = .scaleAspectFill + return imageView + }() + + init() { + super.init(frame: .zero) + self.setupView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupView() { + translatesAutoresizingMaskIntoConstraints = false + accessibilityIdentifier = KHRevealMoreButtonViewID.button + + addSubview(containerView) + + containerView.addSubview(buttonLabel) + containerView.addSubview(dropdownImage) + containerView.addSubview(button) + } + + override func awakeFromNib() { + super.awakeFromNib() + self.setupView() + } + + override func updateConstraints() { + if !didSetupConstraints { + + containerView.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor, + paddingLeft: 5.0, + paddingRight: 5.0) + + buttonLabel.anchor(top: topAnchor, + bottom: bottomAnchor, + trailing: dropdownImage.leadingAnchor, + paddingTop: 5.0, + paddingBottom: 5.0, + paddingRight: 5.0) + + let imageSize: CGFloat = 16.0 + dropdownImage.centerY(inView: self) + dropdownImage.anchor(trailing: containerView.trailingAnchor, + width: imageSize, + height: imageSize) + + button.anchor(top: containerView.topAnchor, + leading: buttonLabel.leadingAnchor, + bottom: containerView.bottomAnchor, + trailing: containerView.trailingAnchor) + + didSetupConstraints = true + } + + super.updateConstraints() + } + + @objc private func learnMorePressed() { + switch currentMode { + case .learnMore: + currentMode = .learnLess + actions?.learnMorePressed() + case .learnLess: + currentMode = .learnMore + actions?.learnLessPressed() + } + + UIView.animate(withDuration: 0.45, animations: { [unowned self] in + self.dropdownImage.image = currentMode.image + self.buttonLabel.text = currentMode.title + }) + } + + func set(actions: LearnMoreButtonDelegate) { + self.actions = actions + } +} diff --git a/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooRideInfoView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooRideInfoView.swift new file mode 100644 index 000000000..6e0fa4886 --- /dev/null +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/CheckoutViews/KarhooRideInfoView.swift @@ -0,0 +1,187 @@ +// +// KarhooRideInfoView.swift +// KarhooUISDK +// +// Created by Anca Feurdean on 18.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit + +protocol RideInfoViewDelegate: AnyObject { + func infoButtonPressed() +} + +final class KarhooRideInfoView: UIView { + private weak var delegate: RideInfoViewDelegate? + private var didSetupConstraints: Bool = false + + private lazy var scheduleCaption: UILabel = { + let scheduleCaption = UILabel() + scheduleCaption.translatesAutoresizingMaskIntoConstraints = false + scheduleCaption.accessibilityIdentifier = KHCheckoutHeaderViewID.etaTitle + scheduleCaption.textColor = KarhooUI.colors.infoColor + scheduleCaption.font = KarhooUI.fonts.getBoldFont(withSize: 12.0) + scheduleCaption.text = UITexts.Generic.etaLong + + return scheduleCaption + }() + + private lazy var scheduleMainValue: UILabel = { + let scheduleMainValue = UILabel() + scheduleMainValue.translatesAutoresizingMaskIntoConstraints = false + scheduleMainValue.accessibilityIdentifier = KHCheckoutHeaderViewID.etaText + scheduleMainValue.textColor = KarhooUI.colors.infoColor + scheduleMainValue.font = KarhooUI.fonts.getBoldFont(withSize: 24.0) + + return scheduleMainValue + }() + + private lazy var rideTypeLabel: UILabel = { + let rideTypeLabel = UILabel() + rideTypeLabel.translatesAutoresizingMaskIntoConstraints = false + rideTypeLabel.accessibilityIdentifier = KHCheckoutHeaderViewID.rideType + rideTypeLabel.textColor = KarhooUI.colors.infoColor + rideTypeLabel.text = UITexts.Generic.meetGreet + rideTypeLabel.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) + + return rideTypeLabel + }() + + private lazy var priceTitle: UILabel = { + let priceTitle = UILabel() + priceTitle.translatesAutoresizingMaskIntoConstraints = false + priceTitle.accessibilityIdentifier = KHCheckoutHeaderViewID.estimatedPrice + priceTitle.textColor = KarhooUI.colors.infoColor + priceTitle.textAlignment = .right + priceTitle.font = KarhooUI.fonts.getBoldFont(withSize: 12.0) + priceTitle.text = UITexts.Generic.estimatedPrice.uppercased() + + return priceTitle + }() + + private lazy var priceText: UILabel = { + let priceText = UILabel() + priceText.translatesAutoresizingMaskIntoConstraints = false + priceText.accessibilityIdentifier = KHCheckoutHeaderViewID.priceText + priceText.textColor = KarhooUI.colors.infoColor + priceText.textAlignment = .right + priceText.font = KarhooUI.fonts.getBoldFont(withSize: 24.0) + + return priceText + }() + + private lazy var ridePriceType: UIButton = { + let ridePriceType = UIButton() + ridePriceType.translatesAutoresizingMaskIntoConstraints = false + ridePriceType.accessibilityIdentifier = KHCheckoutHeaderViewID.ridePriceType + ridePriceType.setTitleColor(KarhooUI.colors.infoColor, for: .normal) + ridePriceType.titleLabel?.font = KarhooUI.fonts.getRegularFont(withSize: 12.0) + ridePriceType.addTarget(self, action: #selector(infoButtonPressed), for: .touchUpInside) + + return ridePriceType + }() + + private lazy var rideTypeInfoButton: UIButton = { + let infoButton = UIButton(type: .custom) + infoButton.translatesAutoresizingMaskIntoConstraints = false + infoButton.accessibilityIdentifier = KHCheckoutHeaderViewID.ridePriceTypeIcon + infoButton.setImage(UIImage.uisdkImage("info_icon").withRenderingMode(.alwaysTemplate), for: .normal) + infoButton.contentVerticalAlignment = .fill + infoButton.contentHorizontalAlignment = .fill + infoButton.imageEdgeInsets = UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3) + infoButton.tintColor = KarhooUI.colors.infoColor + infoButton.addTarget(self, action: #selector(infoButtonPressed), for: .touchUpInside) + + return infoButton + }() + + init() { + super.init(frame: .zero) + self.setupView() + } + + convenience init(viewModel: QuoteViewModel) { + self.init() + self.setDetails(viewModel: viewModel) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupView() { + translatesAutoresizingMaskIntoConstraints = false + accessibilityIdentifier = KHMoreDetailsViewID.container + + addSubview(scheduleCaption) + addSubview(scheduleMainValue) + addSubview(rideTypeLabel) + addSubview(priceTitle) + addSubview(priceText) + addSubview(rideTypeInfoButton) + addSubview(ridePriceType) + } + + override func updateConstraints() { + if !didSetupConstraints { + + [scheduleCaption.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10.0), + scheduleCaption.topAnchor.constraint(equalTo: topAnchor, constant: 10.0), + scheduleCaption.trailingAnchor.constraint(lessThanOrEqualTo: priceTitle.leadingAnchor, + constant: 20.0)].forEach { $0.isActive = true } + + rideTypeLabel.anchor(leading: leadingAnchor, + bottom: bottomAnchor, + trailing: trailingAnchor, + paddingTop: 10.0, + paddingLeft: 10.0, + paddingBottom: 15.0) + + [scheduleMainValue.leadingAnchor.constraint(equalTo: scheduleCaption.leadingAnchor), + scheduleMainValue.topAnchor.constraint(equalTo: scheduleCaption.bottomAnchor, constant: 5.0), + scheduleMainValue.trailingAnchor.constraint(lessThanOrEqualTo: priceText.leadingAnchor, constant: 20.0)] + .forEach { $0.isActive = true } + + priceTitle.anchor(top: scheduleCaption.topAnchor, + trailing: trailingAnchor, + paddingRight: 10.0) + + priceText.anchor(top: priceTitle.bottomAnchor, + bottom: ridePriceType.topAnchor, + trailing: priceTitle.trailingAnchor, + paddingTop: 5.0, + paddingBottom: 10.0) + + ridePriceType.anchor(bottom: bottomAnchor, + trailing: trailingAnchor, + paddingBottom: 10.0, + paddingRight: 10.0) + rideTypeInfoButton.centerYAnchor.constraint(equalTo: ridePriceType.centerYAnchor).isActive = true + rideTypeInfoButton.anchor(trailing: ridePriceType.leadingAnchor, + paddingRight: 3.0, + width: 24.0, + height: 24.0) + + didSetupConstraints = true + } + + super.updateConstraints() + } + + public func setDetails(viewModel: QuoteViewModel) { + scheduleCaption.text = viewModel.scheduleCaption + scheduleMainValue.text = viewModel.scheduleMainValue + ridePriceType.setTitle(viewModel.fareType, for: .normal) + priceText.text = viewModel.fare + rideTypeLabel.text = viewModel.pickUpType + } + + public func setActions(_ actions: RideInfoViewDelegate) { + self.delegate = actions + } + + @objc private func infoButtonPressed() { + delegate?.infoButtonPressed() + } +} diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/SupplierView/SupplierView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/SupplierView/SupplierView.swift similarity index 100% rename from KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/SupplierView/SupplierView.swift rename to KarhooUISDK/Screens/CheckoutScreen/Components/SupplierView/SupplierView.swift diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/TimePriceMVP.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceMVP.swift similarity index 81% rename from KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/TimePriceMVP.swift rename to KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceMVP.swift index d12c907f9..4938b8801 100644 --- a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/TimePriceMVP.swift +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceMVP.swift @@ -9,23 +9,15 @@ import Foundation protocol TimePriceView { - - func set(actions: TimePriceViewActions) - + func set(actions: TimePriceViewDelegate) func set(price: String?) - func setPrebookMode(timeString: String?, dateString: String?) - func setAsapMode(qta: String?) - func set(baseFareHidden: Bool) - func set(quoteType: String) - func set(fareExplanationHidden: Bool) } -protocol TimePriceViewActions: AnyObject { - +protocol TimePriceViewDelegate: AnyObject { func didPressFareExplanation() } diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/KarhooTimePriceView.swift b/KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceView.swift similarity index 97% rename from KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/KarhooTimePriceView.swift rename to KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceView.swift index 1b4239253..8b550c418 100644 --- a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/KarhooTimePriceView.swift +++ b/KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceView.swift @@ -39,7 +39,7 @@ final class KarhooTimePriceView: UIView, TimePriceView { private var baseFareIcon: UIImageView! private var fareExplanationButton: UIButton! - private weak var actions: TimePriceViewActions? + private weak var delegate: TimePriceViewDelegate? init() { super.init(frame: .zero) @@ -163,8 +163,8 @@ final class KarhooTimePriceView: UIView, TimePriceView { .map { $0.isActive = true } } - func set(actions: TimePriceViewActions) { - self.actions = actions + func set(actions: TimePriceViewDelegate) { + self.delegate = actions } func set(price: String?) { @@ -196,6 +196,6 @@ final class KarhooTimePriceView: UIView, TimePriceView { @objc private func didPressFareExplanation() { - actions?.didPressFareExplanation() + delegate?.didPressFareExplanation() } } diff --git a/KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/KarhooTimePriceView.xib b/KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceView.xib similarity index 100% rename from KarhooUISDK/Screens/BookingRequestScreen/BookingRequest/TimePriceMVP/KarhooTimePriceView.xib rename to KarhooUISDK/Screens/CheckoutScreen/Components/TimePrice/KarhooTimePriceView.xib diff --git a/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeTableViewCell.swift b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeTableViewCell.swift new file mode 100644 index 000000000..8fa4e48b9 --- /dev/null +++ b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeTableViewCell.swift @@ -0,0 +1,59 @@ +// +// CountryCodeTableViewCell.swift +// KarhooUISDK +// +// Created by Diana Petrea on 10.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit + +class CountryCodeTableViewCell: UITableViewCell { + + private var view: CountryCodeView! + private var didSetupConstraints: Bool = false + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + self.setUpView() + } + + override func awakeFromNib() { + super.awakeFromNib() + self.setUpView() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + self.setUpView() + } + + private func setUpView() { + view = CountryCodeView() + contentView.addSubview(view) + + updateConstraints() + } + + override func updateConstraints() { + if !didSetupConstraints { + view.anchor(top: contentView.topAnchor, + leading: contentView.leadingAnchor, + bottom: contentView.bottomAnchor, + trailing: contentView.trailingAnchor) + + didSetupConstraints = true + } + super.updateConstraints() + } + + func set(viewModel: CountryCodeViewModel) { + prepareForReuse() + view.set(viewModel: viewModel) + } + + override func prepareForReuse() { + super.prepareForReuse() + view.resetView() + } +} diff --git a/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeView.swift b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeView.swift new file mode 100644 index 000000000..d3e40e43d --- /dev/null +++ b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeView.swift @@ -0,0 +1,102 @@ +// +// CountryCodeView.swift +// KarhooUISDK +// +// Created by Diana Petrea on 10.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit + +public struct KHCountryCodeViewID { + public static let contentView = "content_view" + public static let flagImageView = "flag_image_view" + public static let countryLabel = "country_label" + public static let isSelectedImageView = "is_selected_image_view" +} + +class CountryCodeView: UIView { + private let standardIconSize: CGFloat = 22.0 + private let standardSpacing: CGFloat = 20.0 + + private lazy var flagImageView: UIImageView = { + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.anchor(width: standardIconSize, height: standardIconSize) + return imageView + }() + + private lazy var countryLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = KarhooUI.fonts.bodyRegular() + label.numberOfLines = 1 + return label + }() + + private lazy var isSelectedImageView: UIImageView = { + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.image = UIImage.uisdkImage("circle") + imageView.contentMode = .scaleAspectFit + imageView.anchor(width: standardIconSize, height: standardIconSize) + return imageView + }() + + init() { + super.init(frame: .zero) + self.setUpView() + } + + convenience init(viewModel: CountryCodeViewModel) { + self.init() + self.set(viewModel: viewModel) + } + + override func awakeFromNib() { + super.awakeFromNib() + self.setUpView() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + self.setUpView() + } + + private func setUpView() { + backgroundColor = KarhooUI.colors.white + translatesAutoresizingMaskIntoConstraints = false + accessibilityIdentifier = KHCountryCodeViewID.contentView + + addSubview(flagImageView) + flagImageView.anchor(top: topAnchor, + leading: leadingAnchor, + bottom: bottomAnchor, + paddingTop: standardSpacing, + paddingLeft: standardSpacing) + + addSubview(isSelectedImageView) + isSelectedImageView.anchor(trailing: trailingAnchor, + paddingRight: standardSpacing) + isSelectedImageView.centerYAnchor.constraint(equalTo: flagImageView.centerYAnchor).isActive = true + + addSubview(countryLabel) + countryLabel.anchor(leading: flagImageView.trailingAnchor, + trailing: isSelectedImageView.leadingAnchor, + paddingLeft: standardSpacing, + paddingRight: standardSpacing) + countryLabel.centerYAnchor.constraint(equalTo: flagImageView.centerYAnchor).isActive = true + } + + func set(viewModel: CountryCodeViewModel) { + flagImageView.image = viewModel.flagImage + countryLabel.text = viewModel.printedCountryInfo + isSelectedImageView.image = viewModel.isSelectedImage + } + + func resetView() { + flagImageView.image = nil + countryLabel.text = nil + isSelectedImageView.image = nil + } +} diff --git a/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeViewModel.swift b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeViewModel.swift new file mode 100644 index 000000000..65d23b501 --- /dev/null +++ b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCell/CountryCodeViewModel.swift @@ -0,0 +1,37 @@ +// +// CountryCodeViewModel.swift +// KarhooUISDK +// +// Created by Diana Petrea on 10.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation + +final class CountryCodeViewModel { + var countryCode: String + var phoneCode: String + var countryName: String + var isSelected: Bool + + var printedCountryInfo: String { + return "\(countryName) \(phoneCode)" + } + + var isSelectedImage: UIImage { + return isSelected ? + UIImage.uisdkImage("field_success").coloured(withTint: KarhooUI.colors.primary) : + UIImage.uisdkImage("circle").coloured(withTint: KarhooUI.colors.infoBackgroundColor) + } + + var flagImage: UIImage { + return UIImage.uisdkImage("\(countryCode).png") + } + + init(country: Country, isSelected: Bool) { + self.countryCode = country.code + self.phoneCode = country.phoneCode + self.countryName = country.name + self.isSelected = isSelected + } +} diff --git a/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionMVP.swift b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionMVP.swift new file mode 100644 index 000000000..f1e351886 --- /dev/null +++ b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionMVP.swift @@ -0,0 +1,16 @@ +// +// CountruCodeSelectionMVP.swift +// KarhooUISDK +// +// Created by Diana Petrea on 10.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation + +protocol CountryCodeSelectionActions { + var preSelectedCountry: Country? { get set } + func countrySelected(country: Country) + func backClicked() + func filterData(filter: String?) -> [Country] +} diff --git a/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionPresenter.swift b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionPresenter.swift new file mode 100644 index 000000000..df8c00bf0 --- /dev/null +++ b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionPresenter.swift @@ -0,0 +1,41 @@ +// +// CountryCodeSelectionPresenter.swift +// KarhooUISDK +// +// Created by Diana Petrea on 10.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation + +final class CountryCodeSelectionPresenter: CountryCodeSelectionActions { + var preSelectedCountry: Country? + private let callback: ScreenResultCallback + private let data: [Country]! + + init(preSelectedCountry: Country?, + callback: @escaping ScreenResultCallback) { + self.preSelectedCountry = preSelectedCountry + self.callback = callback + self.data = KarhooCountryParser.getCountries() + } + + func backClicked() { + callback(ScreenResult.cancelled(byUser: true)) + } + + func countrySelected(country: Country) { + callback(ScreenResult.completed(result: country)) + } + + func filterData(filter: String?) -> [Country] { + guard var filter = filter, !filter.isEmpty, filter != " " + else { + return data + } + + filter = filter.trimmingCharacters(in: .whitespacesAndNewlines) + let filtered = data.filter({ $0.name.contains(filter) }) + return filtered + } +} diff --git a/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionViewController.swift b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionViewController.swift new file mode 100644 index 000000000..ba02af133 --- /dev/null +++ b/KarhooUISDK/Screens/CountryCodeSelectionScreen/CountryCodeSelectionViewController.swift @@ -0,0 +1,221 @@ +// +// CountryCodeSelectionViewController.swift +// KarhooUISDK +// +// Created by Diana Petrea on 10.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit + +struct KHCountryCodeSelectionViewID { + static let backButton = "back_button" + static let tableView = "table_view" + static let pageTitleLabel = "title_label" +} + +final class CountryCodeSelectionViewController: UIViewController, UITextFieldDelegate { + + private let tableViewReuseIdentifier = "CountryCodeTableViewCell" + private let sectionKey = 0 + private let delegateKey = "" + + private let standardButtonSize: CGFloat = 44.0 + private let standardSpacing: CGFloat = 20.0 + private let smallSpacing: CGFloat = 8.0 + private let extraSmallSpacing: CGFloat = 4.0 + private let separatorHeight: CGFloat = 1.0 + + private var presenter: CountryCodeSelectionPresenter + private var tableViewBottomConstraint: NSLayoutConstraint! + private let keyboardSizeProvider: KeyboardSizeProviderProtocol = KeyboardSizeProvider.shared + + private var data: TableData! + private var source: TableDataSource! + private var delegate: TableDelegate! // swiftlint:disable:this weak_delegate + + // MARK: - Views and Controls + private lazy var backButton: UIButton = { + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityIdentifier = KHCountryCodeSelectionViewID.backButton + button.tintColor = KarhooUI.colors.darkGrey + button.setImage(UIImage.uisdkImage("backIcon").withRenderingMode(.alwaysTemplate), for: .normal) + button.imageView?.contentMode = .scaleAspectFit + button.setTitle(UITexts.Generic.back, for: .normal) + button.setTitleColor(KarhooUI.colors.darkGrey, for: .normal) + button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 12.0) + button.titleEdgeInsets = UIEdgeInsets(top: 0, left: extraSmallSpacing, bottom: 0, right: 0) + button.addTarget(self, action: #selector(backButtonPressed), for: .touchUpInside) + return button + }() + + private lazy var searchIconImageView: UIImageView = { + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.image = UIImage.uisdkImage("search").coloured(withTint: KarhooUI.colors.lightGrey) + imageView.anchor(width: standardSpacing, height: standardSpacing) + return imageView + }() + + private lazy var searchTextField: UITextField = { + let textField = UITextField() + textField.translatesAutoresizingMaskIntoConstraints = false + textField.borderStyle = .none + textField.clearButtonMode = .whileEditing + textField.delegate = self + textField.placeholder = UITexts.CountryCodeSelection.search + textField.textColor = KarhooUI.colors.primaryTextColor + textField.anchor(height: standardButtonSize) + textField.returnKeyType = .search + textField.addTarget(self, action: #selector(textFieldValueChanged), for: .editingChanged) + return textField + }() + + private lazy var separatorView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.anchor(height: separatorHeight) + view.backgroundColor = KarhooUI.colors.lightGrey + return view + }() + + private lazy var tableView: UITableView = { + let tableView = UITableView(frame: CGRect.zero, style: .plain) + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.accessibilityIdentifier = KHCountryCodeSelectionViewID.tableView + tableView.backgroundColor = UIColor.white + tableView.separatorStyle = .none + tableView.rowHeight = UITableView.automaticDimension + tableView.bounces = false + return tableView + }() + + // MARK: - Init + init(presenter: CountryCodeSelectionPresenter) { + self.presenter = presenter + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(code:) has not been implemented") + } + + override func loadView() { + view = UIView() + view.backgroundColor = UIColor.white + view.translatesAutoresizingMaskIntoConstraints = false + view.anchor(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + view.layer.cornerRadius = 10.0 + setupView() + } + + private func setupView() { + view.addSubview(backButton) + backButton.anchor(top: view.topAnchor, + leading: view.leadingAnchor, + paddingTop: standardSpacing * 2, + width: standardButtonSize * 2, + height: standardButtonSize) + + view.addSubview(searchTextField) + searchTextField.anchor(top: backButton.bottomAnchor, + trailing: view.trailingAnchor, + paddingRight: standardSpacing) + + view.addSubview(searchIconImageView) + searchIconImageView.anchor(leading: view.leadingAnchor, + trailing: searchTextField.leadingAnchor, paddingLeft: + standardSpacing, paddingRight: smallSpacing) + searchIconImageView.centerYAnchor.constraint(equalTo: searchTextField.centerYAnchor).isActive = true + + view.addSubview(separatorView) + separatorView.anchor(top: searchTextField.bottomAnchor, + leading: searchTextField.leadingAnchor, + trailing: searchTextField.trailingAnchor, + paddingTop: extraSmallSpacing) + + view.addSubview(tableView) + tableView.anchor(top: separatorView.bottomAnchor, + leading: view.leadingAnchor, + trailing: view.trailingAnchor, + paddingTop: standardSpacing) + tableViewBottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + tableViewBottomConstraint.isActive = true + setUpTable() + } + + private func setUpTable() { + data = TableData() + source = TableDataSource(reuseIdentifier: tableViewReuseIdentifier, tableData: data) + delegate = TableDelegate(tableData: data) + delegate.setSection(key: delegateKey, to: presenter.filterData(filter: "")) + + tableView.register(CountryCodeTableViewCell.self, forCellReuseIdentifier: tableViewReuseIdentifier) + tableView.dataSource = source + tableView.delegate = delegate + + // Using footerView because content inset can't be used + let footer = UIView(frame: .init(x: 0, y: 0, width: 50, height: 50 + 20)) + footer.backgroundColor = .clear + tableView.tableFooterView = footer + + func cellCallback(country: Country, cell: UITableViewCell, indexPath: IndexPath) { + guard let cell = cell as? CountryCodeTableViewCell else { + return + } + let viewModel = CountryCodeViewModel(country: country, isSelected: presenter.preSelectedCountry?.code == country.code) + cell.set(viewModel: viewModel) + } + + source.set(cellConfigurationCallback: cellCallback) + + delegate.set(selectionCallback: { [weak self] (country: Country) in + guard let self = self else { + return + } + self.dismissScreen() + self.presenter.countrySelected(country: country) + }) + } + + deinit { + keyboardSizeProvider.remove(listener: self) + } + + // MARK: - Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + keyboardSizeProvider.register(listener: self) + forceLightMode() + } + + // MARK: - Actions + @objc private func backButtonPressed() { + dismissScreen() + presenter.backClicked() + } + + @objc private func textFieldValueChanged(_ textField: UITextField) { + filterContentForSearchText(textField.text) + } + + // MARK: - Search + private func filterContentForSearchText(_ searchText: String?) { + let filtered = presenter.filterData(filter: searchText) + delegate.setSection(key: delegateKey, to: filtered) + tableView.reloadData() + } + + // MARK: - Utils + func dismissScreen() { + self.dismiss(animated: true, completion: nil) + } +} + +extension CountryCodeSelectionViewController: KeyboardListener { + func keyboard(updatedHeight: CGFloat) { + tableViewBottomConstraint.constant = -updatedHeight + view.layoutIfNeeded() + } +} diff --git a/KarhooUISDK/Screens/DatePickerScreen/View/DatePickerViewController.swift b/KarhooUISDK/Screens/DatePickerScreen/View/DatePickerViewController.swift index 96bf0d298..b846519da 100644 --- a/KarhooUISDK/Screens/DatePickerScreen/View/DatePickerViewController.swift +++ b/KarhooUISDK/Screens/DatePickerScreen/View/DatePickerViewController.swift @@ -25,6 +25,11 @@ final class DatePickerViewController: UIViewController, DatePickerView { required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + override func viewDidLoad() { + super.viewDidLoad() + forceLightMode() + } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) diff --git a/KarhooUISDK/Screens/FlightDetailsScreen/Domain/FlightDetails.swift b/KarhooUISDK/Screens/FlightDetailsScreen/Domain/FlightDetails.swift deleted file mode 100644 index 66d943d30..000000000 --- a/KarhooUISDK/Screens/FlightDetailsScreen/Domain/FlightDetails.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// FlightDetails.swift -// Karhoo -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -import Foundation - -public struct FlightDetails { - public let flightNumber: String? - public let comments: String? - - public init(flightNumber: String? = nil, - comments: String? = nil) { - self.flightNumber = flightNumber - self.comments = comments - } -} diff --git a/KarhooUISDK/Screens/FlightDetailsScreen/Domain/FlightNumberValidator.swift b/KarhooUISDK/Screens/FlightDetailsScreen/Domain/FlightNumberValidator.swift deleted file mode 100644 index fb9db852d..000000000 --- a/KarhooUISDK/Screens/FlightDetailsScreen/Domain/FlightNumberValidator.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// FlightNumberValidator.swift -// Karhoo -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -import Foundation - -final class FlightNumberValidator: Validator { - - private var listener: ValidatorListener? - private let minimumInput = 2 - - func set(listener: ValidatorListener?) { - self.listener = listener - } - - func validate(text: String) { - text.count >= minimumInput ? listener?.valid() : listener?.invalid(reason: "") - } -} diff --git a/KarhooUISDK/Screens/FlightDetailsScreen/FlightDetailsMVP.swift b/KarhooUISDK/Screens/FlightDetailsScreen/FlightDetailsMVP.swift deleted file mode 100644 index af5fee3e4..000000000 --- a/KarhooUISDK/Screens/FlightDetailsScreen/FlightDetailsMVP.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// FlightDetailsMVP.swift -// Karhoo -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -import Foundation - -protocol FlightDetailsView: AnyObject { - func startKeyboardListener() - func setUpUI() - func set(formButtonEnabled: Bool) - func unfocusInputFields() - func updateFlightNumberField(placeHolder: String) -} - -protocol FlightDetailsPresenter: KarhooTextFieldStateDelegate, KarhooTextFieldEvents { - func load(view: FlightDetailsView) - func screenWillAppear() - func didPressCancel() - func didPressContinue() - func didSet(additionalInformation: String) -} diff --git a/KarhooUISDK/Screens/FlightDetailsScreen/Presenter/KarhooFlightDetailsPresenter.swift b/KarhooUISDK/Screens/FlightDetailsScreen/Presenter/KarhooFlightDetailsPresenter.swift deleted file mode 100644 index ef8c35c59..000000000 --- a/KarhooUISDK/Screens/FlightDetailsScreen/Presenter/KarhooFlightDetailsPresenter.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// KarhooAirportBookingPresenter.swift -// Karhoo -// -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import Foundation - -final class KarhooFlightDetailsPresenter: FlightDetailsPresenter { - - private var flightNumber: String? - private var additionalInformation: String? - private var flightNumberValid: Bool? - private weak var view: FlightDetailsView? - private let completion: ScreenResultCallback - - init(completion: @escaping ScreenResultCallback) { - self.completion = completion - } - - func load(view: FlightDetailsView) { - self.view = view - view.startKeyboardListener() - } - - func didPressCancel() { - view?.unfocusInputFields() - finishWithResult(ScreenResult.cancelled(byUser: true)) - } - - func didSet(additionalInformation: String) { - self.additionalInformation = additionalInformation - } - - func didPressContinue() { - view?.unfocusInputFields() - - let flightDetailsAdded = FlightDetails(flightNumber: flightNumber, - comments: additionalInformation) - finishWithResult(ScreenResult.completed(result: flightDetailsAdded)) - } - - func screenWillAppear() { - view?.setUpUI() - } - - func didChange(text: String, isValid: Bool, identifier: Int) { - if identifier == AirportFields.flightNumber.rawValue { - flightNumber = text - flightNumberValid = isValid - } - updateFormButton() - } - - func fieldDidFocus(identifier: Int) { - guard identifier == AirportFields.flightNumber.rawValue else { - return - } - view?.updateFlightNumberField(placeHolder: UITexts.Errors.flightNumberValidatorError) - } - - func fieldDidUnFocus(identifier: Int) { - guard identifier == AirportFields.flightNumber.rawValue else { - return - } - view?.updateFlightNumberField(placeHolder: UITexts.Airport.flightNumber) - } - - private func updateFormButton() { - guard let flightNumberValid = self.flightNumberValid else { - view?.set(formButtonEnabled: false) - return - } - view?.set(formButtonEnabled: flightNumberValid) - } - - private func finishWithResult(_ result: ScreenResult) { - self.completion(result) - } -} diff --git a/KarhooUISDK/Screens/FlightDetailsScreen/View/FlightDetailsViewController.swift b/KarhooUISDK/Screens/FlightDetailsScreen/View/FlightDetailsViewController.swift deleted file mode 100644 index 7c8899567..000000000 --- a/KarhooUISDK/Screens/FlightDetailsScreen/View/FlightDetailsViewController.swift +++ /dev/null @@ -1,153 +0,0 @@ -// -// FlightDetailsViewController.swift -// Karhoo -// -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import UIKit - -enum AirportFields: Int { - case flightNumber -} - -final class FlightDetailsViewController: UIViewController, FlightDetailsView { - private let animationTime: Double = 0.5 - private let flightNumberCharacterLimit: Int = 10 - private let driverNotesCharacterLimit: Int = 100 - - @IBOutlet private weak var formButtonToBottom: NSLayoutConstraint? - @IBOutlet private weak var formButton: FormButton? - @IBOutlet private weak var flightNumberField: KarhooTextField? - @IBOutlet private weak var additionalInformationField: UITextView? - - private let keyboardObserver: KeyboardSizeProvider = KeyboardSizeProvider.shared - private let presenter: FlightDetailsPresenter - private var firstTimeLoading: Bool = true - private let flightNumberValidator = FlightNumberValidator() - - init(presenter: FlightDetailsPresenter) { - self.presenter = presenter - super.init(nibName: "FlightDetailsViewController", bundle: .current) - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func viewDidLoad() { - super.viewDidLoad() - presenter.load(view: self) - setDelegates() - additionalInformationField?.sizeToFit() - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - if firstTimeLoading == true { - firstTimeLoading = false - presenter.screenWillAppear() - } - } - - func setUpUI() { - let button = UIBarButtonItem(title: UITexts.Generic.cancel, - style: .plain, - target: self, - action: #selector(cancelPressed)) - button.tintColor = KarhooUI.colors.darkGrey - navigationItem.leftBarButtonItem = button - - self.navigationItem.title = UITexts.Airport.airportPickup - self.formButton?.set(title: UITexts.Booking.requestCar) - setUpInputFields() - } - - func startKeyboardListener() { - keyboardObserver.register(listener: self) - } - - func set(formButtonEnabled: Bool) { - if formButtonEnabled { - formButton?.setEnabledMode() - return - } - formButton?.setDisabledMode() - } - - func unfocusInputFields() { - flightNumberField?.setUnFocus() - additionalInformationField?.resignFirstResponder() - } - - func updateFlightNumberField(placeHolder: String) { - flightNumberField?.set(defaultPlaceholder: placeHolder) - } - - @objc private func cancelPressed() { - presenter.didPressCancel() - } - - private func setUpInputFields() { - flightNumberField?.set(autoCapitalisationType: .allCharacters) - flightNumberField?.setFocus() - flightNumberField?.set(defaultPlaceholder: UITexts.Errors.flightNumberValidatorError) - flightNumberField?.set(identifier: AirportFields.flightNumber.rawValue) - flightNumberField?.set(animationTime: animationTime) - flightNumberField?.set(characterLimit: flightNumberCharacterLimit) - flightNumberField?.set(validator: flightNumberValidator) - flightNumberField?.set(fieldEventsDelegate: presenter) - } - - private func setDelegates() { - flightNumberField?.set(stateDelegate: presenter) - formButton?.delegate = self - additionalInformationField?.delegate = self - } - - deinit { - keyboardObserver.remove(listener: self) - } - - final class KarhooFlightDetailsScreenBuilder: FlightDetailsScreenBuilder { - - func buildFlightDetailsScreen(completion: @escaping ScreenResultCallback) -> Screen { - let flightDetailsPresenter = KarhooFlightDetailsPresenter(completion: completion) - - let flightDetailsViewController = FlightDetailsViewController(presenter: flightDetailsPresenter) - let navigationController = UINavigationController(rootViewController: flightDetailsViewController) - - flightDetailsPresenter.load(view: flightDetailsViewController) - return navigationController - } - } - -} - -extension FlightDetailsViewController: KeyboardListener { - func keyboard(updatedHeight: CGFloat) { - self.formButtonToBottom?.constant = updatedHeight - } -} - -extension FlightDetailsViewController: FormButtonDelegate { - func formButtonPressed() { - presenter.didPressContinue() - } -} - -extension FlightDetailsViewController: UITextViewDelegate { - func textViewDidChange(_ textView: UITextView) { - presenter.didSet(additionalInformation: textView.text) - } - - func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { - guard let textViewText = textView.text else { - return true - } - - let newLength = textViewText.count + text.count - range.length - return newLength <= driverNotesCharacterLimit - } -} diff --git a/KarhooUISDK/Screens/FlightDetailsScreen/View/FlightDetailsViewController.xib b/KarhooUISDK/Screens/FlightDetailsScreen/View/FlightDetailsViewController.xib deleted file mode 100644 index 364653c16..000000000 --- a/KarhooUISDK/Screens/FlightDetailsScreen/View/FlightDetailsViewController.xib +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsMVP.swift b/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsMVP.swift new file mode 100644 index 000000000..c99a05e93 --- /dev/null +++ b/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsMVP.swift @@ -0,0 +1,25 @@ +// +// PassengerDetailsMVP.swift +// KarhooUISDK +// +// Created by Jeevan Thandi on 08/07/2020. +// Copyright © 2020 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +protocol PassengerDetailsActions: BaseViewController { + func passengerDetailsValid(_ : Bool) +} + +protocol PassengerDetailsPresenterProtocol { + var details: PassengerDetails? { get set } + func doneClicked(newDetails: PassengerDetails, country: Country) + func backClicked() +} + +struct PassengerDetailsResult { + var details: PassengerDetails? + var country: Country? +} diff --git a/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsPresenter.swift b/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsPresenter.swift new file mode 100644 index 000000000..4c21536a5 --- /dev/null +++ b/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsPresenter.swift @@ -0,0 +1,32 @@ +// +// PassengerDetailsPresenter.swift +// KarhooUISDK +// +// Created by Diana Petrea on 25.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import Foundation +import KarhooSDK + +final class PassengerDetailsPresenter: PassengerDetailsPresenterProtocol { + var details: PassengerDetails? + private let callback: ScreenResultCallback + + init(details: PassengerDetails?, + callback: @escaping ScreenResultCallback) { + self.details = details + self.callback = callback + } + + func doneClicked(newDetails: PassengerDetails, country: Country) { + let data = PassengerDetailsResult(details: newDetails, country: country) + let result = ScreenResult.completed(result: data) + callback(result) + } + + func backClicked() { + let result = ScreenResult.cancelled(byUser: true) + callback(result) + } +} diff --git a/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsViewController.swift b/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsViewController.swift new file mode 100644 index 000000000..73d7f98df --- /dev/null +++ b/KarhooUISDK/Screens/PassengerDetails/PassengerDetailsViewController.swift @@ -0,0 +1,355 @@ +// +// PassengerDetailsViewController.swift +// KarhooUISDK +// +// Created by Diana Petrea on 25.08.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit +import KarhooSDK + +struct KHPassengerDetailsViewID { + static let scrollView = "scroll_view" + static let mainStackView = "main_stack_view" + static let backButton = "back_button" + static let pageInfoStackView = "page_info_stack_view" + static let pageTitleLabel = "page_title_label" + static let pageSubtitleLabel = "page_subtitle_label" + static let firstNameLabel = "first_name_label" + static let firstNameInputView = "first_name_input_view" + static let lastNameInputView = "last_name_input_view" + static let emailInputView = "email_input_view" + static let mobilePhoneInputView = "mobile_phone_input_view" + static let doneButton = "done_button" +} + +final class PassengerDetailsViewController: UIViewController, BaseViewController { + + private var presenter: PassengerDetailsPresenterProtocol + private let keyboardSizeProvider: KeyboardSizeProviderProtocol = KeyboardSizeProvider.shared + private let doneButtonHeight: CGFloat = 55.0 + private let standardButtonSize: CGFloat = 44.0 + private let standardMargin: CGFloat = 20.0 + private let standardSpacing: CGFloat = 20.0 + private let smallSpacing: CGFloat = 8.0 + private let extraSmallSpacing: CGFloat = 4.0 + private var inputViews = [KarhooInputView]() + private var doneButtonBottomConstraint: NSLayoutConstraint! + private var shouldMoveToNextInputViewOnReturn = true + private let currentLocale = NSLocale.current.languageCode ?? "en" + + // MARK: - Views and Controls + private lazy var scrollView: UIScrollView = { + let scrollView = UIScrollView() + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.backgroundColor = UIColor.white + scrollView.accessibilityIdentifier = KHPassengerDetailsViewID.scrollView + return scrollView + }() + + private lazy var mainStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.accessibilityIdentifier = KHPassengerDetailsViewID.mainStackView + stackView.axis = .vertical + stackView.alignment = .fill + stackView.distribution = .fill + stackView.spacing = standardSpacing + return stackView + }() + + private lazy var backButton: UIButton = { + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityIdentifier = KHPassengerDetailsViewID.backButton + button.tintColor = KarhooUI.colors.darkGrey + button.setImage(UIImage.uisdkImage("backIcon").withRenderingMode(.alwaysTemplate), for: .normal) + button.imageView?.contentMode = .scaleAspectFit + button.setTitle(UITexts.Generic.back, for: .normal) + button.setTitleColor(KarhooUI.colors.darkGrey, for: .normal) + button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 12.0) + button.titleEdgeInsets = UIEdgeInsets(top: 0, left: extraSmallSpacing, bottom: 0, right: 0) + button.addTarget(self, action: #selector(backButtonPressed), for: .touchUpInside) + return button + }() + + private lazy var pageInfoStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.accessibilityIdentifier = KHPassengerDetailsViewID.pageInfoStackView + stackView.axis = .vertical + stackView.spacing = smallSpacing + return stackView + }() + + private lazy var pageTitleLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHPassengerDetailsViewID.pageTitleLabel + label.font = KarhooUI.fonts.titleBold() + label.textColor = KarhooUI.colors.infoColor + label.text = UITexts.PassengerDetails.title + label.numberOfLines = 1 + return label + }() + + private lazy var pageSubtitleLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityIdentifier = KHPassengerDetailsViewID.pageSubtitleLabel + label.font = KarhooUI.fonts.bodyRegular() + label.textColor = KarhooUI.colors.infoColor + label.text = UITexts.PassengerDetails.subtitle + label.numberOfLines = 0 + return label + }() + + private lazy var firstNameInputView: KarhooTextInputView = { + let inputView = KarhooTextInputView(contentType: .firstname, + isOptional: false, + accessibilityIdentifier: KHPassengerDetailsViewID.firstNameInputView) + inputView.delegate = self + return inputView + }() + + private lazy var lastNameInputView: KarhooTextInputView = { + let inputView = KarhooTextInputView(contentType: .surname, + isOptional: false, + accessibilityIdentifier: KHPassengerDetailsViewID.lastNameInputView) + inputView.delegate = self + return inputView + }() + + private lazy var emailNameInputView: KarhooTextInputView = { + let inputView = KarhooTextInputView(contentType: .email, + isOptional: false, + accessibilityIdentifier: KHPassengerDetailsViewID.emailInputView) + inputView.delegate = self + return inputView + }() + + private lazy var mobilePhoneInputView: KarhooPhoneInputView = { + let inputView = KarhooPhoneInputView(accessibilityIdentifier: KHPassengerDetailsViewID.mobilePhoneInputView) + inputView.delegate = self + return inputView + }() + + private lazy var doneButton: UIButton = { + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityIdentifier = KHPassengerDetailsViewID.doneButton + button.anchor(height: doneButtonHeight) + button.backgroundColor = KarhooUI.colors.secondary + button.setTitleColor(UIColor.white, for: .normal) + button.setTitle(UITexts.PassengerDetails.saveAction.uppercased(), for: .normal) + button.titleLabel?.font = KarhooUI.fonts.subtitleBold() + button.layer.cornerRadius = 8.0 + button.layer.masksToBounds = true + button.addTarget(self, action: #selector(donePressed), for: .touchUpInside) + return button + }() + + // MARK: - Init + init(presenter: PassengerDetailsPresenterProtocol) { + self.presenter = presenter + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(code:) has not been implemented") + } + + deinit { + keyboardSizeProvider.remove(listener: self) + } + + override func loadView() { + view = UIView() + view.backgroundColor = UIColor.white + view.translatesAutoresizingMaskIntoConstraints = false + view.anchor(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + view.layer.cornerRadius = 10.0 + view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(backgroundClicked))) + setUpView() + } + + private func setUpView() { + view.addSubview(backButton) + backButton.anchor(top: view.safeAreaLayoutGuide.topAnchor, + leading: view.leadingAnchor, + paddingTop: 15.0, + width: standardButtonSize * 2) + + view.addSubview(doneButton) + doneButton.anchor(leading: view.leadingAnchor, + trailing: view.trailingAnchor, + paddingLeft: standardSpacing, + paddingRight: standardSpacing) + enableDoneButton(false) + doneButtonBottomConstraint = doneButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -standardSpacing) + doneButtonBottomConstraint.isActive = true + + view.addSubview(scrollView) + scrollView.anchor(top: backButton.bottomAnchor, + bottom: doneButton.topAnchor, + paddingTop: standardSpacing, + paddingBottom: standardSpacing) + scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true + + scrollView.addSubview(mainStackView) + mainStackView.anchor(top: scrollView.topAnchor, + leading: scrollView.leadingAnchor, + trailing: scrollView.trailingAnchor, + paddingTop: 0, + paddingLeft: standardMargin, + paddingRight: -standardMargin) + mainStackView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true + _ = mainStackView.bottomAnchor.constraint(greaterThanOrEqualTo: scrollView.bottomAnchor, constant: -standardSpacing).isActive = true + + mainStackView.addArrangedSubview(pageInfoStackView) + pageInfoStackView.addArrangedSubview(pageTitleLabel) + pageInfoStackView.addArrangedSubview(pageSubtitleLabel) + + mainStackView.addArrangedSubview(firstNameInputView) + mainStackView.addArrangedSubview(lastNameInputView) + mainStackView.addArrangedSubview(emailNameInputView) + mainStackView.addArrangedSubview(mobilePhoneInputView) + + view.setNeedsDisplay() + view.setNeedsLayout() + view.setNeedsUpdateConstraints() + + inputViews = [firstNameInputView, lastNameInputView, emailNameInputView, mobilePhoneInputView] + addPreInputtedDetails() + } + + // MARK: - Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + keyboardSizeProvider.register(listener: self) + forceLightMode() + } + + // MARK: - Actions + @objc private func backButtonPressed() { + dismissScreen() + presenter.backClicked() + } + + @objc private func donePressed() { + dismissScreen() + let details = PassengerDetails(firstName: firstNameInputView.getInput(), + lastName: lastNameInputView.getInput(), + email: emailNameInputView.getInput(), + phoneNumber: mobilePhoneInputView.getFullPhoneNumber(), + locale: currentLocale) + let country = KarhooCountryParser.getCountry(countryCode: mobilePhoneInputView.getCountryCode()) ?? KarhooCountryParser.defaultCountry + presenter.doneClicked(newDetails: details, country: country) + dismissScreen() + } + + @objc private func backgroundClicked() { + shouldMoveToNextInputViewOnReturn = false + view.endEditing(true) + } + + // MARK: - Utils + func enableDoneButton(_ shouldEnable: Bool) { + doneButton.isEnabled = shouldEnable + doneButton.alpha = shouldEnable ? 1.0 : 0.4 + } + + func dismissScreen() { + self.dismiss(animated: false, completion: nil) + } + + func addPreInputtedDetails() { + guard let details = presenter.details + else { + return + } + + firstNameInputView.set(text: details.firstName) + lastNameInputView.set(text: details.lastName) + emailNameInputView.set(text: details.email) + mobilePhoneInputView.set(country: PassengerInfo.shared.getCountry()) + mobilePhoneInputView.set(text: details.phoneNumber) + didBecomeInactive(identifier: KHPassengerDetailsViewID.mobilePhoneInputView) + + highlightInvalidFields() + } + + private func highlightInvalidFields() { + for (_, inputView) in inputViews.enumerated() { + if !inputView.isValid() { + inputView.showError() + } + } + } +} + +extension PassengerDetailsViewController: PassengerDetailsActions { + func passengerDetailsValid(_ isValid: Bool) { + enableDoneButton(isValid) + } +} + +extension PassengerDetailsViewController: KarhooInputViewDelegate { + func didBecomeInactive(identifier: String) { + goToNextInputField(startingIdentifier: identifier) + updateDoneButtonEnabled() + } + + func didBecomeActive(identifier: String) { + shouldMoveToNextInputViewOnReturn = true + } + + func didChangeCharacterInSet(identifier: String) { + updateDoneButtonEnabled() + } + + private func getValidInputViewCount() -> Int { + var validSet = Set() + + for (_, inputView) in inputViews.enumerated() { + if inputView.isValid() { + validSet.insert(inputView.accessibilityIdentifier!) + } else { + validSet.remove(inputView.accessibilityIdentifier!) + } + } + + return validSet.count + } + + private func goToNextInputField(startingIdentifier: String) { + for (index, inputView) in inputViews.enumerated() { + if shouldMoveToNextInputViewOnReturn, + inputView.accessibilityIdentifier == startingIdentifier, + index != inputViews.count - 1 { + inputViews[index + 1].setActive() + } + } + } + + private func updateDoneButtonEnabled() { + let validCount = getValidInputViewCount() + passengerDetailsValid(validCount == inputViews.count) + } +} + +extension PassengerDetailsViewController: KeyboardListener { + + func keyboard(updatedHeight: CGFloat) { + // This is to stop the animation of the done button's bottom constraint change + UIView.animate(withDuration: 0.1, delay: 0, options: []) { [weak self] in + self?.doneButtonBottomConstraint.constant = -updatedHeight - (self?.standardSpacing ?? 0.0) + self?.view.layoutIfNeeded() + } + } +} + + + diff --git a/KarhooUISDK/Screens/PaymentScreen/BraintreePaymentScreensBuilder.swift b/KarhooUISDK/Screens/PaymentScreen/BraintreePaymentScreensBuilder.swift index 5c43461d5..05715bdc0 100644 --- a/KarhooUISDK/Screens/PaymentScreen/BraintreePaymentScreensBuilder.swift +++ b/KarhooUISDK/Screens/PaymentScreen/BraintreePaymentScreensBuilder.swift @@ -14,7 +14,7 @@ import Braintree final class BraintreePaymentScreenBuilder: PaymentScreenBuilder { func buildAddCardScreen(paymentsToken: PaymentSDKToken, - paymentMethodAdded: ScreenResultCallback?, + paymentMethodAdded: ScreenResultCallback?, flowItemCallback: ScreenResultCallback?) { let request = BTDropInRequest() @@ -26,12 +26,8 @@ final class BraintreePaymentScreenBuilder: PaymentScreenBuilder { } else if result?.isCancelled == true { paymentMethodAdded?(.cancelled(byUser: true)) } else { - let paymentMethod = PaymentMethod(nonce: result!.paymentMethod!.nonce, - nonceType: result!.paymentMethod!.type, - icon: result!.paymentIcon, - paymentDescription: result!.paymentDescription) - - paymentMethodAdded?(ScreenResult.completed(result: paymentMethod)) + let nonce = Nonce(nonce: result!.paymentMethod!.nonce, cardType: result!.paymentMethod!.type, lastFour: String(result!.paymentDescription.suffix(2))) + paymentMethodAdded?(ScreenResult.completed(result: nonce)) } }) else { flowItemCallback?(.failed(error: nil)) diff --git a/KarhooUISDK/Screens/PaymentScreen/PaymentMethod.swift b/KarhooUISDK/Screens/PaymentScreen/PaymentMethod.swift deleted file mode 100644 index 918282c2d..000000000 --- a/KarhooUISDK/Screens/PaymentScreen/PaymentMethod.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// PaymentMethod.swift -// KarhooUISDK -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import Foundation - -public struct PaymentMethod: Equatable { - - let nonce: String - let nonceType: String - let icon: UIView - let paymentDescription: String - - init(nonce: String = "", - nonceType: String = "", - icon: UIView = UIView(), - paymentDescription: String = "") { - self.nonce = nonce - self.nonceType = nonceType - self.icon = icon - self.paymentDescription = paymentDescription - } -} diff --git a/KarhooUISDK/Screens/PaymentView/KarhooAddCardView.swift b/KarhooUISDK/Screens/PaymentView/KarhooAddCardView.swift deleted file mode 100644 index a011409eb..000000000 --- a/KarhooUISDK/Screens/PaymentView/KarhooAddCardView.swift +++ /dev/null @@ -1,204 +0,0 @@ -// -// KarhooAddCardView.swift -// KarhooUISDK -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import UIKit -import KarhooSDK - -public struct KHAddCardViewID { - public static let view = "add_card_view" - public static let image = "logo_image" - public static let title = "title_label" - public static let stackView = "stack_view_container" - public static let button = "add_card_button" - public static let editButton = "edit_card_button" -} - -final class KarhooAddCardView: UIView, PaymentView { - - var baseViewController: BaseViewController? - - private var didSetupConstraints: Bool = false - private var imageView: UIImageView! - private var titleLabel: UILabel! - private var button: UIButton! - private var stackContainer: UIStackView! - private var editButton: UIButton! - private var dotBorderLayer: CAShapeLayer! - private var hasPayment: Bool = false - - var quote: Quote? - var actions: PaymentViewActions? - private var presenter: PaymentPresenter? - - init() { - super.init(frame: .zero) - - self.setUpView() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func draw(_ rect: CGRect) { - super.draw(rect) - - if !hasPayment && dotBorderLayer == nil { - dotBorderLayer = CAShapeLayer() - dotBorderLayer.strokeColor = KarhooUI.colors.paymentLightGrey.cgColor - dotBorderLayer.lineDashPattern = [2, 2] - dotBorderLayer.frame = bounds - dotBorderLayer.fillColor = nil - dotBorderLayer.path = UIBezierPath(rect: bounds).cgPath - layer.addSublayer(dotBorderLayer) - } - } - - private func setUpView() { - backgroundColor = KarhooUI.colors.paymentLightGrey.withAlphaComponent(0.1) - translatesAutoresizingMaskIntoConstraints = false - accessibilityIdentifier = KHAddCardViewID.view - layer.cornerRadius = 4.0 - layer.masksToBounds = true - - stackContainer = UIStackView() - stackContainer.translatesAutoresizingMaskIntoConstraints = false - stackContainer.accessibilityIdentifier = KHAddCardViewID.stackView - stackContainer.axis = .horizontal - stackContainer.spacing = 15.0 - addSubview(stackContainer) - - imageView = UIImageView(image: UIImage.uisdkImage("add_destination").withRenderingMode(.alwaysTemplate)) - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.tintColor = KarhooUI.colors.accent - imageView.accessibilityIdentifier = KHAddCardViewID.image - stackContainer.addArrangedSubview(imageView) - - titleLabel = UILabel() - titleLabel.translatesAutoresizingMaskIntoConstraints = false - titleLabel.accessibilityIdentifier = KHAddCardViewID.title - titleLabel.text = UITexts.Payment.addPaymentMethod - titleLabel.font = KarhooUI.fonts.getRegularFont(withSize: 14.0) - titleLabel.textColor = KarhooUI.colors.accent - stackContainer.addArrangedSubview(titleLabel) - - button = UIButton(type: .custom) - button.translatesAutoresizingMaskIntoConstraints = false - button.accessibilityIdentifier = KHAddCardViewID.button - button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) - addSubview(button) - - editButton = UIButton(type: .custom) - editButton.translatesAutoresizingMaskIntoConstraints = false - editButton.accessibilityIdentifier = KHAddCardViewID.editButton - editButton.addTarget(self, action: #selector(editButtonTapped), for: .touchUpInside) - editButton.setTitle(UITexts.Generic.edit, for: .normal) - editButton.titleLabel?.font = KarhooUI.fonts.getRegularFont(withSize: 14.0) - editButton.setTitleColor(KarhooUI.colors.darkBlue, for: .normal) - editButton.isHidden = true - addSubview(editButton) - - presenter = KarhooPaymentPresenter(view: self) - } - - override func updateConstraints() { - if !didSetupConstraints { - - let imageSize: CGFloat = 18.0 - _ = [imageView.widthAnchor.constraint(equalToConstant: imageSize), - imageView.heightAnchor.constraint(equalToConstant: imageSize)].map { $0.isActive = true } - - let stackInset: CGFloat = 14.0 - _ = [stackContainer.topAnchor.constraint(equalTo: topAnchor, constant: stackInset), - stackContainer.leadingAnchor.constraint(equalTo: leadingAnchor, constant: stackInset), - stackContainer.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -stackInset), - stackContainer.trailingAnchor.constraint(lessThanOrEqualTo: editButton.leadingAnchor, - constant: -5)].map { $0.isActive = true } - - _ = [button.topAnchor.constraint(equalTo: topAnchor), - button.leadingAnchor.constraint(equalTo: leadingAnchor), - button.trailingAnchor.constraint(equalTo: stackContainer.trailingAnchor), - button.bottomAnchor.constraint(equalTo: bottomAnchor)].map { $0.isActive = true } - - _ = [editButton.topAnchor.constraint(equalTo: topAnchor), - editButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -stackInset), - editButton.bottomAnchor.constraint(equalTo: bottomAnchor)].map { $0.isActive = true } - - didSetupConstraints = true - } - - super.updateConstraints() - } - - @objc - private func buttonTapped() { - presenter?.updateCardPressed(showRetryAlert: false) - } - - @objc - private func editButtonTapped() { - presenter?.updateCardPressed(showRetryAlert: false) - } - - func set(nonce: Nonce) { - titleLabel.text = UITexts.Payment.paymentMethod + " **** " + nonce.lastFour.suffix(4) - imageView.image = UIImage.uisdkImage(nonce.cardType) - - updateViewState() - } - - func noPaymentMethod() { - resetViewState() - } - - func startRegisterCardFlow() { - presenter?.updateCardPressed(showRetryAlert: true) - } - - func set(paymentMethod: PaymentMethod) { - titleLabel.text = UITexts.Payment.paymentMethod + " **** " + paymentMethod.paymentDescription.suffix(2) - imageView.image = UIImage.uisdkImage(paymentMethod.nonceType) - updateViewState() - actions?.didGetNonce(nonce: paymentMethod.nonce) - } - - private func updateViewState() { - backgroundColor = KarhooUI.colors.white - layer.borderWidth = 1.0 - layer.borderColor = KarhooUI.colors.guestCheckoutGrey.cgColor - hasPayment = true - editButton.isHidden = false - button.isEnabled = false - - setNeedsDisplay() - } - - private func resetViewState() { - layer.borderWidth = 0.0 - layer.borderColor = UIColor.clear.cgColor - backgroundColor = KarhooUI.colors.paymentLightGrey.withAlphaComponent(0.1) - hasPayment = false - editButton.isHidden = true - titleLabel.text = UITexts.Payment.addPaymentMethod - button.isEnabled = true - - setNeedsDisplay() - } - - func validPayment() -> Bool { - return hasPayment - } - - func showError() { - let generator = UINotificationFeedbackGenerator() - generator.notificationOccurred(.error) - shakeView() - - layer.borderWidth = 1.0 - layer.borderColor = UIColor.red.cgColor - } -} diff --git a/KarhooUISDK/Screens/PaymentView/KarhooPaymentView.swift b/KarhooUISDK/Screens/PaymentView/KarhooPaymentView.swift deleted file mode 100644 index b7b519362..000000000 --- a/KarhooUISDK/Screens/PaymentView/KarhooPaymentView.swift +++ /dev/null @@ -1,126 +0,0 @@ -// -// CardDetailsView.swift -// CardsDetails -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -import UIKit -import KarhooSDK - -public struct KHCardDetailsViewID { - public static let cardIcon = "card_Icon_ImageView" - public static let cardDigits = "card_digits_Label" - public static let updateButton = "update_Button" -} - -public final class KarhooPaymentView: UIView, PaymentView { - - public weak var baseViewController: BaseViewController? - var quote: Quote? - var actions: PaymentViewActions? - var nonce: String? - // UI Components - private var cardIcon: UIImageView! - private var cardDigits: UILabel! - private var updateButton: UIButton! - private var didSetupConstraints: Bool = false - private var presenter: PaymentPresenter? - - public init() { - super.init(frame: .zero) - self.setUpView() - } - - public override init(frame: CGRect) { - super.init(frame: frame) - self.setUpView() - } - - public required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - self.setUpView() - } - - override public func updateConstraints() { - if !didSetupConstraints { - // card icon - _ = [cardIcon.trailingAnchor.constraint(equalTo: cardDigits.leadingAnchor, constant: -20.0), - cardIcon.heightAnchor.constraint(equalToConstant: 35.0), - cardIcon.widthAnchor.constraint(equalToConstant: 35.0), - cardIcon.topAnchor.constraint(equalTo: self.topAnchor, constant: 5.0), - cardIcon.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5.0)] - .map { $0.isActive = true } - // card digits - _ = [cardDigits.centerYAnchor.constraint(equalTo: self.centerYAnchor), - cardDigits.centerXAnchor.constraint(equalTo: self.centerXAnchor)] - .map { $0.isActive = true } - // update button - _ = [updateButton.centerYAnchor.constraint(equalTo: self.centerYAnchor), - updateButton.leadingAnchor.constraint(equalTo: cardDigits.trailingAnchor, constant: 20.0)] - .map { $0.isActive = true } - - didSetupConstraints = true - } - super.updateConstraints() - } - - private func setUpView() { - accessibilityIdentifier = "cardDetails_view" - backgroundColor = .clear - - cardIcon = UIImageView() - cardIcon.accessibilityIdentifier = KHCardDetailsViewID.cardIcon - cardIcon.image = UIImage.uisdkImage("card_icon") - cardIcon.translatesAutoresizingMaskIntoConstraints = false - addSubview(cardIcon) - - cardDigits = UILabel() - cardDigits.translatesAutoresizingMaskIntoConstraints = false - cardDigits.accessibilityIdentifier = KHCardDetailsViewID.cardDigits - cardDigits.textAlignment = .center - cardDigits.font = KarhooUI.fonts.bodyRegular() - cardDigits.textColor = KarhooUI.colors.darkGrey - cardDigits.text = "" - addSubview(cardDigits) - - updateButton = UIButton(type: .custom) - updateButton.accessibilityIdentifier = KHCardDetailsViewID.updateButton - updateButton.translatesAutoresizingMaskIntoConstraints = false - updateButton.setTitle(UITexts.Generic.add, for: .normal) - updateButton.setTitleColor(KarhooUI.colors.medGrey, for: .normal) - updateButton.titleLabel?.font = KarhooUI.fonts.bodyBold() - updateButton.addTarget(self, action: #selector(updateButtonTapped), for: .touchUpInside) - addSubview(updateButton) - - presenter = KarhooPaymentPresenter(view: self) - } - - @objc - private func updateButtonTapped() { - presenter?.updateCardPressed(showRetryAlert: false) - } - - func set(paymentMethod: PaymentMethod) { - cardDigits.text = paymentMethod.paymentDescription - cardIcon.image = UIImage.uisdkImage(paymentMethod.nonceType) - updateButton.setTitle(UITexts.Generic.change, for: .normal) - actions?.didGetNonce(nonce: paymentMethod.nonce) - self.nonce = paymentMethod.nonce - } - - func set(nonce: Nonce) { - updateButton.setTitle(UITexts.Generic.change, for: .normal) - cardDigits.text = "•••• " + nonce.lastFour.suffix(4) - cardIcon.image = UIImage.uisdkImage(nonce.cardType) - } - - func noPaymentMethod() { - updateButton.setTitle(UITexts.Generic.add, for: .normal) - } - - func startRegisterCardFlow() { - presenter?.updateCardPressed(showRetryAlert: true) - } -} diff --git a/KarhooUISDK/Screens/PopupDialog/PopupDialogViewController.swift b/KarhooUISDK/Screens/PopupDialog/PopupDialogViewController.swift index 5b91ce3cf..2368604a4 100644 --- a/KarhooUISDK/Screens/PopupDialog/PopupDialogViewController.swift +++ b/KarhooUISDK/Screens/PopupDialog/PopupDialogViewController.swift @@ -32,6 +32,7 @@ final class PopupDialogViewController: UIViewController, PopupDialogView { formButton?.delegate = self formButton?.setEnabledMode() presenter.load(view: self) + forceLightMode() } func set(dialogMessage: String) { diff --git a/KarhooUISDK/Screens/PrebookConfirmationScreen/KarhooPrebookConfirmationViewController.swift b/KarhooUISDK/Screens/PrebookConfirmationScreen/KarhooPrebookConfirmationViewController.swift index 3ce34414e..156d7aca0 100644 --- a/KarhooUISDK/Screens/PrebookConfirmationScreen/KarhooPrebookConfirmationViewController.swift +++ b/KarhooUISDK/Screens/PrebookConfirmationScreen/KarhooPrebookConfirmationViewController.swift @@ -40,6 +40,7 @@ final class KarhooPrebookConfirmationViewController: UIViewController, PrebookCo presenter.load(view: self) formButton?.delegate = self formButton?.setEnabledMode() + forceLightMode() } diff --git a/KarhooUISDK/Screens/Rides/RidesList/RideDetails/RideDetailsViewController.swift b/KarhooUISDK/Screens/Rides/RidesList/RideDetails/RideDetailsViewController.swift index 90990038c..0c41919a3 100644 --- a/KarhooUISDK/Screens/Rides/RidesList/RideDetails/RideDetailsViewController.swift +++ b/KarhooUISDK/Screens/Rides/RidesList/RideDetails/RideDetailsViewController.swift @@ -74,6 +74,7 @@ final class RideDetailsViewController: UIViewController, RideDetailsView { loadingView.set(backgroundColor: KarhooUI.colors.darkGrey, alpha: loadingViewAlpha) loadingView.set(loadingText: UITexts.Trip.tripCancellingActivityIndicatorText) rideDetailsView.tripMetaDataView.delegate = self + forceLightMode() } public func showLoading() { diff --git a/KarhooUISDK/Screens/Rides/RidesList/RidesListViewController.swift b/KarhooUISDK/Screens/Rides/RidesList/RidesListViewController.swift index 2b7c4db12..ac7581f4e 100644 --- a/KarhooUISDK/Screens/Rides/RidesList/RidesListViewController.swift +++ b/KarhooUISDK/Screens/Rides/RidesList/RidesListViewController.swift @@ -54,6 +54,7 @@ final class RidesListViewController: UIViewController, RidesListView { super.viewDidLoad() presenter.load(screen: self) + forceLightMode() } func set(trips: [TripInfo]) { diff --git a/KarhooUISDK/Screens/Rides/RidesViewController.swift b/KarhooUISDK/Screens/Rides/RidesViewController.swift index 775884d74..e2a46cd94 100644 --- a/KarhooUISDK/Screens/Rides/RidesViewController.swift +++ b/KarhooUISDK/Screens/Rides/RidesViewController.swift @@ -51,6 +51,7 @@ final class RidesViewController: UIViewController, RidesView { tabView?.backgroundColor = KarhooUI.colors.accent upcomingTabLabel?.textColor = KarhooUI.colors.accent + forceLightMode() } func set(title: String) { diff --git a/KarhooUISDK/Screens/SideMenu/SideMenuContent/MenuContentViewController.swift b/KarhooUISDK/Screens/SideMenu/SideMenuContent/MenuContentViewController.swift index b0399b3f8..4ee0f205d 100644 --- a/KarhooUISDK/Screens/SideMenu/SideMenuContent/MenuContentViewController.swift +++ b/KarhooUISDK/Screens/SideMenu/SideMenuContent/MenuContentViewController.swift @@ -35,6 +35,8 @@ final class MenuContentViewController: UIViewController, MenuContentView { self.logo?.image = KarhooUISDKConfigurationProvider.configuration.logo() presenter.checkGuestAuthentication() + + forceLightMode() } func getFlowItem() -> Screen { diff --git a/KarhooUISDK/Screens/SideMenu/SideMenuViewController.swift b/KarhooUISDK/Screens/SideMenu/SideMenuViewController.swift index fd3474d9d..29c1dd156 100644 --- a/KarhooUISDK/Screens/SideMenu/SideMenuViewController.swift +++ b/KarhooUISDK/Screens/SideMenu/SideMenuViewController.swift @@ -28,6 +28,11 @@ final class SideMenuViewController: UIViewController, SideMenu { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } + + override func viewDidLoad() { + super.viewDidLoad() + forceLightMode() + } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) diff --git a/KarhooUISDK/Screens/TripFeedbackScreen/KarhooTripFeedbackViewController.swift b/KarhooUISDK/Screens/TripFeedbackScreen/KarhooTripFeedbackViewController.swift index 89cdf6e81..7a330cf98 100644 --- a/KarhooUISDK/Screens/TripFeedbackScreen/KarhooTripFeedbackViewController.swift +++ b/KarhooUISDK/Screens/TripFeedbackScreen/KarhooTripFeedbackViewController.swift @@ -26,6 +26,7 @@ final class KarhooTripFeedbackViewController: UIViewController, TripFeedbackView override func viewDidLoad() { super.viewDidLoad() + forceLightMode() view.backgroundColor = .white title = UITexts.SideMenu.feedback diff --git a/KarhooUISDK/Screens/TripScreen/KarhooTripViewController.swift b/KarhooUISDK/Screens/TripScreen/KarhooTripViewController.swift index e4545eec6..889339987 100644 --- a/KarhooUISDK/Screens/TripScreen/KarhooTripViewController.swift +++ b/KarhooUISDK/Screens/TripScreen/KarhooTripViewController.swift @@ -183,6 +183,8 @@ final class KarhooTripViewController: UIViewController, TripView { presenter.load(view: self) tripDetailsView.set(actions: self, detailsSuperview: self.view) + + forceLightMode() } override func viewWillAppear(_ animated: Bool) { diff --git a/KarhooUISDK/Screens/TripSummaryScreen/TripSummaryViewController.swift b/KarhooUISDK/Screens/TripSummaryScreen/TripSummaryViewController.swift index 07524a244..abca972b1 100644 --- a/KarhooUISDK/Screens/TripSummaryScreen/TripSummaryViewController.swift +++ b/KarhooUISDK/Screens/TripSummaryScreen/TripSummaryViewController.swift @@ -27,6 +27,7 @@ class TripSummaryViewController: UIViewController, TripSummaryView { override func viewDidLoad() { super.viewDidLoad() presenter.viewLoaded(view: self) + forceLightMode() } func set(trip: TripInfo) { diff --git a/KarhooUISDK/Screens/UINavigation.swift b/KarhooUISDK/Screens/UINavigation.swift index 1749a5bc4..a4168b160 100644 --- a/KarhooUISDK/Screens/UINavigation.swift +++ b/KarhooUISDK/Screens/UINavigation.swift @@ -92,4 +92,9 @@ public final class UINavigation: UIViewController, NavigationItem { public override var childForStatusBarStyle: UIViewController? { return controller.topViewController } + + public override func viewDidLoad() { + super.viewDidLoad() + forceLightMode() + } } diff --git a/KarhooUISDK/Translations/Base.lproj/Localizable.strings b/KarhooUISDK/Translations/Base.lproj/Localizable.strings index a732337c4..726201bf8 100644 --- a/KarhooUISDK/Translations/Base.lproj/Localizable.strings +++ b/KarhooUISDK/Translations/Base.lproj/Localizable.strings @@ -1,433 +1,763 @@ +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Problem Booking"; -/*Localizable.strings - Karhoo +"CURBSIDE" = "Curbside"; + +/* PickUp Type */ +"DEFAULT" = "Default"; + +"ELECTRIC" = "Electric"; + +/* English: Error codes */ +"K0001" = "General request error"; + +"K0002" = "Invalid request payload"; + +"K0003" = "Could not read authorisation token"; + +"K0004" = "Authentication is required for this path"; + +"K0005" = "Missing required role for this request"; + +"K0006" = "Rate limit exceeded"; + +"K0007" = "Circuit breaker has triggered for this route"; + +/* User errors, K1xxx */ +"K1001" = "Could not register user"; + +"K1002" = "Could not register user (user already exists)"; + +"K1003" = "Could not register user (invalid request)"; + +"K1004" = "Could not register user (invalid phone number)"; + +"K1005" = "Could not get user details (invalid token)"; + +"K1006" = "Could not get user details (user does not exist)"; + +"K1999" = "User has been created but not been authorized yet, we will get in touch once enabled."; + +/* Locations errors, K2xxx */ +"K2001" = "Could not get address"; + +/* Quotes errors, K3xxx */ +"K3001" = "Could not get estimates"; + +"K3002" = "Could not get estimates (no availability found within requested area)"; + +"K3003" = "Could not get estimates (could not find specified quote)"; + +/* Bookings errors, K4xxx */ +"K4001" = "Could not book trip"; + +"K4002" = "Could not book trip - invalid request payload (require at least 1 set of passenger-details)"; + +"K4003" = "Could not book trip (could not find specified quote)"; + +"K4004" = "Could not book trip (attempt to book an expired quote)"; + +"K4005" = "Could not book trip (permission denied)"; + +"K4006" = "Could not book trip (payment pre-authorisation failed)"; + +"K4007" = "Could not cancel trip"; + +"K4008" = "Could not cancel trip (could not find specified trip)"; + +"K4009" = "Could not cancel trip (permission denied)"; + +"K4010" = "Could not cancel trip (already cancelled)"; + +"K4011" = "Could not get trip"; + +"K4012" = "Could not get trip (could not find specified trip)"; + +"K4013" = "Could not get trip (permission denied)"; + +"K4014" = "Could not book trip as agent"; + +"K4015" = "Could not book trip as traveller"; + +"k4015" = "Could not book trip as traveller"; + +"K4018" = "Could not book trip as this quote is no longer available"; + +"K4020" = "Could not book trip with the selected DMS"; + +"K4025" = "Quote price increased whilst booking"; + +/* Availability errors, K5xxx */ +"K5001" = "Could not get estimates"; + +"K5002" = "Could not get availability (no availability found within requested area)"; + +"K5003" = "Could not get availability (no categories found within requested area)"; + +/* Authentication errors K6xxx */ +"K6001" = "Invalid email or Password. Please try again"; + +/* KPOI errors, K7xxx */ +"K7001" = "Could not process KPOI request"; + +"K7002" = "Could not find Karhoo POI with matching ID"; + +"K7003" = "Could not read Karhoo POI"; + +"K7004" = "Could not write Karhoo POI"; + +"K7005" = "Could not delete Karhoo POI"; + +/* KSDKxxx Internal SDK */ +"KSDK01" = "Something went wrong but we don't know what it was"; + +"KSDK02" = "Missing user permissions"; + +"KSDK03" = "User already logged in"; + +"MEET_AND_GREET" = "Meet and Greet"; + +/* Qxxxx errors */ +"Q0001" = "Pick up and destination cannot be the same."; + +"STAND_BY" = "Stand by"; + +/* "Version" */ +"Text.About.Version" = "Version"; + +"Text.Address.CurrentLocation" = "Current location"; + +"Text.Address.NoRecentAddress" = "No recent results"; + +"Text.Address.SetOnMap" = "Set on map"; + +/* Address Bar */ +"Text.AddressBar.AddDestination" = "Add destination"; + +"Text.AddressBar.AddPickup" = "Add pickup"; + +"Text.AddressBar.EnterPickupLocation" = "Enter pickup location"; + +"Text.AddressSearch.EnterDestinationLocation" = "Enter destination location"; + +/* "Add Flight Details" used on booking airport ride */ +"Text.Airport.AddFlightDetails" = "Add Flight Details"; + +/* "Flight number" used as the flight number field placeholder */ +"Text.Airport.FlightNumber" = "Flight Number"; + +/* Message on airport screen for encouraging user to enter as much info about airport booking as possible */ +"Text.Airport.HelpfulMessage" = "Please enter a valid flight number"; + +/* "Airport Pickup" used on screen for airport bookinga */ +"Text.Airport.Pickup" = "Airport Pickup"; + +/* "All" used for all categories filter on category list. Write normally as the app will uppercase the string */ +"Text.Availability.AllCategory" = "All"; + +"Text.Availability.NoQuotesForSelectedParameters" = "No availability for the requested time. Please choose a different time."; + +"Text.Availability.NoQuotesInSelectedCategory" = "There are no quotes for this category. \n Please choose another category."; + +/* Base fare title */ +"Text.Booking.BaseFare" = "Base Fare"; + +/* "Your final fare might be affected by tips, tolls, taxes, and other charges." */ +"Text.Booking.BaseFareExplanation" = "Your final fare might be affected by tips, tolls, taxes, and other charges."; + +"Text.Booking.CountryCodeSelection.Search" = "Search country/region"; + +/* Country Code Selection */ +"Text.Booking.CountryCodeSelection.Title" = "Country / Region"; + +"Text.Booking.EnterDestination" = "Enter destination to see available fleets"; + +/* Checkout component */ +"Text.Booking.EstimatedInfoBox" = "This fleet is a non-regulated taxi. The quote is an estimate based on the trip factors (distance, time, etc). Please refer to the fleet's Terms and Conditions for more information."; + +"Text.Booking.FixedInfoBox" = "This fleet charges a flat fare. The final fare may be affected by extras (tolls, delay, etc), please check the fleet's Terms and Conditions."; + +"Text.Booking.FlightTracking" = "Flight tracking"; + +"Text.Booking.GPSTracking" = "GPS tracking"; + +"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Flight number (Optional)"; + +/* Guest checkout */ +"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Passenger Details"; + +"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Payment Methods"; + +"Text.Booking.LearnMore" = "Learn more"; + +"Text.Booking.MaximumLuggages" = "%1$@ luggages maximum"; + +"Text.Booking.MaximumPassengers" = "%1$@ passengers maximum"; + +"Text.Booking.MeteredInfoBox" = "This fleet is a regulated metered taxi. The quote is an estimate based on the trip factors (distance, time, etc)."; + +"Text.Booking.Next" = "NEXT"; + +/* %1$@ if you have suggestions for local fleets. */ +"Text.Booking.NoAvailabilityBody" = "%1$@ if you have suggestions for local fleets."; + +/* We’re not live here yet! */ +"Text.Booking.NoAvailabilityHeader" = "We’re not live here yet!"; + +/* Get in touch */ +"Text.Booking.NoAvailabilityLink" = "Get in touch"; + +"Text.Booking.Passenger" = "Passenger"; + +"Text.Booking.PassengerDetails.Add" = "Add Passenger"; + +"Text.Booking.PassengerDetails.Email" = "Email"; + +"Text.Booking.PassengerDetails.FirstName" = "First Name"; + +"Text.Booking.PassengerDetails.LastName" = "Last Name"; + +"Text.Booking.PassengerDetails.MobilePhone" = "Mobile Phone Number"; + +"Text.Booking.PassengerDetails.SaveAction" = "SAVE"; + +"Text.Booking.PassengerDetails.Subtitle" = "This information allows the smooth running of your ride."; + +/* Passenger Details */ +"Text.Booking.PassengerDetails.Title" = "Passenger"; + +/* Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked */ +"Text.Booking.PrebookConfirmation" = "Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been bookedbooking"; + +/* Prebook Done, Fuzzy */ +"Text.Booking.PrebookConfirmed" = "Prebook Confirmed"; + +/* Ride Details */ +"Text.Booking.PrebookConfirmed.RideDetails" = "Ride Details"; + +/* Booking */ +"Text.Booking.RequestCar" = "Book"; + +"Text.Booking.RequestingCar" = "Booking Ride"; + +"Text.Booking.RequestReceived" = "Booking Received"; + +"Text.Booking.TrainTracking" = "Train tracking"; + +"Text.Bookings.Alert.CancellationFee.Charge" = "You will be charged a cancellation fee estimated at %1$@.\n\nWould you like to proceed?"; + +"Text.Bookings.Alert.CancellationFee.Continue" = "Would you like to proceed?"; + +"Text.Bookings.Alert.CancellationSuccess.Message" = "Your trip has been cancelled successfully."; + +"Text.Bookings.Alert.CancellationSuccess.Title" = "Ride cancellation successful"; + +/* used as a call to action on a button in the empty bookings screen: English: "Book Ride" */ +"Text.Bookings.BookATrip" = "Book Ride"; + +/* "Cancel Ride" button action */ +"Text.Bookings.CancelRide" = "Cancel Ride"; + +/* "Contact Driver" (button action) */ +"Text.Bookings.ContactDriver" = "Contact Driver"; + +/* "Contact Fleet" */ +"Text.Bookings.ContactFleet" = "Contact Fleet"; + +/* Generic fallback message for trip load failure */ +"Text.Bookings.CouldNotLoadTrips" = "Could not load trips."; + +"Text.Bookings.eta" = "ETA"; + +/* English: "No Trips" used if the booking list screen is empty */ +"Text.Bookings.NoTrips" = "No rides"; + +/* used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B" */ +"Text.Bookings.NoTripsBookedMessage" = "You have not booked any rides yet. We can help you get from A to B"; + +/* "Past" used on past tabs on bookings list */ +"Text.Bookings.Past" = "Past"; + +"Text.Bookings.price" = "Price"; + +"Text.Bookings.Price" = "Price"; + +"Text.Bookings.Price.Cancelled" = "Cancelled"; + +"Text.Bookings.Quote" = "Quote"; + +/* Button for rebooking a ride */ +"Text.Bookings.RebookRide" = "Rebook Ride"; + +/* "Report Issue" Button */ +"Text.Bookings.ReportIssue" = "Report Issue"; + +/* "Track Driver" */ +"Text.Bookings.TrackDriver" = "Track Driver"; + +/* "Track Trip" */ +"Text.Bookings.TrackTrip" = "Track Ride"; + +"Text.Bookings.TrackTrip.AlertMessage" = "Would you like to track the vehicle?"; + +"Text.Bookings.TrackTrip.AlertTitle" = "The driver is en route"; + +"Text.Bookings.TrackTrip.DismissAction" = "No"; + +"Text.Bookings.TrackTrip.TrackAction" = "Yes"; + +/* Upcoming: used on upcoming tabs for rides, Fuzzy */ +"Text.Bookings.Upcoming" = "Upcoming"; + +"Text.Error.Alert.CantSendEmail" = "Can't send email message. Configure Mail app first."; + +/* The action button on the force update alert. ie "Update" (this button takes the user to the app store) */ +"Text.Error.Alert.ForceUpdateButton" = "Update"; + +/* The message when the user needs to update the app. ie. "Please update Karhoo to the latest version." */ +"Text.Error.Alert.ForceUpdateMessage" = "Please update the app to continue."; + +/* The title of the alert when user is forced to update ie "App Update Required" */ +"Text.Error.Alert.ForceUpdateTitle" = "New version available"; + +"Text.Error.Booking.EnterDestinationToProceed" = "Enter destination to book a ride"; + +/* Errors */ +"Text.Error.EmailValidationError" = "Check your email address is spelt correctly"; + +/* When the user enters an invalid flight number, Fuzzy */ +"Text.Error.FlightNumberValidationHint" = "Flight number"; + +/* When fetching the user profile fails */ +"Text.Error.GetUserFails" = "There was a problem getting your profile."; + +/* Used to explain an unknown error. ie "Oops, something went wrong. Please try again" */ +"Text.Error.NoDetails" = "Oops, something went wrong. Please try again."; + +"Text.Error.NotLoggedIn" = "You're not signed in"; + +"Text.Error.Payment.Alert.ButtonUpdateCard" = "Update Card"; + +"Text.Error.Payment.Alert.Message" = "We were unable to authorise your credit/debit card."; + +"Text.Error.Payment.Alert.Title" = "Issue With Card"; + +/* Error message when user tries to prebook within the current hour of local time */ +"Text.Error.PrebookingWithinTheHour" = "Prebook cannot be made within the current hour."; + +/* "Something went wrong" used as a title for error alert */ +"Text.Error.SomethingWentWrong" = "Something went wrong"; + +/* Theoretical edge case where the braintree token is missing */ +"Text.Errors.failedToInitialisePaymentSetup" = "Issue with initialising payments, please contact support"; + +"Text.Errors.InvalidPhoneNumber" = "Invalid phone number"; - Copyright © 2020 Karhoo. All rights reserved. - Generics*/ +"Text.Errors.MissingPhoneNumber" = "Empty field not allowed"; + +/* empty table view result */ +"Text.Errors.NoResultsFound" = "No results found"; + +"Text.FeedbackView.addComment" = "Additional comments"; + +"Text.FeedbackView.app" = "How easy did you find using the app?"; + +"Text.FeedbackView.confirmation" = "Thank you for submitting your feedback"; + +"Text.FeedbackView.pob" = "How was your experience whilst in the taxi (e.g. taxi cleanliness, routing and driver)? How easy did you find using the app?"; + +"Text.FeedbackView.pre_pob" = "How was your experience with finding the pick-up location and meeting your driver?"; + +/* FeedBackView */ +"Text.FeedbackView.quote" = "How happy were you with the selection of quotes for your trip (e.g. Fleets, Prices and ETAs)?"; + +"Text.Generic.Add" = "Add"; + +/* "Additional information" used as placeholder on airport details screen */ +"Text.Generic.AdditionalInformation" = "Additional Information"; + +"Text.Generic.Back" = "Back"; + +"Text.Generic.Bookings" = "Bookings"; + +/* Localizable.strings, Karhoo, , Copyright © 2020 Karhoo. All rights reserved., Generics */ "Text.Generic.Cancel" = "Cancel"; -"Text.Generic.Ok" = "OK"; + +/* English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking */ +"Text.Generic.CancellationPolicy" = "Cancellation Policy"; + +/* "Cancelled" */ +"Text.Generic.Cancelled" = "Cancelled"; + +/* english "Card" (referring to payment card) */ +"Text.Generic.Card" = "Card"; + +"Text.Generic.Change" = "Change"; + "Text.Generic.Close" = "Close"; -"Text.Generic.Done" = "Done"; -"Text.Generic.Back" = "Back"; -"Text.Generic.Error" = "Error"; -"Text.Generic.Register" = "Register"; -"Text.Generic.Logout" = "Sign out"; + +"Text.Generic.Comment" = "Comment"; + +"Text.Generic.Comment.Optional" = "Comment (Optional)"; + +/* "Completed" */ +"Text.Generic.Completed" = "Completed"; + "Text.Generic.Contact" = "Contact"; -"Text.Generic.Bookings" = "Bookings"; + +"Text.Generic.Continue" = "Continue"; + "Text.Generic.Destination" = "Destination"; -"Text.Generic.Pickup" = "Pickup"; -"Text.Generic.ETA" = "ETA"; -"Text.Generic.ETALong" = "Estimated arrival time"; -"Text.Generic.EPrice" = "Estimated Price"; -"Text.Generic.Price" = "Price"; -"Text.Generic.Prebook" = "Prebook"; -"Text.Generic.Add" = "Add"; -"Text.Generic.Change" = "Change"; -"Text.Generic.Submit" = "Submit"; -"Text.Generic.Success" = "Success"; -"Text.Generic.Name" = "Name"; -"Text.Generic.Surname" = "Surname"; + +"Text.Generic.Dismiss" = "Dismiss"; + +"Text.Generic.Done" = "Done"; + +/* "Edit" used as a button (call to action) */ +"Text.Generic.Edit" = "Edit"; + "Text.Generic.Email" = "Email address"; -"Text.Generic.PhoneNumber" = "Phone number"; -"Text.Generic.Comment" = "Comment"; -"Text.Generic.Optional" = "Optional"; + +"Text.Generic.EPrice" = "Estimated Price"; + +"Text.Generic.Error" = "Error"; + "Text.Generic.ErrorMessage" = "Oops something went wrong"; -/*english: "creating your Karhoo account". Used in terms conditions construction*/ -"Text.Generic.RegisterAccountAction" = "creating your Karhoo account"; +/* English: "Estimated" */ +"Text.Generic.Estimated" = "Estimated"; + +"Text.Generic.ETA" = "ETA"; -/*english "making a booking". Used in terms conditions construction*/ +"Text.Generic.ETALong" = "Estimated arrival time"; + +/* Reference to fixed pricing.. English equivalent: "Fixed" */ +"Text.Generic.Fixed" = "Fixed"; + +/* "Got It" (generally used on alert buttons) */ +"Text.Generic.GotIt" = "Got It"; + +/* Password Entry Button */ +"Text.Generic.Hide" = "Hide"; + +"Text.Generic.Logout" = "Sign out"; + +/* english "making a booking". Used in terms conditions construction */ "Text.Generic.MakingBookingAction" = "making a booking"; -"Text.Generic.TermsConditions" = "Terms and Conditions"; -"Text.Generic.PrivacyPolicy" = "Privacy Policy"; + +"Text.Generic.MeetGreet" = "Meet and greet"; + +/* Metered fare type displayed in quotes list: English: "Metered" */ +"Text.Generic.Metered" = "Metered"; + "Text.Generic.Minutes" = "min"; -"Text.Generic.Continue" = "Continue"; -/*Address Bar*/ -"Text.AddressBar.AddDestination" = "Add destination"; -"Text.AddressBar.AddPickup" = "Add pickup"; -"Text.AddressBar.EnterPickupLocation" = "Enter pickup location"; -"Text.AddressSearch.EnterDestinationLocation" = "Enter destination location"; +"Text.Generic.Name" = "Name"; -/*User (register / login / user attributes)*/ -"Text.User.FirstName" = "First name"; -"Text.User.LastName" = "Last name"; -"Text.User.Email" = "Email"; -"Text.User.PhoneCountryCode" = "Code"; -"Text.User.MobilePhoneNumber" = "Mobile phone number"; -"Text.User.Password" = "Password"; -"Text.User.EmailSubscription" = "I do not wish to receive free rides, promos or offers"; +"Text.Generic.No" = "No"; -/*Errors*/ -"Text.Error.EmailValidationError" = "Check your email address is spelt correctly"; -"Text.Error.Booking.EnterDestinationToProceed" = "Enter destination to book a ride"; -"Text.Error.NotLoggedIn" = "You're not signed in"; -"Text.TermsConditions.FullString" = "By %1$@, you're agreeing to %2$@'s %3$@ and %4$@"; +"Text.Generic.NoCarsAvailable" = "Unfortunately, no cars are available for your ride at this time.\n\n Please check again soon"; -/*Side Menu*/ -"Text.SideMenu.Login" = "Sign in"; -"Text.SideMenu.SignIn" = "Sign in"; -"Text.SideMenu.Signup" = "Register"; -"Text.SideMenu.Help" = "Help"; -"Text.SideMenu.Feedback" = "Feedback"; +/* The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device" */ +"Text.Generic.NoEmailSetupError" = "Please set up a mail account on your device"; -/*In app email to customer support / feedback*/ -"Text.SupportMailMessage.Feedback" = "Please do not delete this information as it helps us improve the app."; -"Text.SupportMailMessage.ReportIssue" = "Please use the space below to report a specific issue with your ride."; -"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; -"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; -"Text.SupportMailMessage.SupplierEmail" = "suppliers@karhoo.com"; -"Text.SupportMailMessage.FeedbackSubject" = "Feedback"; -"Text.SupportMailMessage.ReportIssueSubject" = "Report Issue"; +"Text.Generic.Ok" = "OK"; -/*Prebook*/ -"Text.Prebook.PrebookPickupTime" = "Prebook Pickup Time"; -"Text.Prebook.SetPrebook" = "Set Pickup Time"; +"Text.Generic.Optional" = "Optional"; -/*Booking*/ -"Text.Booking.RequestCar" = "Book Ride"; -"Text.Booking.RequestingCar" = "Booking Ride"; -"Text.Booking.RequestReceived" = "Booking Received"; -"Text.Bookings.eta" = "ETA"; -"Text.Bookings.price" = "Price"; +/* "Payment" used as a button in the side menu to reach all your payment methods */ +"Text.Generic.Payment" = "Payment"; -/*Trip*/ -"Text.Trip.CancelRide" = "Cancel Ride"; -"Text.Trip.MessageDriver" = "Message driver"; -"Text.Trip.CallDriver" = "Contact Driver"; +/* "Payments" used as the title of the payment method screen */ +"Text.Generic.Payments" = "Payments"; -/*Trip Statuses*/ -"Text.Trip.Requested" = "%1$@ is allocating you a driver. This could take up to 5 minutes."; -"Text.Trip.Confirmed" = "Your booking has been accepted.\nWaiting for a driver to be allocated."; -"Text.Trip.DriverEnRoute" = "Your driver is en route"; -"Text.Trip.DriverArrived" = "Your driver has arrived!"; -"Text.Trip.PassengerOnBoard" = "You're on your way. Have a safe ride!"; -"Text.Trip.Completed" = "You've reached your destination"; -"Text.Trip.CancelledByUser" = "You cancelled the booking"; -"Text.Trip.CancelledByDispatch" = "Your booking has been cancelled."; -"Text.Trip.Completed" = "You've reached your destination. Please take a moment to write some feedback about your ride."; +"Text.Generic.PhoneNumber" = "Phone number"; + +"Text.Generic.Pickup" = "Pickup"; -/*English: "Pickup Time" in booking request screen*/ +/* English: "Pickup Time" in booking request screen */ "Text.Generic.PickupTime" = "Pickup time"; -/*Reference to fixed pricing.. English equivalent: "Fixed"*/ -"Text.Generic.Fixed" = "Fixed"; +"Text.Generic.Prebook" = "Book"; -/*Register on the side menu*/ -"Text.SideMenu.Register" = "Register"; +"Text.Generic.Price" = "Price"; -/*Sign Out on the side menu*/ -"Text.SideMenu.SignOut" = "Sign out"; +"Text.Generic.PrivacyPolicy" = "Privacy Policy"; -/*"Cancelled"*/ -"Text.Generic.Cancelled" = "Cancelled"; +"Text.Generic.Register" = "Register"; -/*"Completed"*/ -"Text.Generic.Completed" = "Completed"; +/* english: "creating your Karhoo account". Used in terms conditions construction */ +"Text.Generic.RegisterAccountAction" = "creating your Karhoo account"; -/*english: "status"*/ -"Text.Generic.Status" = "Status"; +/* English: "Report Issue" */ +"Text.Generic.ReportIssue" = "Report issue"; -/*english: "price"*/ -"Text.Generic.Price" = "Price"; +/* String for when trip is initially loaded and no trip state has yet come through. "Requesting" */ +"Text.Generic.Requesting" = "Requesting"; -/*english "Card" (referring to payment card)*/ -"Text.Generic.Card" = "Card"; +/* used in side menu "Rides" */ +"Text.Generic.Rides" = "Rides"; -/*English: "Report Issue" */ -"Text.Generic.ReportIssue" = "Report issue"; +/* "Save" used as a button (call to action) */ +"Text.Generic.Save" = "Save"; -/*English: "No Trips" used if the booking list screen is empty*/ -"Text.Bookings.NoTrips" = "No rides"; +/* Password Entry Button */ +"Text.Generic.Show" = "Show"; -/*used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B"*/ -"Text.Bookings.NoTripsBookedMessage" = "You have not booked any rides yet. We can help you get from A to B"; +/* english: "status" */ +"Text.Generic.Status" = "Status"; -/*used as a call to action on a button in the empty bookings screen: English: "Book Ride"*/ -"Text.Bookings.BookATrip" = "Book Ride"; +"Text.Generic.Submit" = "Submit"; -/*"Add new card" in english used in the payments section of the app. Referring to credit / debit card*/ -"Text.Payment.AddPaymentMethod" = "Add a Payment Method"; -"Text.Payment.PaymentMethod" = "Card ending"; +"Text.Generic.Success" = "Success"; -/*"Edit" used as a button (call to action) */ -"Text.Generic.Edit" = "Edit"; +"Text.Generic.Surname" = "Surname"; -/*"Save" used as a button (call to action) */ -"Text.Generic.Save" = "Save"; +"Text.Generic.TermsConditions" = "Terms and Conditions"; -/*"Payment" used as a button in the side menu to reach all your payment methods*/ -"Text.Generic.Payment" = "Payment"; +"Text.Generic.TermsOfUse" = "Terms of Use"; -/*"Payments" used as the title of the payment method screen*/ -"Text.Generic.Payments" = "Payments"; +/* "Thanks for your interest" */ +"Text.Generic.Thanks" = "Thanks for your interest"; -/*in english: "Requested"*/ -"Text.GenericTripStatus.Initialised" = "Requested"; +/* Booker cancelled */ +"Text.Generic.TripStatus.BookerCancelled" = "Cancelled"; -/*english: requested*/ -"Text.GenericTripStatus.Requested" = "Requested"; +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "It is taking longer than usual for the fleet to allocate a driver. Please wait, contact the fleet, or cancel and rebook with a different fleet."; -/*Confirmed*/ -"Text.GenericTripStatus.Confirmed" = "Confirmed"; +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Allocation delay"; -/*"Allocated" when a driver has been allocated*/ -"Text.GenericTripStatus.Allocated" = "Allocated"; +/* Driver Cancelled */ +"Text.Generic.TripStatus.DriverCancelled" = "Cancelled by driver/dispatch"; -/*"Driver En Route" when a driver is en route*/ -"Text.GenericTripStatus.EnRoute" = "Driver En Route"; +/* No drivers available */ +"Text.Generic.TripStatus.NoDriversAvailable" = "No Drivers available"; -/*"Driver Approaching"*/ +/* "Unkown" */ +"Text.Generic.Unknown" = "Unknown"; + +"Text.Generic.Yes" = "Yes"; + +/* "Allocated" when a driver has been allocated */ +"Text.GenericTripStatus.Allocated" = "Allocated"; + +/* "Driver Approaching" */ "Text.GenericTripStatus.Approaching" = "Driver Approaching"; -/*Driver Arrived*/ +/* Driver Arrived */ "Text.GenericTripStatus.Arrived" = "Driver Arrived"; -/*"On Board"*/ -"Text.GenericTripStatus.PassengerOnBoard" = "On Board"; +/* "Cancelled" */ +"Text.GenericTripStatus.Cancelled" = "Cancelled"; -/*"Completed" (trip completed)*/ +/* Cancelled by Karhoo */ +"Text.GenericTripStatus.CancelledByKarhoo" = "Cancelled by Karhoo"; + +/* "Completed" (trip completed) */ "Text.GenericTripStatus.Completed" = "Completed"; -/*"Cancelled" */ -"Text.GenericTripStatus.Cancelled" = "Cancelled"; +/* Confirmed */ +"Text.GenericTripStatus.Confirmed" = "Confirmed"; -/*"Failed" */ +/* "Driver En Route" when a driver is en route */ +"Text.GenericTripStatus.EnRoute" = "Driver En Route"; + +/* "Failed" */ "Text.GenericTripStatus.Failed" = "Failed"; -/*"Pending"*/ +/* "Incomplete" */ +"Text.GenericTripStatus.Incomplete" = "Pending State"; + +/* in english: "Requested" */ +"Text.GenericTripStatus.Initialised" = "Requested"; + +/* "On Board" */ +"Text.GenericTripStatus.PassengerOnBoard" = "On Board"; + +/* english: requested */ +"Text.GenericTripStatus.Requested" = "Requested"; + +/* "Pending" */ "Text.GenericTripStatus.Unknown" = "Pending"; -/*"Incomplete"*/ -"Text.GenericTripStatus.Incomplete" = "Pending State"; +"Text.Help.ContactUs.Link" = "https://taxibookermobile.zendesk.com/hc/en-us/requests/new"; -/*"Track Driver"*/ -"Text.Bookings.TrackDriver" = "Track Driver"; +"Text.Help.FAQ.Link" = "https://taxibookermobile.zendesk.com/hc/en-us"; -/*"Contact Driver" (button action)*/ -"Text.Bookings.ContactDriver" = "Contact Driver"; +/* No availability in requested area, Fuzzy */ +"Text.KarhooError.K3002" = "There are no fleets available in this area."; -/*"Contact Fleet"*/ -"Text.Bookings.ContactFleet" = "Contact Fleet"; +"Text.KarhooError.Q0001" = "Pick up and destination cannot be the same."; -/*"Track Trip"*/ -"Text.Bookings.TrackTrip" = "Track Ride"; +/* "Add new card" in english used in the payments section of the app. Referring to credit / debit card */ +"Text.Payment.AddPaymentMethod" = "Add Payment"; -"Text.Bookings.TrackTrip.AlertTitle" = "Ride confirmed"; -"Text.Bookings.TrackTrip.AlertMessage" = "Would you like to track your trip?"; -"Text.Bookings.TrackTrip.TrackAction" = "Track driver"; -"Text.Bookings.TrackTrip.DismissAction" = "Dismiss"; +"Text.Payment.PaymentMethod" = "Card"; -/*"Cancel Ride" button action*/ -"Text.Bookings.CancelRide" = "Cancel Ride"; +/* Prebook */ +"Text.Prebook.PrebookPickupTime" = "Prebook Pickup Time"; -/*"Report Issue" Button*/ -"Text.Bookings.ReportIssue" = "Report Issue"; +"Text.Prebook.SetPrebook" = "Set Pickup Time"; -/*displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking"*/ -"Text.Trip.CancelBookingFailed" = "Cancellation not confirmed, please call supplier"; +/* "Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes */ +"Text.Prebook.TimezoneMessage" = "Booking will be made in local time of pickup (%1$@)"; -/*Used as a button in the trip screen. English: "Ride Options"*/ -"Text.Trip.RideOptions" = "Ride Options"; -"Text.Trip.CancelBookingFailed.AlertTitle" = "Difficulties Cancelling"; -"Text.Trip.CancelBookingFailed.AlertMessage" = "We are experiencing issues cancelling your ride. Please contact the fleet."; -"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Call Fleet"; -"Text.Generic.Yes" = "Yes"; -"Text.Generic.No" = "No"; -"Text.Generic.Dismiss" = "Dismiss"; -"Text.Trip.CancelBookingConfirmation.Alert.Title" = "Cancel your ride?"; -"Text.Trip.CancelBookingConfirmation.Alert.Message" = "You may be charged a cancellation fee by the supplier."; +"Text.Quote.FreeCancellationAndKeyword" = "and"; -/*Call fleet button in trip screen (English: Call Fleet)*/ -"Text.Trip.CallFleet" = "Call Fleet"; -"Text.Trip.ActivityIndicator.Cancelling" = "Cancelling"; +"Text.Quote.FreeCancellationASAP" = "Free cancellation up to %1$@ after booking"; -/*The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device"*/ -"Text.Generic.NoEmailSetupError" = "Please set up a mail account on your device"; -"Text.Trip.CancelledByDispatch.AlertMessage" = "Your booking has been cancelled. Please contact us for more information."; -"Text.Trip.CancelledByDispatch.AlertTitle" = "Cancelled by fleet"; -"Text.Generic.NoCarsAvailable" = "Unfortunately, no cars are available for your ride at this time.\n\n Please check again soon"; +"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Free cancellation until the driver is en route"; + +/* Cancellation info on quotes */ +"Text.Quote.FreeCancellationPrebook" = "Free cancellation up to %1$@ before pickup"; + +"Text.QuoteCategory.Electric" = "Electric"; + +"Text.QuoteCategory.Exec" = "Exec"; + +"Text.QuoteCategory.Executive" = "Executive"; + +"Text.QuoteCategory.Moto" = "Moto"; + +"Text.QuoteCategory.Motorcycle" = "Motorcycle"; + +"Text.QuoteCategory.MPV" = "MPV"; + +"Text.QuoteCategory.Saloon" = "Saloon"; + +"Text.QuoteCategory.Taxi" = "Taxi"; -/*English: "Estimated"*/ -"Text.Generic.Estimated" = "Estimated"; +/* Side Menu "About" section title, Fuzzy */ +"Text.SideMenu.About" = "About"; -/*"Unkown"*/ -"Text.Generic.Unknown" = "Unknown"; +"Text.SideMenu.Feedback" = "Feedback"; -/*"Something went wrong" used as a title for error alert*/ -"Text.Error.SomethingWentWrong" = "Something went wrong"; +"Text.SideMenu.Help" = "Help"; -/*Used to explain an unknown error. ie "Oops, something went wrong. Please try again"*/ -"Text.Error.NoDetails" = "Oops, something went wrong. Please try again."; -"Text.Error.Payment.Alert.Title" = "Issue With Card"; -"Text.Error.Payment.Alert.Message" = "We were unable to authorise your credit/debit card."; -"Text.Error.Payment.Alert.ButtonUpdateCard" = "Update Card"; -"Text.Error.Alert.CantSendEmail" = "Can't send email message. Configure Mail app first."; +/* Side Menu */ +"Text.SideMenu.Login" = "Sign in"; -/*Metered fare type displayed in quotes list: English: "Metered"*/ -"Text.Generic.Metered" = "Metered"; +/* "Profile" button on the side menu */ +"Text.SideMenu.Profile" = "Profile"; -/*English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking*/ -"Text.Generic.CancellationPolicy" = "Cancellation Policy"; +/* Register on the side menu */ +"Text.SideMenu.Register" = "Register"; -/*The title of the alert when user is forced to update ie "App Update Required"*/ -"Text.Error.Alert.ForceUpdateTitle" = "New version available"; +"Text.SideMenu.SignIn" = "Sign in"; -/*The message when the user needs to update the app. ie. "Please update Karhoo to the latest version."*/ -"Text.Error.Alert.ForceUpdateMessage" = "Please update the app to continue."; +/* Sign Out on the side menu */ +"Text.SideMenu.SignOut" = "Sign out"; -/*The action button on the force update alert. ie "Update" (this button takes the user to the app store)*/ -"Text.Error.Alert.ForceUpdateButton" = "Update"; +"Text.SideMenu.Signup" = "Register"; -/*String for when trip is initially loaded and no trip state has yet come through. "Requesting"*/ -"Text.Generic.Requesting" = "Requesting"; -"Text.Booking.EnterDestination" = "Enter destination to see available fleets"; -"Text.Bookings.Quote" = "Quote"; -"Text.Bookings.Price" = "Price"; +/* In app email to customer support / feedback */ +"Text.SupportMailMessage.Feedback" = "Please do not delete this information as it helps us improve the app."; -/*used in side menu "Rides"*/ -"Text.Generic.Rides" = "Rides"; +"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; -/*Generic fallback message for trip load failure*/ -"Text.Bookings.CouldNotLoadTrips" = "Could not load trips."; -"Text.Bookings.Price.Cancelled" = "Cancelled"; -"Text.Bookings.Alert.CancellationSuccess.Title" = "Ride cancellation successful"; -"Text.Bookings.Alert.CancellationSuccess.Message" = "Your trip has been cancelled successfully."; -"Text.Bookings.Alert.CancellationFee.Charge" = "You will be charged a cancellation fee estimated at %1$@.\n\nWould you like to proceed?"; -"Text.Bookings.Alert.CancellationFee.Continue" = "Would you like to proceed?"; +"Text.SupportMailMessage.FeedbackSubject" = "Feedback"; -/*When fetching the user profile fails*/ -"Text.Error.GetUserFails" = "There was a problem getting your profile."; +"Text.SupportMailMessage.NoCoverageBody" = "Thank you for recommending a fleet in your area. To get coverage in your area as fast as possible, please provide us with area and the name of transportation company.\n Area:\n Fleet time:"; -/*"Profile" button on the side menu*/ -"Text.SideMenu.Profile" = "Profile"; +/* No coverage email */ +"Text.SupportMailMessage.NoCoverageSubject" = "Fleet recommendation"; -/*Button for rebooking a ride*/ -"Text.Bookings.RebookRide" = "Rebook Ride"; +"Text.SupportMailMessage.ReportIssue" = "Please use the space below to report a specific issue with your ride."; -/*"Got It" (generally used on alert buttons)*/ -"Text.Generic.GotIt" = "Got It"; +"Text.SupportMailMessage.ReportIssueSubject" = "Report Issue"; -/*"Your final fare might be affected by tips, tolls, taxes, and other charges."*/ -"Text.Booking.BaseFareExplanation" = "Your final fare might be affected by tips, tolls, taxes, and other charges."; +"Text.SupportMailMessage.SupplierEmail" = "suppliers@karhoo.com"; -/*"Additional information" used as placeholder on airport details screen*/ -"Text.Generic.AdditionalInformation" = "Additional Information"; +"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; -/*"Airport Pickup" used on screen for airport bookinga*/ -"Text.Airport.Pickup" = "Airport Pickup"; +/* Used in the checkout component before booking a ride */ +"Text.TermsConditions.BookingFullString" = "By making a booking you agree to the %1$@ | %2$@ and %3$@ %4$@ | %3$@ %5$@."; -/*Message on airport screen for encouraging user to enter as much info about airport booking as possible*/ -"Text.Airport.HelpfulMessage" = "Please enter a valid flight number"; +"Text.TermsConditions.FullString" = "By %1$@, you're agreeing to %2$@'s \n %3$@ | %4$@"; -/*"Flight number" used as the flight number field placeholder*/ -"Text.Airport.FlightNumber" = "Flight Number"; +"Text.TermsConditions.KarhooPolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; -/*"Add Flight Details" used on booking airport ride*/ -"Text.Airport.AddFlightDetails" = "Add Flight Details"; +"Text.TermsConditions.KarhooTermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; -/*"Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes*/ -"Text.Prebook.TimezoneMessage" = "Booking will be made in local time of pickup (%1$@)"; +"Text.TermsConditions.PolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; -/*"Thanks for your interest"*/ -"Text.Generic.Thanks" = "Thanks for your interest"; +"Text.TermsConditions.TermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; -/*"We will notify you via email once your request has been processed."*/ -"Text.User.SignupPendingMessage" = "We will notify you via email once your request has been processed."; +"Text.TrackingLink.production" = "https://agent-portal.karhoo.com/follow/"; -/*Side Menu "About" section title*/ -/*Fuzzy*/ -"Text.SideMenu.About" = "About"; +/* Trip Tracking Links */ +"Text.TrackingLink.sandbox" = "https://agent-portal.sandbox.karhoo.com/follow/"; -/*Error message when user tries to prebook within the current hour of local time*/ -"Text.Error.PrebookingWithinTheHour" = "Prebook cannot be made within the current hour."; +"Text.TrackingLink.staging" = "https://agent-portal.stg.karhoo.net/follow/"; -/*No availability in requested area*/ -/*Fuzzy*/ -"Text.KarhooError.K3002" = "There are no fleets available in this area."; -"Text.KarhooError.Q0001" = "Pick up and destination cannot be the same."; +"Text.Trip.ActivityIndicator.Cancelling" = "Cancelling"; -/*For when demand is too high and there are no drivers available*/ -"Text.Trip.NoDriversAvailable" = "No drivers available"; +/* "Arrival" displayed on arrival box in trip */ +"Text.Trip.Arrival" = "Arrival"; -/*Booker cancelled*/ -"Text.Generic.TripStatus.BookerCancelled" = "Cancelled"; +"Text.Trip.CallDriver" = "Contact Driver"; -/*Driver Cancelled*/ -"Text.Generic.TripStatus.DriverCancelled" = "Cancelled by driver/dispatch"; +/* Call fleet button in trip screen (English: Call Fleet) */ +"Text.Trip.CallFleet" = "Call Fleet"; -/*No drivers available*/ -"Text.Trip.NoDriversAvailable" = "There are no drivers available"; +"Text.Trip.CancelBookingConfirmation.Alert.Message" = "You may be charged a cancellation fee by the supplier."; -/*No drivers available*/ -"Text.Generic.TripStatus.NoDriversAvailable" = "No Drivers available"; +"Text.Trip.CancelBookingConfirmation.Alert.Title" = "Cancel your ride?"; -/*"Driver Allocation Delay Title"*/ -"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Allocation delay"; +/* displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking" */ +"Text.Trip.CancelBookingFailed" = "Cancellation not confirmed, please call supplier"; -/*"Driver Allocation Delay Title"*/ -"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "It is taking longer than usual for the fleet to allocate a driver. Please wait, contact the fleet, or cancel and rebook with a different fleet."; +"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Call Fleet"; -/*"Trip Summary" header used on screen*/ -"Text.TripSummary.TripSummary" = "Ride Summary"; +"Text.Trip.CancelBookingFailed.AlertMessage" = "We are experiencing issues cancelling your ride. Please contact the fleet."; -/*"Payment Summary" header used on Trip Summary Screen*/ -"Text.TripSummary.PaymentSummary" = "Payment Summary"; +"Text.Trip.CancelBookingFailed.AlertTitle" = "Difficulties Cancelling"; -/*Used for the "Book Return Ride" button on the trip summary screen*/ -"Text.TripSummary.BookReturnRide" = "Book Return Ride"; +"Text.Trip.CancelledByDispatch" = "Your booking has been cancelled."; -/*"Date"*/ -"Text.TripSummary.Date" = "Date"; +"Text.Trip.CancelledByDispatch.AlertMessage" = "Your booking has been cancelled. Please contact us for more information."; -/*Fleet*/ -"Text.TripSummary.Fleet" = "Fleet"; -"Text.TripSummary.Vehicle" = "Vehicle"; +"Text.Trip.CancelledByDispatch.AlertTitle" = "Cancelled by fleet"; -/*Total Fare*/ -"Text.TripSummary.TotalFare" = "Total Fare"; +"Text.Trip.CancelledByUser" = "You cancelled the booking"; -/*Popup title message when dispatch cancels due to no drivers*/ -"Text.Trip.NoDriversAvailable.AlertTitle" = "Booking Failed"; +/* Trip */ +"Text.Trip.CancelRide" = "Cancel Ride"; -/*Alert message in popup when dispatch cancels due to no drivers*/ -"Text.Trip.NoDriversAvailable.AlertMessage" = "Sorry, demand is high. %1$@ currently has no available drivers."; +"Text.Trip.Completed" = "You've reached your destination"; -/*Password Entry Button*/ -"Text.Generic.Hide" = "Hide"; +"Text.Trip.Confirmed" = "Your booking has been accepted.\nWaiting for a driver to be allocated."; -/*Password Entry Button*/ -"Text.Generic.Show" = "Show"; +"Text.Trip.DriverArrived" = "Your driver has arrived!"; -/*"Quoted Price": used in trip summary screen when the fare is not available*/ -"Text.TripSummary.QuotedPrice" = "Quoted Price"; +"Text.Trip.DriverEnRoute" = "Your driver is en route"; -/*Base fare title*/ -"Text.Booking.BaseFare" = "Base Fare"; +/* alert message when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertMessage" = "There was a problem making this booking. Please try again or contact support."; -/*Guest checkout*/ -"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Passenger Details"; -"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Payment Details"; -"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Your driver will wait for you"; +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertTitle" = "Problem Booking"; -/*Prebook Done*/ -/*Fuzzy*/ -"Text.Booking.PrebookConfirmed" = "Prebook Confirmed"; +"Text.Trip.MessageDriver" = "Message driver"; -/*Ride Details*/ -"Text.Booking.PrebookConfirmed.RideDetails" = "Ride Details"; +/* For when demand is too high and there are no drivers available */ +"Text.Trip.NoDriversAvailable" = "No drivers available"; -/* We’re not live here yet! */ -"Text.Booking.NoAvailabilityHeader" = "We’re not live here yet!"; +/* Alert message in popup when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertMessage" = "Sorry, demand is high. %1$@ currently has no available drivers."; -/* %1$@ if you have suggestions for local fleets. */ -"Text.Booking.NoAvailabilityBody" = "%1$@ if you have suggestions for local fleets."; +/* Popup title message when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertTitle" = "Booking Failed"; -/* Get in touch */ -"Text.Booking.NoAvailabilityLink" = "Get in touch"; +"Text.Trip.PassengerOnBoard" = "You're on your way. Have a safe ride!"; -/* Finding your ride... */ -"Text.TripAllocation.FindingYourRide" = "Finding your ride..."; +/* Trip Statuses */ +"Text.Trip.Requested" = "%1$@ is allocating you a driver. This could take up to 5 minutes."; + +/* Used as a button in the trip screen. English: "Ride Options" */ +"Text.Trip.RideOptions" = "Ride Options"; /* Please wait whilst you\'re allocated a driver */ "Text.TripAllocation.AllocatingTripOne" = "Please wait whilst you\'re allocated a driver"; @@ -435,151 +765,98 @@ /* This may take a moment or two */ "Text.TripAllocation.AllocatingTripTwo" = "This may take a moment or two"; -"Text.TripAllocation.Cancelling" = "Cancelling"; "Text.TripAllocation.CancelInstruction" = "Tap and hold to cancel"; -/*"Past" used on past tabs on bookings list*/ -"Text.Bookings.Past" = "Past"; +"Text.TripAllocation.Cancelling" = "Cancelling"; -/*Upcoming: used on upcoming tabs for rides*/ -/*Fuzzy*/ -"Text.Bookings.Upcoming" = "Upcoming"; +/* Finding your ride... */ +"Text.TripAllocation.FindingYourRide" = "Finding your ride..."; -/*"All" used for all categories filter on category list. Write normally as the app will uppercase the string*/ -"Text.Availability.AllCategory" = "All"; -"SALOON" = "Saloon"; -"MPV" = "MPV"; -"EXEC" = "Exec"; -"TAXI" = "Taxi"; -"ELECTRIC" = "Electric"; +/* Trip Rating */ +"Text.TripRating.Confirmation" = "Thank you for submitting your Rating."; -/*Cancelled by Karhoo*/ -"Text.GenericTripStatus.CancelledByKarhoo" = "Cancelled by Karhoo"; +"Text.TripRating.ExtraFeedback" = "Tell us more"; -/*alert title when karhoo cancel the trip-supposedly happens for preauth failure*/ -"Text.Trip.KarhooCancelled.AlertTitle" = "Problem Booking"; +"Text.TripRating.Title" = "How would you rate your trip?"; -/*alert message when karhoo cancel the trip-supposedly happens for preauth failure*/ -"Text.Trip.KarhooCancelled.AlertMessage" = "There was a problem making this booking. Please try again or contact support."; +/* Used for the "Book Return Ride" button on the trip summary screen */ +"Text.TripSummary.BookReturnRide" = "Book Return Ride"; -/*When the user enters an invalid flight number*/ -/*Fuzzy*/ -"Text.Error.FlightNumberValidationHint" = "Flight number"; +/* "Date" */ +"Text.TripSummary.Date" = "Date"; -/*"Arrival" displayed on arrival box in trip*/ -"Text.Trip.Arrival" = "Arrival"; +/* Fleet */ +"Text.TripSummary.Fleet" = "Fleet"; -/*Theoretical edge case where the braintree token is missing*/ -"Text.Errors.failedToInitialisePaymentSetup" = "Issue with initialising payments, please contact support"; +/* "Payment Summary" header used on Trip Summary Screen */ +"Text.TripSummary.PaymentSummary" = "Payment Summary"; -/*Text used on button to trigger password reset... English: Forgotten Password? */ +/* "Quoted Price": used in trip summary screen when the fare is not available */ +"Text.TripSummary.QuotedPrice" = "Quoted Price"; + +/* Total Fare */ +"Text.TripSummary.TotalFare" = "Total Fare"; + +/* "Trip Summary" header used on screen */ +"Text.TripSummary.TripSummary" = "Ride Summary"; + +"Text.TripSummary.Vehicle" = "Vehicle"; + +"Text.User.Email" = "Email"; + +"Text.User.EmailSubscription" = "I do not wish to receive free rides, promos or offers"; + +/* User (register / login / user attributes) */ +"Text.User.FirstName" = "First name"; + +/* Text used on button to trigger password reset... English: Forgotten Password? */ "Text.User.ForgottenPassword" = "Forgotten password?"; -/* empty table view result */ -"Text.Errors.NoResultsFound" = "No results found"; +"Text.User.LastName" = "Last name"; -"Text.Availability.NoQuotesInSelectedCategory" = "There are no quotes for this category. \n Please choose another category."; -"Text.Availability.NoQuotesForSelectedParameters" = "No availability for the requested time. Please choose a different time."; +"Text.User.MobilePhoneNumber" = "Mobile phone number"; -"Text.Address.NoRecentAddress" = "No recent results"; +"Text.User.Password" = "Password"; -/* No coverage email */ -"Text.SupportMailMessage.NoCoverageSubject" = "Fleet recommendation"; -"Text.SupportMailMessage.NoCoverageBody" = "Thank you for recommending a fleet in your area. To get coverage in your area as fast as possible, please provide us with area and the name of transportation company.\n Area:\n Fleet time: "; +"Text.User.PhoneCountryCode" = "Code"; -/* Cancellation info on quotes */ -"Text.Quote.FreeCancellationPrebook" = "Free cancellation up to %1$@ before pickup"; -"Text.Quote.FreeCancellationASAP" = "Free cancellation up to %1$@ after booking"; -"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Free cancellation until the driver is en route"; -"Text.Quote.FreeCancellationAndKeyword" = "and"; +/* "We will notify you via email once your request has been processed." */ +"Text.User.SignupPendingMessage" = "We will notify you via email once your request has been processed."; -/*English: Error codes */ -"K0001" = "General request error"; -"K0002" = "Invalid request payload"; -"K0003" = "Could not read authorisation token"; -"K0004" = "Authentication is required for this path"; -"K0005" = "Missing required role for this request"; -"K0006" = "Rate limit exceeded"; -"K0007" = "Circuit breaker has triggered for this route"; +"Text.VehicleClass.Electric" = "Electric"; -/* User errors, K1xxx */ -"K1001" = "Could not register user"; -"K1002" = "Could not register user (user already exists)"; -"K1003" = "Could not register user (invalid request)"; -"K1004" = "Could not register user (invalid phone number)"; -"K1005" = "Could not get user details (invalid token)"; -"K1006" = "Could not get user details (user does not exist)"; -"K1999" = "User has been created but not been authorized yet, we will get in touch once enabled."; +"Text.VehicleClass.Exec" = "Exec"; -/* Locations errors, K2xxx */ -"K2001" = "Could not get address"; +"Text.VehicleClass.Executive" = "Executive"; -/* Quotes errors, K3xxx */ -"K3001" = "Could not get estimates"; -"K3002" = "Could not get estimates (no availability found within requested area)"; -"K3003" = "Could not get estimates (could not find specified quote)"; +"Text.VehicleClass.Moto" = "Moto"; -/* Bookings errors, K4xxx */ -"K4001" = "Could not book trip"; -"K4002" = "Could not book trip - invalid request payload (require at least 1 set of passenger-details)"; -"K4003" = "Could not book trip (could not find specified quote)"; -"K4004" = "Could not book trip (attempt to book an expired quote)"; -"K4005" = "Could not book trip (permission denied)"; -"K4006" = "Could not book trip (payment pre-authorisation failed)"; -"K4007" = "Could not cancel trip"; -"K4008" = "Could not cancel trip (could not find specified trip)"; -"K4009" = "Could not cancel trip (permission denied)"; -"K4010" = "Could not cancel trip (already cancelled)"; -"K4011" = "Could not get trip"; -"K4012" = "Could not get trip (could not find specified trip)"; -"K4013" = "Could not get trip (permission denied)"; -"K4014" = "Could not book trip as agent"; -"K4015" = "Could not book trip as traveller"; -"K4018" = "Could not book trip as this quote is no longer available"; +"Text.VehicleClass.Motorcycle" = "Motorcycle"; -/* Availability errors, K5xxx */ -"K5001" = "Could not get estimates"; -"K5002" = "Could not get availability (no availability found within requested area)"; -"K5003" = "Could not get availability (no categories found within requested area)"; +"Text.VehicleClass.MPV" = "MPV"; -/* Authentication errors K6xxx */ -"K6001" = "Invalid email or Password. Please try again"; +"Text.VehicleClass.Saloon" = "Saloon"; -/* KPOI errors, K7xxx */ -"K7001" = "Could not process KPOI request"; -"K7002" = "Could not find Karhoo POI with matching ID"; -"K7003" = "Could not read Karhoo POI"; -"K7004" = "Could not write Karhoo POI"; -"K7005" = "Could not delete Karhoo POI"; +"Text.VehicleClass.Taxi" = "Taxi"; -/* KSDKxxx Internal SDK */ -"KSDK01" = "Something went wrong but we don't know what it was"; -"KSDK02" = "Missing user permissions"; -"KSDK03" = "User already logged in"; +"Text.VehicleTag.Childseat" = "Child-seat"; -/* PickUp Type */ -"DEFAULT" = "Default"; -"MEET_AND_GREET" = "Meet and Greet"; -"CURBSIDE" = "Curbside"; -"STAND_BY" = "Stand by"; +/* Vehicle tags */ +"Text.VehicleTag.Electric" = "Electric"; -/* Trip Rating */ -"Text.TripRating.Confirmation" = "Thank you for submitting your Rating."; -"Text.TripRating.Title" = "How would you rate your trip?"; -"Text.TripRating.ExtraFeedback" = "Tell us more"; +"Text.VehicleTag.Executive" = "Executive"; -/* FeedBackView */ -"Text.FeedbackView.quote" = "How happy were you with the selection of quotes for your trip (e.g. Fleets, Prices and ETAs)?"; -"Text.FeedbackView.pre_pob" = "How was your experience with finding the pick-up location and meeting your driver?"; -"Text.FeedbackView.pob" = "How was your experience whilst in the taxi (e.g. taxi cleanliness, routing and driver)? How easy did you find using the app?"; -"Text.FeedbackView.app" = "How easy did you find using the app?"; -"Text.FeedbackView.addComment" = "Additional comments"; -"Text.FeedbackView.confirmation" = "Thank you for submitting your feedback"; +"Text.VehicleTag.Hybrid" = "Hybrid"; -"Text.Address.SetOnMap" = "Set on map"; -"Text.Address.CurrentLocation" = "Current location"; +"Text.VehicleTag.Taxi" = "Taxi"; + +"Text.VehicleTag.Wheelchair" = "Wheelchair"; + +"Text.VehicleType.Bus" = "Bus"; + +"Text.VehicleType.Moto" = "Moto"; + +"Text.VehicleType.MPV" = "MPV"; + +"Text.VehicleType.Standard" = "Standard"; -/* Trip Tracking Links */ -"Text.TrackingLink.sandbox" = "https://agent-portal.sandbox.karhoo.com/follow/"; -"Text.TrackingLink.production" = "https://agent-portal.karhoo.com/follow/"; -"Text.TrackingLink.staging" = "https://agent-portal.stg.karhoo.net/follow/"; diff --git a/KarhooUISDK/Translations/de.lproj/Localizable.strings b/KarhooUISDK/Translations/de.lproj/Localizable.strings new file mode 100644 index 000000000..73af35717 --- /dev/null +++ b/KarhooUISDK/Translations/de.lproj/Localizable.strings @@ -0,0 +1,862 @@ +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Problem Buchung"; + +"CURBSIDE" = "Bordsteinkante"; + +/* PickUp Type */ +"DEFAULT" = "Standard"; + +"ELECTRIC" = "Elektrisch"; + +/* English: Error codes */ +"K0001" = "Allgemeiner Anfragefehler"; + +"K0002" = "Ungültiger Request-Payload"; + +"K0003" = "Autorisierungs-Token konnte nicht gelesen werden"; + +"K0004" = "Für diesen Pfad ist eine Authentifizierung erforderlich"; + +"K0005" = "Fehlende erforderliche Rolle für diese Anfrage"; + +"K0006" = "Ratengrenze überschritten"; + +"K0007" = "Der Leistungsschalter für diese Strecke hat ausgelöst"; + +/* User errors, K1xxx */ +"K1001" = "Benutzer konnte nicht registriert werden"; + +"K1002" = "Benutzer konnte nicht registriert werden (Benutzer existiert bereits)"; + +"K1003" = "Benutzer konnte nicht registriert werden (ungültige Anfrage)."; + +"K1004" = "Benutzer konnte nicht registriert werden (ungültige Telefonnummer)"; + +"K1005" = "Konnte keine Benutzerdetails erhalten (ungültiges Token)"; + +"K1006" = "Benutzerdetails konnten nicht abgerufen werden (Benutzer existiert nicht)"; + +"K1999" = "Der Benutzer wurde erstellt, aber noch nicht autorisiert. Wir werden uns melden, sobald er aktiviert ist."; + +/* Locations errors, K2xxx */ +"K2001" = "Adresse konnte nicht ermittelt werden"; + +/* Quotes errors, K3xxx */ +"K3001" = "Konnte keine Schätzungen erhalten"; + +"K3002" = "Kein Kostenvoranschlag möglich (keine Verfügbarkeit im angefragten Gebiet gefunden)"; + +"K3003" = "Kann keinen Kostenvoranschlag erhalten (konnte kein bestimmtes Angebot finden)"; + +/* Bookings errors, K4xxx */ +"K4001" = "Konnte keine Reise buchen"; + +"K4002" = "Reise konnte nicht gebucht werden - ungültiger Request Payload (erfordert mindestens 1 Satz Passagierdaten)"; + +"K4003" = "Konnte keine Reise buchen (konnte kein bestimmtes Angebot finden)"; + +"K4004" = "Reise konnte nicht gebucht werden (Versuch, ein abgelaufenes Angebot zu buchen)"; + +"K4005" = "Konnte keine Reise buchen (Genehmigung verweigert)"; + +"K4006" = "Reise konnte nicht gebucht werden (Vorautorisierung der Zahlung fehlgeschlagen)"; + +"K4007" = "Kann die Reise nicht stornieren"; + +"K4008" = "Die Reise konnte nicht storniert werden (die angegebene Reise konnte nicht gefunden werden)"; + +"K4009" = "Reise konnte nicht storniert werden (Erlaubnis verweigert)"; + +"K4010" = "Reise kann nicht storniert werden (bereits storniert)"; + +"K4011" = "Konnte keine Reise bekommen"; + +"K4012" = "Kann keine Reise abrufen (konnte die angegebene Reise nicht finden)"; + +"K4013" = "Die Reise konnte nicht angetreten werden (Erlaubnis verweigert)"; + +"K4014" = "Konnte als Agent keine Reise buchen"; + +"K4015" = "Konnte als Reisender keine Reise buchen"; + +"k4015" = "Konnte als Reisender keine Reise buchen"; + +"K4018" = "Die Reise konnte nicht gebucht werden, da dieses Angebot nicht mehr verfügbar ist."; + +"K4020" = "Konnte keine Reise mit dem ausgewählten DMS buchen"; + +"K4025" = "Angebotspreis während der Buchung erhöht"; + +/* Availability errors, K5xxx */ +"K5001" = "Konnte keine Schätzungen erhalten"; + +"K5002" = "Keine Verfügbarkeit (keine Verfügbarkeit im gewünschten Bereich gefunden)"; + +"K5003" = "Keine Verfügbarkeit (keine Kategorien im gewünschten Bereich gefunden)"; + +/* Authentication errors K6xxx */ +"K6001" = "E-Mail oder Passwort ungültig. Bitte versuchen Sie es erneut"; + +/* KPOI errors, K7xxx */ +"K7001" = "KPOI-Anfrage konnte nicht verarbeitet werden"; + +"K7002" = "Karhoo POI mit passender ID konnte nicht gefunden werden"; + +"K7003" = "Konnte Karhoo POI nicht lesen"; + +"K7004" = "Karhoo POI konnte nicht geschrieben werden"; + +"K7005" = "Karhoo POI konnte nicht gelöscht werden"; + +/* KSDKxxx Internal SDK */ +"KSDK01" = "Etwas ist schief gelaufen, aber wir wissen nicht, was es war."; + +"KSDK02" = "Fehlende Benutzerberechtigungen"; + +"KSDK03" = "Benutzer bereits eingeloggt"; + +"MEET_AND_GREET" = "Treffen und Begrüßung"; + +/* Qxxxx errors */ +"Q0001" = "Abholort und Zielort können nicht identisch sein."; + +"STAND_BY" = "Bereitschaft"; + +/* "Version" */ +"Text.About.Version" = "Version"; + +"Text.Address.CurrentLocation" = "Aktueller Standort"; + +"Text.Address.NoRecentAddress" = "Keine aktuellen Ergebnisse"; + +"Text.Address.SetOnMap" = "Auf Karte setzen"; + +/* Address Bar */ +"Text.AddressBar.AddDestination" = "Ziel hinzufügen"; + +"Text.AddressBar.AddPickup" = "Abholung hinzufügen"; + +"Text.AddressBar.EnterPickupLocation" = "Abholort eingeben"; + +"Text.AddressSearch.EnterDestinationLocation" = "Zielort eingeben"; + +/* "Add Flight Details" used on booking airport ride */ +"Text.Airport.AddFlightDetails" = "Flugdetails hinzufügen"; + +/* "Flight number" used as the flight number field placeholder */ +"Text.Airport.FlightNumber" = "Flugnummer"; + +/* Message on airport screen for encouraging user to enter as much info about airport booking as possible */ +"Text.Airport.HelpfulMessage" = "Bitte geben Sie eine gültige Flugnummer ein"; + +/* "Airport Pickup" used on screen for airport bookinga */ +"Text.Airport.Pickup" = "Abholung vom Flughafen"; + +/* "All" used for all categories filter on category list. Write normally as the app will uppercase the string */ +"Text.Availability.AllCategory" = "Alle"; + +"Text.Availability.NoQuotesForSelectedParameters" = "Keine Verfügbarkeit für die gewünschte Zeit. Bitte wählen Sie eine andere Zeit."; + +"Text.Availability.NoQuotesInSelectedCategory" = "Es gibt keine Angebote für diese Kategorie.\nBitte wählen Sie eine andere Kategorie."; + +/* Base fare title */ +"Text.Booking.BaseFare" = "Grundtarif"; + +/* "Your final fare might be affected by tips, tolls, taxes, and other charges." */ +"Text.Booking.BaseFareExplanation" = "Ihr Endpreis kann durch Trinkgelder, Mautgebühren, Steuern und andere Abgaben beeinflusst werden."; + +"Text.Booking.CountryCodeSelection.Search" = "Land/Region suchen"; + +/* Country Code Selection */ +"Text.Booking.CountryCodeSelection.Title" = "Land / Region"; + +"Text.Booking.EnterDestination" = "Zielort eingeben, um verfügbare Flotten zu sehen"; + +/* Checkout component */ +"Text.Booking.EstimatedInfoBox" = "Diese Flotte ist ein nicht reguliertes Taxi. Der Kostenvoranschlag ist eine Schätzung auf der Grundlage der Fahrtfaktoren (Entfernung, Zeit usw.). Weitere Informationen entnehmen Sie bitte den Allgemeinen Geschäftsbedingungen der Flotte."; + +"Text.Booking.FixedInfoBox" = "Diese Flotte berechnet einen Pauschaltarif. Der Endpreis kann durch Extras (Mautgebühren, Verspätungen usw.) beeinflusst werden, bitte prüfen Sie die Allgemeinen Geschäftsbedingungen der Flotte."; + +"Text.Booking.FlightTracking" = "Flugverfolgung"; + +"Text.Booking.GPSTracking" = "GPS-Ortung"; + +"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Flugnummer (fakultativ)"; + +/* Guest checkout */ +"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Passagier-Details"; + +"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Zahlungsarten"; + +"Text.Booking.LearnMore" = "Erfahren Sie mehr"; + +"Text.Booking.MaximumLuggages" = "%1$@ Gepäckstücke maximal"; + +"Text.Booking.MaximumPassengers" = "%1$@ Passagiere maximal"; + +"Text.Booking.MeteredInfoBox" = "Bei dieser Flotte handelt es sich um ein reguliertes Sammeltaxi. Der Kostenvoranschlag ist eine Schätzung auf der Grundlage der Reisefaktoren (Entfernung, Zeit, etc.)."; + +"Text.Booking.Next" = "Weiter"; + +/* %1$@ if you have suggestions for local fleets. */ +"Text.Booking.NoAvailabilityBody" = "%1$@ wenn Sie Vorschläge für lokale Flotten haben."; + +/* We’re not live here yet! */ +"Text.Booking.NoAvailabilityHeader" = "Wir sind hier noch nicht live!"; + +/* Get in touch */ +"Text.Booking.NoAvailabilityLink" = "Nehmen Sie Kontakt auf"; + +"Text.Booking.Passenger" = "Passagier"; + +"Text.Booking.PassengerDetails.Add" = "Passagier hinzufügen"; + +"Text.Booking.PassengerDetails.Email" = "E-Mail"; + +"Text.Booking.PassengerDetails.FirstName" = "Vorname"; + +"Text.Booking.PassengerDetails.LastName" = "Nachname"; + +"Text.Booking.PassengerDetails.MobilePhone" = "Nummer des Mobiltelefons"; + +"Text.Booking.PassengerDetails.SaveAction" = "Speichern"; + +"Text.Booking.PassengerDetails.Subtitle" = "Diese Informationen ermöglichen einen reibungslosen Ablauf Ihrer Fahrt."; + +/* Passenger Details */ +"Text.Booking.PassengerDetails.Title" = "Passagier"; + +/* Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked */ +"Text.Booking.PrebookConfirmation" = "Ihre Buchung: von: %1$@\nbis: %2$@\nat: %3$@\nh wurde gebucht"; + +/* Prebook Done, Fuzzy */ +"Text.Booking.PrebookConfirmed" = "Vormerkung Bestätigt"; + +/* Ride Details */ +"Text.Booking.PrebookConfirmed.RideDetails" = "Details zur Fahrt"; + +/* Booking */ +"Text.Booking.RequestCar" = "Buchen Sie"; + +"Text.Booking.RequestingCar" = "Fahrt buchen"; + +"Text.Booking.RequestReceived" = "Erhaltene Buchung"; + +"Text.Booking.TrainTracking" = "Zugverfolgung"; + +"Text.Bookings.Alert.CancellationFee.Charge" = "Ihnen wird eine Stornierungsgebühr in Rechnung gestellt, die auf %1$@ geschätzt wird.\n\nMöchten Sie fortfahren?"; + +"Text.Bookings.Alert.CancellationFee.Continue" = "Möchten Sie fortfahren?"; + +"Text.Bookings.Alert.CancellationSuccess.Message" = "Ihre Reise wurde erfolgreich storniert."; + +"Text.Bookings.Alert.CancellationSuccess.Title" = "Fahrtabsage erfolgreich"; + +/* used as a call to action on a button in the empty bookings screen: English: "Book Ride" */ +"Text.Bookings.BookATrip" = "Fahrt buchen"; + +/* "Cancel Ride" button action */ +"Text.Bookings.CancelRide" = "Fahrt abbrechen"; + +/* "Contact Driver" (button action) */ +"Text.Bookings.ContactDriver" = "Kontakt Fahrer"; + +/* "Contact Fleet" */ +"Text.Bookings.ContactFleet" = "Kontakt Flotte"; + +/* Generic fallback message for trip load failure */ +"Text.Bookings.CouldNotLoadTrips" = "Es konnten keine Reisen geladen werden."; + +"Text.Bookings.eta" = "Geschätzte Ankunft"; + +/* English: "No Trips" used if the booking list screen is empty */ +"Text.Bookings.NoTrips" = "Keine Fahrten"; + +/* used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B" */ +"Text.Bookings.NoTripsBookedMessage" = "Sie haben noch keine Fahrten gebucht. Wir können Ihnen helfen, von A nach B zu kommen"; + +/* "Past" used on past tabs on bookings list */ +"Text.Bookings.Past" = "Vergangene"; + +"Text.Bookings.price" = "Preis"; + +"Text.Bookings.Price" = "Preis"; + +"Text.Bookings.Price.Cancelled" = "Abgebrochen"; + +"Text.Bookings.Quote" = "Zitat"; + +/* Button for rebooking a ride */ +"Text.Bookings.RebookRide" = "Rebooking-Fahrt"; + +/* "Report Issue" Button */ +"Text.Bookings.ReportIssue" = "Ausgabe melden"; + +/* "Track Driver" */ +"Text.Bookings.TrackDriver" = "Lokführer"; + +/* "Track Trip" */ +"Text.Bookings.TrackTrip" = "Bahnfahrt"; + +"Text.Bookings.TrackTrip.AlertMessage" = "Möchten Sie das Fahrzeug verfolgen?"; + +"Text.Bookings.TrackTrip.AlertTitle" = "Der Fahrer ist auf dem Weg"; + +"Text.Bookings.TrackTrip.DismissAction" = "Nein"; + +"Text.Bookings.TrackTrip.TrackAction" = "Ja"; + +/* Upcoming: used on upcoming tabs for rides, Fuzzy */ +"Text.Bookings.Upcoming" = "Demnächst"; + +"Text.Error.Alert.CantSendEmail" = "Kann keine E-Mail-Nachricht senden. Konfigurieren Sie zuerst die Mail-App."; + +/* The action button on the force update alert. ie "Update" (this button takes the user to the app store) */ +"Text.Error.Alert.ForceUpdateButton" = "Update"; + +/* The message when the user needs to update the app. ie. "Please update Karhoo to the latest version." */ +"Text.Error.Alert.ForceUpdateMessage" = "Bitte aktualisieren Sie die App, um fortzufahren."; + +/* The title of the alert when user is forced to update ie "App Update Required" */ +"Text.Error.Alert.ForceUpdateTitle" = "Neue Version verfügbar"; + +"Text.Error.Booking.EnterDestinationToProceed" = "Zielort eingeben, um eine Fahrt zu buchen"; + +/* Errors */ +"Text.Error.EmailValidationError" = "Überprüfen Sie die korrekte Schreibweise Ihrer E-Mail-Adresse"; + +/* When the user enters an invalid flight number, Fuzzy */ +"Text.Error.FlightNumberValidationHint" = "Flugnummer"; + +/* When fetching the user profile fails */ +"Text.Error.GetUserFails" = "Es gab ein Problem beim Abrufen Ihres Profils."; + +/* Used to explain an unknown error. ie "Oops, something went wrong. Please try again" */ +"Text.Error.NoDetails" = "Ups, da ist etwas schief gelaufen. Bitte versuchen Sie es erneut."; + +"Text.Error.NotLoggedIn" = "Sie sind nicht eingeloggt"; + +"Text.Error.Payment.Alert.ButtonUpdateCard" = "Karte aktualisieren"; + +"Text.Error.Payment.Alert.Message" = "Wir konnten Ihre Kredit-/Debitkarte nicht autorisieren."; + +"Text.Error.Payment.Alert.Title" = "Problem mit der Karte"; + +/* Error message when user tries to prebook within the current hour of local time */ +"Text.Error.PrebookingWithinTheHour" = "Vormerkungen können nicht innerhalb der aktuellen Stunde vorgenommen werden."; + +/* "Something went wrong" used as a title for error alert */ +"Text.Error.SomethingWentWrong" = "Es ist ein Fehler aufgetreten."; + +/* Theoretical edge case where the braintree token is missing */ +"Text.Errors.failedToInitialisePaymentSetup" = "Problem mit der Initialisierung von Zahlungen, bitte kontaktieren Sie den Support"; + +"Text.Errors.InvalidPhoneNumber" = "Ungültige Telefonnummer"; + +"Text.Errors.MissingPhoneNumber" = "Leeres Feld nicht erlaubt"; + +/* empty table view result */ +"Text.Errors.NoResultsFound" = "Keine Ergebnisse gefunden"; + +"Text.FeedbackView.addComment" = "Zusätzliche Bemerkungen"; + +"Text.FeedbackView.app" = "Wie einfach war es für Sie, die App zu benutzen?"; + +"Text.FeedbackView.confirmation" = "Vielen Dank für Ihr Feedback"; + +"Text.FeedbackView.pob" = "Wie war Ihre Erfahrung im Taxi (z. B. Sauberkeit des Taxis, Streckenführung und Fahrer)? Wie einfach war es für Sie, die App zu nutzen?"; + +"Text.FeedbackView.pre_pob" = "Wie war Ihre Erfahrung mit der Suche nach dem Abholort und dem Treffen mit dem Fahrer?"; + +/* FeedBackView */ +"Text.FeedbackView.quote" = "Wie zufrieden waren Sie mit der Auswahl der Angebote für Ihre Reise (z. B. Flotten, Preise und ETAs)?"; + +"Text.Generic.Add" = "Hinzufügen"; + +/* "Additional information" used as placeholder on airport details screen */ +"Text.Generic.AdditionalInformation" = "Zusätzliche Informationen"; + +"Text.Generic.Back" = "Zurück"; + +"Text.Generic.Bookings" = "Buchungen"; + +/* Localizable.strings, Karhoo, , Copyright © 2020 Karhoo. All rights reserved., Generics */ +"Text.Generic.Cancel" = "Abbrechen"; + +/* English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking */ +"Text.Generic.CancellationPolicy" = "Stornierungsbedingungen"; + +/* "Cancelled" */ +"Text.Generic.Cancelled" = "Abgebrochen"; + +/* english "Card" (referring to payment card) */ +"Text.Generic.Card" = "Karte"; + +"Text.Generic.Change" = "CHANGE"; + +"Text.Generic.Close" = "Schließen"; + +"Text.Generic.Comment" = "Kommentar"; + +"Text.Generic.Comment.Optional" = "Kommentar (fakultativ)"; + +/* "Completed" */ +"Text.Generic.Completed" = "Abgeschlossen"; + +"Text.Generic.Contact" = "Kontakt"; + +"Text.Generic.Continue" = "Weitermachen"; + +"Text.Generic.Destination" = "Zielort"; + +"Text.Generic.Dismiss" = "DISMISS"; + +"Text.Generic.Done" = "Erledigt"; + +/* "Edit" used as a button (call to action) */ +"Text.Generic.Edit" = "Bearbeiten"; + +"Text.Generic.Email" = "Die E-Mail-Adresse"; + +"Text.Generic.EPrice" = "Geschätzter Preis"; + +"Text.Generic.Error" = "Fehler"; + +"Text.Generic.ErrorMessage" = "Ups, da ist etwas schief gelaufen"; + +/* English: "Estimated" */ +"Text.Generic.Estimated" = "Geschätzt"; + +"Text.Generic.ETA" = "Geschätzte Ankunft"; + +"Text.Generic.ETALong" = "Geschätzte Ankunftszeit"; + +/* Reference to fixed pricing.. English equivalent: "Fixed" */ +"Text.Generic.Fixed" = "Fest"; + +/* "Got It" (generally used on alert buttons) */ +"Text.Generic.GotIt" = "Ich hab's"; + +/* Password Entry Button */ +"Text.Generic.Hide" = "Ausblenden"; + +"Text.Generic.Logout" = "Abmeldung"; + +/* english "making a booking". Used in terms conditions construction */ +"Text.Generic.MakingBookingAction" = "eine Reservierung vornehmen"; + +"Text.Generic.MeetGreet" = "Treffen und Begrüßung"; + +/* Metered fare type displayed in quotes list: English: "Metered" */ +"Text.Generic.Metered" = "Taxameter"; + +"Text.Generic.Minutes" = "Min."; + +"Text.Generic.Name" = "Name"; + +"Text.Generic.No" = "Nein"; + +"Text.Generic.NoCarsAvailable" = "Leider sind zur Zeit keine Fahrzeuge für Ihre Fahrt verfügbar.\n\nBitte schauen Sie bald wieder vorbei."; + +/* The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device" */ +"Text.Generic.NoEmailSetupError" = "Bitte richten Sie ein E-Mail-Konto auf Ihrem Gerät ein"; + +"Text.Generic.Ok" = "OK"; + +"Text.Generic.Optional" = "Optional"; + +/* "Payment" used as a button in the side menu to reach all your payment methods */ +"Text.Generic.Payment" = "Bezahlung"; + +/* "Payments" used as the title of the payment method screen */ +"Text.Generic.Payments" = "Zahlungen"; + +"Text.Generic.PhoneNumber" = "Telefon-Nummer"; + +"Text.Generic.Pickup" = "Abholung"; + +/* English: "Pickup Time" in booking request screen */ +"Text.Generic.PickupTime" = "Abholzeit"; + +"Text.Generic.Prebook" = "Buchen Sie"; + +"Text.Generic.Price" = "Preis"; + +"Text.Generic.PrivacyPolicy" = "Datenschutzrichtlinie"; + +"Text.Generic.Register" = "Registrieren"; + +/* english: "creating your Karhoo account". Used in terms conditions construction */ +"Text.Generic.RegisterAccountAction" = "Ihr Karhoo-Konto erstellen"; + +/* English: "Report Issue" */ +"Text.Generic.ReportIssue" = "Ausgabe melden"; + +/* String for when trip is initially loaded and no trip state has yet come through. "Requesting" */ +"Text.Generic.Requesting" = "Anfrage an"; + +/* used in side menu "Rides" */ +"Text.Generic.Rides" = "Fahrten"; + +/* "Save" used as a button (call to action) */ +"Text.Generic.Save" = "Speichern"; + +/* Password Entry Button */ +"Text.Generic.Show" = "Anzeigen"; + +/* english: "status" */ +"Text.Generic.Status" = "Status"; + +"Text.Generic.Submit" = "UNTERZEICHNUNG"; + +"Text.Generic.Success" = "Erfolg"; + +"Text.Generic.Surname" = "Nachname"; + +"Text.Generic.TermsConditions" = "Geschäftsbedingungen"; + +"Text.Generic.TermsOfUse" = "Nutzungsbedingungen"; + +/* "Thanks for your interest" */ +"Text.Generic.Thanks" = "Danke für Ihr Interesse"; + +/* Booker cancelled */ +"Text.Generic.TripStatus.BookerCancelled" = "Abgebrochen"; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "Es dauert länger als gewöhnlich, bis die Flotte einen Fahrer zuweist. Bitte warten Sie, kontaktieren Sie die Flotte oder stornieren Sie und buchen Sie bei einer anderen Flotte neu."; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Verzögerung bei der Zuteilung"; + +/* Driver Cancelled */ +"Text.Generic.TripStatus.DriverCancelled" = "Vom Fahrer/Versand storniert"; + +/* No drivers available */ +"Text.Generic.TripStatus.NoDriversAvailable" = "Keine Treiber verfügbar"; + +/* "Unkown" */ +"Text.Generic.Unknown" = "Unbekannt"; + +"Text.Generic.Yes" = "Ja"; + +/* "Allocated" when a driver has been allocated */ +"Text.GenericTripStatus.Allocated" = "Zuteilung"; + +/* "Driver Approaching" */ +"Text.GenericTripStatus.Approaching" = "Fahrer nähert sich"; + +/* Driver Arrived */ +"Text.GenericTripStatus.Arrived" = "Fahrer eingetroffen"; + +/* "Cancelled" */ +"Text.GenericTripStatus.Cancelled" = "Abgebrochen"; + +/* Cancelled by Karhoo */ +"Text.GenericTripStatus.CancelledByKarhoo" = "Storniert von Karhoo"; + +/* "Completed" (trip completed) */ +"Text.GenericTripStatus.Completed" = "Abgeschlossen"; + +/* Confirmed */ +"Text.GenericTripStatus.Confirmed" = "Bestätigt"; + +/* "Driver En Route" when a driver is en route */ +"Text.GenericTripStatus.EnRoute" = "Fahrer unterwegs"; + +/* "Failed" */ +"Text.GenericTripStatus.Failed" = "Fehlgeschlagen"; + +/* "Incomplete" */ +"Text.GenericTripStatus.Incomplete" = "Anhängiger Zustand"; + +/* in english: "Requested" */ +"Text.GenericTripStatus.Initialised" = "Erwünscht"; + +/* "On Board" */ +"Text.GenericTripStatus.PassengerOnBoard" = "An Bord"; + +/* english: requested */ +"Text.GenericTripStatus.Requested" = "Erwünscht"; + +/* "Pending" */ +"Text.GenericTripStatus.Unknown" = "ausstehend"; + +"Text.Help.ContactUs.Link" = "https://taxibookermobile.zendesk.com/hc/en-us/requests/new"; + +"Text.Help.FAQ.Link" = "https://taxibookermobile.zendesk.com/hc/en-us"; + +/* No availability in requested area, Fuzzy */ +"Text.KarhooError.K3002" = "In diesem Gebiet sind keine Flotten verfügbar."; + +"Text.KarhooError.Q0001" = "Abholort und Zielort können nicht identisch sein."; + +/* "Add new card" in english used in the payments section of the app. Referring to credit / debit card */ +"Text.Payment.AddPaymentMethod" = "Zahlung hinzufügen"; + +"Text.Payment.PaymentMethod" = "Ende der Karte"; + +/* Prebook */ +"Text.Prebook.PrebookPickupTime" = "Abholzeit vormerken"; + +"Text.Prebook.SetPrebook" = "Abholzeit einstellen"; + +/* "Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes */ +"Text.Prebook.TimezoneMessage" = "Die Buchung wird in der Ortszeit der Abholung vorgenommen (%1$@)"; + +"Text.Quote.FreeCancellationAndKeyword" = "und"; + +"Text.Quote.FreeCancellationASAP" = "Kostenlose Stornierung bis zu %1$@ nach der Buchung"; + +"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Kostenlose Stornierung bis der Fahrer unterwegs ist"; + +/* Cancellation info on quotes */ +"Text.Quote.FreeCancellationPrebook" = "Kostenlose Stornierung bis zu %1$@ vor der Abholung"; + +"Text.QuoteCategory.Electric" = "Elektrisch"; + +"Text.QuoteCategory.Exec" = "Exec"; + +"Text.QuoteCategory.Executive" = "Exekutive"; + +"Text.QuoteCategory.Moto" = "Moto"; + +"Text.QuoteCategory.Motorcycle" = "Motorrad"; + +"Text.QuoteCategory.MPV" = "Großraum"; + +"Text.QuoteCategory.Saloon" = "Standard"; + +"Text.QuoteCategory.Taxi" = "Taxi"; + +/* Side Menu "About" section title, Fuzzy */ +"Text.SideMenu.About" = "Über"; + +"Text.SideMenu.Feedback" = "Rückmeldung"; + +"Text.SideMenu.Help" = "Hilfe"; + +/* Side Menu */ +"Text.SideMenu.Login" = "Anmelden"; + +/* "Profile" button on the side menu */ +"Text.SideMenu.Profile" = "Profil"; + +/* Register on the side menu */ +"Text.SideMenu.Register" = "Registrieren"; + +"Text.SideMenu.SignIn" = "Anmelden"; + +/* Sign Out on the side menu */ +"Text.SideMenu.SignOut" = "Abmeldung"; + +"Text.SideMenu.Signup" = "Registrieren"; + +/* In app email to customer support / feedback */ +"Text.SupportMailMessage.Feedback" = "Bitte löschen Sie diese Informationen nicht, da sie uns helfen, die App zu verbessern."; + +"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; + +"Text.SupportMailMessage.FeedbackSubject" = "Rückmeldung"; + +"Text.SupportMailMessage.NoCoverageBody" = "Vielen Dank, dass Sie uns einen Fuhrpark in Ihrer Nähe empfehlen. Um die Abdeckung in Ihrem Gebiet so schnell wie möglich zu erhalten, geben Sie uns bitte das Gebiet und den Namen des Transportunternehmens an.\nGebiet:\nFlottenzeit:"; + +/* No coverage email */ +"Text.SupportMailMessage.NoCoverageSubject" = "Empfehlung für die Flotte"; + +"Text.SupportMailMessage.ReportIssue" = "Bitte nutzen Sie das folgende Feld, um ein bestimmtes Problem mit Ihrer Fahrt zu melden."; + +"Text.SupportMailMessage.ReportIssueSubject" = "Ausgabe melden"; + +"Text.SupportMailMessage.SupplierEmail" = "suppliers@karhoo.com"; + +"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; + +/* Used in the checkout component before booking a ride */ +"Text.TermsConditions.BookingFullString" = "Mit der Buchung erklären Sie sich mit den %1$@ | %2$@ und %3$@ %4$@ | %3$@ %5$@ einverstanden."; + +"Text.TermsConditions.FullString" = "Mit %1$@ erklären Sie sich mit %2$@ einverstanden.\n%3$@ | %4$@"; + +"Text.TermsConditions.KarhooPolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.KarhooTermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TermsConditions.PolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.TermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TrackingLink.production" = "https://agent-portal.karhoo.com/follow/"; + +/* Trip Tracking Links */ +"Text.TrackingLink.sandbox" = "https://agent-portal.sandbox.karhoo.com/follow/"; + +"Text.TrackingLink.staging" = "https://agent-portal.stg.karhoo.net/follow/"; + +"Text.Trip.ActivityIndicator.Cancelling" = "Abbrechen"; + +/* "Arrival" displayed on arrival box in trip */ +"Text.Trip.Arrival" = "Anreise"; + +"Text.Trip.CallDriver" = "Kontakt Fahrer"; + +/* Call fleet button in trip screen (English: Call Fleet) */ +"Text.Trip.CallFleet" = "Flotte anrufen"; + +"Text.Trip.CancelBookingConfirmation.Alert.Message" = "Der Anbieter kann Ihnen eine Stornierungsgebühr in Rechnung stellen."; + +"Text.Trip.CancelBookingConfirmation.Alert.Title" = "Ihre Fahrt absagen?"; + +/* displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking" */ +"Text.Trip.CancelBookingFailed" = "Stornierung nicht bestätigt, bitte rufen Sie den Anbieter an"; + +"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Flotte anrufen"; + +"Text.Trip.CancelBookingFailed.AlertMessage" = "Wir haben Probleme, Ihre Fahrt zu stornieren. Bitte kontaktieren Sie die Flotte."; + +"Text.Trip.CancelBookingFailed.AlertTitle" = "Schwierigkeiten bei der Annullierung"; + +"Text.Trip.CancelledByDispatch" = "Ihre Buchung wurde storniert."; + +"Text.Trip.CancelledByDispatch.AlertMessage" = "Ihre Buchung wurde storniert. Bitte kontaktieren Sie uns für weitere Informationen."; + +"Text.Trip.CancelledByDispatch.AlertTitle" = "Von der Flotte annulliert"; + +"Text.Trip.CancelledByUser" = "Sie haben die Buchung storniert"; + +/* Trip */ +"Text.Trip.CancelRide" = "Fahrt abbrechen"; + +"Text.Trip.Completed" = "Sie haben Ihr Ziel erreicht"; + +"Text.Trip.Confirmed" = "Ihre Buchung wurde angenommen.\nWarten Sie auf die Zuweisung eines Fahrers."; + +"Text.Trip.DriverArrived" = "Ihr Fahrer ist angekommen"; + +"Text.Trip.DriverEnRoute" = "Ihr Fahrer ist auf dem Weg"; + +/* alert message when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertMessage" = "Bei dieser Buchung ist ein Problem aufgetreten. Bitte versuchen Sie es erneut oder kontaktieren Sie den Support."; + +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertTitle" = "Problem Buchung"; + +"Text.Trip.MessageDriver" = "Nachrichtentreiber"; + +/* For when demand is too high and there are no drivers available */ +"Text.Trip.NoDriversAvailable" = "Keine Treiber verfügbar"; + +/* Alert message in popup when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertMessage" = "Leider ist die Nachfrage hoch. %1$@ hat keine verfügbaren Fahrer."; + +/* Popup title message when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertTitle" = "Buchung fehlgeschlagen"; + +"Text.Trip.PassengerOnBoard" = "Sie sind auf dem Weg. Gute Fahrt!"; + +/* Trip Statuses */ +"Text.Trip.Requested" = "%1$@ weist Ihnen einen Fahrer zu. Dies kann bis zu 5 Minuten dauern."; + +/* Used as a button in the trip screen. English: "Ride Options" */ +"Text.Trip.RideOptions" = "Fahrten-Optionen"; + +/* Please wait whilst you\'re allocated a driver */ +"Text.TripAllocation.AllocatingTripOne" = "Bitte warten Sie, bis Ihnen ein Fahrer zugewiesen wird."; + +/* This may take a moment or two */ +"Text.TripAllocation.AllocatingTripTwo" = "Dies kann einen oder zwei Augenblicke dauern."; + +"Text.TripAllocation.CancelInstruction" = "Tippen und halten Sie zum Abbrechen"; + +"Text.TripAllocation.Cancelling" = "Abbrechen"; + +/* Finding your ride... */ +"Text.TripAllocation.FindingYourRide" = "Ihr Fahrzeug finden..."; + +/* Trip Rating */ +"Text.TripRating.Confirmation" = "Vielen Dank für die Abgabe Ihrer Bewertung."; + +"Text.TripRating.ExtraFeedback" = "Bitte erzählen Sie uns mehr"; + +"Text.TripRating.Title" = "Wie würden Sie Ihre Reise bewerten?"; + +/* Used for the "Book Return Ride" button on the trip summary screen */ +"Text.TripSummary.BookReturnRide" = "Rückfahrt buchen"; + +/* "Date" */ +"Text.TripSummary.Date" = "Datum"; + +/* Fleet */ +"Text.TripSummary.Fleet" = "Flotte"; + +/* "Payment Summary" header used on Trip Summary Screen */ +"Text.TripSummary.PaymentSummary" = "Zusammenfassung der Zahlungen"; + +/* "Quoted Price": used in trip summary screen when the fare is not available */ +"Text.TripSummary.QuotedPrice" = "Preisangebot"; + +/* Total Fare */ +"Text.TripSummary.TotalFare" = "Gesamtpreis"; + +/* "Trip Summary" header used on screen */ +"Text.TripSummary.TripSummary" = "Zusammenfassung der Fahrt"; + +"Text.TripSummary.Vehicle" = "Fahrzeug"; + +"Text.User.Email" = "E-Mail"; + +"Text.User.EmailSubscription" = "Ich möchte keine Freifahrten, Werbeaktionen oder Angebote erhalten"; + +/* User (register / login / user attributes) */ +"Text.User.FirstName" = "Vorname"; + +/* Text used on button to trigger password reset... English: Forgotten Password? */ +"Text.User.ForgottenPassword" = "Haben Sie Ihr Passwort vergessen?"; + +"Text.User.LastName" = "Nachname"; + +"Text.User.MobilePhoneNumber" = "Nummer des Mobiltelefons"; + +"Text.User.Password" = "Passwort"; + +"Text.User.PhoneCountryCode" = "Code"; + +/* "We will notify you via email once your request has been processed." */ +"Text.User.SignupPendingMessage" = "Wir werden Sie per E-Mail benachrichtigen, sobald Ihr Antrag bearbeitet wurde."; + +"Text.VehicleClass.Electric" = "Elektrisch"; + +"Text.VehicleClass.Exec" = "Exec"; + +"Text.VehicleClass.Executive" = "Exekutive"; + +"Text.VehicleClass.Moto" = "Moto"; + +"Text.VehicleClass.Motorcycle" = "Motorrad"; + +"Text.VehicleClass.MPV" = "Großraum"; + +"Text.VehicleClass.Saloon" = "Standard"; + +"Text.VehicleClass.Taxi" = "Taxi"; + +"Text.VehicleTag.Childseat" = "Kindersitz"; + +/* Vehicle tags */ +"Text.VehicleTag.Electric" = "Elektrisch"; + +"Text.VehicleTag.Executive" = "Exekutive"; + +"Text.VehicleTag.Hybrid" = "Hybrid"; + +"Text.VehicleTag.Taxi" = "Taxi"; + +"Text.VehicleTag.Wheelchair" = "Rollstuhl"; + +"Text.VehicleType.Bus" = "Bus"; + +"Text.VehicleType.Moto" = "Moto"; + +"Text.VehicleType.MPV" = "Großraum"; + +"Text.VehicleType.Standard" = "Standard"; + diff --git a/KarhooUISDK/Translations/de.lproj/Localizable.stringsdict b/KarhooUISDK/Translations/de.lproj/Localizable.stringsdict new file mode 100644 index 000000000..d53b78960 --- /dev/null +++ b/KarhooUISDK/Translations/de.lproj/Localizable.stringsdict @@ -0,0 +1,38 @@ + + + + + Text.Quote.FreeCancellationBeforePickupMinutes + + NSStringLocalizedFormatKey + %#@MINUTE@ + MINUTE + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + 1 minute + other + %d minuten + + + Text.Quote.FreeCancellationBeforePickupHours + + NSStringLocalizedFormatKey + %#@HOUR@ + HOUR + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + 1 stunde + other + %d stunden + + + + diff --git a/KarhooUISDK/Translations/es.lproj/Localizable.strings b/KarhooUISDK/Translations/es.lproj/Localizable.strings index aba0974e3..2a0fd56e3 100644 --- a/KarhooUISDK/Translations/es.lproj/Localizable.strings +++ b/KarhooUISDK/Translations/es.lproj/Localizable.strings @@ -1,468 +1,763 @@ +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Cancelación"; -/*Localizable.strings - Karhoo +"CURBSIDE" = "Recoger afuera"; - Copyright © 2020 Karhoo. All rights reserved. - Generics*/ -"Text.Generic.Cancel" = "Cancelar"; -"Text.Generic.Ok" = "OK"; -"Text.Generic.Close" = "Cerrar"; -"Text.Generic.Done" = "Hecho"; -"Text.Generic.Back" = "Volver"; -"Text.Generic.Error" = "Error"; -"Text.Generic.Register" = "Registrarse"; -"Text.Generic.Logout" = "Salir"; -"Text.Generic.Contact" = "Contacto"; -"Text.Generic.Bookings" = "Reservas"; -"Text.Generic.Destination" = "Destino"; -"Text.Generic.Pickup" = "Punto de partida"; -"Text.Generic.Add" = "Adjuntar"; -"Text.Generic.Change" = "Cambiar"; -"Text.Generic.Submit" = "Enviar"; -"Text.Generic.Success" = "El éxito"; -"Text.Generic.ETALong" = "Hora de llegada estimada"; -"Text.Generic.EPrice" = "Precio estimado"; -"Text.Generic.ETA" = "Tiempo estimado"; -"Text.Generic.Price" = "Precio"; -"Text.Generic.Prebook" = "Reservar"; -"Text.Generic.Name" = "Nombre"; -"Text.Generic.Surname" = "Apellido"; -"Text.Generic.Email" = "Email"; -"Text.Generic.PhoneNumber" = "Número de teléfono"; -"Text.Generic.Comment" = "Comentario"; -"Text.Generic.Optional" = "Opcional"; -"Text.Generic.ErrorMessage" = "¡Hubo un problema!"; +/* PickUp Type */ +"DEFAULT" = "Default"; -/*Fuzzy*/ -"Text.Generic.ETA" = "Proximidad"; -"Text.Generic.Price" = "Tarifa"; -"Text.Generic.Prebook" = "Reserva"; +"ELECTRIC" = "Eléctrico"; -/*english: "creating your Karhoo account". Used in terms conditions construction*/ -"Text.Generic.RegisterAccountAction" = "crear una cuenta de Karhoo"; +/* English: Error codes */ +"K0001" = "Error general"; -/*english "making a booking". Used in terms conditions construction*/ -"Text.Generic.MakingBookingAction" = "reservar"; -"Text.Generic.TermsConditions" = "condiciones generales"; -"Text.Generic.PrivacyPolicy" = "política de privacidad"; -"Text.Generic.Minutes" = "min"; -"Text.Generic.Continue" = "Continuar"; +"K0002" = "Petición de solicitud no válida"; -/*Address Bar*/ -"Text.AddressBar.AddDestination" = "Añadir destino"; -"Text.AddressBar.AddPickup" = "Agregar recogida"; -"Text.AddressBar.EnterPickupLocation" = "¿Dónde estás?"; -"Text.AddressSearch.EnterDestinationLocation" = "¿Dónde vas?"; +"K0003" = "Imposible leer el token de autorización"; -/*User (register / login / user attributes)*/ -"Text.User.FirstName" = "Nombre"; -"Text.User.LastName" = "Apellidos"; -"Text.User.Email" = "Email"; -"Text.User.PhoneCountryCode" = "Prefijo"; -"Text.User.MobilePhoneNumber" = "Número de teléfono"; -"Text.User.Password" = "Contraseña"; -"Text.User.EmailSubscription" = "No deseo recibir viajes gratuitos, promociones ni ofertas"; +"K0004" = "La autenticación es necesaria para esta ruta"; -/*Errors*/ -"Text.Error.EmailValidationError" = "Comprueba que tu email está escrito correctamente"; -"Text.Error.Booking.EnterDestinationToProceed" = "Introduce tu destino para solicitar un viaje"; -"Text.Error.NotLoggedIn" = "No estás conectado"; +"K0005" = "Falta el rol requerido para esta solicitud"; -/*Terms Condition full string - 1:Making a booking / Registering an account, 2: Supplier name "Terms and Conditions","Privacy Policy"*/ -"Text.TermsConditions.FullString" = "Al %1$@, aceptas las %3$@ y la %4$@ de %2$@"; +"K0006" = "Límite excedido"; -/*Side Menu*/ -"Text.SideMenu.Login" = "Acceder"; -"Text.SideMenu.SignIn" = "Acceder"; -"Text.SideMenu.Signup" = "Registrarse"; -"Text.SideMenu.Help" = "Ayuda"; -"Text.SideMenu.Feedback" = "Sugerencias"; +"K0007" = "Error generalizado"; -/*In app email to customer support / feedback*/ -/*Fuzzy*/ -"Text.SupportMailMessage.Feedback" = "Por favor no elimines esta información ya que nos ayuda a mejorar la app."; -"Text.SupportMailMessage.ReportIssue" = "Por favor, deje sus comentarios sobre un tema específico en el espacio a continuación."; -"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; -"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; -"Text.SupportMailMessage.SupplierEmail" = "suppliers@karhoo.com"; -"Text.SupportMailMessage.FeedbackSubject" = "Sugerencias"; -"Text.SupportMailMessage.ReportIssueSubject" = "Reportar problema"; +/* User errors, K1xxx */ +"K1001" = "Imposible registrar usuario"; -/*Prebook*/ -"Text.Prebook.PrebookPickupTime" = "Día y hora de partida"; -"Text.Prebook.SetPrebook" = "Seleccionar"; +"K1002" = "Imposible registrar usuario (el usuario ya existe)"; -/*Booking*/ -"Text.Booking.RequestCar" = "Solicitar"; -"Text.Booking.RequestingCar" = "Solicitar"; -"Text.Booking.RequestReceived" = "Solicitud recibida"; -"Text.Bookings.eta" = "Proximidad"; -"Text.Bookings.price" = "Tarifa"; +"K1003" = "Imposible registrar usuario"; -/*Trips*/ -/*Fuzzy*/ -"Text.Trip.CancelRide" = "Cancelar reserva"; -"Text.Trip.MessageDriver" = "Enviar SMS"; -"Text.Trip.CallDriver" = "Llamar conductor"; +"K1004" = "Imposible registrar usuario (número de teléfono no válido)"; -/*Trip Statuses*/ -/*Fuzzy*/ -"Text.Trip.Requested" = "Esto puede demorarse unos instantes"; -"Text.Trip.Confirmed" = "Tu solicitud ha sido aceptada. \nSe te está asignando un conductor."; -"Text.Trip.DriverEnRoute" = "Tu conductor está de camino"; +"K1005" = "Imposible obtener los datos del usuario (token no válido)"; -/*1) driver first name: 2) license plate 3) make and model*/ -"Text.Trip.DriverArrived" = "¡Tu conductor ha llegado!"; -"Text.Trip.PassengerOnBoard" = "Ya estás de camino ¡Buen viaje!"; -"Text.Trip.Completed" = "Llegaste a tu destino"; -"Text.Trip.CancelledByUser" = "Has cancelado la reserva"; -"Text.Trip.CancelledByDispatch" = "Lo sentimos, la flota canceló tu reserva."; -"Text.Trip.Completed" = "Has llegado a tu destino. Cuéntanos qué te ha parecido el viaje."; +"K1006" = "Imposible obtener los datos del usuario (el usuario ya existe)"; -/*English: "Pickup Time" in booking request screen*/ -/*Fuzzy*/ -"Text.Generic.PickupTime" = "Proximidad"; +"K1999" = "El usuario ha sido creado pero aún no ha sido autorizado, nos pondremos en contacto una vez habilitado."; -/*Reference to fixed pricing.. English equivalent: "Fixed"*/ -/*Fuzzy*/ -"Text.Generic.Fixed" = "Fijo"; +/* Locations errors, K2xxx */ +"K2001" = "Imposible obtener dirección"; -/*Register on the side menu*/ -"Text.SideMenu.Register" = "Registrarse"; +/* Quotes errors, K3xxx */ +"K3001" = "Imposible obtener estimaciones"; -/*Sign Out on the side menu*/ -"Text.SideMenu.SignOut" = "Salir"; +"K3002" = "Imposible obtener estimaciones (no se encontró disponibilidad en el área solicitada)"; -/*"Cancelled"*/ -"Text.Generic.Cancelled" = "Cancelado"; +"K3003" = "Imposible obtener estimaciones (no se encontró la tarifa específica)"; -/*"Completed"*/ -"Text.Generic.Completed" = "Completado"; +/* Bookings errors, K4xxx */ +"K4001" = "Imposible reservar"; -/*english: "status"*/ -"Text.Generic.Status" = "Estado"; +"K4002" = "Imposible reservar - solicitud inválida (se requiere al menos un valor para detalles de pasajero 'passenger-details')"; -/*english: "price"*/ -"Text.Generic.Price" = "Tarifa"; +"K4003" = "Imposible reservar (no se encontró la cotización especificada)"; -/*english "Card" (referring to payment card)*/ -"Text.Generic.Card" = "Tarjeta"; +"K4004" = "Imposible reservar (intento de reserva de cotización caducada)"; -/*English: "Report Issue" */ -/*Fuzzy*/ -"Text.Generic.ReportIssue" = "Reportar problema"; +"K4005" = "Imposible reservar (Permiso denegado)"; -/*English: "No Trips" used if the booking list screen is empty*/ -/*Fuzzy*/ -"Text.Bookings.NoTrips" = "Sin reservas"; +"K4006" = "Imposible reservar (Pre-autorización de pago fallida)"; -/*used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B"*/ -/*Fuzzy*/ -"Text.Bookings.NoTripsBookedMessage" = "Aún no has reservado ningún viaje. Podemos ayudarte a ir de un lugar a otro."; +"K4007" = "Cancelación fallida"; -/*used as a call to action on a button in the empty bookings screen: English: "Book A Trip"*/ -"Text.Bookings.BookATrip" = "Solicitar viaje"; +"K4008" = "Cancelación fallida (No se ha encontrado la reserva)"; -/*"Add new card" in english used in the payments section of the app. Referring to credit / debit card*/ -"Text.Payment.AddPaymentMethod" = "Añada su metodo de pago"; -"Text.Payment.PaymentMethod" = "Tarjeta finalizada en"; +"K4009" = "Cancelación fallida (Permiso denegado)"; -/*"Edit" used as a button (call to action) */ -"Text.Generic.Edit" = "Editar"; +"K4010" = "Cancelación fallida (Este viaje ya ha sido cancelado)"; -/*"Save" used as a button (call to action) */ -"Text.Generic.Save" = "Salvar"; +"K4011" = "No se pudo obtener la reserva"; -/*"Payment" used as a button in the side menu to reach all your payment methods*/ -"Text.Generic.Payment" = "Pago"; +"K4012" = "No se pudo obtener la reserva (No se ha encontrado la reserva)"; -/*"Payments" used as the title of the payment method screen*/ -"Text.Generic.Payments" = "Pagos"; +"K4013" = "No se pudo obtener la reserva (Permiso denegado)"; -/*in english: "Requested"*/ -"Text.GenericTripStatus.Initialised" = "Solicitado"; +"K4014" = "No pudo completarse la reserva como agente (Agent)"; -/*english: requested*/ -"Text.GenericTripStatus.Requested" = "Solicitado"; +"K4015" = "No pudo completarse la reserva como pasajero (Traveller)"; -/*Confirmed*/ -"Text.GenericTripStatus.Confirmed" = "Confirmado"; +"k4015" = "No pudo completarse la reserva como pasajero (Traveller)"; -/*"Allocated" when a driver has been allocated*/ -"Text.GenericTripStatus.Allocated" = "Asignado"; +"K4018" = "No pudo realizarse la reserva al no estar ya disponible la cotización"; -/*"Driver En Route" when a driver is en route*/ -"Text.GenericTripStatus.EnRoute" = "Conductor de camino"; +"K4020" = "No se pudo reservar el viaje con el DMS seleccionado"; -/*or "El conductor se acerca"*/ -/*"Driver Approaching"*/ -/*Fuzzy*/ -"Text.GenericTripStatus.Approaching" = "Conductor cerca"; +"K4025" = "Precio de cotización aumentado durante la reserva"; -/*Driver Arrived*/ -"Text.GenericTripStatus.Arrived" = "El conductor ha llegado"; +/* Availability errors, K5xxx */ +"K5001" = "No se pudo obtener estimaciones"; -/*"On Board"*/ -"Text.GenericTripStatus.PassengerOnBoard" = "Viaje en curso"; +"K5002" = "Sin disponibilidad (no se encontró disponibilidad en el área solicitada)"; -/*"Completed" (trip completed)*/ -"Text.GenericTripStatus.Completed" = "Completado"; +"K5003" = "Sin disponibilidad (no se encontraron categorías en el área solicitada)"; -/*"Cancelled" */ -"Text.GenericTripStatus.Cancelled" = "Cancelado"; +/* Authentication errors K6xxx */ +"K6001" = "No se puede autenticar"; -/*"Failed" */ -"Text.GenericTripStatus.Failed" = "Error"; +/* KPOI errors, K7xxx */ +"K7001" = "Imposible procesar la solicitud del PDIK"; -/*"Pending"*/ -/*Fuzzy*/ -"Text.GenericTripStatus.Unknown" = "Pendiente"; +"K7002" = "No se pudo encontrar el PDI de Karhoo con el ID correspondiente"; -/*"Incomplete"*/ -"Text.GenericTripStatus.Incomplete" = "Estado pendiente"; +"K7003" = "No se pudo leer el PDI de Karhoo"; -/*"Driver Allocation Delay Title"*/ -"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Retraso en asignación"; +"K7004" = "No se pudo añadir el PDI de Karhoo"; -/*"Driver Allocation Delay Title"*/ -"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "La flota está tardando más de lo habitual en asignar un conductor. Por favor espere, contacte con la flota o cancele y vuelva a reservar con una flota diferente."; +"K7005" = "No se pudo eliminar el PDI de Karhoo"; -/*"Track Driver"*/ -"Text.Bookings.TrackDriver" = "Localizar conductor"; +/* KSDKxxx Internal SDK */ +"KSDK01" = "Se ha producido un error. Inténtelo de nuevo."; -/*"Contact Driver" (button action)*/ -"Text.Bookings.ContactDriver" = "Llamar conductor"; +"KSDK02" = "Falta una función de usuario requerida para esta solicitud"; -/*"Contact Fleet"*/ -"Text.Bookings.ContactFleet" = "Llamar a la flota"; +"KSDK03" = "Usuario ya ha iniciado sesión"; -/*"Track Trip"*/ -"Text.Bookings.TrackTrip" = "Seguir viaje"; +"MEET_AND_GREET" = "Dar la bienvenida"; -"Text.Bookings.TrackTrip.AlertTitle" = "Ride confirmed"; -"Text.Bookings.TrackTrip.AlertMessage" = "Would you like to track your trip?"; -"Text.Bookings.TrackTrip.TrackAction" = "Track driver"; -"Text.Bookings.TrackTrip.DismissAction" = "Dismiss"; +/* Qxxxx errors */ +"Q0001" = "La recogida y el destino no pueden ser iguales."; -/*"Cancel Ride" button action*/ -"Text.Bookings.CancelRide" = "Cancelar viaje"; +"STAND_BY" = "Llamar conductor"; -/*"Report Issue" Button*/ -"Text.Bookings.ReportIssue" = "Reportar problema"; +/* "Version" */ +"Text.About.Version" = "Versión"; -/*displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking"*/ -"Text.Trip.CancelBookingFailed" = "Cancelación no confirmada. Llama a la flota."; +"Text.Address.CurrentLocation" = "Posición actual"; -/*Used as a button in the trip screen. English: "Ride Options"*/ -"Text.Trip.RideOptions" = "Opciones"; -"Text.Trip.CancelBookingFailed.AlertTitle" = "Cancelación fallida"; -"Text.Trip.CancelBookingFailed.AlertMessage" = "Hubo un problema cancelando tu solicitud. Llama a la flota."; -"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Llamar a la flota"; -"Text.Generic.Yes" = "Si"; -"Text.Generic.No" = "No"; -"Text.Generic.Dismiss" = "Descartar"; -"Text.Trip.CancelBookingConfirmation.Alert.Title" = "¿Cancelar tu viaje?"; -"Text.Trip.CancelBookingConfirmation.Alert.Message" = "Puede que se te cobre una tarifa de cancelación"; +"Text.Address.NoRecentAddress" = "No hay resultados recientes"; -/*Call fleet button in trip screen (English: Call Fleet)*/ -"Text.Trip.CallFleet" = "Llamar flota"; -"Text.Trip.ActivityIndicator.Cancelling" = "Cancelando"; +"Text.Address.SetOnMap" = "Establecer en el mapa"; -/*The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device"*/ -"Text.Generic.NoEmailSetupError" = "Configura una cuenta de correo en tu dispositivo"; -"Text.Trip.CancelledByDispatch.AlertMessage" = "Lo sentimos, la flota canceló tu reserva. Inténtalo de nuevo."; -"Text.Trip.CancelledByDispatch.AlertTitle" = "Cancelado por la flota"; -"Text.Generic.NoCarsAvailable" = "No hay taxis disponibles en este momento. Inténtalo de nuevo mas tarde."; +/* Address Bar */ +"Text.AddressBar.AddDestination" = "Añadir destino"; -/*English: "Estimated"*/ -"Text.Generic.Estimated" = "Estimado"; +"Text.AddressBar.AddPickup" = "Agregar recogida"; -/*"Unkown"*/ -/*Fuzzy*/ -"Text.Generic.Unknown" = "Desconocido"; +"Text.AddressBar.EnterPickupLocation" = "¿Dónde estás?"; -/*"Something went wrong" used as a title for error alert*/ -"Text.Error.SomethingWentWrong" = "Hubo un problema"; +"Text.AddressSearch.EnterDestinationLocation" = "¿Dónde vas?"; -/*Used to explain an unknown error. ie "Oops, something went wrong. Please try again"*/ -"Text.Error.NoDetails" = "¡Hubo un problema! Inténtalo de nuevo."; -"Text.Error.Payment.Alert.Title" = "Problemas con el pago"; -"Text.Error.Payment.Alert.Message" = "No pudimos autorizar tu tarjeta de crédito/débito."; -"Text.Error.Payment.Alert.ButtonUpdateCard" = "Actualizar Pago"; -"Text.Error.Alert.CantSendEmail" = "Email no enviado. Configura tu correo primero."; +/* "Add Flight Details" used on booking airport ride */ +"Text.Airport.AddFlightDetails" = "Agregar información de vuelo"; -/*Metered fare type displayed in quotes list: English: "Metered"*/ -"Text.Generic.Metered" = "taxímetro"; +/* "Flight number" used as the flight number field placeholder */ +"Text.Airport.FlightNumber" = "Número de vuelo"; -/*English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking*/ -"Text.Generic.CancellationPolicy" = "política de cancelación"; +/* Message on airport screen for encouraging user to enter as much info about airport booking as possible */ +"Text.Airport.HelpfulMessage" = "Por favor ingrese un número de vuelo válido"; -/*The title of the alert when user is forced to update ie "App Update Required"*/ -"Text.Error.Alert.ForceUpdateTitle" = "Nueva versión disponible"; +/* "Airport Pickup" used on screen for airport bookinga */ +"Text.Airport.Pickup" = "Recogida en aeropuerto"; -/*The message when the user needs to update the app. ie. "Please update Karhoo to the latest version."*/ -"Text.Error.Alert.ForceUpdateMessage" = "Actualiza la app para continuar"; +/* "All" used for all categories filter on category list. Write normally as the app will uppercase the string */ +"Text.Availability.AllCategory" = "Todo"; -/*The action button on the force update alert. ie "Update" (this button takes the user to the app store)*/ -"Text.Error.Alert.ForceUpdateButton" = "Actualizar"; +"Text.Availability.NoQuotesForSelectedParameters" = "No hay disponibilidad para la hora solicitada. Por favor, seleccione una hora diferente."; -/*String for when trip is initially loaded and no trip state has yet come through. "Requesting"*/ -"Text.Generic.Requesting" = "Solicitando"; -"Text.Booking.EnterDestination" = "Introduce un destino para ver las flotas disponibles"; +"Text.Availability.NoQuotesInSelectedCategory" = "No hay disponibilidad en la categoría solicitada.\n Por favor seleccione otra categoría."; -/*Fuzzy*/ -"Text.Bookings.Quote" = "Cuota"; -"Text.Bookings.Price" = "Tarifa"; +/* Base fare title */ +"Text.Booking.BaseFare" = "Tarifa Básica"; -/*used in side menu "Rides"*/ -"Text.Generic.Rides" = "Viajes"; +/* "Your final fare might be affected by tips, tolls, taxes, and other charges." */ +"Text.Booking.BaseFareExplanation" = "La tarifa final puede verse afectada por propinas, peajes, impuestos u otros cargos."; -/*Generic fallback message for trip load failure*/ -"Text.Bookings.CouldNotLoadTrips" = "Imposible cargar viajes."; -"Text.Bookings.Price.Cancelled" = "Cancelado"; -"Text.Bookings.Alert.CancellationSuccess.Title" = "Viaje cancelado con éxito"; -"Text.Bookings.Alert.CancellationSuccess.Message" = "Tu viaje fue cancelado con éxito."; -"Text.Bookings.Alert.CancellationFee.Charge" = "Se le cargará una tasa de cancelación estimada en %1$@.\n\n¿Quiere continuar?"; -"Text.Bookings.Alert.CancellationFee.Continue" = "¿Quiere continuar?"; +"Text.Booking.CountryCodeSelection.Search" = "Buscar país/región"; -/*When fetching the user profile fails*/ -"Text.Error.GetUserFails" = "Hubo un problema cargando tu perfil."; +/* Country Code Selection */ +"Text.Booking.CountryCodeSelection.Title" = "País / Región"; -/*"Profile" button on the side menu*/ -"Text.SideMenu.Profile" = "Perfil"; +"Text.Booking.EnterDestination" = "Introduce un destino para ver las flotas disponibles"; -/*Button for rebooking a ride*/ -"Text.Bookings.RebookRide" = "Volver a reservar"; +/* Checkout component */ +"Text.Booking.EstimatedInfoBox" = "Esta flota es un taxi no regulado. El presupuesto es una estimación basada en los factores del viaje (distancia, tiempo, etc.). Por favor, consulte los Términos y Condiciones de la flota para más información."; -/*"Got It" (generally used on alert buttons)*/ -"Text.Generic.GotIt" = "Entendido"; +"Text.Booking.FixedInfoBox" = "Esta flota cobra una tarifa plana. La tarifa final puede verse afectada por extras (peajes, retrasos, etc.), por favor, compruebe los Términos y Condiciones de la flota."; -/*"Your final fare might be affected by tips, tolls, taxes, and other charges."*/ -"Text.Booking.BaseFareExplanation" = "La tarifa final puede verse afectada por propinas, peajes, impuestos u otros cargos."; +"Text.Booking.FlightTracking" = "Vincule su vuelo"; -/*"Additional information" used as placeholder on airport details screen*/ -"Text.Generic.AdditionalInformation" = "Información adicional"; +"Text.Booking.GPSTracking" = "Seguimiento GPS"; -/*"Airport Pickup" used on screen for airport bookinga*/ -"Text.Airport.Pickup" = "Recogida en aeropuerto"; +"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Número de vuelo (Opcional)"; -/*Message on airport screen for encouraging user to enter as much info about airport booking as possible*/ -"Text.Airport.HelpfulMessage" = "Por favor ingrese un número de vuelo válido"; +/* Guest checkout */ +"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Detalles del pasajero"; -/*"Flight number" used as the flight number field placeholder*/ -"Text.Airport.FlightNumber" = "Número de vuelo"; +"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Métodos de pago"; -/*"Add Flight Details" used on booking airport ride*/ -"Text.Airport.AddFlightDetails" = "Agregar información de vuelo"; +"Text.Booking.LearnMore" = "Leer más"; -/*"Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes*/ -"Text.Prebook.TimezoneMessage" = "Zona horaria (%1$@)"; +"Text.Booking.MaximumLuggages" = "Máximo %1$@ piezas de equipaje"; -/*"Thanks for your interest"*/ -"Text.Generic.Thanks" = "Muchas gracias for tu interés"; +"Text.Booking.MaximumPassengers" = "Máximo %1$@ pasajeros"; -/*"We will notify you via email once your request has been processed."*/ -"Text.User.SignupPendingMessage" = "Te notificaremos por email una vez tu solicitud haya sido aceptada."; +"Text.Booking.MeteredInfoBox" = "Esta flota es un taxi con taxímetro regulado. El presupuesto es una estimación basada en los factores del viaje (distancia, tiempo, etc.)."; -/*Side Menu "About" section title*/ -"Text.SideMenu.About" = "Información"; +"Text.Booking.Next" = "SIGUIENTE"; -/*"Version"*/ -"Text.About.Version" = "Versión"; +/* %1$@ if you have suggestions for local fleets. */ +"Text.Booking.NoAvailabilityBody" = "Ponte en %1$@ si conoces flotas locales."; -/*Error message when user tries to prebook within the current hour of local time*/ -"Text.Error.PrebookingWithinTheHour" = "Reserva realizada para la misma hora"; +/* We’re not live here yet! */ +"Text.Booking.NoAvailabilityHeader" = "¡Todavía no estamos operativos aquí!"; -/*No availability in requested area*/ -/*Fuzzy*/ -"Text.KarhooError.K3002" = "Sin disponibilidad en la zona"; -"Text.KarhooError.Q0001" = "La recogida y el destino no pueden ser iguales."; -/*For when demand is too high and there are no drivers available*/ -"Text.Trip.NoDriversAvailable" = "No hay conductores disponibles"; +/* Get in touch */ +"Text.Booking.NoAvailabilityLink" = "contacto"; -/*Booker cancelled*/ -"Text.Generic.TripStatus.BookerCancelled" = "El agente ha cancelado "; +"Text.Booking.Passenger" = "Pasajero"; -/*Driver Cancelled*/ -"Text.Generic.TripStatus.DriverCancelled" = "El conductor ha cancelado"; +"Text.Booking.PassengerDetails.Add" = "Añadir pasajero"; -/*No drivers available*/ -"Text.Trip.NoDriversAvailable" = "No hay conductores disponibles"; +"Text.Booking.PassengerDetails.Email" = "Correo electrónico"; -/*No drivers available*/ -"Text.Generic.TripStatus.NoDriversAvailable" = "No hay conductores disponibles"; +"Text.Booking.PassengerDetails.FirstName" = "Nombre"; -/*"Trip Summary" header used on screen*/ -"Text.TripSummary.TripSummary" = "Resumen del viaje"; +"Text.Booking.PassengerDetails.LastName" = "Apellido"; + +"Text.Booking.PassengerDetails.MobilePhone" = "Número de móvil"; + +"Text.Booking.PassengerDetails.SaveAction" = "SALVAR"; + +"Text.Booking.PassengerDetails.Subtitle" = "Esta información permite el buen desarrollo de su carrera"; + +/* Passenger Details */ +"Text.Booking.PassengerDetails.Title" = "Pasajero"; + +/* Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked */ +"Text.Booking.PrebookConfirmation" = "Tu viaje de %1$@\na %2$@\nel %3$@ ha sido confirmado."; + +/* Prebook Done, Fuzzy */ +"Text.Booking.PrebookConfirmed" = "Viaje confirmado"; + +/* Ride Details */ +"Text.Booking.PrebookConfirmed.RideDetails" = "Detalles del viaje"; + +/* Booking */ +"Text.Booking.RequestCar" = "RESERVAR"; + +"Text.Booking.RequestingCar" = "Solicitar"; + +"Text.Booking.RequestReceived" = "Solicitud recibida"; + +"Text.Booking.TrainTracking" = "Vincule su tren"; + +"Text.Bookings.Alert.CancellationFee.Charge" = "Se le cargará una tasa de cancelación estimada en %1$@.\n\n¿Quiere continuar?"; + +"Text.Bookings.Alert.CancellationFee.Continue" = "¿Quiere continuar?"; + +"Text.Bookings.Alert.CancellationSuccess.Message" = "Tu viaje fue cancelado con éxito."; + +"Text.Bookings.Alert.CancellationSuccess.Title" = "Viaje cancelado con éxito"; + +/* used as a call to action on a button in the empty bookings screen: English: "Book Ride" */ +"Text.Bookings.BookATrip" = "Solicitar viaje"; + +/* "Cancel Ride" button action */ +"Text.Bookings.CancelRide" = "Cancelar viaje"; + +/* "Contact Driver" (button action) */ +"Text.Bookings.ContactDriver" = "Llamar conductor"; + +/* "Contact Fleet" */ +"Text.Bookings.ContactFleet" = "Llamar a la flota"; + +/* Generic fallback message for trip load failure */ +"Text.Bookings.CouldNotLoadTrips" = "Imposible cargar viajes."; + +"Text.Bookings.eta" = "Proximidad"; + +/* English: "No Trips" used if the booking list screen is empty */ +"Text.Bookings.NoTrips" = "Sin reservas"; + +/* used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B" */ +"Text.Bookings.NoTripsBookedMessage" = "Aún no has reservado ningún viaje. Podemos ayudarte a ir de un lugar a otro."; + +/* "Past" used on past tabs on bookings list */ +"Text.Bookings.Past" = "Anteriores"; + +"Text.Bookings.price" = "Tarifa"; + +"Text.Bookings.Price" = "Tarifa"; + +"Text.Bookings.Price.Cancelled" = "Cancelado"; + +"Text.Bookings.Quote" = "Cuota"; + +/* Button for rebooking a ride */ +"Text.Bookings.RebookRide" = "Volver a reservar"; + +/* "Report Issue" Button */ +"Text.Bookings.ReportIssue" = "Reportar problema"; + +/* "Track Driver" */ +"Text.Bookings.TrackDriver" = "Localizar conductor"; + +/* "Track Trip" */ +"Text.Bookings.TrackTrip" = "Seguir viaje"; + +"Text.Bookings.TrackTrip.AlertMessage" = "¿Le gustaría seguir la ubicación del vehículo?"; + +"Text.Bookings.TrackTrip.AlertTitle" = "El conductor está en camino"; + +"Text.Bookings.TrackTrip.DismissAction" = "No"; + +"Text.Bookings.TrackTrip.TrackAction" = "Sí"; + +/* Upcoming: used on upcoming tabs for rides, Fuzzy */ +"Text.Bookings.Upcoming" = "Próximos"; + +"Text.Error.Alert.CantSendEmail" = "Email no enviado. Configura tu correo primero."; + +/* The action button on the force update alert. ie "Update" (this button takes the user to the app store) */ +"Text.Error.Alert.ForceUpdateButton" = "Actualizar"; + +/* The message when the user needs to update the app. ie. "Please update Karhoo to the latest version." */ +"Text.Error.Alert.ForceUpdateMessage" = "Actualiza la app para continuar"; + +/* The title of the alert when user is forced to update ie "App Update Required" */ +"Text.Error.Alert.ForceUpdateTitle" = "Nueva versión disponible"; + +"Text.Error.Booking.EnterDestinationToProceed" = "Introduce tu destino para solicitar un viaje"; + +/* Errors */ +"Text.Error.EmailValidationError" = "Comprueba que tu email está escrito correctamente"; + +/* When the user enters an invalid flight number, Fuzzy */ +"Text.Error.FlightNumberValidationHint" = "Número de vuelo"; + +/* When fetching the user profile fails */ +"Text.Error.GetUserFails" = "Hubo un problema cargando tu perfil."; + +/* Used to explain an unknown error. ie "Oops, something went wrong. Please try again" */ +"Text.Error.NoDetails" = "¡Hubo un problema! Inténtalo de nuevo."; + +"Text.Error.NotLoggedIn" = "No estás conectado"; + +"Text.Error.Payment.Alert.ButtonUpdateCard" = "Actualizar Pago"; + +"Text.Error.Payment.Alert.Message" = "No pudimos autorizar tu tarjeta de crédito/débito."; + +"Text.Error.Payment.Alert.Title" = "Problemas con el pago"; + +/* Error message when user tries to prebook within the current hour of local time */ +"Text.Error.PrebookingWithinTheHour" = "Reserva realizada para la misma hora"; + +/* "Something went wrong" used as a title for error alert */ +"Text.Error.SomethingWentWrong" = "Hubo un problema"; + +/* Theoretical edge case where the braintree token is missing */ +"Text.Errors.failedToInitialisePaymentSetup" = "Error al iniciar la configuración del pago"; + +"Text.Errors.InvalidPhoneNumber" = "Número de teléfono invalido"; + +"Text.Errors.MissingPhoneNumber" = "Error: no se permiten campos vacíos"; + +/* empty table view result */ +"Text.Errors.NoResultsFound" = "Sin resultados"; + +"Text.FeedbackView.addComment" = "Additional comments"; + +"Text.FeedbackView.app" = "How easy did you find using the app?"; + +"Text.FeedbackView.confirmation" = "Gracias por enviar sus comentarios"; + +"Text.FeedbackView.pob" = "How was your experience whilst in the taxi (e.g. taxi cleanliness, routing and driver)? How easy did you find using the app?"; + +"Text.FeedbackView.pre_pob" = "How was your experience with finding the pick-up location and meeting your driver?"; + +/* FeedBackView */ +"Text.FeedbackView.quote" = "How happy were you with the selection of quotes for your trip (e.g. Fleets, Prices and ETAs)?"; + +"Text.Generic.Add" = "Adjuntar"; + +/* "Additional information" used as placeholder on airport details screen */ +"Text.Generic.AdditionalInformation" = "Información adicional"; + +"Text.Generic.Back" = "Volver"; + +"Text.Generic.Bookings" = "Reservas"; + +/* Localizable.strings, Karhoo, , Copyright © 2020 Karhoo. All rights reserved., Generics */ +"Text.Generic.Cancel" = "Cancelar"; + +/* English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking */ +"Text.Generic.CancellationPolicy" = "Política de Cancelación"; + +/* "Cancelled" */ +"Text.Generic.Cancelled" = "Cancelado"; + +/* english "Card" (referring to payment card) */ +"Text.Generic.Card" = "Tarjeta"; + +"Text.Generic.Change" = "Cambiar"; + +"Text.Generic.Close" = "Cerrar"; + +"Text.Generic.Comment" = "Comentario"; + +"Text.Generic.Comment.Optional" = "Comentario (Opcional)"; + +/* "Completed" */ +"Text.Generic.Completed" = "Completado"; + +"Text.Generic.Contact" = "Contacto"; + +"Text.Generic.Continue" = "Continuar"; + +"Text.Generic.Destination" = "Destino"; + +"Text.Generic.Dismiss" = "Descartar"; + +"Text.Generic.Done" = "Hecho"; + +/* "Edit" used as a button (call to action) */ +"Text.Generic.Edit" = "Editar"; + +"Text.Generic.Email" = "Email"; + +"Text.Generic.EPrice" = "Precio estimado"; + +"Text.Generic.Error" = "Error"; + +"Text.Generic.ErrorMessage" = "¡Hubo un problema!"; + +/* English: "Estimated" */ +"Text.Generic.Estimated" = "Precio estimado"; + +"Text.Generic.ETA" = "Tiempo estimado"; + +"Text.Generic.ETALong" = "Hora de llegada estimada"; + +/* Reference to fixed pricing.. English equivalent: "Fixed" */ +"Text.Generic.Fixed" = "Precio fijo"; + +/* "Got It" (generally used on alert buttons) */ +"Text.Generic.GotIt" = "Entendido"; + +/* Password Entry Button */ +"Text.Generic.Hide" = "Ocultar"; + +"Text.Generic.Logout" = "Salir"; + +/* english "making a booking". Used in terms conditions construction */ +"Text.Generic.MakingBookingAction" = "realizar una reserva"; + +"Text.Generic.MeetGreet" = "Dar la bienvenida"; + +/* Metered fare type displayed in quotes list: English: "Metered" */ +"Text.Generic.Metered" = "Precio taxímetro"; + +"Text.Generic.Minutes" = "min"; + +"Text.Generic.Name" = "Nombre"; + +"Text.Generic.No" = "No"; + +"Text.Generic.NoCarsAvailable" = "No hay taxis disponibles en este momento. Inténtalo de nuevo mas tarde."; + +/* The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device" */ +"Text.Generic.NoEmailSetupError" = "Configura una cuenta de correo en tu dispositivo"; + +"Text.Generic.Ok" = "OK"; + +"Text.Generic.Optional" = "Opcional"; + +/* "Payment" used as a button in the side menu to reach all your payment methods */ +"Text.Generic.Payment" = "Pago"; + +/* "Payments" used as the title of the payment method screen */ +"Text.Generic.Payments" = "Pagos"; + +"Text.Generic.PhoneNumber" = "Número de teléfono"; + +"Text.Generic.Pickup" = "Punto de partida"; + +/* English: "Pickup Time" in booking request screen */ +"Text.Generic.PickupTime" = "Proximidad"; + +"Text.Generic.Prebook" = "Reservar"; + +"Text.Generic.Price" = "Precio"; + +"Text.Generic.PrivacyPolicy" = "Política de Privacidad"; + +"Text.Generic.Register" = "Registrarse"; + +/* english: "creating your Karhoo account". Used in terms conditions construction */ +"Text.Generic.RegisterAccountAction" = "crear una cuenta de Karhoo"; + +/* English: "Report Issue" */ +"Text.Generic.ReportIssue" = "Reportar problema"; + +/* String for when trip is initially loaded and no trip state has yet come through. "Requesting" */ +"Text.Generic.Requesting" = "Solicitando"; + +/* used in side menu "Rides" */ +"Text.Generic.Rides" = "Viajes"; + +/* "Save" used as a button (call to action) */ +"Text.Generic.Save" = "Salvar"; + +/* Password Entry Button */ +"Text.Generic.Show" = "Mostrar"; + +/* english: "status" */ +"Text.Generic.Status" = "Estado"; + +"Text.Generic.Submit" = "Enviar"; + +"Text.Generic.Success" = "El éxito"; + +"Text.Generic.Surname" = "Apellido"; + +"Text.Generic.TermsConditions" = "Condiciones Generales"; + +"Text.Generic.TermsOfUse" = "Condiciones de Uso"; + +/* "Thanks for your interest" */ +"Text.Generic.Thanks" = "Muchas gracias for tu interés"; + +/* Booker cancelled */ +"Text.Generic.TripStatus.BookerCancelled" = "El agente ha cancelado"; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "La flota está tardando más de lo habitual en asignar un conductor. Por favor espere, contacte con la flota o cancele y vuelva a reservar con una flota diferente."; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Retraso en asignación"; + +/* Driver Cancelled */ +"Text.Generic.TripStatus.DriverCancelled" = "El conductor ha cancelado"; + +/* No drivers available */ +"Text.Generic.TripStatus.NoDriversAvailable" = "No hay conductores disponibles"; + +/* "Unkown" */ +"Text.Generic.Unknown" = "Desconocido"; + +"Text.Generic.Yes" = "Si"; + +/* "Allocated" when a driver has been allocated */ +"Text.GenericTripStatus.Allocated" = "Asignado"; + +/* "Driver Approaching" */ +"Text.GenericTripStatus.Approaching" = "Conductor cerca"; + +/* Driver Arrived */ +"Text.GenericTripStatus.Arrived" = "El conductor ha llegado"; + +/* "Cancelled" */ +"Text.GenericTripStatus.Cancelled" = "Cancelado"; + +/* Cancelled by Karhoo */ +"Text.GenericTripStatus.CancelledByKarhoo" = "Cancelado por Karhoo"; + +/* "Completed" (trip completed) */ +"Text.GenericTripStatus.Completed" = "Completado"; + +/* Confirmed */ +"Text.GenericTripStatus.Confirmed" = "Confirmado"; + +/* "Driver En Route" when a driver is en route */ +"Text.GenericTripStatus.EnRoute" = "Conductor de camino"; + +/* "Failed" */ +"Text.GenericTripStatus.Failed" = "Error"; + +/* "Incomplete" */ +"Text.GenericTripStatus.Incomplete" = "Estado pendiente"; + +/* in english: "Requested" */ +"Text.GenericTripStatus.Initialised" = "Solicitado"; + +/* "On Board" */ +"Text.GenericTripStatus.PassengerOnBoard" = "Viaje en curso"; + +/* english: requested */ +"Text.GenericTripStatus.Requested" = "Solicitado"; + +/* "Pending" */ +"Text.GenericTripStatus.Unknown" = "Pendiente"; + +"Text.Help.ContactUs.Link" = "https://taxibookermobile.zendesk.com/hc/en-us/requests/new"; + +"Text.Help.FAQ.Link" = "https://taxibookermobile.zendesk.com/hc/en-us"; + +/* No availability in requested area, Fuzzy */ +"Text.KarhooError.K3002" = "Sin disponibilidad en la zona"; + +"Text.KarhooError.Q0001" = "La recogida y el destino no pueden ser iguales."; + +/* "Add new card" in english used in the payments section of the app. Referring to credit / debit card */ +"Text.Payment.AddPaymentMethod" = "Añadir un método de pago"; + +"Text.Payment.PaymentMethod" = "Tarjeta"; + +/* Prebook */ +"Text.Prebook.PrebookPickupTime" = "Día y hora de partida"; + +"Text.Prebook.SetPrebook" = "Seleccionar"; -/*"Payment Summary" header used on Trip Summary Screen*/ -"Text.TripSummary.PaymentSummary" = "Recibo"; +/* "Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes */ +"Text.Prebook.TimezoneMessage" = "Zona horaria (%1$@)"; -/*Used for the "Book Return Ride" button on the trip summary screen*/ -"Text.TripSummary.BookReturnRide" = "Reservar viaje de vuelta"; +"Text.Quote.FreeCancellationAndKeyword" = "y"; -/*"Date"*/ -"Text.TripSummary.Date" = "Fecha"; +"Text.Quote.FreeCancellationASAP" = "Cancelación gratuita hasta %1$@ minutos después de la reserva"; -/*Fleet*/ -"Text.TripSummary.Fleet" = "Flota"; -"Text.TripSummary.Vehicle" = "Vehículo"; +"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Cancelación gratuita hasta que el conductor esté en camino"; -/*Total Fare*/ -"Text.TripSummary.TotalFare" = "Tarifa total"; +/* Cancellation info on quotes */ +"Text.Quote.FreeCancellationPrebook" = "Cancelación gratuita hasta %1$@ antes de la recogida"; -/*Popup title message when dispatch cancels due to no drivers*/ -"Text.Trip.NoDriversAvailable.AlertTitle" = "No hay conductores disponibles"; +"Text.QuoteCategory.Electric" = "Eléctrico"; -/*Alert message in popup when dispatch cancels due to no drivers*/ -"Text.Trip.NoDriversAvailable.AlertMessage" = "No hay conductores disponibles"; +"Text.QuoteCategory.Exec" = "Ejecutivo"; -/*Password Entry Button*/ -/*Fuzzy*/ -"Text.Generic.Hide" = "Ocultar"; +"Text.QuoteCategory.Executive" = "Ejecutivo"; -/*Password Entry Button*/ -"Text.Generic.Show" = "Mostrar"; +"Text.QuoteCategory.Moto" = "Moto"; -/*"Quoted Price": used in trip summary screen when the fare is not available*/ -"Text.TripSummary.QuotedPrice" = "Tarifa estimada"; +"Text.QuoteCategory.Motorcycle" = "Motocicleta"; -/*Base fare title*/ -"Text.Booking.BaseFare" = "Tarifa Básica"; +"Text.QuoteCategory.MPV" = "Monovolumen"; -/*Guest checkout*/ -"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Detalles del pasajero"; -"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Detalles del pago"; -"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Su conductor esperará por usted"; +"Text.QuoteCategory.Saloon" = "Sedán"; -/*Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked*/ -"Text.Booking.PrebookConfirmation" = "Tu viaje de %1$@\na %2$@\nel %3$@ ha sido confirmado."; +"Text.QuoteCategory.Taxi" = "Taxi"; -/*Prebook Done*/ -"Text.Booking.PrebookConfirmed" = "Viaje confirmado"; +/* Side Menu "About" section title, Fuzzy */ +"Text.SideMenu.About" = "Información"; -/*Ride Details*/ -"Text.Booking.PrebookConfirmed.RideDetails" = "Detalles del viaje"; +"Text.SideMenu.Feedback" = "Sugerencias"; -/*"Past" used on past tabs on bookings list*/ -"Text.Bookings.Past" = "Anteriores"; +"Text.SideMenu.Help" = "Ayuda"; -/*Upcoming: used on upcoming tabs for rides*/ -/*Fuzzy*/ -"Text.Bookings.Upcoming" = "Próximos"; +/* Side Menu */ +"Text.SideMenu.Login" = "Acceder"; -/* We’re not live here yet! */ -"Text.Booking.NoAvailabilityHeader" = "¡Todavía no estamos operativos aquí!"; +/* "Profile" button on the side menu */ +"Text.SideMenu.Profile" = "Perfil"; -/* %1$@ if you have suggestions for local fleets. */ -"Text.Booking.NoAvailabilityBody" = "Ponte en %1$@ si conoces flotas locales."; +/* Register on the side menu */ +"Text.SideMenu.Register" = "Registrarse"; -/* Get in touch */ -"Text.Booking.NoAvailabilityLink" = "contacto"; +"Text.SideMenu.SignIn" = "Acceder"; -/* Finding your ride... */ -"Text.TripAllocation.FindingYourRide" = "Cargando tu viaje.."; +/* Sign Out on the side menu */ +"Text.SideMenu.SignOut" = "Salir"; + +"Text.SideMenu.Signup" = "Registrarse"; + +/* In app email to customer support / feedback */ +"Text.SupportMailMessage.Feedback" = "Por favor no elimines esta información ya que nos ayuda a mejorar la app."; + +"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; + +"Text.SupportMailMessage.FeedbackSubject" = "Sugerencias"; + +"Text.SupportMailMessage.NoCoverageBody" = "Gracias por recomendarnos una flota en tu zona. Para poder llegar a tu zona lo antes posible, indícanos el nombre de tu zona y de la flota.\n Zona:\n Flota:"; + +/* No coverage email */ +"Text.SupportMailMessage.NoCoverageSubject" = "Flota recomendada"; + +"Text.SupportMailMessage.ReportIssue" = "Por favor, deje sus comentarios sobre un tema específico en el espacio a continuación."; + +"Text.SupportMailMessage.ReportIssueSubject" = "Reportar problema"; + +"Text.SupportMailMessage.SupplierEmail" = "suppliers@karhoo.com"; + +"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; + +/* Used in the checkout component before booking a ride */ +"Text.TermsConditions.BookingFullString" = "Al hacer una reserva, usted acepta las %1$@ | %2$@ así como los %4$@ de %3$@ | %5$@ de %3$@."; + +"Text.TermsConditions.FullString" = "Al %1$@ con %2$@, aceptas las \n %3$@ | %4$@"; + +"Text.TermsConditions.KarhooPolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.KarhooTermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TermsConditions.PolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.TermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TrackingLink.production" = "https://agent-portal.karhoo.com/follow/"; + +/* Trip Tracking Links */ +"Text.TrackingLink.sandbox" = "https://agent-portal.sandbox.karhoo.com/follow/"; + +"Text.TrackingLink.staging" = "https://agent-portal.stg.karhoo.net/follow/"; + +"Text.Trip.ActivityIndicator.Cancelling" = "Cancelando"; + +/* "Arrival" displayed on arrival box in trip */ +"Text.Trip.Arrival" = "Llegada"; + +"Text.Trip.CallDriver" = "Llamar conductor"; + +/* Call fleet button in trip screen (English: Call Fleet) */ +"Text.Trip.CallFleet" = "Llamar flota"; + +"Text.Trip.CancelBookingConfirmation.Alert.Message" = "Puede que se te cobre una tarifa de cancelación"; + +"Text.Trip.CancelBookingConfirmation.Alert.Title" = "¿Cancelar tu viaje?"; + +/* displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking" */ +"Text.Trip.CancelBookingFailed" = "Cancelación no confirmada. Llama a la flota."; + +"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Llamar a la flota"; + +"Text.Trip.CancelBookingFailed.AlertMessage" = "Hubo un problema cancelando tu solicitud. Llama a la flota."; + +"Text.Trip.CancelBookingFailed.AlertTitle" = "Cancelación fallida"; + +"Text.Trip.CancelledByDispatch" = "Lo sentimos, la flota canceló tu reserva."; + +"Text.Trip.CancelledByDispatch.AlertMessage" = "Lo sentimos, la flota canceló tu reserva. Inténtalo de nuevo."; + +"Text.Trip.CancelledByDispatch.AlertTitle" = "Cancelado por la flota"; + +"Text.Trip.CancelledByUser" = "Has cancelado la reserva"; + +/* Trip */ +"Text.Trip.CancelRide" = "Cancelar reserva"; + +"Text.Trip.Completed" = "Llegaste a tu destino"; + +"Text.Trip.Confirmed" = "Tu solicitud ha sido aceptada. \nSe te está asignando un conductor."; + +"Text.Trip.DriverArrived" = "¡Tu conductor ha llegado!"; + +"Text.Trip.DriverEnRoute" = "Tu conductor está de camino"; + +/* alert message when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertMessage" = "Karhoo canceló tu reserva"; + +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertTitle" = "Cancelación"; + +"Text.Trip.MessageDriver" = "Enviar SMS"; + +/* For when demand is too high and there are no drivers available */ +"Text.Trip.NoDriversAvailable" = "No hay conductores disponibles"; + +/* Alert message in popup when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertMessage" = "No hay conductores disponibles"; + +/* Popup title message when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertTitle" = "No hay conductores disponibles"; + +"Text.Trip.PassengerOnBoard" = "Ya estás de camino ¡Buen viaje!"; + +/* Trip Statuses */ +"Text.Trip.Requested" = "Esto puede demorarse unos instantes"; + +/* Used as a button in the trip screen. English: "Ride Options" */ +"Text.Trip.RideOptions" = "Opciones"; /* Please wait whilst you\'re allocated a driver */ "Text.TripAllocation.AllocatingTripOne" = "Espera hasta que se te asigne un conductor"; @@ -470,142 +765,98 @@ /* This may take a moment or two */ "Text.TripAllocation.AllocatingTripTwo" = "Esto puede llevar unos minutos"; -/* cancelling */ +"Text.TripAllocation.CancelInstruction" = "Mantenga pulsado para cancelar"; + "Text.TripAllocation.Cancelling" = "Cancelando"; -/* cancel instructions (tap and hold to cancel) prompt on allocation screen */ -"Text.TripAllocation.CancelInstruction" = "Mantenga pulsado para cancelar"; +/* Finding your ride... */ +"Text.TripAllocation.FindingYourRide" = "Cargando tu viaje.."; -/*"All" used for all categories filter on category list. Write normally as the app will uppercase the string*/ -"Text.Availability.AllCategory" = "Todo"; -"SALOON" = "Salón"; -"MPV" = "MPV"; -"EXEC" = "Ejecutivo"; -"TAXI" = "Taxi"; -"ELECTRIC" = "Eléctrico"; +/* Trip Rating */ +"Text.TripRating.Confirmation" = "Gracias por enviar tu calificación."; -/*Cancelled by Karhoo*/ -"Text.GenericTripStatus.CancelledByKarhoo" = "Cancelado por Karhoo"; +"Text.TripRating.ExtraFeedback" = "Cuentanos más"; -/*alert title when karhoo cancel the trip-supposedly happens for preauth failure*/ -"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Cancelación"; +"Text.TripRating.Title" = "¿Como clasifica usted este viaje?"; -/*alert message when karhoo cancel the trip-supposedly happens for preauth failure*/ -"Text.Trip.KarhooCancelled.AlertMessage" = "Karhoo canceló tu reserva"; +/* Used for the "Book Return Ride" button on the trip summary screen */ +"Text.TripSummary.BookReturnRide" = "Reservar viaje de vuelta"; -/*When the user enters an invalid flight number*/ -/*Fuzzy*/ -"Text.Error.FlightNumberValidationHint" = "Número de vuelo"; +/* "Date" */ +"Text.TripSummary.Date" = "Fecha"; -/*"Arrival" displayed on arrival box in trip*/ -"Text.Trip.Arrival" = "Llegada"; +/* Fleet */ +"Text.TripSummary.Fleet" = "Flota"; -/*Theoretical edge case where the braintree token is missing*/ -"Text.Errors.failedToInitialisePaymentSetup" = "Error al iniciar la configuración del pago"; +/* "Payment Summary" header used on Trip Summary Screen */ +"Text.TripSummary.PaymentSummary" = "Recibo"; + +/* "Quoted Price": used in trip summary screen when the fare is not available */ +"Text.TripSummary.QuotedPrice" = "Tarifa estimada"; + +/* Total Fare */ +"Text.TripSummary.TotalFare" = "Tarifa total"; + +/* "Trip Summary" header used on screen */ +"Text.TripSummary.TripSummary" = "Resumen del viaje"; + +"Text.TripSummary.Vehicle" = "Vehículo"; + +"Text.User.Email" = "Email"; + +"Text.User.EmailSubscription" = "No deseo recibir viajes gratuitos, promociones ni ofertas"; + +/* User (register / login / user attributes) */ +"Text.User.FirstName" = "Nombre"; -/*Text used on button to trigger password reset... English: Forgotten Password? */ +/* Text used on button to trigger password reset... English: Forgotten Password? */ "Text.User.ForgottenPassword" = "¿Olvidaste tu contraseña?"; -/* empty table view result */ -"Text.Errors.NoResultsFound" = "Sin resultados"; +"Text.User.LastName" = "Apellidos"; -"Text.Availability.NoQuotesInSelectedCategory" = "No hay disponibilidad en la categoría solicitada.\n Por favor seleccione otra categoría."; -"Text.Availability.NoQuotesForSelectedParameters" = "No hay disponibilidad para la hora solicitada. Por favor, seleccione una hora diferente."; +"Text.User.MobilePhoneNumber" = "Número de teléfono"; -"Text.Address.NoRecentAddress" = "No hay resultados recientes"; +"Text.User.Password" = "Contraseña"; -"Text.SupportMailMessage.NoCoverageSubject" = "Flota recomendada"; -"Text.SupportMailMessage.NoCoverageBody" = "Gracias por recomendarnos una flota en tu zona. Para poder llegar a tu zona lo antes posible, indícanos el nombre de tu zona y de la flota.\n Zona:\n Flota:"; +"Text.User.PhoneCountryCode" = "Prefijo"; -/* Cancellation info on quotes */ -"Text.Quote.FreeCancellationPrebook" = "Cancelación gratuita hasta %1$@ antes de la recogida"; -"Text.Quote.FreeCancellationASAP" = "Cancelación gratuita hasta %1$@ minutos después de la reserva"; -"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Cancelación gratuita hasta que el conductor esté en camino"; -"Text.Quote.FreeCancellationAndKeyword" = "y"; +/* "We will notify you via email once your request has been processed." */ +"Text.User.SignupPendingMessage" = "Te notificaremos por email una vez tu solicitud haya sido aceptada."; -/* General errors, K0xxx */ -"K0001" = "Error general"; -"K0002" = "Petición de solicitud no válida"; -"K0003" = "Imposible leer el token de autorización"; -"K0004" = "La autenticación es necesaria para esta ruta"; -"K0005" = "Falta el rol requerido para esta solicitud"; -"K0006" = "Límite excedido"; -"K0007" = "Error generalizado"; +"Text.VehicleClass.Electric" = "Eléctrico"; -/* User errors, K1xxx */ -"K1001" = "Imposible registrar usuario"; -"K1002" = "Imposible registrar usuario (el usuario ya existe)"; -"K1003" = "Imposible registrar usuario"; -"K1004" = "Imposible registrar usuario (número de teléfono no válido)"; -"K1005" = "Imposible obtener los datos del usuario (token no válido)"; -"K1006" = "Imposible obtener los datos del usuario (el usuario ya existe)"; +"Text.VehicleClass.Exec" = "Ejecutivo"; -/* Locations errors, K2xxx */ -"K2001" = "Imposible obtener dirección"; +"Text.VehicleClass.Executive" = "Ejecutivo"; -/* Quotes errors, K3xxx */ -"K3001" = "Imposible obtener estimaciones"; -"K3002" = "Imposible obtener estimaciones (no se encontró disponibilidad en el área solicitada)"; -"K3003" = "Imposible obtener estimaciones (no se encontró la tarifa específica)"; +"Text.VehicleClass.Moto" = "Moto"; -/* Bookings errors, K4xxx */ -"K4001" = "Imposible reservar"; -"K4002" = "Imposible reservar - solicitud inválida (se requiere al menos un valor para detalles de pasajero 'passenger-details')"; -"K4003" = "Imposible reservar (no se encontró la cotización especificada)"; -"K4004" = "Imposible reservar (intento de reserva de cotización caducada)"; -"K4005" = "Imposible reservar (Permiso denegado)"; -"K4006" = "Imposible reservar (Pre-autorización de pago fallida)"; -"K4007" = "Cancelación fallida"; -"K4008" = "Cancelación fallida (No se ha encontrado la reserva)"; -"K4009" = "Cancelación fallida (Permiso denegado)"; -"K4010" = "Cancelación fallida (Este viaje ya ha sido cancelado)"; -"K4011" = "No se pudo obtener la reserva"; -"K4012" = "No se pudo obtener la reserva (No se ha encontrado la reserva)"; -"K4013" = "No se pudo obtener la reserva (Permiso denegado)"; -"K4014" = "No pudo completarse la reserva como agente (Agent)"; -"K4015" = "No pudo completarse la reserva como pasajero (Traveller)"; -"K4018" = "No pudo realizarse la reserva al no estar ya disponible la cotización"; +"Text.VehicleClass.Motorcycle" = "Motocicleta"; -/* Availability errors, K5xxx */ -"K5001" = "No se pudo obtener estimaciones"; -"K5002" = "Sin disponibilidad (no se encontró disponibilidad en el área solicitada)"; -"K5003" = "Sin disponibilidad (no se encontraron categorías en el área solicitada)"; +"Text.VehicleClass.MPV" = "Monovolumen"; -/* Authentication errors K6xxx */ -"K6001" = "No se puede autenticar"; +"Text.VehicleClass.Saloon" = "Sedán"; -/* KPOI errors, K7xxx */ -"K7001" = "Imposible procesar la solicitud del PDIK"; -"K7002" = "No se pudo encontrar el PDI de Karhoo con el ID correspondiente"; -"K7003" = "No se pudo leer el PDI de Karhoo"; -"K7004" = "No se pudo añadir el PDI de Karhoo"; -"K7005" = "No se pudo eliminar el PDI de Karhoo"; -/* Qxxxx errors */ -"Q0001" = "La recogida y el destino no pueden ser iguales."; +"Text.VehicleClass.Taxi" = "Taxi"; -/* KSDKxxx Internal SDK */ -"KSDK01" = "Se ha producido un error. Inténtelo de nuevo."; -"KSDK02" = "Falta una función de usuario requerida para esta solicitud"; -"KSDK03" = "Usuario ya ha iniciado sesión"; +"Text.VehicleTag.Childseat" = "Sillita bebe"; -/* PickUp Type */ -"DEFAULT" = "Default"; -"MEET_AND_GREET" = "Dar la bienvenida"; -"CURBSIDE" = "Recoger afuera"; -"STAND_BY" = "Llamar conductor"; +/* Vehicle tags */ +"Text.VehicleTag.Electric" = "Eléctrico"; -/* Trip Rating */ -"Text.TripRating.Confirmation" = "Gracias por enviar tu calificación."; -"Text.TripRating.Title" = "¿Como clasifica usted este viaje?"; -"Text.TripRating.ExtraFeedback" = "Cuentanos más"; +"Text.VehicleTag.Executive" = "Ejecutivo"; -/* FeedBackView */ -"Text.FeedbackView.quote" = "How happy were you with the selection of quotes for your trip (e.g. Fleets, Prices and ETAs)?"; -"Text.FeedbackView.pre_pob" = "How was your experience with finding the pick-up location and meeting your driver?"; -"Text.FeedbackView.pob" = "How was your experience whilst in the taxi (e.g. taxi cleanliness, routing and driver)? How easy did you find using the app?"; -"Text.FeedbackView.app" = "How easy did you find using the app?"; -"Text.FeedbackView.addComment" = "Additional comments"; -"Text.FeedbackView.confirmation" = "Gracias por enviar sus comentarios"; +"Text.VehicleTag.Hybrid" = "Híbrido"; + +"Text.VehicleTag.Taxi" = "Taxi"; + +"Text.VehicleTag.Wheelchair" = "Adaptado"; + +"Text.VehicleType.Bus" = "Autobús"; + +"Text.VehicleType.Moto" = "Moto"; + +"Text.VehicleType.MPV" = "Monovolumen"; + +"Text.VehicleType.Standard" = "Estándar"; -"Text.Address.SetOnMap" = "Establecer en el mapa"; -"Text.Address.CurrentLocation" = "Posición actual"; diff --git a/KarhooUISDK/Translations/fr.lproj/Localizable.strings b/KarhooUISDK/Translations/fr.lproj/Localizable.strings index e438f09d1..a41615963 100644 --- a/KarhooUISDK/Translations/fr.lproj/Localizable.strings +++ b/KarhooUISDK/Translations/fr.lproj/Localizable.strings @@ -1,590 +1,883 @@ +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Annulation par Karhoo"; -/*Localizable.strings - Karhoo +"CURBSIDE" = "Prise en charge à l'extérieur"; - Copyright © 2020 Karhoo. All rights reserved. - Generics*/ +/* PickUp Type */ +"DEFAULT" = "Default"; -"Text.Generic.Cancel" = "Annuler"; -"Text.Generic.Ok" = "OK"; -"Text.Generic.Close" = "Fermer"; -"Text.Generic.Done" = "Terminer"; -"Text.Generic.Back" = "Retour"; -"Text.Generic.Error" = "Erreur"; -"Text.Generic.Register" = "Inscription"; -"Text.Generic.Logout" = "Déconnexion"; -"Text.Generic.Contact" = "Contact"; -"Text.Generic.Bookings" = "Réservations"; -"Text.Generic.Destination" = "Arrivée"; -"Text.Generic.Pickup" = "Départ"; -"Text.Generic.ETA" = "Proximité"; -"Text.Generic.ETALong" = "Proximité"; -"Text.Generic.EPrice" = "Prix estimé"; -"Text.Generic.Price" = "Prix"; -"Text.Generic.Prebook" = "Réserver"; -"Text.Generic.Add" = "Ajouter"; -"Text.Generic.Change" = "Modifier"; -"Text.Generic.Submit" = "Envoyer"; -"Text.Generic.Success" = "Réussite"; -"Text.Generic.Name" = "Prénom"; -"Text.Generic.Surname" = "Nom"; -"Text.Generic.Email" = "Adresse email"; -"Text.Generic.PhoneNumber" = "Numéro de téléphone"; -"Text.Generic.Comment" = "Commentaire"; -"Text.Generic.Optional" = "Optionnel"; -"Text.Generic.ErrorMessage" = "Une erreur est survenue"; +"ELECTRIC" = "Electrique"; -/*english: "creating your Karhoo account". Used in terms conditions construction*/ -"Text.Generic.RegisterAccountAction" = "créant un compte Karhoo"; +"EXEC" = "BUSINESS"; -/*english "making a booking". Used in terms conditions construction*/ -"Text.Generic.MakingBookingAction" = "confirmant la commande"; -"Text.Generic.TermsConditions" = "Conditions générales d'utilisation"; -"Text.Generic.PrivacyPolicy" = "Règles de confidentialité"; -"Text.Generic.Minutes" = "min"; -"Text.Generic.Continue" = "Continuer"; +/* English: Error codes */ +"K0001" = "Désolé! Une erreur s'est produite"; + +"K0002" = "Requête non valide"; + +"K0003" = "Impossible de lire le jeton d'autorisation"; + +"K0004" = "Authentification nécessaire"; + +"K0005" = "Rôle non défini pour effectuer cette action"; + +"K0006" = "Limite de débit dépassée"; + +"K0007" = "Connection coupée pour cette URL"; + +/* User errors, K1xxx */ +"K1001" = "Impossible d'enregistrer l'utilisateur"; + +"K1002" = "Impossible d'enregistrer l'utilisateur (utilisateur déjà inscrit)"; + +"K1003" = "Impossible d'enregistrer l'utilisateur (requête non valide)"; + +"K1004" = "Impossible d'enregistrer l'utilisateur (numéro de téléphone non valide)"; + +"K1005" = "Impossible de trouver les détails de l'utilisateur (authentification non valide)"; + +"K1006" = "Impossible de trouver les détails de l'utilisateur (utilisateur non créé)"; + +"K1999" = "Utilisateur enregistré, nous vous contacterons par email dès que votre compte sera activé."; + +/* Locations errors, K2xxx */ +"K2001" = "Impossible de trouver l'adresse"; + +/* Quotes errors, K3xxx */ +"K3001" = "Impossible de trouver un devis"; + +"K3002" = "Impossible de trouver un devis (aucune flotte trouvée dans la zone demandée)"; + +"K3003" = "Impossible de trouver un devis (devis en question non trouvé)"; + +/* Bookings errors, K4xxx */ +"K4001" = "Impossible de compléter la commande"; + +"K4002" = "Impossible de compléter la commande - requête non valide (au moins une valeur de detail(s)-passager est requise)"; + +"K4003" = "Impossible de compléter la commande (impossible de trouver le devis en question)"; + +"K4004" = "Impossible de compléter la commande (le devis a expiré et n’est plus valable)"; + +"K4005" = "Impossible de compléter la commande (Permission refusée.)"; + +"K4006" = "Impossible de compléter la commande (Refus d'autorisation de paiement.)"; + +"K4007" = "Impossible d'annuler la commande"; + +"K4008" = "Impossible d'annuler la commande (Impossible de trouver la course.)"; + +"K4009" = "Impossible d'annuler la commande (Permission refusée.)"; + +"K4010" = "Impossible d'annuler la commande (Cette course est déjà annulée)"; + +"K4011" = "Impossible de trouver cette course"; + +"K4012" = "Impossible de trouver la commande (Impossible de trouver la course.)"; + +"K4013" = "Impossible de trouver la commande (Permission refusée.)"; + +"K4014" = "Impossible de compléter la commande en tant qu’Agent"; + +"K4015" = "Impossible de compléter la commande en tant que Traveller"; + +"k4015" = "Impossible de compléter la commande en tant que Traveller"; + +"K4018" = "Impossible de compléter la réservation car le devis n'est plus disponible"; + +"K4020" = "Impossible de réserver un voyage avec le DMS sélectionné"; + +"K4025" = "Prix du devis augmenté lors de la réservation"; + +/* Availability errors, K5xxx */ +"K5001" = "Impossible de trouver un devis"; + +"K5002" = "Impossible de trouver un devis (aucune flotte trouvée dans la zone demandée)"; + +"K5003" = "Impossible de trouver un devis (aucune catégorie trouvée dans la zone demandée)"; + +/* Authentication errors K6xxx */ +"K6001" = "Identifiant ou mot de passe incorrect. Merci d'essayer à nouveau"; + +/* KPOI errors, K7xxx */ +"K7001" = "Impossible de completer la requête KPOI"; -/*Address Bar*/ +"K7002" = "Impossible de faire correspondre le KPOI à une identité"; + +"K7003" = "Impossible de lire le KPOI"; + +"K7004" = "Impossible d'écrire le KPOI"; + +"K7005" = "Impossible d'effacer le KPOI"; + +/* KSDKxxx Internal SDK */ +"KSDK01" = "Une erreur inconnue s’est produite. Veuillez réessayer."; + +"KSDK02" = "Permission(s) manquante(s) pour cette requête."; + +"KSDK03" = "Utilisateur déjà connecté"; + +"MEET_AND_GREET" = "Accueil pancarte"; + +"MPV" = "VAN"; + +/* Qxxxx errors */ +"Q0001" = "Départ et destination ne peuvent pas être identiques."; + +"SALOON" = "BERLINE"; + +"STAND_BY" = "Contacter chauffeur"; + +"TAXI" = "TAXI"; + +/* "Version" */ +"Text.About.Version" = "Version"; + +"Text.Address.CurrentLocation" = "Position actuelle"; + +"Text.Address.NoRecentAddress" = "Aucune adresse récente trouvée"; + +"Text.Address.SetOnMap" = "Situer sur la carte"; + +/* Address Bar */ "Text.AddressBar.AddDestination" = "Ajouter une destination"; + "Text.AddressBar.AddPickup" = "Ajouter une adresse de départ"; + "Text.AddressBar.EnterPickupLocation" = "Adresse de départ"; + "Text.AddressSearch.EnterDestinationLocation" = "Adresse de destination"; -/*User (register / login / user attributes)*/ -"Text.User.FirstName" = "Prénom"; -"Text.User.LastName" = "Nom"; -"Text.User.Email" = "Email"; -"Text.User.PhoneCountryCode" = "Préfixe"; -"Text.User.MobilePhoneNumber" = "Téléphone"; -"Text.User.Password" = "Mot de passe"; -"Text.User.EmailSubscription" = "Je ne souhaite pas recevoir de courses gratuites ou d'offres promotionnelles"; +/* "Add Flight Details" used on booking airport ride */ +"Text.Airport.AddFlightDetails" = "Détails supplémentaires"; -/*Errors*/ -"Text.Error.EmailValidationError" = "Vérifiez que votre adresse Email est écrite correctement"; -"Text.Error.Booking.EnterDestinationToProceed" = "Entrez une destination pour procéder à la réservation"; -"Text.Error.NotLoggedIn" = "Vous n'êtes pas identifié."; -"Text.TermsConditions.FullString" = "En %1$@, vous acceptez les %3$@ et %4$@ de %2$@"; +/* "Flight number" used as the flight number field placeholder */ +"Text.Airport.FlightNumber" = "Numéro de vol"; -/*Side Menu*/ -"Text.SideMenu.Login" = "S'identifier"; -"Text.SideMenu.SignIn" = "S'identifier"; -"Text.SideMenu.Signup" = "S'inscrire"; -"Text.SideMenu.Help" = "Aide"; -"Text.SideMenu.Feedback" = "Remarques"; +/* Message on airport screen for encouraging user to enter as much info about airport booking as possible */ +"Text.Airport.HelpfulMessage" = "Veuillez entrer un numéro de vol valide"; -/*In app email to customer support / feedback*/ -/*Fuzzy*/ -"Text.SupportMailMessage.Feedback" = "Veuillez ne pas supprimer ces informations car elles nous aident à améliorer l\'application."; -/*english: "Please leave your comments regarding a specific issue in the space below." used when reporting issue with trip*/ -/*Fuzzy*/ -"Text.SupportMailMessage.ReportIssue" = "Veuillez laisser vos commentaires regardant un problème spécifique dans l'espace ci-dessous."; -"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; -"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; -"Text.SupportMailMessage.SupplierEmail" = "suppliers@karhoo.com"; -"Text.SupportMailMessage.FeedbackSubject" = "Remarques"; -"Text.SupportMailMessage.ReportIssueSubject" = "Signaler un problème"; +/* "Airport Pickup" used on screen for airport bookinga */ +"Text.Airport.Pickup" = "Prise en charge aéroport"; -/*Prebook*/ -"Text.Prebook.PrebookPickupTime" = "Date et heure du départ"; -"Text.Prebook.SetPrebook" = "Choisir"; +/* "All" used for all categories filter on category list. Write normally as the app will uppercase the string */ +"Text.Availability.AllCategory" = "Tous"; + +"Text.Availability.NoQuotesForSelectedParameters" = "Aucune course disponible à l\'horaire demandé. Veuillez modifier votre horaire."; + +"Text.Availability.NoQuotesInSelectedCategory" = "Aucun devis disponible pour cette catégorie. \n Veuillez choisir une autre catégorie."; + +/* Base fare title */ +"Text.Booking.BaseFare" = "Prix de base"; + +/* "Your final fare might be affected by tips, tolls, taxes, and other charges." */ +"Text.Booking.BaseFareExplanation" = "Le prix final peut être affecté par des péages, pourboires, taxes ou autres surcharges."; + +"Text.Booking.CountryCodeSelection.Search" = "Recherche pays/région"; + +/* Country Code Selection */ +"Text.Booking.CountryCodeSelection.Title" = "Pays / Région"; + +"Text.Booking.EnterDestination" = "Ajoutez une destination pour voir les véhicules disponibles"; + +/* Checkout component */ +"Text.Booking.EstimatedInfoBox" = "Cette flotte est un taxi non réglementé. Le devis est une estimation basée sur les facteurs du trajet (distance, temps, etc.). Veuillez consulter les conditions générales de la flotte pour plus d'informations."; + +"Text.Booking.FixedInfoBox" = "Cette flotte applique un tarif forfaitaire. Le tarif final peut être affecté par des extras (péages, retard, etc.), veuillez consulter les conditions générales de la flotte."; + +"Text.Booking.FlightTracking" = "Associe votre vol"; + +"Text.Booking.GPSTracking" = "Suivi GPS"; + +"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Numéro de vol (Optionnel)"; + +/* Guest checkout */ +"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Informations sur le passager"; + +"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Méthodes de paiement"; + +"Text.Booking.LearnMore" = "Plus"; + +"Text.Booking.MaximumLuggages" = "%1$@ bagages maximum"; + +"Text.Booking.MaximumPassengers" = "%1$@ passagers maximum"; + +"Text.Booking.MeteredInfoBox" = "Cette flotte est un taxi à compteur réglementé. Le devis est une estimation basée sur les facteurs de la course (distance, temps, etc.)."; + +"Text.Booking.Next" = "SUIVANT"; + +/* %1$@ if you have suggestions for local fleets. */ +"Text.Booking.NoAvailabilityBody" = "%1$@ pour nous en suggérer."; + +/* We’re not live here yet! */ +"Text.Booking.NoAvailabilityHeader" = "Nous n'avons pas encore de flottes dans cette zone."; + +/* Get in touch */ +"Text.Booking.NoAvailabilityLink" = "Contactez-nous"; + +"Text.Booking.Passenger" = "Passager"; + +"Text.Booking.PassengerDetails.Add" = "Ajouter passager"; + +"Text.Booking.PassengerDetails.Email" = "Email"; + +"Text.Booking.PassengerDetails.FirstName" = "Prénom"; + +"Text.Booking.PassengerDetails.LastName" = "Nom"; + +"Text.Booking.PassengerDetails.MobilePhone" = "Numéro de mobile"; + +"Text.Booking.PassengerDetails.SaveAction" = "SAUVEGARDER"; + +"Text.Booking.PassengerDetails.Subtitle" = "Ces informations permettent le bon déroulement de votre course"; + +/* Passenger Details */ +"Text.Booking.PassengerDetails.Title" = "Passager"; + +/* Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked */ +"Text.Booking.PrebookConfirmation" = "Votre réservation\nde: %1$@.\nÀ: %2$@.\nLe: %3$@ est confirmée."; + +/* Prebook Done, Fuzzy */ +"Text.Booking.PrebookConfirmed" = "Course confirmée"; + +/* Ride Details */ +"Text.Booking.PrebookConfirmed.RideDetails" = "Détails de la course"; + +/* Booking */ +"Text.Booking.RequestCar" = "RÉSERVER"; -/*Booking*/ -"Text.Booking.RequestCar" = "Commander"; "Text.Booking.RequestingCar" = "Commande en cours"; -"Text.Booking.RequestReceived" = "Commande reçue"; + +"Text.Booking.RequestReceived" = "Réservation reçue"; + +"Text.Booking.TrainTracking" = "Associe votre train"; + +"Text.Bookings.Alert.CancellationFee.Charge" = "Des frais d'annulation estimés à %1$@ vont s'appliquer.\n\nSouhaitez-vous continuer ?"; + +"Text.Bookings.Alert.CancellationFee.Continue" = "Souhaitez-vous continuer ?"; + +"Text.Bookings.Alert.CancellationSuccess.Message" = "Votre course a été annulée avec succès."; + +"Text.Bookings.Alert.CancellationSuccess.Title" = "Annulation confirmée"; + +/* used as a call to action on a button in the empty bookings screen: English: "Book Ride" */ +"Text.Bookings.BookATrip" = "Réserver"; + +/* "Cancel Ride" button action */ +"Text.Bookings.CancelRide" = "Annuler la course"; + +/* "Contact Driver" (button action) */ +"Text.Bookings.ContactDriver" = "Contacter le chauffeur"; + +/* "Contact Fleet" */ +"Text.Bookings.ContactFleet" = "Contacter la flotte"; + +/* Generic fallback message for trip load failure */ +"Text.Bookings.CouldNotLoadTrips" = "Impossible de charger les courses"; + "Text.Bookings.eta" = "Proximité"; + +/* English: "No Trips" used if the booking list screen is empty */ +"Text.Bookings.NoTrips" = "Aucune réservation"; + +/* used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B" */ +"Text.Bookings.NoTripsBookedMessage" = "Vous n'avez aucune réservation. Nous pouvons vous aider pour votre prochain trajet."; + +/* "Past" used on past tabs on bookings list */ +"Text.Bookings.Past" = "Terminées"; + "Text.Bookings.price" = "Prix"; -/*Trip*/ -/*Fuzzy*/ -"Text.Trip.CancelRide" = "Annuler"; -"Text.Trip.MessageDriver" = "Envoyer un SMS"; -"Text.Trip.CallDriver" = "Appeler le chauffeur"; +"Text.Bookings.Price" = "Prix"; -/*Trip Statuses*/ -/*Fuzzy*/ -"Text.Trip.Requested" = "Ceci peut prendre quelques instants."; -"Text.Trip.Confirmed" = "Votre commande a été acceptée. Attente d'attribution du chauffeur."; -"Text.Trip.DriverEnRoute" = "Votre chauffeur est en route."; -"Text.Trip.DriverArrived" = "Votre chauffeur est arrivé."; -"Text.Trip.PassengerOnBoard" = "Vous êtes en route. Faites un bon voyage."; -"Text.Trip.Completed" = "Vous avez atteint votre destination."; -"Text.Trip.CancelledByUser" = "Vous avez annulé la course."; -"Text.Trip.CancelledByDispatch" = "Nous sommes désolés, votre course a été annulée par le fournisseur. Veuillez nous excuser et utiliser l'application pour voir les taxis disponibles."; -"Text.Trip.Completed" = "Vous avez atteint votre destination. Prenez un moment pour nous laisser vos commentaires sur votre course."; +"Text.Bookings.Price.Cancelled" = "Annulé"; -/*English: "Pickup Time" in booking request screen*/ -"Text.Generic.PickupTime" = "Temps d'attente"; +"Text.Bookings.Quote" = "Devis"; -/*Reference to fixed pricing.. English equivalent: "Fixed"*/ -/*Fuzzy*/ -"Text.Generic.Fixed" = "Fixe"; +/* Button for rebooking a ride */ +"Text.Bookings.RebookRide" = "Re-commander"; -/*Register on the side menu*/ -"Text.SideMenu.Register" = "Inscription"; +/* "Report Issue" Button */ +"Text.Bookings.ReportIssue" = "Signaler un problème"; -/*Sign Out on the side menu*/ -"Text.SideMenu.SignOut" = "Déconnexion"; +/* "Track Driver" */ +"Text.Bookings.TrackDriver" = "Suivre le chauffeur"; + +/* "Track Trip" */ +"Text.Bookings.TrackTrip" = "Suivre la course"; + +"Text.Bookings.TrackTrip.AlertMessage" = "Voulez-vous suivre le véhicule ?"; + +"Text.Bookings.TrackTrip.AlertTitle" = "Le chauffeur est en route"; + +"Text.Bookings.TrackTrip.DismissAction" = "Non"; + +"Text.Bookings.TrackTrip.TrackAction" = "Oui"; + +/* Upcoming: used on upcoming tabs for rides, Fuzzy */ +"Text.Bookings.Upcoming" = "À venir"; + +"Text.Error.Alert.CantSendEmail" = "Le message ne peut être envoyé. Veuillez configurer votre compte email sur votre téléphone."; + +/* The action button on the force update alert. ie "Update" (this button takes the user to the app store) */ +"Text.Error.Alert.ForceUpdateButton" = "Mise à jour"; + +/* The message when the user needs to update the app. ie. "Please update Karhoo to the latest version." */ +"Text.Error.Alert.ForceUpdateMessage" = "Veuillez actualiser l'application pour continuer"; + +/* The title of the alert when user is forced to update ie "App Update Required" */ +"Text.Error.Alert.ForceUpdateTitle" = "Une mise à jour est disponible"; + +"Text.Error.Booking.EnterDestinationToProceed" = "Entrez une destination pour procéder à la réservation"; + +/* Errors */ +"Text.Error.EmailValidationError" = "Vérifiez que votre adresse Email est écrite correctement"; + +/* When the user enters an invalid flight number, Fuzzy */ +"Text.Error.FlightNumberValidationHint" = "Numéro de vol"; + +/* When fetching the user profile fails */ +"Text.Error.GetUserFails" = "Impossible de charger le profil d'utilisateur"; + +/* Used to explain an unknown error. ie "Oops, something went wrong. Please try again" */ +"Text.Error.NoDetails" = "Une erreur est survenue, veuillez réessayer plus tard."; + +"Text.Error.NotLoggedIn" = "Vous n'êtes pas connecté."; + +"Text.Error.Payment.Alert.ButtonUpdateCard" = "Modifier carte"; + +"Text.Error.Payment.Alert.Message" = "Nous n'avons pas pu obtenir l'autorisation pour ce paiement."; + +"Text.Error.Payment.Alert.Title" = "Un problème est survenu avec votre carte"; + +/* Error message when user tries to prebook within the current hour of local time */ +"Text.Error.PrebookingWithinTheHour" = "L'heure et date de la commande doit être supérieure à une heure"; -/*"Cancelled"*/ +/* "Something went wrong" used as a title for error alert */ +"Text.Error.SomethingWentWrong" = "Une erreur est survenue"; + +/* Theoretical edge case where the braintree token is missing */ +"Text.Errors.failedToInitialisePaymentSetup" = "Erreur d'initialisation du processus de paiement. Veuillez réessayer."; + +"Text.Errors.InvalidPhoneNumber" = "Numéro de portable non valide"; + +"Text.Errors.MissingPhoneNumber" = "Ce champ ne peut pas rester vide."; + +/* empty table view result */ +"Text.Errors.NoResultsFound" = "Aucun résultat trouvé"; + +"Text.FeedbackView.addComment" = "Commentaires supplémentaires"; + +"Text.FeedbackView.app" = "Avez-vous trouvé l’application facile à utiliser ?"; + +"Text.FeedbackView.confirmation" = "Merci d'avoir envoyé vos commentaires"; + +"Text.FeedbackView.pob" = "Comment s’est passé votre voyage (ex: propreté du véhicule, trajet et chauffeur) ?"; + +"Text.FeedbackView.pre_pob" = "Le point de rencontre et le chauffeur ont-ils été faciles à trouver ?"; + +/* FeedBackView */ +"Text.FeedbackView.quote" = "Étiez-vous satisfait(e) des choix disponibles concernant les devis pour votre course (ex: Flottes, Prix, Proximité) ?"; + +"Text.Generic.Add" = "Ajouter"; + +/* "Additional information" used as placeholder on airport details screen */ +"Text.Generic.AdditionalInformation" = "Notes supplémentaires"; + +"Text.Generic.Back" = "Retour"; + +"Text.Generic.Bookings" = "Réservations"; + +/* Localizable.strings, Karhoo, , Copyright © 2020 Karhoo. All rights reserved., Generics */ +"Text.Generic.Cancel" = "Annuler"; + +/* English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking */ +"Text.Generic.CancellationPolicy" = "Conditions d'Annulation"; + +/* "Cancelled" */ "Text.Generic.Cancelled" = "Annulé"; -/*"Completed"*/ +/* english "Card" (referring to payment card) */ +"Text.Generic.Card" = "Carte"; + +"Text.Generic.Change" = "Modifier"; + +"Text.Generic.Close" = "Fermer"; + +"Text.Generic.Comment" = "Commentaire"; + +"Text.Generic.Comment.Optional" = "Commentaire (Optionnel)"; + +/* "Completed" */ "Text.Generic.Completed" = "Completé"; -/*english: "status"*/ -"Text.Generic.Status" = "État actuel"; +"Text.Generic.Contact" = "Contact"; + +"Text.Generic.Continue" = "Continuer"; + +"Text.Generic.Destination" = "Arrivée"; + +"Text.Generic.Dismiss" = "Fermer"; + +"Text.Generic.Done" = "Terminer"; + +/* "Edit" used as a button (call to action) */ +"Text.Generic.Edit" = "Modifier"; + +"Text.Generic.Email" = "Adresse email"; + +"Text.Generic.EPrice" = "Prix estimé"; + +"Text.Generic.Error" = "Erreur"; + +"Text.Generic.ErrorMessage" = "Une erreur est survenue"; + +/* English: "Estimated" */ +"Text.Generic.Estimated" = "Prix estimé"; + +"Text.Generic.ETA" = "Proximité"; + +"Text.Generic.ETALong" = "Proximité"; + +/* Reference to fixed pricing.. English equivalent: "Fixed" */ +"Text.Generic.Fixed" = "Prix fixe"; + +/* "Got It" (generally used on alert buttons) */ +"Text.Generic.GotIt" = "OK"; + +/* Password Entry Button */ +"Text.Generic.Hide" = "Masquer"; + +"Text.Generic.Logout" = "Déconnexion"; + +/* english "making a booking". Used in terms conditions construction */ +"Text.Generic.MakingBookingAction" = "effectuant une réservation avec"; + +"Text.Generic.MeetGreet" = "Accueil pancarte"; + +/* Metered fare type displayed in quotes list: English: "Metered" */ +"Text.Generic.Metered" = "Prix compteur"; + +"Text.Generic.Minutes" = "min"; + +"Text.Generic.Name" = "Prénom"; + +"Text.Generic.No" = "Non"; + +"Text.Generic.NoCarsAvailable" = "Aucun véhicule disponible pour votre course en ce moment. Veuillez réessayer plus tard"; + +/* The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device" */ +"Text.Generic.NoEmailSetupError" = "Veuillez configurer votre compte email sur votre téléphone"; + +"Text.Generic.Ok" = "OK"; + +"Text.Generic.Optional" = "Optionnel"; + +/* "Payment" used as a button in the side menu to reach all your payment methods */ +"Text.Generic.Payment" = "Paiement"; + +/* "Payments" used as the title of the payment method screen */ +"Text.Generic.Payments" = "Paiements"; + +"Text.Generic.PhoneNumber" = "Numéro de téléphone"; + +"Text.Generic.Pickup" = "Départ"; + +/* English: "Pickup Time" in booking request screen */ +"Text.Generic.PickupTime" = "Temps d'attente"; + +"Text.Generic.Prebook" = "Réserver"; -/*english: "price"*/ "Text.Generic.Price" = "Prix"; -/*english "Card" (referring to payment card)*/ -"Text.Generic.Card" = "Carte"; +"Text.Generic.PrivacyPolicy" = "Politique de Confidentialité"; + +"Text.Generic.Register" = "Inscription"; -/*English: "Report Issue" */ +/* english: "creating your Karhoo account". Used in terms conditions construction */ +"Text.Generic.RegisterAccountAction" = "créant un compte Karhoo"; + +/* English: "Report Issue" */ "Text.Generic.ReportIssue" = "Signaler un problème"; -/*English: "No Trips" used if the booking list screen is empty*/ -"Text.Bookings.NoTrips" = "Aucune réservation"; +/* String for when trip is initially loaded and no trip state has yet come through. "Requesting" */ +"Text.Generic.Requesting" = "Demande en cours"; -/*used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B"*/ -"Text.Bookings.NoTripsBookedMessage" = "Vous n'avez aucune réservation. Nous pouvons vous aider pour votre prochain trajet."; +/* used in side menu "Rides" */ +"Text.Generic.Rides" = "Courses"; -/*used as a call to action on a button in the empty bookings screen: English: "Book A Trip"*/ -"Text.Bookings.BookATrip" = "Réserver"; +/* "Save" used as a button (call to action) */ +"Text.Generic.Save" = "Sauvegarder"; + +/* Password Entry Button */ +"Text.Generic.Show" = "Afficher"; + +/* english: "status" */ +"Text.Generic.Status" = "État actuel"; + +"Text.Generic.Submit" = "Envoyer"; + +"Text.Generic.Success" = "Réussite"; + +"Text.Generic.Surname" = "Nom"; -/*"Add new card" in english used in the payments section of the app. Referring to credit / debit card*/ +"Text.Generic.TermsConditions" = "Conditions Générales d'Utilisation"; + +"Text.Generic.TermsOfUse" = "Conditions d'Utilisation"; + +/* "Thanks for your interest" */ +"Text.Generic.Thanks" = "Merci de votre intérêt."; + +/* Booker cancelled */ +"Text.Generic.TripStatus.BookerCancelled" = "Annulation utilisateur"; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "L’attribution d’un véhicule prend plus de temps que prévu. Veuillez patienter, contacter la flotte partenaire, ou annuler la course et recommander avec une autre flotte."; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Délai d’attribution"; + +/* Driver Cancelled */ +"Text.Generic.TripStatus.DriverCancelled" = "Annulation par le chauffeur"; + +/* No drivers available */ +"Text.Generic.TripStatus.NoDriversAvailable" = "Aucun chauffeur disponible"; + +/* "Unkown" */ +"Text.Generic.Unknown" = "Inconnu"; + +"Text.Generic.Yes" = "Oui"; + +/* "Allocated" when a driver has been allocated */ +"Text.GenericTripStatus.Allocated" = "Attribué"; + +/* "Driver Approaching" */ +"Text.GenericTripStatus.Approaching" = "Chauffeur en approche"; + +/* Driver Arrived */ +"Text.GenericTripStatus.Arrived" = "Chauffeur est arrivé"; + +/* "Cancelled" */ +"Text.GenericTripStatus.Cancelled" = "Course annulée"; + +/* Cancelled by Karhoo */ +"Text.GenericTripStatus.CancelledByKarhoo" = "Annulée par Karhoo"; + +/* "Completed" (trip completed) */ +"Text.GenericTripStatus.Completed" = "Course terminée"; + +/* Confirmed */ +"Text.GenericTripStatus.Confirmed" = "Confirmé"; + +/* "Driver En Route" when a driver is en route */ +"Text.GenericTripStatus.EnRoute" = "Chauffeur en route"; + +/* "Failed" */ +"Text.GenericTripStatus.Failed" = "Echec"; + +/* "Incomplete" */ +"Text.GenericTripStatus.Incomplete" = "En attente"; + +/* in english: "Requested" */ +"Text.GenericTripStatus.Initialised" = "Demande en cours"; + +/* "On Board" */ +"Text.GenericTripStatus.PassengerOnBoard" = "À bord"; + +/* english: requested */ +"Text.GenericTripStatus.Requested" = "Demande en cours"; + +/* "Pending" */ +"Text.GenericTripStatus.Unknown" = "En cours"; + +"Text.Help.ContactUs.Link" = "https://taxibookermobile.zendesk.com/hc/fr/requests/new"; + +"Text.Help.FAQ.Link" = "https://taxibookermobile.zendesk.com/hc/fr"; + +/* No availability in requested area, Fuzzy */ +"Text.KarhooError.K3002" = "Aucune flotte disponible dans cette zone."; + +"Text.KarhooError.Q0001" = "Départ et destination ne peuvent pas être identiques."; + +/* "Add new card" in english used in the payments section of the app. Referring to credit / debit card */ "Text.Payment.AddPaymentMethod" = "Ajouter une méthode de paiement"; -"Text.Payment.PaymentMethod" = "Carte finissant en"; -/*"Edit" used as a button (call to action) */ -"Text.Generic.Edit" = "Modifier"; +"Text.Payment.PaymentMethod" = "Carte"; + +/* Prebook */ +"Text.Prebook.PrebookPickupTime" = "Date et heure du départ"; + +"Text.Prebook.SetPrebook" = "Choisir"; + +/* "Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes */ +"Text.Prebook.TimezoneMessage" = "Heure locale sera utilisée pour la réservation (%1$@)"; + +"Text.Quote.FreeCancellationAndKeyword" = "et"; + +"Text.Quote.FreeCancellationASAP" = "Annulation sans frais jusqu'à %1$@ minutes après la réservation"; -/*"Save" used as a button (call to action) */ -"Text.Generic.Save" = "Sauvegarder"; +"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Annulation sans frais jusqu'au départ du chauffeur"; -/*"Payment" used as a button in the side menu to reach all your payment methods*/ -"Text.Generic.Payment" = "Paiement"; +/* Cancellation info on quotes */ +"Text.Quote.FreeCancellationPrebook" = "Annulation gratuite jusqu’à %1$@ avant la prise en charge"; -/*"Payments" used as the title of the payment method screen*/ -"Text.Generic.Payments" = "Paiements"; +"Text.QuoteCategory.Electric" = "Electrique"; -/*in english: "Requested"*/ -"Text.GenericTripStatus.Initialised" = "Demande en cours"; +"Text.QuoteCategory.Exec" = "Business"; -/*english: requested*/ -"Text.GenericTripStatus.Requested" = "Demande en cours"; +"Text.QuoteCategory.Executive" = "Business"; -/*Confirmed*/ -"Text.GenericTripStatus.Confirmed" = "Confirmé"; +"Text.QuoteCategory.Moto" = "Moto"; -/*"Allocated" when a driver has been allocated*/ -"Text.GenericTripStatus.Allocated" = "Attribué"; +"Text.QuoteCategory.Motorcycle" = "Moto"; -/*"Driver En Route" when a driver is en route*/ -"Text.GenericTripStatus.EnRoute" = "Chauffeur en route"; +"Text.QuoteCategory.MPV" = "Van"; -/*"Driver Approaching"*/ -"Text.GenericTripStatus.Approaching" = "Chauffeur en approche"; +"Text.QuoteCategory.Saloon" = "Berline"; -/*Driver Arrived*/ -"Text.GenericTripStatus.Arrived" = "Chauffeur est arrivé"; +"Text.QuoteCategory.Taxi" = "Taxi"; -/*"On Board"*/ -"Text.GenericTripStatus.PassengerOnBoard" = "À bord"; +/* Side Menu "About" section title, Fuzzy */ +"Text.SideMenu.About" = "À propos"; -/*"Completed" (trip completed)*/ -"Text.GenericTripStatus.Completed" = "Course terminée"; +"Text.SideMenu.Feedback" = "Remarques"; -/*"Cancelled" */ -"Text.GenericTripStatus.Cancelled" = "Course annulée"; +"Text.SideMenu.Help" = "Aide"; -/*"Failed" */ -"Text.GenericTripStatus.Failed" = "Echec"; +/* Side Menu */ +"Text.SideMenu.Login" = "S'identifier"; -/*"Pending"*/ -/*Fuzzy*/ -"Text.GenericTripStatus.Unknown" = "En cours"; +/* "Profile" button on the side menu */ +"Text.SideMenu.Profile" = "Profil"; -/*"Incomplete"*/ -"Text.GenericTripStatus.Incomplete" = "En attente"; +/* Register on the side menu */ +"Text.SideMenu.Register" = "Inscription"; -/*"Driver Allocation Delay Title"*/ -"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Délai d’attribution"; +"Text.SideMenu.SignIn" = "Connexion"; -/*"Driver Allocation Delay Title"*/ -"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "L’attribution d’un véhicule prend plus de temps que prévu. Veuillez patienter, contacter la flotte partenaire, ou annuler la course et recommander avec une autre flotte."; +/* Sign Out on the side menu */ +"Text.SideMenu.SignOut" = "Déconnexion"; -/*"Track Driver"*/ -"Text.Bookings.TrackDriver" = "Suivre le chauffeur"; +"Text.SideMenu.Signup" = "Inscription"; -/*"Contact Driver" (button action)*/ -"Text.Bookings.ContactDriver" = "Contacter le chauffeur"; +/* In app email to customer support / feedback */ +"Text.SupportMailMessage.Feedback" = "Veuillez ne pas supprimer ces informations car elles nous aident à améliorer l'application."; -/*"Contact Fleet"*/ -"Text.Bookings.ContactFleet" = "Contacter la flotte"; +"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; -/*"Track Trip"*/ -"Text.Bookings.TrackTrip" = "Suivre la course"; +"Text.SupportMailMessage.FeedbackSubject" = "Remarques"; -"Text.Bookings.TrackTrip.AlertTitle" = "Ride confirmed"; -"Text.Bookings.TrackTrip.AlertMessage" = "Would you like to track your trip?"; -"Text.Bookings.TrackTrip.TrackAction" = "Track driver"; -"Text.Bookings.TrackTrip.DismissAction" = "Dismiss"; +"Text.SupportMailMessage.NoCoverageBody" = "Merci de nous recommander une flotte. Pour activer nos services le plus rapidement possible dans cette zone, veuillez nous donner le nom de la flotte ainsi que la zone qu'elle dessert..\n Zone:\n Nom de la flotte:"; -/*"Cancel Ride" button action*/ -"Text.Bookings.CancelRide" = "Annuler la course"; +/* No coverage email */ +"Text.SupportMailMessage.NoCoverageSubject" = "Recommandation de flotte"; -/*"Report Issue" Button*/ -"Text.Bookings.ReportIssue" = "Signaler un problème"; +"Text.SupportMailMessage.ReportIssue" = "Veuillez laisser vos commentaires regardant un problème spécifique dans l'espace ci-dessous."; -/*displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking"*/ -"Text.Trip.CancelBookingFailed" = "Annulation non confirmée. Veuillez appeler le fournisseur."; +"Text.SupportMailMessage.ReportIssueSubject" = "Signaler un problème"; -/*Used as a button in the trip screen. English: "Ride Options"*/ -"Text.Trip.RideOptions" = "Options"; -"Text.Trip.CancelBookingFailed.AlertTitle" = "Problème lors de l'annulation"; -"Text.Trip.CancelBookingFailed.AlertMessage" = "Nous n'arrivons pas à annuler votre course. Veuillez contacter le fournisseur."; -"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Appeler le fournisseur"; -"Text.Generic.Yes" = "Oui"; -"Text.Generic.No" = "Non"; -"Text.Generic.Dismiss" = "Fermer"; -"Text.Trip.CancelBookingConfirmation.Alert.Title" = "Confirmer l'annulation?"; -"Text.Trip.CancelBookingConfirmation.Alert.Message" = "Des frais d'annulation pourraient être facturés par le fournisseur."; +"Text.SupportMailMessage.SupplierEmail" = "suppliers@karhoo.com"; -/*Call fleet button in trip screen (English: Call Fleet)*/ -"Text.Trip.CallFleet" = "Appeler le fournisseur"; -"Text.Trip.ActivityIndicator.Cancelling" = "Annulation en cours"; +"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; -/*The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device"*/ -"Text.Generic.NoEmailSetupError" = "Veuillez configurer votre compte email sur votre téléphone"; -"Text.Trip.CancelledByDispatch.AlertMessage" = "Votre course a été annulée par le fournisseur. Veuillez réessayer ou nous contacter pour plus d'informations."; -"Text.Trip.CancelledByDispatch.AlertTitle" = "Course annulée par le fournisseur"; -"Text.Generic.NoCarsAvailable" = "Il n'y a aucune voiture disponible pour votre course en ce moment. Veuillez réessayer plus tard"; +/* Used in the checkout component before booking a ride */ +"Text.TermsConditions.BookingFullString" = "En effectuant une réservation, vous acceptez les %1$@ | %2$@ ainsi que les %4$@ de %3$@ | %5$@ de %3$@."; -/*English: "Estimated"*/ -"Text.Generic.Estimated" = "Estimé"; +"Text.TermsConditions.FullString" = "En %1$@ %2$@, vous acceptez les \n %3$@ | %4$@"; -/*"Unkown"*/ -"Text.Generic.Unknown" = "Inconnu"; +"Text.TermsConditions.KarhooPolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; -/*"Something went wrong" used as a title for error alert*/ -"Text.Error.SomethingWentWrong" = "Une erreur est survenue"; +"Text.TermsConditions.KarhooTermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; -/*Used to explain an unknown error. ie "Oops, something went wrong. Please try again"*/ -"Text.Error.NoDetails" = "Une erreur est survenue, veuillez réessayer plus tard."; -"Text.Error.Payment.Alert.Title" = "Problème de paiement"; -"Text.Error.Payment.Alert.Message" = "Nous n'avons pas pu obtenir l'autorisation pour ce paiement."; -"Text.Error.Payment.Alert.ButtonUpdateCard" = "Modifier carte"; -"Text.Error.Alert.CantSendEmail" = "Le message ne peut être envoyé. Veuillez configurer votre compte email sur votre téléphone."; +"Text.TermsConditions.PolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; -/*Metered fare type displayed in quotes list: English: "Metered"*/ -"Text.Generic.Metered" = "Prix compteur"; +"Text.TermsConditions.TermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; -/*English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking*/ -"Text.Generic.CancellationPolicy" = "Conditions d'annulation"; +"Text.TrackingLink.production" = "https://agent-portal.karhoo.com/follow/"; -/*The title of the alert when user is forced to update ie "App Update Required"*/ -"Text.Error.Alert.ForceUpdateTitle" = "Mise à jour de l'application est requise"; +/* Trip Tracking Links */ +"Text.TrackingLink.sandbox" = "https://agent-portal.sandbox.karhoo.com/follow/"; -/*The message when the user needs to update the app. ie. "Please update Karhoo to the latest version."*/ -"Text.Error.Alert.ForceUpdateMessage" = "Veuillez actualiser l'application pour continuer"; +"Text.TrackingLink.staging" = "https://agent-portal.stg.karhoo.net/follow/"; -/*The action button on the force update alert. ie "Update" (this button takes the user to the app store)*/ -"Text.Error.Alert.ForceUpdateButton" = "Mise à jour"; +"Text.Trip.ActivityIndicator.Cancelling" = "Annulation en cours"; -/*String for when trip is initially loaded and no trip state has yet come through. "Requesting"*/ -"Text.Generic.Requesting" = "Demande en cours"; -"Text.Booking.EnterDestination" = "Ajoutez une destination pour voir les véhicules disponibles"; -"Text.Bookings.Quote" = "Devis"; -"Text.Bookings.Price" = "Prix"; +/* "Arrival" displayed on arrival box in trip */ +"Text.Trip.Arrival" = "Arrivée"; -/*used in side menu "Rides"*/ -"Text.Generic.Rides" = "Courses"; +"Text.Trip.CallDriver" = "Appeler le chauffeur"; -/*Generic fallback message for trip load failure*/ -"Text.Bookings.CouldNotLoadTrips" = "Impossible de charger les courses"; -"Text.Bookings.Price.Cancelled" = "Annulé"; -"Text.Bookings.Alert.CancellationSuccess.Title" = "Annulation confirmée"; -"Text.Bookings.Alert.CancellationSuccess.Message" = "Votre course a été annulée."; -"Text.Bookings.Alert.CancellationFee.Charge" = "Des frais d'annulation estimés à %1$@ vont s'appliquer.\n\nSouhaitez-vous continuer?"; -"Text.Bookings.Alert.CancellationFee.Continue" = "Souhaitez-vous continuer?"; +/* Call fleet button in trip screen (English: Call Fleet) */ +"Text.Trip.CallFleet" = "Appeler le fournisseur"; -/*When fetching the user profile fails*/ -"Text.Error.GetUserFails" = "Impossible de charger le profil d'utilisateur"; +"Text.Trip.CancelBookingConfirmation.Alert.Message" = "Des frais d'annulation pourraient être facturés par le fournisseur."; -/*"Profile" button on the side menu*/ -"Text.SideMenu.Profile" = "Profil"; +"Text.Trip.CancelBookingConfirmation.Alert.Title" = "Confirmer l'annulation ?"; -/*Button for rebooking a ride*/ -"Text.Bookings.RebookRide" = "Re-commander"; +/* displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking" */ +"Text.Trip.CancelBookingFailed" = "Annulation non confirmée. Veuillez appeler le fournisseur."; -/*"Got It" (generally used on alert buttons)*/ -"Text.Generic.GotIt" = "OK"; +"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Appeler le fournisseur"; -/*"Your final fare might be affected by tips, tolls, taxes, and other charges."*/ -"Text.Booking.BaseFareExplanation" = "Le prix final peut être affecté par des péages, pourboires, taxes ou autres surcharges."; +"Text.Trip.CancelBookingFailed.AlertMessage" = "Nous n'arrivons pas à annuler votre course. Veuillez contacter le fournisseur."; -/*"Additional information" used as placeholder on airport details screen*/ -"Text.Generic.AdditionalInformation" = "Notes supplémentaires"; +"Text.Trip.CancelBookingFailed.AlertTitle" = "Problème lors de l'annulation"; -/*"Airport Pickup" used on screen for airport bookinga*/ -"Text.Airport.Pickup" = "Prise en charge aéroport"; +"Text.Trip.CancelledByDispatch" = "Nous sommes désolés, votre course a été annulée par le fournisseur. Veuillez nous excuser et utiliser l'application pour voir les taxis disponibles."; -/*Message on airport screen for encouraging user to enter as much info about airport booking as possible*/ -"Text.Airport.HelpfulMessage" = "Veuillez entrer un numéro de vol valide"; +"Text.Trip.CancelledByDispatch.AlertMessage" = "Votre course a été annulée par le fournisseur. Veuillez réessayer ou nous contacter pour plus d'informations."; -/*"Flight number" used as the flight number field placeholder*/ -"Text.Airport.FlightNumber" = "Numéro de vol"; +"Text.Trip.CancelledByDispatch.AlertTitle" = "Course annulée par le fournisseur"; -/*"Add Flight Details" used on booking airport ride*/ -"Text.Airport.AddFlightDetails" = "Détails supplémentaires"; +"Text.Trip.CancelledByUser" = "Vous avez annulé la réservation."; -/*"Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes*/ -"Text.Prebook.TimezoneMessage" = "Heure locale sera utilisée pour la réservation (%1$@)"; +/* Trip */ +"Text.Trip.CancelRide" = "Annuler la course"; -/*"Thanks for your interest"*/ -"Text.Generic.Thanks" = "Merci de votre intérêt."; +"Text.Trip.Completed" = "Vous avez atteint votre destination."; -/*"We will notify you via email once your request has been processed."*/ -"Text.User.SignupPendingMessage" = "Nous vous contacterons par email dès que votre compte sera activé."; +"Text.Trip.Confirmed" = "Votre commande a été acceptée. Attente d'attribution du chauffeur."; -/*Side Menu "About" section title*/ -"Text.SideMenu.About" = "À propos"; +"Text.Trip.DriverArrived" = "Votre chauffeur est arrivé."; -/*Error message when user tries to prebook within the current hour of local time*/ -"Text.Error.PrebookingWithinTheHour" = "L'heure et date de la commande doit être supérieure à une heure"; +"Text.Trip.DriverEnRoute" = "Votre chauffeur est en route."; -/*No availability in requested area*/ -/*Fuzzy*/ -"Text.KarhooError.K3002" = "Aucune disponibilité dans cette zone"; -"Text.KarhooError.Q0001" = "Départ et destination ne peuvent pas être identiques."; +/* alert message when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertMessage" = "Il y a eu un problème lors de la création de la course. Veuillez réessayer ou contacter le support."; -/*For when demand is too high and there are no drivers available*/ -"Text.Trip.NoDriversAvailable" = "Aucun chauffeur disponible en ce moment. Veuillez réessayer plus tard."; +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertTitle" = "Annulation par Karhoo"; -/*Booker cancelled*/ -"Text.Generic.TripStatus.BookerCancelled" = "Annulation utilisateur"; +"Text.Trip.MessageDriver" = "Envoyer un SMS"; -/*Driver Cancelled*/ -"Text.Generic.TripStatus.DriverCancelled" = "Annulation chauffeur"; +/* For when demand is too high and there are no drivers available */ +"Text.Trip.NoDriversAvailable" = "Aucun chauffeur disponible en ce moment. Veuillez réessayer plus tard."; -/*No drivers available*/ -"Text.Trip.NoDriversAvailable" = "Aucun chauffeur disponible"; +/* Alert message in popup when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertMessage" = "La flotte a annulée votre course à cause d'un manque de chauffeurs disponibles. Veuillez réessayer plus tard."; -/*No drivers available*/ -"Text.Generic.TripStatus.NoDriversAvailable" = "Aucun chauffeur disponible"; +/* Popup title message when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertTitle" = "Course annulée"; -/*"Trip Summary" header used on screen*/ -"Text.TripSummary.TripSummary" = "Détails de la course"; +"Text.Trip.PassengerOnBoard" = "Vous êtes en route. Faites un bon voyage."; -/*"Payment Summary" header used on Trip Summary Screen*/ -"Text.TripSummary.PaymentSummary" = "Détails de paiement"; +/* Trip Statuses */ +"Text.Trip.Requested" = "‪%1$@‬ vous assigne un chauffeur. Cela peut prendre quelques instants."; -/*Used for the "Book Return Ride" button on the trip summary screen*/ -"Text.TripSummary.BookReturnRide" = "Réserver le trajet retour"; +/* Used as a button in the trip screen. English: "Ride Options" */ +"Text.Trip.RideOptions" = "Options"; -/*"Date"*/ -"Text.TripSummary.Date" = "Date"; +/* Please wait whilst you\'re allocated a driver */ +"Text.TripAllocation.AllocatingTripOne" = "Veuillez patienter durant l\'allocation de votre chauffeur"; -/*Fleet*/ -"Text.TripSummary.Fleet" = "Flotte"; -"Text.TripSummary.Vehicle" = "Vehicule"; +/* This may take a moment or two */ +"Text.TripAllocation.AllocatingTripTwo" = "Ceci peut prendre quelques instants"; -/*Total Fare*/ -"Text.TripSummary.TotalFare" = "Prix total"; +"Text.TripAllocation.CancelInstruction" = "Appuyez et maintenez pour annuler"; -/*Popup title message when dispatch cancels due to no drivers*/ -"Text.Trip.NoDriversAvailable.AlertTitle" = "Course annulée"; +"Text.TripAllocation.Cancelling" = "Annuler"; -/*Alert message in popup when dispatch cancels due to no drivers*/ -"Text.Trip.NoDriversAvailable.AlertMessage" = "La flotte a annulée votre course à cause d'un manque de chauffeurs disponibles. Veuillez réessayer plus tard."; +/* Finding your ride... */ +"Text.TripAllocation.FindingYourRide" = "Création de votre course..."; -/*Password Entry Button*/ -"Text.Generic.Hide" = "Masquer"; +/* Trip Rating */ +"Text.TripRating.Confirmation" = "Merci pour votre évaluation."; -/*Password Entry Button*/ -"Text.Generic.Show" = "Afficher"; +"Text.TripRating.ExtraFeedback" = "Dites-nous en plus"; -/*"Quoted Price": used in trip summary screen when the fare is not available*/ -"Text.TripSummary.QuotedPrice" = "Prix devis"; +"Text.TripRating.Title" = "Quelle note donnez-vous à votre voyage ?"; -/*Base fare title*/ -"Text.Booking.BaseFare" = "Prix de base"; +/* Used for the "Book Return Ride" button on the trip summary screen */ +"Text.TripSummary.BookReturnRide" = "Réserver le trajet retour"; -/*Guest checkout*/ -"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Informations sur le passager"; -"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Détails de paiement"; -"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Votre chauffeur vous attendra"; +/* "Date" */ +"Text.TripSummary.Date" = "Date"; -/*Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked*/ -"Text.Booking.PrebookConfirmation" = "Votre réservation\nde: %1$@.\nÀ: %2$@.\nLe: %3$@ est confirmée."; +/* Fleet */ +"Text.TripSummary.Fleet" = "Flotte"; -/*Prebook Done*/ -"Text.Booking.PrebookConfirmed" = "Course confirmée"; +/* "Payment Summary" header used on Trip Summary Screen */ +"Text.TripSummary.PaymentSummary" = "Détails de paiement"; -/*Ride Details*/ -"Text.Booking.PrebookConfirmed.RideDetails" = "Détails de la course"; +/* "Quoted Price": used in trip summary screen when the fare is not available */ +"Text.TripSummary.QuotedPrice" = "Prix devis"; -/*"Past" used on past tabs on bookings list*/ -"Text.Bookings.Past" = "Terminées"; +/* Total Fare */ +"Text.TripSummary.TotalFare" = "Prix total"; -/*Upcoming: used on upcoming tabs for rides*/ -/*Fuzzy*/ -"Text.Bookings.Upcoming" = "À venir"; +/* "Trip Summary" header used on screen */ +"Text.TripSummary.TripSummary" = "Détails de la course"; -/* We’re not live here yet! */ -"Text.Booking.NoAvailabilityHeader" = "Nous n'avons pas encore de flottes dans cette zone."; +"Text.TripSummary.Vehicle" = "Vehicule"; -/* %1$@ if you have suggestions for local fleets. */ -"Text.Booking.NoAvailabilityBody" = "%1$@ pour nous en suggérer."; +"Text.User.Email" = "Email"; -/* Get in touch */ -"Text.Booking.NoAvailabilityLink" = "Contactez-nous"; +"Text.User.EmailSubscription" = "Je ne souhaite pas recevoir de courses gratuites ou d'offres promotionnelles"; -/*"All" used for all categories filter on category list. Write normally as the app will uppercase the string*/ -"Text.Availability.AllCategory" = "Tous"; -"SALOON" = "Eco"; -"MPV" = "Van"; -"EXEC" = "Berline"; -"ELECTRIC" = "Electrique"; -"TAXI" = "Taxi"; +/* User (register / login / user attributes) */ +"Text.User.FirstName" = "Prénom"; -/*Cancelled by Karhoo*/ -"Text.GenericTripStatus.CancelledByKarhoo" = "Annulée par Karhoo"; +/* Text used on button to trigger password reset... English: Forgotten Password? */ +"Text.User.ForgottenPassword" = "Mot de passe oublié ?"; -/*alert title when karhoo cancel the trip-supposedly happens for preauth failure*/ -"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Annulation par Karhoo"; +"Text.User.LastName" = "Nom"; -/*alert message when karhoo cancel the trip-supposedly happens for preauth failure*/ -"Text.Trip.KarhooCancelled.AlertMessage" = "Votre course a été annulée par Karhoo. Veuillez réessayer ou nous contacter."; +"Text.User.MobilePhoneNumber" = "Téléphone"; -/*When the user enters an invalid flight number*/ -"Text.Error.FlightNumberValidationHint" = "Numéro de vol"; +"Text.User.Password" = "Mot de passe"; -/*"Arrival" displayed on arrival box in trip*/ -"Text.Trip.Arrival" = "Arrivée"; +"Text.User.PhoneCountryCode" = "Préfixe"; -/*Theoretical edge case where the braintree token is missing*/ -"Text.Errors.failedToInitialisePaymentSetup" = "Erreur d'initialisation du processus de paiement. Veuillez réessayer."; +/* "We will notify you via email once your request has been processed." */ +"Text.User.SignupPendingMessage" = "Nous vous contacterons par email dès que votre compte sera activé."; -/*Text used on button to trigger password reset... English: Forgotten Password? */ -"Text.User.ForgottenPassword" = "Mot de passe oublié?"; +"Text.VehicleClass.Electric" = "Electrique"; -/* empty table view result */ -"Text.Errors.NoResultsFound" = "Aucun résultat trouvé"; +"Text.VehicleClass.Exec" = "Business"; +"Text.VehicleClass.Executive" = "Business"; -"Text.Availability.NoQuotesInSelectedCategory" = "Aucun devis disponible pour cette catégorie. \n Veuillez choisir une autre catégorie."; -"Text.Availability.NoQuotesForSelectedParameters" = "Aucune course disponible à l\'horaire demandé. Veuillez modifier votre horaire."; +"Text.VehicleClass.Moto" = "Moto"; -/* Finding your ride... */ -"Text.TripAllocation.FindingYourRide" = "Création de votre course..."; +"Text.VehicleClass.Motorcycle" = "Moto"; -/* Please wait whilst you\'re allocated a driver */ -"Text.TripAllocation.AllocatingTripOne" = "Veuillez patienter durant l\'allocation de votre chauffeur"; +"Text.VehicleClass.MPV" = "Van"; -/* This may take a moment or two */ -"Text.TripAllocation.AllocatingTripTwo" = "Ceci peut prendre quelques instants"; +"Text.VehicleClass.Saloon" = "Berline"; -"Text.TripAllocation.Cancelling" = "Annuler"; -"Text.TripAllocation.CancelInstruction" = "Appuyez et maintenez pour annuler"; +"Text.VehicleClass.Taxi" = "Taxi"; -"Text.Address.NoRecentAddress" = "Aucune adresse récente trouvée"; +"Text.VehicleTag.Childseat" = "Siège enfant"; -"Text.SupportMailMessage.NoCoverageSubject" = "Recommandation de flotte"; -"Text.SupportMailMessage.NoCoverageBody" = "Nous vous remercions de vouloir recommander une flotte. Pour que cela s'effectue le plus rapidement possible veuillez nous donner le nom de la flotte ainsi que la zone qu'elle dessert..\n Zone:\n Nom de la flotte:"; +/* Vehicle tags */ +"Text.VehicleTag.Electric" = "Électrique"; -/* Cancellation info on quotes */ -"Text.Quote.FreeCancellationPrebook" = "Annulation gratuite jusqu’à %1$@ avant la prise en charge"; -"Text.Quote.FreeCancellationASAP" = "Annulation sans frais jusqu'à %1$@ minutes après la réservation"; -"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Annulation sans frais jusqu'au départ du chauffeur"; -"Text.Quote.FreeCancellationAndKeyword" = "et"; +"Text.VehicleTag.Executive" = "Business"; -/* General errors, K0xxx */ -"K0001" = "Désolé! Une erreur s'est produite"; -"K0002" = "Requête non valide"; -"K0003" = "Impossible de confirmer l'authentification"; -"K0004" = "Authentification nécessaire"; -"K0005" = "Rôle non défini pour effectuer cette action"; -"K0006" = "Limite de débit dépassée"; -"K0007" = "Connection coupée pour cette URL"; +"Text.VehicleTag.Hybrid" = "Hybride"; -/* User errors, K1xxx */ -"K1001" = "Impossible d'enregistrer l'utilisateur"; -"K1002" = "Impossible d'enregistrer l'utilisateur (utilisateur déjà inscrit)"; -"K1003" = "Impossible d'enregistrer l'utilisateur (requête non valide)"; -"K1004" = "Impossible d'enregistrer l'utilisateur (numéro de téléphone non valide)"; -"K1005" = "Impossible de trouver les détails de l'utilisateur (authentification non valide)"; -"K1006" = "Impossible de trouver les détails de l'utilisateur (utilisateur non créé)"; -"K1999" = "Utilisateur enregistré, nous vous contacterons par email dès que votre compte sera activé."; -"K1004" = "Impossible d'enregistrer l'utilisateur (numéro téléphone non valide)"; +"Text.VehicleTag.Taxi" = "Taxi"; -/* Locations errors, K2xxx */ -"K2001" = "Impossible de trouver l'adresse"; +"Text.VehicleTag.Wheelchair" = "Fauteuil roulant"; -/* Quotes errors, K3xxx */ -"K3001" = "Impossible de trouver un devis"; -"K3002" = "Impossible de trouver un devis (aucune flotte trouvée dans la zone demandée)"; -"K3003" = "Impossible de trouver un devis (devis en question non trouvé)"; +"Text.VehicleType.Bus" = "Bus"; -/* Bookings errors, K4xxx */ -"K4001" = "Impossible de compléter la commande"; -"K4002" = "Impossible de compléter la commande - requête non valide (au moins une valeur de detail(s)-passager est requise)"; -"K4003" = "Impossible de compléter la commande (impossible de trouver le devis en question)"; -"K4004" = "Impossible de compléter la commande (le devis a expiré et n’est plus valable)"; -"K4005" = "Impossible de compléter la commande (Permission refusée.)"; -"K4006" = "Impossible de compléter la commande (Refus d'autorisation de paiement.)"; -"K4007" = "Impossible d'annuler la commande"; -"K4008" = "Impossible d'annuler la commande (Impossible de trouver la course.)"; -"K4009" = "Impossible d'annuler la commande (Permission refusée.)"; -"K4010" = "Impossible d'annuler la commande (Cette course est déjà annulée)"; -"K4011" = "Impossible de trouver la commande"; -"K4012" = "Impossible de trouver la commande (Impossible de trouver la course.)"; -"K4013" = "Impossible de trouver la commande (Permission refusée.)"; -"K4014" = "Impossible de compléter la commande en tant qu’Agent"; -"k4015" = "Impossible de compléter la commande en tant que Traveller"; -"K4018" = "Impossible de compléter la réservation car le devis n'est plus disponible"; +"Text.VehicleType.Moto" = "Moto"; -/* Availability errors, K5xxx */ -"K5001" = "Impossible de trouver un devis"; -"K5002" = "Impossible de trouver un devis (aucune flotte trouvée dans la zone demandée)"; -"K5003" = "Impossible de trouver un devis (aucune catégorie trouvée dans la zone demandée)"; +"Text.VehicleType.MPV" = "Van"; -/* Authentication errors K6xxx */ -"K6001" = "Identifiant ou mot de passe incorrect. Merci d'essayer à nouveau"; +"Text.VehicleType.Standard" = "Standard"; -/* KPOI errors, K7xxx */ -"K7001" = "Impossible de completer la requête KPOI"; -"K7002" = "Impossible de faire correspondre le KPOI à une identité"; -"K7003" = "Impossible de lire le KPOI"; -"K7004" = "Impossible d'écrire le KPOI"; -"K7005" = "Impossible d'effacer le KPOI"; +"Vehicle.Tag.Childseat" = "Siège enfant"; -/* KSDKxxx Internal SDK */ -"KSDK01" = "Une erreur s’est produite. Veuillez réessayer."; -"KSDK02" = "Permission(s) manquante(s) pour cette requête."; -"KSDK03" = "Utilisateur déjà connecté"; +/* Vehicle tags */ +"Vehicle.Tag.Electric" = "Electrique"; -/* PickUp Type */ -"DEFAULT" = "Default"; -"MEET_AND_GREET" = "Accueil pancarte"; -"CURBSIDE" = "Prise en charge à l'extérieur"; -"STAND_BY" = "Contacter chauffeur"; +"Vehicle.Tag.Executive" = "Business"; -/* Trip Rating */ -"Text.TripRating.Confirmation" = "Merci pour votre évaluation."; -"Text.TripRating.Title" = "Veuillez donner une évaluation à votre voyage."; +"Vehicle.Tag.Hybrid" = "Hybride"; -"Text.TripRating.ExtraFeedback" = "Dites-nous en plus"; +"Vehicle.Tag.Taxi" = "Taxi"; -/* FeedBackView */ -"Text.FeedbackView.quote" = "Étiez-vous satisfait(e) des choix disponibles concernant les devis pour votre course (ex: Flottes, Prix, Proximité)?"; -"Text.FeedbackView.pre_pob" = "Le point de rencontre et le chauffeur ont-ils été faciles à trouver?"; -"Text.FeedbackView.pob" = "Comment s’est passé votre voyage (ex: propreté du véhicule, trajet et chauffeur)?"; -"Text.FeedbackView.app" = "Avez-vous trouvé l’application facile à utiliser?"; -"Text.FeedbackView.addComment" = "Commentaires supplémentaires"; -"Text.FeedbackView.confirmation" = "Merci d'avoir envoyé vos commentaires"; +"Vehicle.Tag.Wheelchair" = "Fauteuil roulant"; -"Text.Address.SetOnMap" = "Situer sur la carte"; -"Text.Address.CurrentLocation" = "Position actuelle"; diff --git a/KarhooUISDK/Translations/it.lproj/Localizable.strings b/KarhooUISDK/Translations/it.lproj/Localizable.strings new file mode 100644 index 000000000..918ac8685 --- /dev/null +++ b/KarhooUISDK/Translations/it.lproj/Localizable.strings @@ -0,0 +1,877 @@ +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Problema Prenotazione"; + +"CURBSIDE" = "bordo marciapiede"; + +/* PickUp Type */ +"DEFAULT" = "Difetto"; + +"ELECTRIC" = "Elettrico"; + +/* English: Error codes */ +"K0001" = "Errore di richiesta generale"; + +"K0002" = "Payload della richiesta non valido"; + +"K0003" = "Impossibile leggere il token di autorizzazione"; + +"K0004" = "L'autenticazione è richiesta per questo percorso"; + +"K0005" = "Ruolo richiesto mancante per questa richiesta"; + +"K0006" = "Limite di velocità superato"; + +"K0007" = "L'interruttore automatico è scattato per questo percorso"; + +/* User errors, K1xxx */ +"K1001" = "Impossibile registrare l'utente"; + +"K1002" = "Impossibile registrare l'utente (l'utente esiste già)"; + +"K1003" = "Impossibile registrare l'utente (richiesta non valida)"; + +"K1004" = "Impossibile registrare l'utente (numero di telefono non valido)"; + +"K1005" = "Impossibile ottenere i dettagli dell'utente (token non valido)"; + +"K1006" = "Impossibile ottenere i dettagli dell'utente (l'utente non esiste)"; + +"K1999" = "L'utente è stato creato ma non è stato ancora autorizzato, ci metteremo in contatto una volta abilitato."; + +/* Locations errors, K2xxx */ +"K2001" = "Impossibile ottenere l'indirizzo"; + +/* Quotes errors, K3xxx */ +"K3001" = "Impossibile ottenere stime"; + +"K3002" = "Impossibile ottenere preventivi (nessuna disponibilità trovata nell'area richiesta)"; + +"K3003" = "Impossibile ottenere le stime (impossibile trovare il preventivo specificato)"; + +/* Bookings errors, K4xxx */ +"K4001" = "Impossibile prenotare il viaggio"; + +"K4002" = "Impossibile prenotare il viaggio - payload della richiesta non valido (richiede almeno 1 set di dettagli del passeggero)"; + +"K4003" = "Impossibile prenotare il viaggio (impossibile trovare il preventivo specificato)"; + +"K4004" = "Impossibile prenotare il viaggio (tentativo di prenotare un preventivo scaduto)"; + +"K4005" = "Impossibile prenotare il viaggio (autorizzazione negata)"; + +"K4006" = "Impossibile prenotare il viaggio (pre-autorizzazione al pagamento non riuscita)"; + +"K4007" = "Impossibile annullare il viaggio"; + +"K4008" = "Impossibile annullare il viaggio (impossibile trovare il viaggio specificato)"; + +"K4009" = "Impossibile annullare il viaggio (autorizzazione negata)"; + +"K4010" = "Impossibile annullare il viaggio (già annullato)"; + +"K4011" = "Impossibile ottenere il viaggio"; + +"K4012" = "Impossibile ottenere il viaggio (impossibile trovare il viaggio specificato)"; + +"K4013" = "Impossibile ottenere il viaggio (autorizzazione negata)"; + +"K4014" = "Impossibile prenotare il viaggio come agente"; + +"K4015" = "Impossibile prenotare il viaggio come viaggiatore?"; + +"k4015" = "Impossibile prenotare il viaggio come viaggiatore?"; + +"K4018" = "Impossibile prenotare il viaggio perché questo preventivo non è più disponibile"; + +"K4020" = "Impossibile prenotare il viaggio con il DMS selezionato"; + +"K4025" = "Prezzo preventivo aumentato in fase di prenotazione"; + +/* Availability errors, K5xxx */ +"K5001" = "Impossibile ottenere stime"; + +"K5002" = "Impossibile ottenere la disponibilità (nessuna disponibilità trovata nell'area richiesta)"; + +"K5003" = "Impossibile ottenere la disponibilità (nessuna categoria trovata nell'area richiesta)"; + +/* Authentication errors K6xxx */ +"K6001" = "E-mail o password non validi. Per favore riprova"; + +/* KPOI errors, K7xxx */ +"K7001" = "Impossibile elaborare la richiesta KPOI"; + +"K7002" = "Impossibile trovare Karhoo POI con ID corrispondente"; + +"K7003" = "Impossibile leggere Karhoo POI"; + +"K7004" = "Impossibile scrivere Karhoo POI"; + +"K7005" = "Impossibile eliminare Karhoo POI"; + +/* KSDKxxx Internal SDK */ +"KSDK01" = "Qualcosa è andato storto ma non sappiamo cosa fosse"; + +"KSDK02" = "Permessi utente mancanti"; + +"KSDK03" = "Utente già loggato"; + +"MEET_AND_GREET" = "Incontra e saluta"; + +"MPV" = "Multiposto"; + +/* Qxxxx errors */ +"Q0001" = "Ritiro e destinazione non possono essere gli stessi."; + +"STAND_BY" = "Pausa"; + +"TAXI" = "Taxi"; + +/* "Version" */ +"Text.About.Version" = "Versione"; + +"Text.Address.CurrentLocation" = "Posizione attuale"; + +"Text.Address.NoRecentAddress" = "Nessun risultato recente"; + +"Text.Address.SetOnMap" = "Imposta sulla mappa"; + +/* Address Bar */ +"Text.AddressBar.AddDestination" = "Aggiungi destinazione"; + +"Text.AddressBar.AddPickup" = "Aggiungi partenza"; + +"Text.AddressBar.EnterPickupLocation" = "Aggiungi partenza"; + +"Text.AddressSearch.EnterDestinationLocation" = "Aggiungi destinazione"; + +/* "Add Flight Details" used on booking airport ride */ +"Text.Airport.AddFlightDetails" = "Aggiungi i dettagli del volo"; + +/* "Flight number" used as the flight number field placeholder */ +"Text.Airport.FlightNumber" = "Numero del volo"; + +/* Message on airport screen for encouraging user to enter as much info about airport booking as possible */ +"Text.Airport.HelpfulMessage" = "Inserisci un numero di volo valido"; + +/* "Airport Pickup" used on screen for airport bookinga */ +"Text.Airport.Pickup" = "Prelievo dall'aeroporto"; + +/* "All" used for all categories filter on category list. Write normally as the app will uppercase the string */ +"Text.Availability.AllCategory" = "Tutti"; + +"Text.Availability.NoQuotesForSelectedParameters" = "Nessuna disponibilità per l'orario richiesto. Si prega di scegliere un orario diverso."; + +"Text.Availability.NoQuotesInSelectedCategory" = "Non ci sono quotazioni per questa categoria.\nSi prega di scegliere un'altra categoria."; + +/* Base fare title */ +"Text.Booking.BaseFare" = "Tariffa base"; + +/* "Your final fare might be affected by tips, tolls, taxes, and other charges." */ +"Text.Booking.BaseFareExplanation" = "La tua tariffa finale può essere influenzata da mancia, pedaggi, tasse e costi extra."; + +"Text.Booking.CountryCodeSelection.Search" = "Cerca paese/regione"; + +/* Country Code Selection */ +"Text.Booking.CountryCodeSelection.Title" = "Paese/regione"; + +"Text.Booking.EnterDestination" = "Inserisci la destinazione per vedere le flotte disponibili"; + +/* Checkout component */ +"Text.Booking.EstimatedInfoBox" = "Questa flotta è un taxi non regolamentato. Il preventivo è una stima basata sui fattori di viaggio (distanza, tempo, ecc.). Per ulteriori informazioni, fare riferimento ai Termini e condizioni della flotta."; + +"Text.Booking.FixedInfoBox" = "Questa flotta addebita una tariffa fissa. La tariffa finale può essere influenzata da extra (pedaggi, ritardi, ecc.), controlla i Termini e condizioni della flotta."; + +"Text.Booking.FlightTracking" = "Monitoraggio del volo"; + +"Text.Booking.GPSTracking" = "Tracciamento GPS"; + +"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Numero del volo (opzionale)"; + +/* Guest checkout */ +"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Dettagli del passeggero"; + +"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Modalità di pagamento"; + +"Text.Booking.LearnMore" = "Per saperne di più"; + +"Text.Booking.MaximumLuggages" = "%1$@ bagagli massimo"; + +"Text.Booking.MaximumPassengers" = "%1$@ passeggeri massimo"; + +"Text.Booking.MeteredInfoBox" = "Questa flotta è un taxi con tassametro regolamentato. Il preventivo è una stima basata sui fattori di viaggio (distanza, tempo, ecc.)."; + +"Text.Booking.Next" = "Successivo"; + +/* %1$@ if you have suggestions for local fleets. */ +"Text.Booking.NoAvailabilityBody" = "%1$@ se hai suggerimenti per flotte locali."; + +/* We’re not live here yet! */ +"Text.Booking.NoAvailabilityHeader" = "Non siamo ancora qui!"; + +/* Get in touch */ +"Text.Booking.NoAvailabilityLink" = "Entra in contatto"; + +"Text.Booking.Passenger" = "Passeggeri"; + +"Text.Booking.PassengerDetails.Add" = "Aggiungi passeggero"; + +"Text.Booking.PassengerDetails.Email" = "E-mail"; + +"Text.Booking.PassengerDetails.FirstName" = "Nome"; + +"Text.Booking.PassengerDetails.LastName" = "Cognome"; + +"Text.Booking.PassengerDetails.MobilePhone" = "Numero di cellulare"; + +"Text.Booking.PassengerDetails.SaveAction" = "Salvare"; + +"Text.Booking.PassengerDetails.Subtitle" = "Queste informazioni consentono il regolare svolgimento della tua corsa."; + +/* Passenger Details */ +"Text.Booking.PassengerDetails.Title" = "Passeggeri"; + +/* Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked */ +"Text.Booking.PrebookConfirmation" = "La tua prenotazione\nda: %1$@ \nto: %2$@ \nat: %3$@ \nè stata prenotataprenotazione"; + +/* Prebook Done, Fuzzy */ +"Text.Booking.PrebookConfirmed" = "Corsa confermata"; + +/* Ride Details */ +"Text.Booking.PrebookConfirmed.RideDetails" = "Dettagli della corsa"; + +/* Booking */ +"Text.Booking.RequestCar" = "Libro"; + +"Text.Booking.RequestingCar" = "Prenotazione corsa"; + +"Text.Booking.RequestReceived" = "Prenotazione ricevuta"; + +"Text.Booking.TrainTracking" = "Monitoraggio del treno"; + +"Text.Bookings.Alert.CancellationFee.Charge" = "Ti verrà addebitata una penale di cancellazione stimata in %1$@ .\n\nVuoi continuare?"; + +"Text.Bookings.Alert.CancellationFee.Continue" = "Vuoi continuare?"; + +"Text.Bookings.Alert.CancellationSuccess.Message" = "Il tuo viaggio è stato annullato con successo."; + +"Text.Bookings.Alert.CancellationSuccess.Title" = "Annullamento corsa riuscito"; + +/* used as a call to action on a button in the empty bookings screen: English: "Book Ride" */ +"Text.Bookings.BookATrip" = "Prenota corsa"; + +/* "Cancel Ride" button action */ +"Text.Bookings.CancelRide" = "Annulla corsa"; + +/* "Contact Driver" (button action) */ +"Text.Bookings.ContactDriver" = "Contatta l'autista"; + +/* "Contact Fleet" */ +"Text.Bookings.ContactFleet" = "Contatta la flotta"; + +/* Generic fallback message for trip load failure */ +"Text.Bookings.CouldNotLoadTrips" = "Impossibile caricare i viaggi."; + +"Text.Bookings.eta" = "Ora di arrivo stimata"; + +/* English: "No Trips" used if the booking list screen is empty */ +"Text.Bookings.NoTrips" = "Nessuna corsa"; + +/* used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B" */ +"Text.Bookings.NoTripsBookedMessage" = "Non hai ancora prenotato nessuna corsa. Possiamo aiutarti ad andare da A a B"; + +/* "Past" used on past tabs on bookings list */ +"Text.Bookings.Past" = "Precedenti"; + +"Text.Bookings.price" = "Prezzo"; + +"Text.Bookings.Price" = "Prezzo"; + +"Text.Bookings.Price.Cancelled" = "Cancellato"; + +"Text.Bookings.Quote" = "Preventivo"; + +/* Button for rebooking a ride */ +"Text.Bookings.RebookRide" = "Riprenota corsa"; + +/* "Report Issue" Button */ +"Text.Bookings.ReportIssue" = "Segnala problema"; + +/* "Track Driver" */ +"Text.Bookings.TrackDriver" = "SEGUI L’AUTISTA"; + +/* "Track Trip" */ +"Text.Bookings.TrackTrip" = "Corsa in pista"; + +"Text.Bookings.TrackTrip.AlertMessage" = "Vuoi tracciare il veicolo?"; + +"Text.Bookings.TrackTrip.AlertTitle" = "L'autista è in viaggio"; + +"Text.Bookings.TrackTrip.DismissAction" = "No"; + +"Text.Bookings.TrackTrip.TrackAction" = "Sì"; + +/* Upcoming: used on upcoming tabs for rides, Fuzzy */ +"Text.Bookings.Upcoming" = "Prossime"; + +"Text.Error.Alert.CantSendEmail" = "Impossibile inviare un messaggio di posta elettronica. Configura prima l'app di posta."; + +/* The action button on the force update alert. ie "Update" (this button takes the user to the app store) */ +"Text.Error.Alert.ForceUpdateButton" = "AGGIORNARE"; + +/* The message when the user needs to update the app. ie. "Please update Karhoo to the latest version." */ +"Text.Error.Alert.ForceUpdateMessage" = "Aggiorna l'app per continuare."; + +/* The title of the alert when user is forced to update ie "App Update Required" */ +"Text.Error.Alert.ForceUpdateTitle" = "Nuova versione disponibile"; + +"Text.Error.Booking.EnterDestinationToProceed" = "Inserisci la destinazione per prenotare una corsa"; + +/* Errors */ +"Text.Error.EmailValidationError" = "Controlla che il tuo indirizzo email sia scritto correttamente"; + +/* When the user enters an invalid flight number, Fuzzy */ +"Text.Error.FlightNumberValidationHint" = "Numero del volo"; + +/* When fetching the user profile fails */ +"Text.Error.GetUserFails" = "Si è verificato un problema durante l'acquisizione del tuo profilo."; + +/* Used to explain an unknown error. ie "Oops, something went wrong. Please try again" */ +"Text.Error.NoDetails" = "Oops! Qualcosa è andato storto. Per favore riprova."; + +"Text.Error.NotLoggedIn" = "Non hai effettuato l'accesso"; + +"Text.Error.Payment.Alert.ButtonUpdateCard" = "Aggiorna i dati della tua carta"; + +"Text.Error.Payment.Alert.Message" = "Non siamo stati in grado di autorizzare la tua carta di credito/debito."; + +"Text.Error.Payment.Alert.Title" = "Problema con la carta"; + +/* Error message when user tries to prebook within the current hour of local time */ +"Text.Error.PrebookingWithinTheHour" = "La prenotazione anticipata non può essere effettuata entro l'ora corrente."; + +/* "Something went wrong" used as a title for error alert */ +"Text.Error.SomethingWentWrong" = "Si è verificato un errore"; + +/* Theoretical edge case where the braintree token is missing */ +"Text.Errors.failedToInitialisePaymentSetup" = "Problema con l'inizializzazione dei pagamenti, contatta l'assistenza"; + +"Text.Errors.InvalidPhoneNumber" = "Numero di telefono invalido"; + +"Text.Errors.MissingPhoneNumber" = "Campo vuoto non consentito"; + +/* empty table view result */ +"Text.Errors.NoResultsFound" = "Nessun risultato trovato"; + +"Text.FeedbackView.addComment" = "Commenti aggiuntivi"; + +"Text.FeedbackView.app" = "Quanto è stato facile usare l'app?"; + +"Text.FeedbackView.confirmation" = "Grazie per aver inviato il tuo feedback"; + +"Text.FeedbackView.pob" = "Com'è stata la tua esperienza mentre sei in taxi (ad es. pulizia del taxi, percorso e autista)? Quanto è stato facile usare l'app?"; + +"Text.FeedbackView.pre_pob" = "Com'è stata la tua esperienza con la ricerca del luogo di ritiro e l'incontro con il tuo autista?"; + +/* FeedBackView */ +"Text.FeedbackView.quote" = "Quanto sei soddisfatto della selezione dei preventivi per il tuo viaggio (ad es. Flotte, Prezzi ed ETA)?"; + +"Text.Generic.Add" = "Aggiungere"; + +/* "Additional information" used as placeholder on airport details screen */ +"Text.Generic.AdditionalInformation" = "Informazioni aggiuntive"; + +"Text.Generic.Back" = "Indietro"; + +"Text.Generic.Bookings" = "Prenotazioni"; + +/* Localizable.strings, Karhoo, , Copyright © 2020 Karhoo. All rights reserved., Generics */ +"Text.Generic.Cancel" = "Annulla"; + +/* English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking */ +"Text.Generic.CancellationPolicy" = "Criteri di Cancellazione"; + +/* "Cancelled" */ +"Text.Generic.Cancelled" = "Cancellato"; + +/* english "Card" (referring to payment card) */ +"Text.Generic.Card" = "Carta"; + +"Text.Generic.Change" = "MODIFICARE"; + +"Text.Generic.Close" = "Chiudi"; + +"Text.Generic.Comment" = "Commento"; + +"Text.Generic.Comment.Optional" = "Commento (facoltativo)"; + +/* "Completed" */ +"Text.Generic.Completed" = "Completato"; + +"Text.Generic.Contact" = "CONTATTO"; + +"Text.Generic.Continue" = "Continuare"; + +"Text.Generic.Destination" = "Destinazione"; + +"Text.Generic.Dismiss" = "CHIUDI"; + +"Text.Generic.Done" = "Fatto"; + +/* "Edit" used as a button (call to action) */ +"Text.Generic.Edit" = "Modifica"; + +"Text.Generic.Email" = "Indirizzo email"; + +"Text.Generic.EPrice" = "Prezzo stimato"; + +"Text.Generic.Error" = "Errore"; + +"Text.Generic.ErrorMessage" = "Oops! Qualcosa è andato storto"; + +/* English: "Estimated" */ +"Text.Generic.Estimated" = "Stimato"; + +"Text.Generic.ETA" = "Ora di arrivo stimata"; + +"Text.Generic.ETALong" = "Orario di arrivo stimato"; + +/* Reference to fixed pricing.. English equivalent: "Fixed" */ +"Text.Generic.Fixed" = "Fisso"; + +/* "Got It" (generally used on alert buttons) */ +"Text.Generic.GotIt" = "FATTO"; + +/* Password Entry Button */ +"Text.Generic.Hide" = "Nascondere"; + +"Text.Generic.Logout" = "Esci"; + +/* english "making a booking". Used in terms conditions construction */ +"Text.Generic.MakingBookingAction" = "fare una prenotazione"; + +"Text.Generic.MeetGreet" = "Incontra e saluta"; + +/* Metered fare type displayed in quotes list: English: "Metered" */ +"Text.Generic.Metered" = "Tassametro"; + +"Text.Generic.Minutes" = "min"; + +"Text.Generic.Name" = "Nome"; + +"Text.Generic.No" = "No"; + +"Text.Generic.NoCarsAvailable" = "Sfortunatamente, non ci sono auto disponibili per il tuo viaggio in questo momento.\n\nSi prega di ricontrollare presto"; + +/* The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device" */ +"Text.Generic.NoEmailSetupError" = "Per favore imposta un account di posta sul tuo dispositivo"; + +"Text.Generic.Ok" = "OK"; + +"Text.Generic.Optional" = "Opzionale"; + +/* "Payment" used as a button in the side menu to reach all your payment methods */ +"Text.Generic.Payment" = "Pagamento"; + +/* "Payments" used as the title of the payment method screen */ +"Text.Generic.Payments" = "Pagamenti"; + +"Text.Generic.PhoneNumber" = "Numero di telefono"; + +"Text.Generic.Pickup" = "Partenza"; + +/* English: "Pickup Time" in booking request screen */ +"Text.Generic.PickupTime" = "Orario di ritiro"; + +"Text.Generic.Prebook" = "Libro"; + +"Text.Generic.Price" = "Prezzo"; + +"Text.Generic.PrivacyPolicy" = "Politica sulla Riservatezza"; + +"Text.Generic.Register" = "Registrati"; + +/* english: "creating your Karhoo account". Used in terms conditions construction */ +"Text.Generic.RegisterAccountAction" = "creare il tuo account Karhoo"; + +/* English: "Report Issue" */ +"Text.Generic.ReportIssue" = "Segnala problema"; + +/* String for when trip is initially loaded and no trip state has yet come through. "Requesting" */ +"Text.Generic.Requesting" = "Richiedere"; + +/* used in side menu "Rides" */ +"Text.Generic.Rides" = "Le tue corse"; + +/* "Save" used as a button (call to action) */ +"Text.Generic.Save" = "Salvare"; + +/* Password Entry Button */ +"Text.Generic.Show" = "Spettacolo"; + +/* english: "status" */ +"Text.Generic.Status" = "Stato"; + +"Text.Generic.Submit" = "INVIA"; + +"Text.Generic.Success" = "Successo"; + +"Text.Generic.Surname" = "Cognome"; + +"Text.Generic.TermsConditions" = "Termini e Condizioni"; + +"Text.Generic.TermsOfUse" = "Condizioni di Utilizzo"; + +/* "Thanks for your interest" */ +"Text.Generic.Thanks" = "Grazie per il tuo interesse"; + +/* Booker cancelled */ +"Text.Generic.TripStatus.BookerCancelled" = "Cancellato"; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "Ci vuole più tempo del solito perché la flotta assegni un autista. Attendi, contatta la flotta o annulla e riprenota con una flotta diversa."; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Ritardo nell'assegnazione"; + +/* Driver Cancelled */ +"Text.Generic.TripStatus.DriverCancelled" = "Annullato dal conducente/spedizione"; + +/* No drivers available */ +"Text.Generic.TripStatus.NoDriversAvailable" = "Nessun driver disponibile"; + +/* "Unkown" */ +"Text.Generic.Unknown" = "Sconosciuto"; + +"Text.Generic.Yes" = "Sì"; + +/* "Allocated" when a driver has been allocated */ +"Text.GenericTripStatus.Allocated" = "Assegnato"; + +/* "Driver Approaching" */ +"Text.GenericTripStatus.Approaching" = "Autista in avvicinamento"; + +/* Driver Arrived */ +"Text.GenericTripStatus.Arrived" = "Autista arrivato"; + +/* "Cancelled" */ +"Text.GenericTripStatus.Cancelled" = "Cancellato"; + +/* Cancelled by Karhoo */ +"Text.GenericTripStatus.CancelledByKarhoo" = "Cancellato da Karhoo"; + +/* "Completed" (trip completed) */ +"Text.GenericTripStatus.Completed" = "Completato"; + +/* Confirmed */ +"Text.GenericTripStatus.Confirmed" = "Confermato"; + +/* "Driver En Route" when a driver is en route */ +"Text.GenericTripStatus.EnRoute" = "Conducente lungo il percorso"; + +/* "Failed" */ +"Text.GenericTripStatus.Failed" = "Impossibile"; + +/* "Incomplete" */ +"Text.GenericTripStatus.Incomplete" = "Stato in sospeso"; + +/* in english: "Requested" */ +"Text.GenericTripStatus.Initialised" = "Richiesto"; + +/* "On Board" */ +"Text.GenericTripStatus.PassengerOnBoard" = "A bordo"; + +/* english: requested */ +"Text.GenericTripStatus.Requested" = "Richiesto"; + +/* "Pending" */ +"Text.GenericTripStatus.Unknown" = "in sospeso"; + +"Text.Help.ContactUs.Link" = "https://taxibookermobile.zendesk.com/hc/en-us/requests/new"; + +"Text.Help.FAQ.Link" = "https://taxibookermobile.zendesk.com/hc/en-us"; + +/* No availability in requested area, Fuzzy */ +"Text.KarhooError.K3002" = "Non ci sono flotte disponibili in quest'area."; + +"Text.KarhooError.Q0001" = "Ritiro e destinazione non possono essere gli stessi."; + +/* "Add new card" in english used in the payments section of the app. Referring to credit / debit card */ +"Text.Payment.AddPaymentMethod" = "Aggiungi pagamento"; + +"Text.Payment.PaymentMethod" = "Fine della carta"; + +/* Prebook */ +"Text.Prebook.PrebookPickupTime" = "Prenota in anticipo l'orario di ritiro"; + +"Text.Prebook.SetPrebook" = "Imposta l'orario di ritiro"; + +/* "Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes */ +"Text.Prebook.TimezoneMessage" = "La prenotazione verrà effettuata nell'ora locale del ritiro ( %1$@ )"; + +"Text.Quote.FreeCancellationAndKeyword" = "e"; + +"Text.Quote.FreeCancellationASAP" = "Cancellazione gratuita fino a %1$@ dopo la prenotazione"; + +"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Cancellazione gratuita fino a quando l'autista non è in viaggio"; + +/* Cancellation info on quotes */ +"Text.Quote.FreeCancellationPrebook" = "Cancellazione gratuita fino a %1$@ prima del ritiro"; + +"Text.QuoteCategory.Electric" = "Elettrico"; + +"Text.QuoteCategory.Exec" = "Esecutivo"; + +"Text.QuoteCategory.Executive" = "Esecutivo"; + +"Text.QuoteCategory.Moto" = "Moto"; + +"Text.QuoteCategory.Motorcycle" = "Motociclo"; + +"Text.QuoteCategory.MPV" = "Multiposto"; + +"Text.QuoteCategory.Saloon" = "Standard"; + +"Text.QuoteCategory.Taxi" = "Taxi"; + +/* Side Menu "About" section title, Fuzzy */ +"Text.SideMenu.About" = "Circa"; + +"Text.SideMenu.Feedback" = "Feedback"; + +"Text.SideMenu.Help" = "Aiuto"; + +/* Side Menu */ +"Text.SideMenu.Login" = "Registrati"; + +/* "Profile" button on the side menu */ +"Text.SideMenu.Profile" = "Profilo"; + +/* Register on the side menu */ +"Text.SideMenu.Register" = "Registrati"; + +"Text.SideMenu.SignIn" = "Registrati"; + +/* Sign Out on the side menu */ +"Text.SideMenu.SignOut" = "Esci"; + +"Text.SideMenu.Signup" = "Registrati"; + +/* In app email to customer support / feedback */ +"Text.SupportMailMessage.Feedback" = "Si prega di non eliminare queste informazioni in quanto ci aiutano a migliorare l'app."; + +"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; + +"Text.SupportMailMessage.FeedbackSubject" = "Feedback"; + +"Text.SupportMailMessage.NoCoverageBody" = "Grazie per aver consigliato una flotta nella tua zona. Per ottenere la copertura nella tua zona il più velocemente possibile, ti preghiamo di fornirci l'area e il nome della compagnia di trasporto.\nLa zona:\nTempo della flotta:"; + +/* No coverage email */ +"Text.SupportMailMessage.NoCoverageSubject" = "Raccomandazione per la flotta"; + +"Text.SupportMailMessage.ReportIssue" = "Utilizza lo spazio sottostante per segnalare un problema specifico con la tua corsa."; + +"Text.SupportMailMessage.ReportIssueSubject" = "Segnala problema"; + +"Text.SupportMailMessage.SupplierEmail" = "fornitori@karhoo.com"; + +"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; + +/* Used in the checkout component before booking a ride */ +"Text.TermsConditions.BookingFullString" = "Effettuando una prenotazione accetti i %1$@ | %2$@ e %4$@ di %3$@ | %5$@ di %3$@."; + +"Text.TermsConditions.FullString" = "Entro %1$@ , accetti %2$@ 's \n%3$@ | %4$@"; + +"Text.TermsConditions.KarhooPolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.KarhooTermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TermsConditions.PolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.TermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TrackingLink.production" = "https://agent-portal.karhoo.com/follow/"; + +/* Trip Tracking Links */ +"Text.TrackingLink.sandbox" = "https://agent-portal.sandbox.karhoo.com/follow/"; + +"Text.TrackingLink.staging" = "https://agent-portal.stg.karhoo.net/follow/"; + +"Text.Trip.ActivityIndicator.Cancelling" = "Annullamento"; + +/* "Arrival" displayed on arrival box in trip */ +"Text.Trip.Arrival" = "Arrivo"; + +"Text.Trip.CallDriver" = "Contatta l'autista"; + +/* Call fleet button in trip screen (English: Call Fleet) */ +"Text.Trip.CallFleet" = "Chiama flotta"; + +"Text.Trip.CancelBookingConfirmation.Alert.Message" = "Potrebbe esserti addebitata una penale di cancellazione da parte del fornitore."; + +"Text.Trip.CancelBookingConfirmation.Alert.Title" = "Annullare la tua corsa?"; + +/* displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking" */ +"Text.Trip.CancelBookingFailed" = "Cancellazione non confermata, chiamare il fornitore"; + +"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Chiama flotta"; + +"Text.Trip.CancelBookingFailed.AlertMessage" = "Stiamo riscontrando problemi durante l'annullamento della corsa. Si prega di contattare la flotta."; + +"Text.Trip.CancelBookingFailed.AlertTitle" = "Difficoltà nell'annullamento"; + +"Text.Trip.CancelledByDispatch" = "La tua prenotazione è stata cancellata."; + +"Text.Trip.CancelledByDispatch.AlertMessage" = "La tua prenotazione è stata cancellata. Vi preghiamo di contattarci per ulteriori informazioni."; + +"Text.Trip.CancelledByDispatch.AlertTitle" = "Annullato dalla flotta"; + +"Text.Trip.CancelledByUser" = "Hai cancellato la prenotazione"; + +/* Trip */ +"Text.Trip.CancelRide" = "Annulla corsa"; + +"Text.Trip.Completed" = "Hai raggiunto la tua destinazione"; + +"Text.Trip.Confirmed" = "La tua prenotazione è stata accettata.\nIn attesa che venga assegnato un driver."; + +"Text.Trip.DriverArrived" = "Il tuo autista è arrivato!"; + +"Text.Trip.DriverEnRoute" = "Il tuo autista è in viaggio"; + +/* alert message when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertMessage" = "Si è verificato un problema durante la prenotazione. Riprova o contatta l'assistenza."; + +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertTitle" = "Problema Prenotazione"; + +"Text.Trip.MessageDriver" = "Driver del messaggio"; + +/* For when demand is too high and there are no drivers available */ +"Text.Trip.NoDriversAvailable" = "Nessun driver disponibile"; + +/* Alert message in popup when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertMessage" = "Siamo spiacenti, la domanda è alta. %1$@ attualmente non ha driver disponibili."; + +/* Popup title message when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertTitle" = "Prenotazione fallita"; + +"Text.Trip.PassengerOnBoard" = "Stai arrivando. Buon viaggio!"; + +/* Trip Statuses */ +"Text.Trip.Requested" = "%1$@ sta assegnando un driver. Questo potrebbe richiedere fino a 5 minuti."; + +/* Used as a button in the trip screen. English: "Ride Options" */ +"Text.Trip.RideOptions" = "Opzioni di corsa"; + +/* Please wait whilst you\'re allocated a driver */ +"Text.TripAllocation.AllocatingTripOne" = "Attendi mentre ti viene assegnato un driver"; + +/* This may take a moment or two */ +"Text.TripAllocation.AllocatingTripTwo" = "Questo potrebbe richiedere un momento o due"; + +"Text.TripAllocation.CancelInstruction" = "Tocca e tieni premuto per annullare"; + +"Text.TripAllocation.Cancelling" = "Annullamento"; + +/* Finding your ride... */ +"Text.TripAllocation.FindingYourRide" = "Trovare la tua corsa..."; + +/* Trip Rating */ +"Text.TripRating.Confirmation" = "Grazie per aver inviato la tua valutazione."; + +"Text.TripRating.ExtraFeedback" = "Ci dica di più"; + +"Text.TripRating.Title" = "Come valuteresti il tuo viaggio?"; + +/* Used for the "Book Return Ride" button on the trip summary screen */ +"Text.TripSummary.BookReturnRide" = "Prenota andata e ritorno"; + +/* "Date" */ +"Text.TripSummary.Date" = "Data"; + +/* Fleet */ +"Text.TripSummary.Fleet" = "Compagnia"; + +/* "Payment Summary" header used on Trip Summary Screen */ +"Text.TripSummary.PaymentSummary" = "Sommario Pagamento"; + +/* "Quoted Price": used in trip summary screen when the fare is not available */ +"Text.TripSummary.QuotedPrice" = "Prezzo dell'offerta"; + +/* Total Fare */ +"Text.TripSummary.TotalFare" = "Tariffa totale"; + +/* "Trip Summary" header used on screen */ +"Text.TripSummary.TripSummary" = "Riepilogo della corsa"; + +"Text.TripSummary.Vehicle" = "Veicolo"; + +"Text.User.Email" = "E-mail"; + +"Text.User.EmailSubscription" = "Non desidero ricevere corse, promozioni o offerte gratis"; + +/* User (register / login / user attributes) */ +"Text.User.FirstName" = "Nome"; + +/* Text used on button to trigger password reset... English: Forgotten Password? */ +"Text.User.ForgottenPassword" = "Password dimenticata?"; + +"Text.User.LastName" = "Cognome"; + +"Text.User.MobilePhoneNumber" = "Numero di cellulare"; + +"Text.User.Password" = "Password"; + +"Text.User.PhoneCountryCode" = "Codice"; + +/* "We will notify you via email once your request has been processed." */ +"Text.User.SignupPendingMessage" = "Ti avviseremo via e-mail una volta che la tua richiesta sarà stata elaborata."; + +"Text.VehicleClass.Electric" = "Elettrico"; + +"Text.VehicleClass.Exec" = "Esecutivo"; + +"Text.VehicleClass.Executive" = "Esecutivo"; + +"Text.VehicleClass.Moto" = "Moto"; + +"Text.VehicleClass.Motorcycle" = "Motociclo"; + +"Text.VehicleClass.MPV" = "Multiposto"; + +"Text.VehicleClass.Saloon" = "Standard"; + +"Text.VehicleClass.Taxi" = "Taxi"; + +"Text.VehicleTag.Childseat" = "Seggiolino per bambini"; + +/* Vehicle tags */ +"Text.VehicleTag.Electric" = "Elettrico"; + +"Text.VehicleTag.Executive" = "Esecutivo"; + +"Text.VehicleTag.Hybrid" = "Ibrido"; + +"Text.VehicleTag.Taxi" = "Taxi"; + +"Text.VehicleTag.Wheelchair" = "Sedia a rotelle"; + +"Text.VehicleType.Bus" = "Autobus"; + +"Text.VehicleType.Moto" = "Moto"; + +"Text.VehicleType.MPV" = "Multiposto"; + +"Text.VehicleType.Standard" = "Standard"; + +"Vehicle.Tag.Childseat" = "Seggiolino per bambini"; + +/* Vehicle tags */ +"Vehicle.Tag.Electric" = "Elettrico"; + +"Vehicle.Tag.Hybrid" = "Ibrido"; + +"Vehicle.Tag.Taxi" = "Taxi"; + +"Vehicle.Tag.Wheelchair" = "Sedia a rotelle"; + diff --git a/KarhooUISDK/Translations/it.lproj/Localizable.stringsdict b/KarhooUISDK/Translations/it.lproj/Localizable.stringsdict new file mode 100644 index 000000000..90a0e1095 --- /dev/null +++ b/KarhooUISDK/Translations/it.lproj/Localizable.stringsdict @@ -0,0 +1,38 @@ + + + + + Text.Quote.FreeCancellationBeforePickupMinutes + + NSStringLocalizedFormatKey + %#@MINUTE@ + MINUTE + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + 1 minuto + other + %d minuti + + + Text.Quote.FreeCancellationBeforePickupHours + + NSStringLocalizedFormatKey + %#@HOUR@ + HOUR + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + 1 ora + other + %d ore + + + + diff --git a/KarhooUISDK/Translations/nl.lproj/Localizable.strings b/KarhooUISDK/Translations/nl.lproj/Localizable.strings new file mode 100644 index 000000000..e008f1206 --- /dev/null +++ b/KarhooUISDK/Translations/nl.lproj/Localizable.strings @@ -0,0 +1,883 @@ +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"\"Text.Trip.KarhooCancelled.AlertTitle\"" = "Probleem met reserveren"; + +"CURBSIDE" = "Curbside"; + +/* PickUp Type */ +"DEFAULT" = "STANDAARD"; + +"ELECTRIC" = "Elektrisch"; + +"EXEC" = "Executive"; + +/* English: Error codes */ +"K0001" = "Algemene fout in de aanvraag"; + +"K0002" = "Invalid request payload"; + +"K0003" = "Could not read authorisation token"; + +"K0004" = "Authentication is required for this path"; + +"K0005" = "Vereiste rol ontbreekt voor dit verzoek"; + +"K0006" = "Snelheidslimiet overschreden"; + +"K0007" = "Circuit breaker has triggered for this route"; + +/* User errors, K1xxx */ +"K1001" = "Kan gebruiker niet registreren"; + +"K1002" = "Kan gebruiker niet registreren (gebruiker bestaat al)"; + +"K1003" = "Kon de gebruiker niet registreren (incorrecte aanvraag)"; + +"K1004" = "Kan gebruiker niet registreren (ongeldig telefoonnummer)"; + +"K1005" = "Kan gebruikersgegevens niet ophalen (ongeldige token)"; + +"K1006" = "Kan gebruikersgegevens niet ophalen (gebruiker bestaat niet)"; + +"K1999" = "Gebruiker is aangemaakt maar nog niet geautoriseerd. We nemen contact met je op zodra deze is ingeschakeld."; + +/* Locations errors, K2xxx */ +"K2001" = "Kon adres niet krijgen"; + +/* Quotes errors, K3xxx */ +"K3001" = "Kan geen schattingen krijgen"; + +"K3002" = "Kan geen schattingen krijgen (geen beschikbaarheid gevonden in het gevraagde gebied)"; + +"K3003" = "Kan geen schattingen krijgen (kon gespecificeerde offerte niet vinden)"; + +/* Bookings errors, K4xxx */ +"K4001" = "Kon reis niet boeken"; + +"K4002" = "Kon reis niet boeken - ongeldige lading van verzoek (minimaal 1 set passagiersgegevens vereist)"; + +"K4003" = "Kon reis niet boeken (kon gespecificeerde offerte niet vinden)"; + +"K4004" = "Kon reis niet boeken (poging om een verlopen offerte te boeken)"; + +"K4005" = "Kon reis niet boeken (toestemming geweigerd)"; + +"K4006" = "Kon reis niet boeken (pre-autorisatie betaling mislukt)"; + +"K4007" = "Kon reis niet annuleren"; + +"K4008" = "Kon reis niet annuleren (kon gespecificeerde reis niet vinden)"; + +"K4009" = "Kan reis niet annuleren (toestemming geweigerd)"; + +"K4010" = "Kon reis niet annuleren (al geannuleerd)"; + +"K4011" = "Kon geen reis krijgen"; + +"K4012" = "Kon reis niet ophalen (kon gespecificeerde reis niet vinden)"; + +"K4013" = "Kan reis niet ophalen (toestemming geweigerd)"; + +"K4014" = "Kon reis niet boeken als agent"; + +"K4015" = "Kon reis niet boeken als reiziger"; + +"k4015" = "Kon reis niet boeken als reiziger"; + +"K4018" = "Kon reis niet boeken omdat deze offerte niet langer beschikbaar is"; + +"K4020" = "Kon reis niet boeken met het geselecteerde DMS"; + +"K4025" = "Offerteprijs verhoogd tijdens boeking"; + +/* Availability errors, K5xxx */ +"K5001" = "Kan geen schattingen krijgen"; + +"K5002" = "Kon geen beschikbaarheid krijgen (geen beschikbaarheid gevonden in het gevraagde gebied)"; + +"K5003" = "Kon geen beschikbaarheid krijgen (geen categorieën gevonden binnen het gevraagde gebied)"; + +/* Authentication errors K6xxx */ +"K6001" = "Ongeldig e-mailadres of wachtwoord. Probeer het opnieuw"; + +/* KPOI errors, K7xxx */ +"K7001" = "Kon KPOI-verzoek niet verwerken"; + +"K7002" = "Kan Karhoo POI met overeenkomende ID niet vinden"; + +"K7003" = "Kan Karhoo POI niet lezen"; + +"K7004" = "Kan Karhoo POI niet schrijven"; + +"K7005" = "Kan Karhoo POI niet verwijderen"; + +/* KSDKxxx Internal SDK */ +"KSDK01" = "Er is iets misgegaan, maar we weten niet wat het was"; + +"KSDK02" = "Ontbrekende gebruikersrechten"; + +"KSDK03" = "Gebruiker is al ingelogd"; + +"MEET_AND_GREET" = "Meet & Greet"; + +"MPV" = "Minibus"; + +/* Qxxxx errors */ +"Q0001" = "De ophaallocatie en eindbestemming kunnen niet hetzelfde zijn."; + +"SALOON" = "Standaard voertuig"; + +"STAND_BY" = "Stand-by"; + +"TAXI" = "Taxi"; + +/* "Version" */ +"Text.About.Version" = "Versie"; + +"Text.Address.CurrentLocation" = "Huidige locatie"; + +"Text.Address.NoRecentAddress" = "Geen recente resultaten"; + +"Text.Address.SetOnMap" = "Op kaart zetten"; + +/* Address Bar */ +"Text.AddressBar.AddDestination" = "Bestemming toevoegen"; + +"Text.AddressBar.AddPickup" = "Ophaallocatie toevoegen"; + +"Text.AddressBar.EnterPickupLocation" = "Vul ophaallocatie in"; + +"Text.AddressSearch.EnterDestinationLocation" = "Voer de bestemmingslocatie in"; + +/* "Add Flight Details" used on booking airport ride */ +"Text.Airport.AddFlightDetails" = "Vluchtgegevens toevoegen"; + +/* "Flight number" used as the flight number field placeholder */ +"Text.Airport.FlightNumber" = "Vluchtnummer"; + +/* Message on airport screen for encouraging user to enter as much info about airport booking as possible */ +"Text.Airport.HelpfulMessage" = "Voer een geldig vluchtnummer in"; + +/* "Airport Pickup" used on screen for airport bookinga */ +"Text.Airport.Pickup" = "Ophalen op de luchthaven"; + +/* "All" used for all categories filter on category list. Write normally as the app will uppercase the string */ +"Text.Availability.AllCategory" = "Alle"; + +"Text.Availability.NoQuotesForSelectedParameters" = "Geen beschikbaarheid voor de gevraagde tijd. Kies een ander tijdstip."; + +"Text.Availability.NoQuotesInSelectedCategory" = "Er zijn geen offertes voor deze categorie.\nKies een andere categorie."; + +/* Base fare title */ +"Text.Booking.BaseFare" = "Basistarief"; + +/* "Your final fare might be affected by tips, tolls, taxes, and other charges." */ +"Text.Booking.BaseFareExplanation" = "Uw uiteindelijke tarief kan worden beïnvloed door fooien, tolgelden, belastingen en andere heffingen."; + +"Text.Booking.CountryCodeSelection.Search" = "Land/regio zoeken"; + +/* Country Code Selection */ +"Text.Booking.CountryCodeSelection.Title" = "Land / Regio"; + +"Text.Booking.EnterDestination" = "Voer bestemming in om beschikbare taxibedrijven te zien"; + +/* Checkout component */ +"Text.Booking.EstimatedInfoBox" = "Dit taxibedrijf is een niet-gereguleerde taxi. De offerte is een schatting op basis van de reisfactoren (afstand, tijd, etc). Raadpleeg de algemene voorwaarden van het taxibedrijf voor meer informatie."; + +"Text.Booking.FixedInfoBox" = "Dit taxibedrijft rekent een vast tarief. Het uiteindelijke tarief kan worden beïnvloed door extra's (tolgeld, vertraging, enz.). Raadpleeg de algemene voorwaarden van het taxibedrijf."; + +"Text.Booking.FlightTracking" = "Vlucht volgen"; + +"Text.Booking.GPSTracking" = "GPS-tracking"; + +"Text.Booking.GuestCheckoutFlightNumberPlaceholder" = "Vluchtnummer (optioneel)"; + +/* Guest checkout */ +"Text.Booking.GuestCheckoutPassengerDetailsTitle" = "Passagiersgegevens"; + +"Text.Booking.GuestCheckoutPaymentDetailsTitle" = "Betalingsmethoden"; + +"Text.Booking.LearnMore" = "Meer informatie"; + +"Text.Booking.MaximumLuggages" = "%1$@ maximum aantal bagage"; + +"Text.Booking.MaximumPassengers" = "%1$@ maximum aantal passagiers"; + +"Text.Booking.MeteredInfoBox" = "Dit taxibedrijf werkt met een gereguleerde taximeter. De offerte is een schatting op basis van de reisfactoren (afstand, tijd, etc)."; + +"Text.Booking.Next" = "Volgende"; + +/* %1$@ if you have suggestions for local fleets. */ +"Text.Booking.NoAvailabilityBody" = "%1$@ als u suggesties heeft voor lokale taxibedrijven."; + +/* We’re not live here yet! */ +"Text.Booking.NoAvailabilityHeader" = "We zijn hier nog niet live!"; + +/* Get in touch */ +"Text.Booking.NoAvailabilityLink" = "Neem contact op"; + +"Text.Booking.Passenger" = "Passagier"; + +"Text.Booking.PassengerDetails.Add" = "Passagier toevoegen"; + +"Text.Booking.PassengerDetails.Email" = "E-Mail"; + +"Text.Booking.PassengerDetails.FirstName" = "Voornaam"; + +"Text.Booking.PassengerDetails.LastName" = "Achternaam"; + +"Text.Booking.PassengerDetails.MobilePhone" = "Mobiel telefoonnummer"; + +"Text.Booking.PassengerDetails.SaveAction" = "BEWAREN"; + +"Text.Booking.PassengerDetails.Subtitle" = "Deze informatie zorgt voor een soepel verloop van uw rit."; + +/* Passenger Details */ +"Text.Booking.PassengerDetails.Title" = "Passagiersgegevens"; + +/* Your booking\nfrom: %1$@\nto: %2$@\nat: %3$@\nhas been booked */ +"Text.Booking.PrebookConfirmation" = "Uw boeking\nvanaf: %1$@ \ntot: %2$@ \nat: %3$@ \nis geboektboeking"; + +/* Prebook Done, Fuzzy */ +"Text.Booking.PrebookConfirmed" = "Prebook bevestigd"; + +/* Ride Details */ +"Text.Booking.PrebookConfirmed.RideDetails" = "Ritgegevens"; + +/* Booking */ +"Text.Booking.RequestCar" = "RESERVEER"; + +"Text.Booking.RequestingCar" = "Rit reserveren"; + +"Text.Booking.RequestReceived" = "Reservering ontvangen"; + +"Text.Booking.TrainTracking" = "Trein volgen"; + +"Text.Bookings.Alert.CancellationFee.Charge" = "Er worden annuleringskosten in rekening gebracht die worden geschat op %1$@ .\n\nWilt u doorgaan?"; + +"Text.Bookings.Alert.CancellationFee.Continue" = "Wilt u doorgaan?"; + +"Text.Bookings.Alert.CancellationSuccess.Message" = "Uw rit is succesvol geannuleerd."; + +"Text.Bookings.Alert.CancellationSuccess.Title" = "Annulering rit succesvol"; + +/* used as a call to action on a button in the empty bookings screen: English: "Book Ride" */ +"Text.Bookings.BookATrip" = "Reserveer een rit"; + +/* "Cancel Ride" button action */ +"Text.Bookings.CancelRide" = "Rit annuleren"; + +/* "Contact Driver" (button action) */ +"Text.Bookings.ContactDriver" = "Neem contact op met de chauffeur"; + +/* "Contact Fleet" */ +"Text.Bookings.ContactFleet" = "Neem contact op met het taxibedrijf"; + +/* Generic fallback message for trip load failure */ +"Text.Bookings.CouldNotLoadTrips" = "Kan de ritten niet laden."; + +"Text.Bookings.eta" = "Geschatte aankomsttijd"; + +/* English: "No Trips" used if the booking list screen is empty */ +"Text.Bookings.NoTrips" = "Geen ritten"; + +/* used as a message on the booking screen if the user has no trips. English: "You have no booked trips yet. We can help you get from A to B" */ +"Text.Bookings.NoTripsBookedMessage" = "U heeft nog geen ritten geboekt. Wij kunnen u helpen om van A naar B te komen"; + +/* "Past" used on past tabs on bookings list */ +"Text.Bookings.Past" = "Voorgaande ritten"; + +"Text.Bookings.price" = "Prijs"; + +"Text.Bookings.Price" = "Prijs"; + +"Text.Bookings.Price.Cancelled" = "Geannuleerd"; + +"Text.Bookings.Quote" = "Prijsopgave"; + +/* Button for rebooking a ride */ +"Text.Bookings.RebookRide" = "Rit opnieuw reserveren"; + +/* "Report Issue" Button */ +"Text.Bookings.ReportIssue" = "Probleem melden"; + +/* "Track Driver" */ +"Text.Bookings.TrackDriver" = "Track de bestuurder"; + +/* "Track Trip" */ +"Text.Bookings.TrackTrip" = "Track de rit"; + +"Text.Bookings.TrackTrip.AlertMessage" = "Wilt u het voertuig volgen?"; + +"Text.Bookings.TrackTrip.AlertTitle" = "De chauffeur is onderweg"; + +"Text.Bookings.TrackTrip.DismissAction" = "Nee"; + +"Text.Bookings.TrackTrip.TrackAction" = "Ja"; + +/* Upcoming: used on upcoming tabs for rides, Fuzzy */ +"Text.Bookings.Upcoming" = "Aankomende"; + +"Text.Error.Alert.CantSendEmail" = "Kan geen e-mailbericht verzenden. Configureer eerst de Mail-app."; + +/* The action button on the force update alert. ie "Update" (this button takes the user to the app store) */ +"Text.Error.Alert.ForceUpdateButton" = "Update"; + +/* The message when the user needs to update the app. ie. "Please update Karhoo to the latest version." */ +"Text.Error.Alert.ForceUpdateMessage" = "Werk de app bij om door te gaan."; + +/* The title of the alert when user is forced to update ie "App Update Required" */ +"Text.Error.Alert.ForceUpdateTitle" = "Nieuwe versie beschikbaar"; + +"Text.Error.Booking.EnterDestinationToProceed" = "Voer bestemming in om een rit te reserveren"; + +/* Errors */ +"Text.Error.EmailValidationError" = "Controleer of uw e-mailadres correct is gespeld"; + +/* When the user enters an invalid flight number, Fuzzy */ +"Text.Error.FlightNumberValidationHint" = "Vluchtnummer"; + +/* When fetching the user profile fails */ +"Text.Error.GetUserFails" = "Er is een probleem opgetreden bij het ophalen van uw profiel."; + +/* Used to explain an unknown error. ie "Oops, something went wrong. Please try again" */ +"Text.Error.NoDetails" = "Oeps! Er is iets misgegaan. Probeer het opnieuw."; + +"Text.Error.NotLoggedIn" = "U bent niet ingelogd"; + +"Text.Error.Payment.Alert.ButtonUpdateCard" = "Update kaart"; + +"Text.Error.Payment.Alert.Message" = "We kunnen uw creditcard/betaalpas niet autoriseren."; + +"Text.Error.Payment.Alert.Title" = "Probleem met kaart"; + +/* Error message when user tries to prebook within the current hour of local time */ +"Text.Error.PrebookingWithinTheHour" = "Prebook kan niet binnen het huidige uur worden gereserveerd."; + +/* "Something went wrong" used as a title for error alert */ +"Text.Error.SomethingWentWrong" = "Er is een fout opgetreden"; + +/* Theoretical edge case where the braintree token is missing */ +"Text.Errors.failedToInitialisePaymentSetup" = "Probleem met het initialiseren van betalingen, neem contact op met de helpdesk"; + +"Text.Errors.InvalidPhoneNumber" = "Ongeldig telefoonnummer"; + +"Text.Errors.MissingPhoneNumber" = "Leeg veld niet toegestaan"; + +/* empty table view result */ +"Text.Errors.NoResultsFound" = "Geen resultaten gevonden"; + +"Text.FeedbackView.addComment" = "Aanvullende opmerkingen"; + +"Text.FeedbackView.app" = "Hoe gemakkelijk vond u het gebruik van de app?"; + +"Text.FeedbackView.confirmation" = "Bedankt voor het doorgeven van uw feedback"; + +"Text.FeedbackView.pob" = "Hoe was uw ervaring in de taxi (bijv. netheid van de taxi, route en chauffeur)? Hoe gemakkelijk vond u het gebruik van de app?"; + +"Text.FeedbackView.pre_pob" = "Hoe was uw ervaring met het vinden van de ophaallocatie en het ontmoeten van uw chauffeur?"; + +/* FeedBackView */ +"Text.FeedbackView.quote" = "Hoe tevreden was u met de selectie van offertes voor uw reis (bijv. Taxibedrijven, Prijzen en ETA's)?"; + +"Text.Generic.Add" = "Toevoegen"; + +/* "Additional information" used as placeholder on airport details screen */ +"Text.Generic.AdditionalInformation" = "Extra informatie"; + +"Text.Generic.Back" = "Terug"; + +"Text.Generic.Bookings" = "Reserveringen"; + +/* Localizable.strings, Karhoo, , Copyright © 2020 Karhoo. All rights reserved., Generics */ +"Text.Generic.Cancel" = "Annuleren"; + +/* English: "cancellation policy" used as an injection in terms and conditions box when requesting a booking */ +"Text.Generic.CancellationPolicy" = "Annuleringsvoorwaarden Taxibedrijf"; + +/* "Cancelled" */ +"Text.Generic.Cancelled" = "Geannuleerd"; + +/* english "Card" (referring to payment card) */ +"Text.Generic.Card" = "Kaart"; + +"Text.Generic.Change" = "Wijzigen"; + +"Text.Generic.Close" = "Sluiten"; + +"Text.Generic.Comment" = "Opmerkingen"; + +"Text.Generic.Comment.Optional" = "Opmerkingen (optioneel)"; + +/* "Completed" */ +"Text.Generic.Completed" = "Voltooid"; + +"Text.Generic.Contact" = "Contact"; + +"Text.Generic.Continue" = "Verder gaan"; + +"Text.Generic.Destination" = "Bestemming"; + +"Text.Generic.Dismiss" = "Stoppen"; + +"Text.Generic.Done" = "Klaar"; + +/* "Edit" used as a button (call to action) */ +"Text.Generic.Edit" = "Wijzigen"; + +"Text.Generic.Email" = "E-mailadres"; + +"Text.Generic.EPrice" = "Geschatte prijs"; + +"Text.Generic.Error" = "Fout"; + +"Text.Generic.ErrorMessage" = "Oeps! Er is iets misgegaan"; + +/* English: "Estimated" */ +"Text.Generic.Estimated" = "Geschatte prijs"; + +"Text.Generic.ETA" = "Geschatte aankomsttijd"; + +"Text.Generic.ETALong" = "Geschatte aankomsttijd"; + +/* Reference to fixed pricing.. English equivalent: "Fixed" */ +"Text.Generic.Fixed" = "Vaste prijs"; + +/* "Got It" (generally used on alert buttons) */ +"Text.Generic.GotIt" = "Ik begrijp het"; + +/* Password Entry Button */ +"Text.Generic.Hide" = "Verbergen"; + +"Text.Generic.Logout" = "Afmelden"; + +/* english "making a booking". Used in terms conditions construction */ +"Text.Generic.MakingBookingAction" = "Reservering maken"; + +"Text.Generic.MeetGreet" = "Meet & Greet"; + +/* Metered fare type displayed in quotes list: English: "Metered" */ +"Text.Generic.Metered" = "meterprijs"; + +"Text.Generic.Minutes" = "min"; + +"Text.Generic.Name" = "Naam"; + +"Text.Generic.No" = "Nee"; + +"Text.Generic.NoCarsAvailable" = "Helaas zijn er op dit moment geen auto's beschikbaar voor uw rit. Probeer het alstublieft binnenkort nog eens"; + +/* The message when the user tries to send feedback but they have no mail account set up on their device: English: "Please set up a mail account on your device" */ +"Text.Generic.NoEmailSetupError" = "Stel alstublieft een e-mailaccount in op uw apparaat"; + +"Text.Generic.Ok" = "OK"; + +"Text.Generic.Optional" = "Optioneel"; + +/* "Payment" used as a button in the side menu to reach all your payment methods */ +"Text.Generic.Payment" = "Betaling"; + +/* "Payments" used as the title of the payment method screen */ +"Text.Generic.Payments" = "Betalingen"; + +"Text.Generic.PhoneNumber" = "Telefoonnummer"; + +"Text.Generic.Pickup" = "Ophaallocatie"; + +/* English: "Pickup Time" in booking request screen */ +"Text.Generic.PickupTime" = "Ophaaltijd"; + +"Text.Generic.Prebook" = "RESERVEER"; + +"Text.Generic.Price" = "Prijs"; + +"Text.Generic.PrivacyPolicy" = "Privacybeleid"; + +"Text.Generic.Register" = "Registreren"; + +/* english: "creating your Karhoo account". Used in terms conditions construction */ +"Text.Generic.RegisterAccountAction" = "uw Karhoo-account aanmaken"; + +/* English: "Report Issue" */ +"Text.Generic.ReportIssue" = "Probleem melden"; + +/* String for when trip is initially loaded and no trip state has yet come through. "Requesting" */ +"Text.Generic.Requesting" = "Aanvragen"; + +/* used in side menu "Rides" */ +"Text.Generic.Rides" = "Ritten"; + +/* "Save" used as a button (call to action) */ +"Text.Generic.Save" = "BEWAREN"; + +/* Password Entry Button */ +"Text.Generic.Show" = "Laat zien"; + +/* english: "status" */ +"Text.Generic.Status" = "Status"; + +"Text.Generic.Submit" = "Indienen"; + +"Text.Generic.Success" = "Succes"; + +"Text.Generic.Surname" = "Achternaam"; + +"Text.Generic.TermsConditions" = "Algemene Gebruiksvoorwaarden Taxibedrijf"; + +"Text.Generic.TermsOfUse" = "Gebruiksvoorwaarden"; + +/* "Thanks for your interest" */ +"Text.Generic.Thanks" = "Bedankt voor uw interesse"; + +/* Booker cancelled */ +"Text.Generic.TripStatus.BookerCancelled" = "Geannuleerd"; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Message" = "Het duurt langer dan normaal voordat het taxibedrijf een chauffeur heeft toegewezen. Een ogenblik geduld alstublieft, neem contact op met het taxibedrijf of annuleer en reserveer bij een ander taxibedrijf."; + +/* "Driver Allocation Delay Title" */ +"Text.Generic.TripStatus.DriverAllocationDelay.Title" = "Vertraging"; + +/* Driver Cancelled */ +"Text.Generic.TripStatus.DriverCancelled" = "Geannuleerd door chauffeur/dispatch"; + +/* No drivers available */ +"Text.Generic.TripStatus.NoDriversAvailable" = "Geen chauffeurs beschikbaar"; + +/* "Unkown" */ +"Text.Generic.Unknown" = "Onbekend"; + +"Text.Generic.Yes" = "Ja"; + +/* "Allocated" when a driver has been allocated */ +"Text.GenericTripStatus.Allocated" = "Toegewezen"; + +/* "Driver Approaching" */ +"Text.GenericTripStatus.Approaching" = "De chauffeur is in de buurt"; + +/* Driver Arrived */ +"Text.GenericTripStatus.Arrived" = "De chauffeur is aangekomen"; + +/* "Cancelled" */ +"Text.GenericTripStatus.Cancelled" = "Geannuleerd"; + +/* Cancelled by Karhoo */ +"Text.GenericTripStatus.CancelledByKarhoo" = "Geannuleerd door Karhoo"; + +/* "Completed" (trip completed) */ +"Text.GenericTripStatus.Completed" = "Voltooid"; + +/* Confirmed */ +"Text.GenericTripStatus.Confirmed" = "Bevestigd"; + +/* "Driver En Route" when a driver is en route */ +"Text.GenericTripStatus.EnRoute" = "De chauffeur is onderweg"; + +/* "Failed" */ +"Text.GenericTripStatus.Failed" = "Mislukt"; + +/* "Incomplete" */ +"Text.GenericTripStatus.Incomplete" = "Status te bevestigen"; + +/* in english: "Requested" */ +"Text.GenericTripStatus.Initialised" = "Aangevraagd"; + +/* "On Board" */ +"Text.GenericTripStatus.PassengerOnBoard" = "In de auto"; + +/* english: requested */ +"Text.GenericTripStatus.Requested" = "Aangevraagd"; + +/* "Pending" */ +"Text.GenericTripStatus.Unknown" = "In behandeling"; + +"Text.Help.ContactUs.Link" = "https://taxibookermobile.zendesk.com/hc/en-us/requests/new"; + +"Text.Help.FAQ.Link" = "https://taxibookermobile.zendesk.com/hc/en-us"; + +/* No availability in requested area, Fuzzy */ +"Text.KarhooError.K3002" = "Er zijn geen vloten beschikbaar in dit gebied."; + +"Text.KarhooError.Q0001" = "De ophaallocatie en eindbestemming kunnen niet hetzelfde zijn."; + +/* "Add new card" in english used in the payments section of the app. Referring to credit / debit card */ +"Text.Payment.AddPaymentMethod" = "Betaling toevoegen"; + +"Text.Payment.PaymentMethod" = "Kaart"; + +/* Prebook */ +"Text.Prebook.PrebookPickupTime" = "Prebook ophaaltijd"; + +"Text.Prebook.SetPrebook" = "Ophaaltijd instellen"; + +/* "Booking will be made in local time %1$@" please include %1$@ at the end of the translation as this is where the timezone abbreviation goes */ +"Text.Prebook.TimezoneMessage" = "De reservering wordt gemaakt in de lokale tijd van ophalen ( %1$@ )"; + +"Text.Quote.FreeCancellationAndKeyword" = "en"; + +"Text.Quote.FreeCancellationASAP" = "Gratis annulering tot %1$@ na reserveren"; + +"Text.Quote.FreeCancellationBeforeDriverEnRoute" = "Gratis annuleren tot de chauffeur onderweg is"; + +/* Cancellation info on quotes */ +"Text.Quote.FreeCancellationPrebook" = "Gratis annuleren tot %1$@ voor ophalen"; + +"Text.QuoteCategory.Electric" = "Elektrisch"; + +"Text.QuoteCategory.Exec" = "Executive"; + +"Text.QuoteCategory.Executive" = "Executive"; + +"Text.QuoteCategory.Moto" = "Moto"; + +"Text.QuoteCategory.Motorcycle" = "Motorfiets"; + +"Text.QuoteCategory.MPV" = "Minibus"; + +"Text.QuoteCategory.Saloon" = "Standaard voertuig"; + +"Text.QuoteCategory.Taxi" = "Taxi"; + +/* Side Menu "About" section title, Fuzzy */ +"Text.SideMenu.About" = "Over"; + +"Text.SideMenu.Feedback" = "Feedback"; + +"Text.SideMenu.Help" = "Help"; + +/* Side Menu */ +"Text.SideMenu.Login" = "Inloggen"; + +/* "Profile" button on the side menu */ +"Text.SideMenu.Profile" = "Profiel"; + +/* Register on the side menu */ +"Text.SideMenu.Register" = "Registreren"; + +"Text.SideMenu.SignIn" = "Inloggen"; + +/* Sign Out on the side menu */ +"Text.SideMenu.SignOut" = "Afmelden"; + +"Text.SideMenu.Signup" = "Registreren"; + +/* In app email to customer support / feedback */ +"Text.SupportMailMessage.Feedback" = "Verwijder alstublieft deze informatie niet, omdat dit ons helpt de app te verbeteren."; + +"Text.SupportMailMessage.FeedbackEmail" = "support@karhoo.com"; + +"Text.SupportMailMessage.FeedbackSubject" = "Feedback"; + +"Text.SupportMailMessage.NoCoverageBody" = "Bedankt voor het aanbevelen van een taxibedrijf bij u in de buurt. Om zo snel mogelijk dekking in uw regio te krijgen, verzoeken wij u ons het gebied en de naam van het taxibedrijf door te geven.\nGebied:\nTaxibedrijf::"; + +/* No coverage email */ +"Text.SupportMailMessage.NoCoverageSubject" = "Aanbeveling taxibedrijf"; + +"Text.SupportMailMessage.ReportIssue" = "Gebruik alstublieft de ruimte hieronder om een specifiek probleem van uw rit te melden."; + +"Text.SupportMailMessage.ReportIssueSubject" = "Probleem melden"; + +"Text.SupportMailMessage.SupplierEmail" = "leveranciers@karhoo.com"; + +"Text.SupportMailMessage.SupportEmail" = "support@karhoo.com"; + +/* Used in the checkout component before booking a ride */ +"Text.TermsConditions.BookingFullString" = "Door een reservering te maken gaat u akkoord met de %1$@ | %2$@ en %3$@ %4$@ | %3$@ %5$@."; + +"Text.TermsConditions.FullString" = "Tegen %1$@ gaat u akkoord met %2$@ 's \n%3$@ | %4$@"; + +"Text.TermsConditions.KarhooPolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.KarhooTermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TermsConditions.PolicyLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/privacy-policy-sdk.en-gb.html"; + +"Text.TermsConditions.TermsLink" = "https://cdn.karhoo.com/s/mobile/sdk/terms/general-terms-of-use-sdk.en-gb.html"; + +"Text.TrackingLink.production" = "https://agent-portal.karhoo.com/follow/"; + +/* Trip Tracking Links */ +"Text.TrackingLink.sandbox" = "https://agent-portal.sandbox.karhoo.com/follow/"; + +"Text.TrackingLink.staging" = "https://agent-portal.stg.karhoo.net/follow/"; + +"Text.Trip.ActivityIndicator.Cancelling" = "Annuleren"; + +/* "Arrival" displayed on arrival box in trip */ +"Text.Trip.Arrival" = "Aankomst"; + +"Text.Trip.CallDriver" = "Neem contact op met de chauffeur"; + +/* Call fleet button in trip screen (English: Call Fleet) */ +"Text.Trip.CallFleet" = "Taxibedrijf bellen"; + +"Text.Trip.CancelBookingConfirmation.Alert.Message" = "Mogelijk worden er door het taxibedrijf annuleringskosten in rekening gebracht."; + +"Text.Trip.CancelBookingConfirmation.Alert.Title" = "Wilt u uw rit annuleren?"; + +/* displayed in the bookings list for an 'as soon as possible booking' prebooks show the date of the prebooks. Asaps show this. English: "ASAP Booking" */ +"Text.Trip.CancelBookingFailed" = "Annulering niet bevestigd, neem alstublieft contact op met het taxibedrijf."; + +"Text.Trip.CancelBookingFailed.AlertCallFleetButton" = "Taxibedrijf bellen"; + +"Text.Trip.CancelBookingFailed.AlertMessage" = "We ondervinden problemen bij het annuleren van uw rit. Neem alstublieft contact op met het taxibedrijf."; + +"Text.Trip.CancelBookingFailed.AlertTitle" = "Moeilijkheden bij annuleren"; + +"Text.Trip.CancelledByDispatch" = "Uw reservering is geannuleerd."; + +"Text.Trip.CancelledByDispatch.AlertMessage" = "Uw reservering is geannuleerd. Neem alstublieft contact met ons op voor meer informatie."; + +"Text.Trip.CancelledByDispatch.AlertTitle" = "Geannuleerd door het taxibedrijf"; + +"Text.Trip.CancelledByUser" = "U heeft de reservering geannuleerd"; + +/* Trip */ +"Text.Trip.CancelRide" = "Rit annuleren"; + +"Text.Trip.Completed" = "U heeft uw bestemming bereikt"; + +"Text.Trip.Confirmed" = "Uw reservering is geaccepteerd.\nEen moment geduld, er wordt een chauffeur toegewezen."; + +"Text.Trip.DriverArrived" = "Uw chauffeur is gearriveerd!"; + +"Text.Trip.DriverEnRoute" = "Uw chauffeur is onderweg"; + +/* alert message when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertMessage" = "Er is een probleem opgetreden bij het maken van deze reservering. Probeer het alstublieft opnieuw of neem contact op met de helpdesk."; + +/* alert title when karhoo cancel the trip-supposedly happens for preauth failure */ +"Text.Trip.KarhooCancelled.AlertTitle" = "Probleem met reserveren"; + +"Text.Trip.MessageDriver" = "Stuur de chauffeur een bericht"; + +/* For when demand is too high and there are no drivers available */ +"Text.Trip.NoDriversAvailable" = "Geen chauffeurs beschikbaar"; + +/* Alert message in popup when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertMessage" = "Sorry, de vraag is groot. %1$@ momenteel geen beschikbare chauffeurs"; + +/* Popup title message when dispatch cancels due to no drivers */ +"Text.Trip.NoDriversAvailable.AlertTitle" = "Reservering is mislukt"; + +"Text.Trip.PassengerOnBoard" = "U bent onderweg. Veilige rit!"; + +/* Trip Statuses */ +"Text.Trip.Requested" = "%1$@ wijst u een chauffeur toe. Dit kan tot 5 minuten duren."; + +/* Used as a button in the trip screen. English: "Ride Options" */ +"Text.Trip.RideOptions" = "Ritopties"; + +/* Please wait whilst you\'re allocated a driver */ +"Text.TripAllocation.AllocatingTripOne" = "Even geduld a.u.b. u krijgt een chauffeur toegewezen"; + +/* This may take a moment or two */ +"Text.TripAllocation.AllocatingTripTwo" = "Dit kan een moment of twee duren"; + +"Text.TripAllocation.CancelInstruction" = "Tik en houd vast om te annuleren"; + +"Text.TripAllocation.Cancelling" = "Annuleren"; + +/* Finding your ride... */ +"Text.TripAllocation.FindingYourRide" = "Uw rit vinden..."; + +/* Trip Rating */ +"Text.TripRating.Confirmation" = "Bedankt voor het doorgeven van uw beoordeling."; + +"Text.TripRating.ExtraFeedback" = "Vertel ons meer"; + +"Text.TripRating.Title" = "Hoe zou u uw reis beoordelen?"; + +/* Used for the "Book Return Ride" button on the trip summary screen */ +"Text.TripSummary.BookReturnRide" = "Retourrit boeken"; + +/* "Date" */ +"Text.TripSummary.Date" = "Datum"; + +/* Fleet */ +"Text.TripSummary.Fleet" = "Vervoersbedrijf"; + +/* "Payment Summary" header used on Trip Summary Screen */ +"Text.TripSummary.PaymentSummary" = "Betalingsoverzicht"; + +/* "Quoted Price": used in trip summary screen when the fare is not available */ +"Text.TripSummary.QuotedPrice" = "Prijsopgave"; + +/* Total Fare */ +"Text.TripSummary.TotalFare" = "Totale kosten"; + +/* "Trip Summary" header used on screen */ +"Text.TripSummary.TripSummary" = "Ritoverzicht"; + +"Text.TripSummary.Vehicle" = "Voertuig"; + +"Text.User.Email" = "E-Mail"; + +"Text.User.EmailSubscription" = "Ik wens geen gratis ritten, promo's of aanbiedingen te ontvangen"; + +/* User (register / login / user attributes) */ +"Text.User.FirstName" = "Voornaam"; + +/* Text used on button to trigger password reset... English: Forgotten Password? */ +"Text.User.ForgottenPassword" = "Wachtwoord vergeten?"; + +"Text.User.LastName" = "Achternaam"; + +"Text.User.MobilePhoneNumber" = "Mobiel telefoonnummer"; + +"Text.User.Password" = "Wachtwoord"; + +"Text.User.PhoneCountryCode" = "Code"; + +/* "We will notify you via email once your request has been processed." */ +"Text.User.SignupPendingMessage" = "We zullen u per e-mail op de hoogte stellen zodra uw verzoek is verwerkt."; + +"Text.VehicleClass.Electric" = "Elektrisch"; + +"Text.VehicleClass.Exec" = "Executive"; + +"Text.VehicleClass.Executive" = "Executive"; + +"Text.VehicleClass.Moto" = "Moto"; + +"Text.VehicleClass.Motorcycle" = "Motorfiets"; + +"Text.VehicleClass.MPV" = "Minibus"; + +"Text.VehicleClass.Saloon" = "Standaard voertuig"; + +"Text.VehicleClass.Taxi" = "Taxi"; + +"Text.VehicleTag.Childseat" = "Kinderzitje"; + +/* Vehicle tags */ +"Text.VehicleTag.Electric" = "Elektrisch"; + +"Text.VehicleTag.Executive" = "Executive"; + +"Text.VehicleTag.Hybrid" = "Hybride"; + +"Text.VehicleTag.Taxi" = "Taxi"; + +"Text.VehicleTag.Wheelchair" = "Rolstoel"; + +"Text.VehicleType.Bus" = "Bus"; + +"Text.VehicleType.Moto" = "Moto"; + +"Text.VehicleType.MPV" = "Minibus"; + +"Text.VehicleType.Standard" = "Standaard"; + +"Vehicle.Tag.Childseat" = "Kinderzitje"; + +/* Vehicle tags */ +"Vehicle.Tag.Electric" = "Elektrisch"; + +"Vehicle.Tag.Executive" = "Executive"; + +"Vehicle.Tag.Hybrid" = "Hybride"; + +"Vehicle.Tag.Taxi" = "Taxi"; + +"Vehicle.Tag.Wheelchair" = "Rolstoel"; + diff --git a/KarhooUISDK/Translations/nl.lproj/Localizable.stringsdict b/KarhooUISDK/Translations/nl.lproj/Localizable.stringsdict new file mode 100644 index 000000000..cd3fe3fb8 --- /dev/null +++ b/KarhooUISDK/Translations/nl.lproj/Localizable.stringsdict @@ -0,0 +1,38 @@ + + + + + Text.Quote.FreeCancellationBeforePickupMinutes + + NSStringLocalizedFormatKey + %#@MINUTE@ + MINUTE + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + 1 minuut + other + %d minuten + + + Text.Quote.FreeCancellationBeforePickupHours + + NSStringLocalizedFormatKey + %#@HOUR@ + HOUR + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + 1 uur + other + %d uur + + + + diff --git a/KarhooUISDK/Utils.swift b/KarhooUISDK/Utils.swift index 36f3f4760..6b4c06d94 100644 --- a/KarhooUISDK/Utils.swift +++ b/KarhooUISDK/Utils.swift @@ -9,6 +9,9 @@ import Foundation import PhoneNumberKit public class Utils { + // The unicode values are possible variations for apostrophe / single quote + private static let acceptedNameChars = ["-", "\u{0027}", "\u{2018}", "\u{2019}", ".", " "] + static func isValidEmail(email: String) -> Bool { let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" let emailPred = NSPredicate(format: "SELF MATCHES %@", emailRegEx) @@ -40,4 +43,37 @@ public class Utils { return ["": ""] } + + static func isValidName(name: String?) -> Bool { + guard let name = name, !name.isEmpty, name.count >= 2 else { + return false + } + + for char in name { + guard char.isLetter || acceptedNameChars.contains(String(char)) + else { + return false + } + } + + return true + } +} + +class ViewControllerUtils { + static var topBaseViewController: BaseViewController? { + var topVC = UIApplication.shared.keyWindow?.rootViewController + while topVC!.presentedViewController != nil { + topVC = topVC!.presentedViewController + } + return topVC as? BaseViewController + } + + static var topViewController: UIViewController? { + var topVC = UIApplication.shared.keyWindow?.rootViewController + while topVC!.presentedViewController != nil { + topVC = topVC!.presentedViewController + } + return topVC + } } diff --git a/KarhooUISDKTests/Mocks/Builders/MockCheckoutScreenBuilder.swift b/KarhooUISDKTests/Mocks/Builders/MockCheckoutScreenBuilder.swift new file mode 100644 index 000000000..094f05b4b --- /dev/null +++ b/KarhooUISDKTests/Mocks/Builders/MockCheckoutScreenBuilder.swift @@ -0,0 +1,32 @@ +// +// MockCheckoutScreenBuilder.swift +// KarhooTests +// +// +// Copyright © 2020 Karhoo. All rights reserved. +// + +import Foundation +import KarhooSDK + +@testable import KarhooUISDK + +final class MockCheckoutScreenBuilder: CheckoutScreenBuilder { + + var quote: Quote? + var callback: ScreenResultCallback? + let screenInstance = Screen() + + func buildCheckoutScreen(quote: Quote, + bookingDetails: BookingDetails, + bookingMetadata: [String: Any]?, + callback: @escaping ScreenResultCallback) -> Screen { + self.quote = quote + self.callback = callback + return screenInstance + } + + func triggerCheckoutScreenResult(_ result: ScreenResult) { + callback?(result) + } +} diff --git a/KarhooUISDKTests/Mocks/Builders/MockFlightDetailsScreenBuilder.swift b/KarhooUISDKTests/Mocks/Builders/MockFlightDetailsScreenBuilder.swift deleted file mode 100644 index 1541c5994..000000000 --- a/KarhooUISDKTests/Mocks/Builders/MockFlightDetailsScreenBuilder.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// MockFlightDetailsScreenFactory.swift -// KarhooTests -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -import Foundation - -@testable import KarhooUISDK - -final class MockFlightDetailsScreenBuilder: FlightDetailsScreenBuilder { - - private(set) var returnViewController: MockViewController? - private var completionSet: ScreenResultCallback? - func buildFlightDetailsScreen(completion: @escaping ScreenResultCallback) -> Screen { - completionSet = completion - - returnViewController = MockViewController() - return returnViewController! - } - - func triggerFlightDetailsScreenResult(_ result: ScreenResult) { - completionSet?(result) - } -} diff --git a/KarhooUISDKTests/Mocks/Builders/MockPaymentScreenBuilder.swift b/KarhooUISDKTests/Mocks/Builders/MockPaymentScreenBuilder.swift index fbe82d7be..57ef8fa5d 100644 --- a/KarhooUISDKTests/Mocks/Builders/MockPaymentScreenBuilder.swift +++ b/KarhooUISDKTests/Mocks/Builders/MockPaymentScreenBuilder.swift @@ -14,11 +14,11 @@ import KarhooSDK final class MockPaymentScreenBuilder: PaymentScreenBuilder { private(set) var paymentsTokenSet: PaymentSDKToken? - private(set) var paymentMethodAddedSet: ScreenResultCallback? + private(set) var paymentMethodAddedSet: ScreenResultCallback? private(set) var flowItemCallbackSet: ScreenResultCallback? func buildAddCardScreen(paymentsToken: PaymentSDKToken, - paymentMethodAdded: ScreenResultCallback?, + paymentMethodAdded: ScreenResultCallback?, flowItemCallback: ScreenResultCallback?) { paymentsTokenSet = paymentsToken paymentMethodAddedSet = paymentMethodAdded diff --git a/KarhooUISDKTests/Mocks/Classes/MockPaymentNonceProvider.swift b/KarhooUISDKTests/Mocks/Classes/MockPaymentNonceProvider.swift index 5712965bd..86daa781b 100644 --- a/KarhooUISDKTests/Mocks/Classes/MockPaymentNonceProvider.swift +++ b/KarhooUISDKTests/Mocks/Classes/MockPaymentNonceProvider.swift @@ -14,16 +14,16 @@ final class MockPaymentNonceProvider: PaymentNonceProvider { private var callback: ((OperationResult) -> Void)? private(set) var userSet: UserInfo? - private(set) var organisationSet: Organisation? + private(set) var organisationSet: String = "" private(set) var quoteSet: Quote? private(set) var getNonceCalled = false func getPaymentNonce(user: UserInfo, - organisation: Organisation, + organisationId: String, quote: Quote, result: @escaping (OperationResult) -> Void) { self.callback = result userSet = user - organisationSet = organisation + organisationSet = organisationId quoteSet = quote getNonceCalled = true } diff --git a/KarhooUISDKTests/Mocks/Common/MockKarhooPaymentView.swift b/KarhooUISDKTests/Mocks/Common/MockKarhooPaymentView.swift index 30dbfd078..4319aaf2e 100644 --- a/KarhooUISDKTests/Mocks/Common/MockKarhooPaymentView.swift +++ b/KarhooUISDKTests/Mocks/Common/MockKarhooPaymentView.swift @@ -9,19 +9,14 @@ import Foundation @testable import KarhooUISDK import KarhooSDK -final class MockKarhooPaymentView: MockBaseView, PaymentView { +final class MockKarhooPaymentView: MockBaseView, AddPaymentView { var baseViewController: BaseViewController? - var actions: PaymentViewActions? + var actions: AddPaymentViewDelegate? var quote: Quote? - private(set) var paymentMethodSet: PaymentMethod? - func set(paymentMethod: PaymentMethod) { - paymentMethodSet = paymentMethod - } - private(set) var nonceSet: Nonce? func set(nonce: Nonce) { nonceSet = nonce @@ -33,7 +28,7 @@ final class MockKarhooPaymentView: MockBaseView, PaymentView { } private(set) var startCardFlowCalled = false - func startRegisterCardFlow() { + func startRegisterCardFlow(showRetryAlert: Bool = true) { startCardFlowCalled = true } } diff --git a/KarhooUISDKTests/Mocks/Screen/BookingScreen/MockBookingView.swift b/KarhooUISDKTests/Mocks/Screen/BookingScreen/MockBookingView.swift index 0cacc8b4e..1dae24a55 100644 --- a/KarhooUISDKTests/Mocks/Screen/BookingScreen/MockBookingView.swift +++ b/KarhooUISDKTests/Mocks/Screen/BookingScreen/MockBookingView.swift @@ -74,6 +74,7 @@ final class MockBookingView: MockBaseViewController, BookingView { private(set) var tripToOpen: TripInfo? private(set) var openRidesListCalled = false private(set) var availabilityValueSet: Bool! + private(set) var openRidesDetailsCalled = false } extension MockBookingView: BookingScreen { @@ -85,6 +86,10 @@ extension MockBookingView: BookingScreen { func openRidesList(presentationStyle: UIModalPresentationStyle?) { openRidesListCalled = true } + + func openRideDetailsFor(_ trip: TripInfo) { + openRidesDetailsCalled = true + } } extension MockBookingView: QuoteListActions { diff --git a/KarhooUISDKTests/Mocks/Screen/FlightDetails/MockFlightDetailsView.swift b/KarhooUISDKTests/Mocks/Screen/FlightDetails/MockFlightDetailsView.swift deleted file mode 100644 index 93ed50715..000000000 --- a/KarhooUISDKTests/Mocks/Screen/FlightDetails/MockFlightDetailsView.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// MockFlightDetailsView.swift -// KarhooUISDKTests -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -@testable import KarhooUISDK - -final class MockFlightDetailsView: MockBaseViewController, FlightDetailsView { - - private(set) var startKeyboardListenerCalled = false - func startKeyboardListener() { - startKeyboardListenerCalled = true - } - - private(set) var setUpUICalled = false - func setUpUI() { - setUpUICalled = true - } - - private(set) var formButtonEnabledSet: Bool? - func set(formButtonEnabled: Bool) { - formButtonEnabledSet = formButtonEnabled - } - - private(set) var unfocusInputCalled = false - func unfocusInputFields() { - unfocusInputCalled = true - } - - private(set) var flightNumberPlaceHolderSet: String? - func updateFlightNumberField(placeHolder: String) { - flightNumberPlaceHolderSet = placeHolder - } -} diff --git a/KarhooUISDKTests/Mocks/TestUtil.swift b/KarhooUISDKTests/Mocks/TestUtil.swift index f591f3e8b..e7a46c7f7 100644 --- a/KarhooUISDKTests/Mocks/TestUtil.swift +++ b/KarhooUISDKTests/Mocks/TestUtil.swift @@ -284,11 +284,10 @@ class TestUtil: PrimitiveUtil { date: Date()) } - class func getRandomBraintreePaymentMethod(nonce: String = getRandomString()) -> PaymentMethod { - return PaymentMethod(nonce: nonce, - nonceType: getRandomString(), - icon: UIView(), - paymentDescription: getRandomString()) + class func getRandomBraintreePaymentMethod(nonce: String = getRandomString()) -> Nonce { + return Nonce(nonce: nonce, + cardType: getRandomString(), + lastFour: "1111") } class func getRandomGuestSettings(organisationId: String = getRandomString()) -> GuestSettings { diff --git a/KarhooUISDKTests/TestCases/Common/BraintreePaymentNonceProviderSpec.swift b/KarhooUISDKTests/TestCases/Common/BraintreePaymentNonceProviderSpec.swift index 221a97ffa..dd1de532a 100644 --- a/KarhooUISDKTests/TestCases/Common/BraintreePaymentNonceProviderSpec.swift +++ b/KarhooUISDKTests/TestCases/Common/BraintreePaymentNonceProviderSpec.swift @@ -22,7 +22,7 @@ final class BraintreePaymentNonceProviderSpec: XCTestCase { private let mockThreeDSecureProvider = MockThreeDSecureProvider() private let mockCardRegistrationFlow = MockCardRegistrationFlow() private let userInAnOrg: UserInfo = TestUtil.getRandomUser(inOrganisation: true) - private let mockOrganisation = Organisation(id: "some", name: "Karhoo", roles: ["bread"]) + private let mockOrganisation = "OrgId" private let mockQuote = TestUtil.getRandomQuote() private var mockBaseView = MockBaseViewController() private var getNonceResult: PaymentNonceProviderResult? @@ -47,7 +47,7 @@ final class BraintreePaymentNonceProviderSpec: XCTestCase { private func loadTestObject() { testObject.getPaymentNonce(user: userInAnOrg, - organisation: mockOrganisation, + organisationId: mockOrganisation, quote: mockQuote, result: getPaymentNonceResult) } @@ -118,7 +118,7 @@ final class BraintreePaymentNonceProviderSpec: XCTestCase { mockBaseView.selectUpdateCardOnAddCardAlert() let paymentAdded = TestUtil.getRandomBraintreePaymentMethod(nonce: "some_nonce") - mockCardRegistrationFlow.triggerAddCardResult(.completed(value: .didAddPaymentMethod(method: paymentAdded))) + mockCardRegistrationFlow.triggerAddCardResult(.completed(value: .didAddPaymentMethod(nonce: paymentAdded))) XCTAssertEqual(mockThreeDSecureProvider.currencyCodeSet, mockQuote.price.currencyCode) XCTAssertEqual(mockThreeDSecureProvider.paymentAmountSet, NSDecimalNumber(value: mockQuote.price.highPrice)) diff --git a/KarhooUISDKTests/TestCases/Common/ViewModel/KarhooPaymentPresenterSpec.swift b/KarhooUISDKTests/TestCases/Common/ViewModel/KarhooPaymentPresenterSpec.swift index dac76c009..b36448468 100644 --- a/KarhooUISDKTests/TestCases/Common/ViewModel/KarhooPaymentPresenterSpec.swift +++ b/KarhooUISDKTests/TestCases/Common/ViewModel/KarhooPaymentPresenterSpec.swift @@ -12,7 +12,7 @@ import KarhooSDK final class KarhooPaymentPresenterSpec: XCTestCase { - private var testObject: KarhooPaymentPresenter! + private var testObject: KarhooAddPaymentPresenter! private var mockAnalyticsService = MockAnalyticsService() private var mockUserService = MockUserService() private var mockView = MockKarhooPaymentView() @@ -28,7 +28,7 @@ final class KarhooPaymentPresenterSpec: XCTestCase { mockUserService.currentUserToReturn = user mockView.quote = TestUtil.getRandomQuote() - testObject = KarhooPaymentPresenter(analyticsService: mockAnalyticsService, + testObject = KarhooAddPaymentPresenter(analyticsService: mockAnalyticsService, userService: mockUserService, cardRegistrationFlow: mockCardRegistrationFlow, view: mockView) @@ -84,9 +84,9 @@ final class KarhooPaymentPresenterSpec: XCTestCase { testObject.updateCardPressed(showRetryAlert: false) let paymentMethodAdded = TestUtil.getRandomBraintreePaymentMethod() mockCardRegistrationFlow.triggerAddCardResult( - .completed(value: .didAddPaymentMethod(method: paymentMethodAdded))) + .completed(value: .didAddPaymentMethod(nonce: paymentMethodAdded))) - XCTAssertEqual(paymentMethodAdded, mockView.paymentMethodSet) + XCTAssertEqual(paymentMethodAdded, mockView.nonceSet) KarhooTestConfiguration.authenticationMethod = .karhooUser KarhooUI.set(configuration: KarhooTestConfiguration()) @@ -101,7 +101,7 @@ final class KarhooPaymentPresenterSpec: XCTestCase { testObject.updateCardPressed(showRetryAlert: false) let paymentMethodAdded = TestUtil.getRandomBraintreePaymentMethod() mockCardRegistrationFlow.triggerAddCardResult( - .completed(value: .didAddPaymentMethod(method: paymentMethodAdded))) + .completed(value: .didAddPaymentMethod(nonce: paymentMethodAdded))) let updatedUser = TestUtil.getRandomUser(nonce: Nonce(nonce: "some_nonce")) mockUserService.currentUserToReturn = updatedUser diff --git a/KarhooUISDKTests/TestCases/Common/ViewModel/QuoteCellViewModelSpec.swift b/KarhooUISDKTests/TestCases/Common/ViewModel/QuoteCellViewModelSpec.swift index 1f1ce6d2d..ee0143bb1 100644 --- a/KarhooUISDKTests/TestCases/Common/ViewModel/QuoteCellViewModelSpec.swift +++ b/KarhooUISDKTests/TestCases/Common/ViewModel/QuoteCellViewModelSpec.swift @@ -37,8 +37,8 @@ class QuoteCellViewModelSpec: XCTestCase { XCTAssertEqual(testObject.fleetName, "TestFleet") XCTAssertEqual(testObject.scheduleCaption, UITexts.Generic.etaLong.uppercased()) XCTAssertEqual(testObject.scheduleMainValue, expectedEta) - XCTAssertEqual("1", testObject.passengerCapacity) - XCTAssertEqual("2", testObject.baggageCapacity) + XCTAssertEqual(1, testObject.passengerCapacity) + XCTAssertEqual(2, testObject.baggageCapacity) XCTAssertNil(testObject.freeCancellationMessage) } diff --git a/KarhooUISDKTests/TestCases/Routing/KarhooCardRegistrationFlowSpec.swift b/KarhooUISDKTests/TestCases/Routing/KarhooCardRegistrationFlowSpec.swift index b79ff0bc1..adca1e2dd 100644 --- a/KarhooUISDKTests/TestCases/Routing/KarhooCardRegistrationFlowSpec.swift +++ b/KarhooUISDKTests/TestCases/Routing/KarhooCardRegistrationFlowSpec.swift @@ -154,7 +154,7 @@ final class BraintreeCardRegistrationFlowSpec: XCTestCase { func testAddCardScreenSuccessResult() { simulateShowingAddCardScreen() - mockPaymentScreensBuilder.paymentMethodAddedSet?(.completed(result: PaymentMethod(nonce: "123"))) + mockPaymentScreensBuilder.paymentMethodAddedSet?(.completed(result: Nonce(nonce: "123"))) XCTAssertTrue(mockBaseViewController.showLoadingOverlaySet!) XCTAssert(mockBaseViewController.dismissCalled) diff --git a/KarhooUISDKTests/TestCases/Screens/BookingScreen/KarhooBookingPresenterSpec.swift b/KarhooUISDKTests/TestCases/Screens/BookingScreen/KarhooBookingPresenterSpec.swift index ee6443155..15fc44c57 100644 --- a/KarhooUISDKTests/TestCases/Screens/BookingScreen/KarhooBookingPresenterSpec.swift +++ b/KarhooUISDKTests/TestCases/Screens/BookingScreen/KarhooBookingPresenterSpec.swift @@ -23,7 +23,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { private var mockPhoneNumberCaller: MockPhoneNumberCaller! private var mockTripScreenBuilder: MockTripScreenBuilder! private var mockRideDetailsScreenBuilder: MockRideDetailsScreenBuilder! - private var mockBookingRequestScreenBuilder: MockBookingRequestScreenBuilder! + private var mockCheckoutScreenBuilder: MockCheckoutScreenBuilder! private var mockPrebookConfirmationScreenBuilder: MockPrebookConfirmationScreenBuilder! private var mockAddressScreenBuilder: MockAddressScreenBuilder! private var mockDatePickerScreenBuilder: MockDatePickerScreenBuilder! @@ -42,7 +42,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { mockPhoneNumberCaller = MockPhoneNumberCaller() mockTripScreenBuilder = MockTripScreenBuilder() mockRideDetailsScreenBuilder = MockRideDetailsScreenBuilder() - mockBookingRequestScreenBuilder = MockBookingRequestScreenBuilder() + mockCheckoutScreenBuilder = MockCheckoutScreenBuilder() mockPrebookConfirmationScreenBuilder = MockPrebookConfirmationScreenBuilder() mockBookingStatus.bookingDetailsToReturn = TestUtil.getRandomBookingDetails() mockAddressScreenBuilder = MockAddressScreenBuilder() @@ -64,7 +64,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { tripScreenBuilder: mockTripScreenBuilder, rideDetailsScreenBuilder: mockRideDetailsScreenBuilder, ridesScreenBuilder: mockRidesScreenBuilder, - bookingRequestScreenBuilder: mockBookingRequestScreenBuilder, + checkoutScreenBuilder: mockCheckoutScreenBuilder, prebookConfirmationScreenBuilder: mockPrebookConfirmationScreenBuilder, addressScreenBuilder: mockAddressScreenBuilder, datePickerScreenBuilder: mockDatePickerScreenBuilder, @@ -277,7 +277,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { testObject.didSelectQuote(quote: quoteBooked) - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult(.completed(result: tripBooked)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult(.completed(result: tripBooked)) mockBookingView.triggerDismissCallback() XCTAssertTrue(mockBookingView.dismissCalled) @@ -295,7 +295,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { testObject.didSelectQuote(quote: TestUtil.getRandomQuote()) let error = TestUtil.getRandomError() - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult(.failed(error: error)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult(.failed(error: error)) mockBookingView.triggerDismissCallback() XCTAssertTrue(mockBookingView.dismissCalled) @@ -313,7 +313,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { testObject.didSelectQuote(quote: quote) - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult( .cancelled(byUser: true)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult( .cancelled(byUser: true)) mockBookingView.triggerDismissCallback() XCTAssertTrue(mockBookingView.dismissCalled) @@ -330,7 +330,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { let trip = TestUtil.getRandomTrip(state: .karhooCancelled) testObject.didSelectQuote(quote: quote) - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult(.completed(result: trip)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult(.completed(result: trip)) mockBookingView.triggerDismissCallback() XCTAssertTrue(mockBookingView.dismissCalled) @@ -351,7 +351,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { testObject.didSelectQuote(quote: quote) - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult(.completed(result: trip)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult(.completed(result: trip)) mockBookingView.triggerDismissCallback() XCTAssertTrue(mockBookingView.dismissCalled) @@ -372,7 +372,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { let quoteBooked = TestUtil.getRandomQuote() testObject.didSelectQuote(quote: quoteBooked) - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult(.completed(result: tripBooked)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult(.completed(result: tripBooked)) mockBookingView.triggerDismissCallback() mockPrebookConfirmationScreenBuilder.triggerScreenResult(closeAction) @@ -391,7 +391,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { let rideDetailsResult = ScreenResult.completed(result: .rideDetails) testObject.didSelectQuote(quote: TestUtil.getRandomQuote()) - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult(.completed(result: tripBooked)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult(.completed(result: tripBooked)) mockBookingView.triggerDismissCallback() mockPrebookConfirmationScreenBuilder.triggerScreenResult(rideDetailsResult) @@ -415,7 +415,7 @@ final class KarhooBookingPresenterSpec: XCTestCase { testObject.didSelectQuote(quote: TestUtil.getRandomQuote()) - mockBookingRequestScreenBuilder.triggerBookingRequestScreenResult(.completed(result: tripBooked)) + mockCheckoutScreenBuilder.triggerCheckoutScreenResult(.completed(result: tripBooked)) mockBookingView.triggerDismissCallback() mockPrebookConfirmationScreenBuilder.triggerScreenResult(rideDetailsResult) diff --git a/KarhooUISDKTests/TestCases/Screens/BookingScreen/Map/DestinationSetStrategySpec.swift b/KarhooUISDKTests/TestCases/Screens/BookingScreen/Map/DestinationSetStrategySpec.swift index 5aea0d763..845015ee2 100644 --- a/KarhooUISDKTests/TestCases/Screens/BookingScreen/Map/DestinationSetStrategySpec.swift +++ b/KarhooUISDKTests/TestCases/Screens/BookingScreen/Map/DestinationSetStrategySpec.swift @@ -107,7 +107,6 @@ class DestinationSetStrategySpec: XCTestCase { var details = TestUtil.getRandomBookingDetails() testObject.changed(bookingDetails: details) - mockMap = MockKarhooMapView() // Start with empty testObject.load(map: mockMap) diff --git a/KarhooUISDKTests/TestCases/Screens/BookingRequestScreen/KarhooBookingRequestPresenterSpec.swift b/KarhooUISDKTests/TestCases/Screens/CheckoutScreen/KarhooCheckoutPresenterSpec.swift similarity index 78% rename from KarhooUISDKTests/TestCases/Screens/BookingRequestScreen/KarhooBookingRequestPresenterSpec.swift rename to KarhooUISDKTests/TestCases/Screens/CheckoutScreen/KarhooCheckoutPresenterSpec.swift index 80d911db6..5ccc87d41 100644 --- a/KarhooUISDKTests/TestCases/Screens/BookingRequestScreen/KarhooBookingRequestPresenterSpec.swift +++ b/KarhooUISDKTests/TestCases/Screens/CheckoutScreen/KarhooCheckoutPresenterSpec.swift @@ -1,5 +1,5 @@ // -// BookingRequestPresenterSpec.swift +// KarhooCheckoutPresenterSpec.swift // Karhoo // // @@ -10,19 +10,17 @@ import XCTest import KarhooSDK @testable import KarhooUISDK -class KarhooBookingRequestPresenterSpec: XCTestCase { +class KarhooCheckoutPresenterSpec: XCTestCase { - private var testObject: KarhooBookingRequestPresenter! - private var mockView: MockBookingRequestView! + private var testObject: KarhooCheckoutPresenter! + private var mockView: MockCheckoutView! private var testQuote: Quote! private var testBookingDetails: BookingDetails! private var testCallbackResult: ScreenResult? private var mockUserService: MockUserService! private var mockTripService: MockTripService! - private var mockFlightDetails: FlightDetails! private var mockAppStateNotifier: MockAppStateNotifier! private var mockAnalytics: MockAnalytics! - private var mockFlightScreenBuilder: MockFlightDetailsScreenBuilder! private var mockPopupDialogScreenBuilder: MockPopupDialogScreenBuilder! private let mockPaymentNonceProvider = MockPaymentNonceProvider() private let mockCardRegistrationFlow = MockCardRegistrationFlow() @@ -31,15 +29,13 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { override func setUp() { super.setUp() - mockView = MockBookingRequestView() + mockView = MockCheckoutView() testQuote = TestUtil.getRandomQuote(highPrice: 10) - mockFlightDetails = FlightDetails(flightNumber: "flight_number", comments: "comments") testBookingDetails = TestUtil.getRandomBookingDetails() mockUserService = MockUserService() mockTripService = MockTripService() mockAppStateNotifier = MockAppStateNotifier() mockAnalytics = MockAnalytics() - mockFlightScreenBuilder = MockFlightDetailsScreenBuilder() mockPopupDialogScreenBuilder = MockPopupDialogScreenBuilder() loadTestObject() @@ -126,7 +122,7 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { XCTAssertFalse(mockPaymentNonceProvider.getNonceCalled) XCTAssertNotNil(mockTripService.tripBookingSet?.meta) XCTAssertTrue(mockAnalytics.bookingRequestedCalled) - let value: String = mockTripService.tripBookingSet?.meta["key"] as! String + let value: String? = mockTripService.tripBookingSet?.meta["key"] as? String XCTAssertEqual(value, "value") } @@ -168,7 +164,7 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { testObject.bookTripPressed() mockPaymentNonceProvider.triggerResult(.completed(value: .nonce(nonce: Nonce(nonce: "some")))) mockTripService.bookCall.triggerSuccess(TestUtil.getRandomTrip()) - XCTAssertFalse(mockView.isBookingRequestViewVisible) + XCTAssertFalse(mockView.isCheckoutViewVisible) } /** @@ -180,7 +176,7 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { func testRequestCarCallbackSuccess() { mockUserService.currentUserToReturn = TestUtil.getRandomUser() testObject.bookTripPressed() - mockPaymentNonceProvider.triggerResult(.completed(value: .nonce(nonce: Nonce(nonce: "some")))) + mockPaymentNonceProvider.triggerResult(OperationResult.completed(value: .nonce(nonce: Nonce(nonce: "some")))) mockTripService.bookCall.triggerSuccess(TestUtil.getRandomTrip()) testObject.screenHasFadedOut() XCTAssert(testCallbackResult?.isComplete() == true) @@ -206,6 +202,30 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { XCTAssertEqual(testCallbackResult?.errorValue()?.code, bookingError.code) } + + /** + * When: Guest user logged in + * Then: view should be set to more details + * And: user details should be null initially + */ + func testAddPassengerDetails() { + let mockGuestSettings = GuestSettings(identifier: "test", referer: "test", organisationId: "test") + loadTestObject(configuration: .guest(settings: mockGuestSettings)) + XCTAssertTrue(mockView.setMoreDetailsCalled) + testObject.addMoreDetails() + XCTAssertNil(mockView.details) + } + + /** + * When: Guest karhoo user logged in + * Then: view should be set to default state + * And: user details should NOT be null initially + */ + func testAddPassengerDetailsFailed() { + loadTestObject() + XCTAssertFalse(mockView.setMoreDetailsCalled) + XCTAssertTrue(mockView.setDefaultStateCalled) + } /** * When: Booking fails due to payment pre-auth error @@ -224,7 +244,7 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { func testUpdateCardSuccessContinuesBooking() { startWithPaymentBookingError() - mockCardRegistrationFlow.triggerAddCardResult(.completed(value: .didAddPaymentMethod(method: PaymentMethod()))) + mockCardRegistrationFlow.triggerAddCardResult(.completed(value: .didAddPaymentMethod(nonce: Nonce()))) XCTAssertNotNil(mockTripService.tripBookingSet) XCTAssertTrue(mockView.setRequestingStateCalled) @@ -303,12 +323,12 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { func testFixedQuoteHidesBaseFare() { testQuote = TestUtil.getRandomQuote(highPrice: 10, quoteType: .fixed) - let fixedFareRequestScreen = KarhooBookingRequestPresenter(quote: testQuote, - bookingDetails: testBookingDetails, - bookingMetadata: mockBookingMetadata, - userService: mockUserService, - tripService: mockTripService, - callback: bookingRequestTrip) + let fixedFareRequestScreen = KarhooCheckoutPresenter(quote: testQuote, + bookingDetails: testBookingDetails, + bookingMetadata: mockBookingMetadata, + tripService: mockTripService, + userService: mockUserService, + callback: bookingRequestTrip) fixedFareRequestScreen.load(view: mockView) @@ -342,7 +362,6 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { * Then: Screen should not be closed */ func testAppEnteringBackgroundWhenAddingFlightDetails() { - testObject.didPressAddFlightDetails() mockAppStateNotifier.signalAppDidEnterBackground() XCTAssertFalse(mockView.fadeOutCalled) } @@ -355,7 +374,7 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { */ func testAppEnteringBackgroundWhenNotRequestingTrip() { mockAppStateNotifier.signalAppDidEnterBackground() - XCTAssertFalse(mockView.isBookingRequestViewVisible) + XCTAssertFalse(mockView.isCheckoutViewVisible) XCTAssertNil(testCallbackResult?.completedValue()) } @@ -380,41 +399,6 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { XCTAssertTrue(mockView.dismissCalled) } - - /** - * When: User added flight details - * Then: view should be set to requesting - * And: View should dismiss - * And: trip booking should be made (with added flight number) - */ - func testFlightDetailsAdded() { - testObject.didPressAddFlightDetails() - - let flightDetailsAdded = FlightDetails(flightNumber: "some", comments: "someComment") - - mockFlightScreenBuilder.triggerFlightDetailsScreenResult(.completed(result: flightDetailsAdded)) - mockPaymentNonceProvider.triggerResult(.completed(value: .nonce(nonce: Nonce(nonce: "some")))) - XCTAssertTrue(mockView.setRequestingStateCalled) - XCTAssertTrue(mockFlightScreenBuilder.returnViewController!.dismissCalled) - XCTAssertTrue(mockTripService.bookCall.executed) - XCTAssertEqual(mockTripService.tripBookingSet?.flightNumber, flightDetailsAdded.flightNumber) - } - - /** - * When: User cancels adding flight details - * Then: view should not be set to requesting - * And: View should dismiss - * And: trip booking should NOT be made - */ - func testNoFlightDetailsAdded() { - testObject.didPressAddFlightDetails() - - mockFlightScreenBuilder.triggerFlightDetailsScreenResult(.cancelled(byUser: true)) - - XCTAssertFalse(mockView.setRequestingStateCalled) - XCTAssertFalse(mockTripService.bookCall.executed) - XCTAssertTrue(mockFlightScreenBuilder.returnViewController!.dismissCalled) - } private func startWithPaymentBookingError() { mockUserService.currentUserToReturn = TestUtil.getRandomUser() @@ -431,18 +415,18 @@ class KarhooBookingRequestPresenterSpec: XCTestCase { testCallbackResult = result } - private func loadTestObject() { - testObject = KarhooBookingRequestPresenter(quote: testQuote, - bookingDetails: testBookingDetails, - bookingMetadata: mockBookingMetadata, - userService: mockUserService, - tripService: mockTripService, - analytics: mockAnalytics, - appStateNotifier: mockAppStateNotifier, - flightDetailsScreenBuilder: mockFlightScreenBuilder, - paymentNonceProvider: mockPaymentNonceProvider, - baseFarePopupDialogBuilder: mockPopupDialogScreenBuilder, - callback: bookingRequestTrip) + private func loadTestObject(configuration: AuthenticationMethod = .karhooUser) { + KarhooTestConfiguration.authenticationMethod = configuration + testObject = KarhooCheckoutPresenter(quote: testQuote, + bookingDetails: testBookingDetails, + bookingMetadata: mockBookingMetadata, + tripService: mockTripService, + userService: mockUserService, + analytics: mockAnalytics, + appStateNotifier: mockAppStateNotifier, + baseFarePopupDialogBuilder: mockPopupDialogScreenBuilder, + paymentNonceProvider: mockPaymentNonceProvider, + callback: bookingRequestTrip) testObject.load(view: mockView) } } diff --git a/KarhooUISDKTests/TestCases/Screens/BookingRequestScreen/MockBookingRequestView.swift b/KarhooUISDKTests/TestCases/Screens/CheckoutScreen/MockCheckoutView.swift similarity index 70% rename from KarhooUISDKTests/TestCases/Screens/BookingRequestScreen/MockBookingRequestView.swift rename to KarhooUISDKTests/TestCases/Screens/CheckoutScreen/MockCheckoutView.swift index b52c79da0..49d881046 100644 --- a/KarhooUISDKTests/TestCases/Screens/BookingRequestScreen/MockBookingRequestView.swift +++ b/KarhooUISDKTests/TestCases/Screens/CheckoutScreen/MockCheckoutView.swift @@ -1,5 +1,5 @@ // -// BookingRequestScreen.swift +// MockCheckoutView.swift // KarhooTests // // @@ -10,13 +10,13 @@ import Foundation import KarhooSDK @testable import KarhooUISDK -final class MockBookingRequestView: MockBaseViewController, BookingRequestView { +final class MockCheckoutView: MockBaseViewController, CheckoutView { - var showBookingRequestView = false - var showBookingRequestViewValue = false - func showBookingRequestView(_ show: Bool) { - showBookingRequestView = true - showBookingRequestViewValue = show + var showCheckoutView = false + var showCheckoutViewValue = false + func showCheckoutView(_ show: Bool) { + showCheckoutView = true + showCheckoutViewValue = show } var fadeOutCalled = false @@ -39,6 +39,21 @@ final class MockBookingRequestView: MockBaseViewController, BookingRequestView { asapQtaString = qta } + var details: PassengerDetails? + func setPassenger(details: PassengerDetails?) { + self.details = details + } + + var setMoreDetailsCalled = false + func setMoreDetailsState() { + setMoreDetailsCalled = true + } + + var resetPaymentNonceCalled = false + func resetPaymentNonce() { + resetPaymentNonceCalled = true + } + var timeStringSet: String? var dateStringSet: String? func setPrebookState(timeString: String?, dateString: String?) { @@ -71,20 +86,19 @@ final class MockBookingRequestView: MockBaseViewController, BookingRequestView { theQuoteSet = quote } - var isBookingRequestViewVisible = false - func BookingRequestView(_ show: Bool) { - - isBookingRequestViewVisible = show + var isCheckoutViewVisible = false + func isCheckoutViewVisible(_ show: Bool) { + isCheckoutViewVisible = show } var retryAddPaymentMethodCalled = false - func retryAddPaymentMethod() { + func retryAddPaymentMethod(showRetryAlert: Bool) { retryAddPaymentMethodCalled = true } var passengerDetailsToReturn: PassengerDetails? func getPassengerDetails() -> PassengerDetails? { - return passengerDetailsToReturn! + return passengerDetailsToReturn } var paymentNonceToReturn: String? diff --git a/KarhooUISDKTests/TestCases/Screens/FlightDetails/FlightDetailsPresenterSpec.swift b/KarhooUISDKTests/TestCases/Screens/FlightDetails/FlightDetailsPresenterSpec.swift deleted file mode 100644 index c51777e64..000000000 --- a/KarhooUISDKTests/TestCases/Screens/FlightDetails/FlightDetailsPresenterSpec.swift +++ /dev/null @@ -1,139 +0,0 @@ -// -// FlightDetailsPresenterSpec.swift -// KarhooTests -// -// -// Copyright © 2020 Karhoo All rights reserved. -// - -import XCTest -@testable import KarhooUISDK - -class FlightDetailsPresenterSpec: XCTestCase { - - private var testObject: KarhooFlightDetailsPresenter! - private var testCallback: ScreenResult? - private var mockFlightDetailsView: MockFlightDetailsView! - - override func setUp() { - mockFlightDetailsView = MockFlightDetailsView() - testObject = KarhooFlightDetailsPresenter(completion: airportScreenCallback) - testObject.load(view: mockFlightDetailsView) - } - - /** - * When: the screen will appear - * Then: Presenter should tell screen to set up UI - */ - func testScreenWillAppear() { - testObject.screenWillAppear() - XCTAssertTrue(mockFlightDetailsView.setUpUICalled) - XCTAssertTrue(mockFlightDetailsView.startKeyboardListenerCalled) - } - - /** - * When: The user presses cancel - * Then: Callback should be cancelled by user - * And: Keyboard should resign - */ - func testCancelPressed() { - testObject.screenWillAppear() - testObject.didPressCancel() - - XCTAssert(testCallback?.isCancelledByUser() == true) - XCTAssertTrue(mockFlightDetailsView.unfocusInputCalled) - } - - /** - * When: The flight number field is focused - * Then: the screen should update the placeholder text with flight number validation message - */ - func testFlightNumberFieldFocused() { - testObject.fieldDidFocus(identifier: AirportFields.flightNumber.rawValue) - XCTAssertEqual(UITexts.Errors.flightNumberValidatorError, mockFlightDetailsView.flightNumberPlaceHolderSet) - } - - /** - * Given: The flight number field is unfocused - * When: no flight number has been set - * Then: the screen should update the placeholder text with default placeholder (Flight Number) - */ - func testFlightNumberFieldUnfocusedWithNoInput() { - testObject.fieldDidUnFocus(identifier: AirportFields.flightNumber.rawValue) - XCTAssertEqual(UITexts.Airport.flightNumber, mockFlightDetailsView.flightNumberPlaceHolderSet) - } - - /** - * Given: The flight number field is unfocused - * When: A flight number has been set and it is valid - * Then: the screen should update the placeholder text with default placeholder (Flight Number) - */ - func testFlightNumberFieldUnfocusedWithValidInput() { - testObject.didChange(text: "AA123", isValid: true, identifier: AirportFields.flightNumber.rawValue) - testObject.fieldDidUnFocus(identifier: AirportFields.flightNumber.rawValue) - XCTAssertEqual(UITexts.Airport.flightNumber, mockFlightDetailsView.flightNumberPlaceHolderSet) - } - - /** - * When: Flight number is empty - * Then: Formbutton should be disabled - */ - func testEmptyFlightNumber() { - testObject.didChange(text: "", isValid: false, identifier: AirportFields.flightNumber.rawValue) - XCTAssert(mockFlightDetailsView.formButtonEnabledSet == false) - } - - /** - * When: A valid flight number is present - * Then: Formbutton should be enabled - */ - func testValidFlightNumberEntered() { - testObject.didChange(text: "LL123", isValid: true, identifier: AirportFields.flightNumber.rawValue) - XCTAssert(mockFlightDetailsView.formButtonEnabledSet == true) - } - - /** - * When: A flight number is invalid - * Then: Formbutton should be disabled - */ - func testInvalidlightNumberLength() { - testObject.didChange(text: "12", isValid: false, identifier: AirportFields.flightNumber.rawValue) - XCTAssert(mockFlightDetailsView.formButtonEnabledSet == false) - } - - /** - * Given: User presses continue - * When: Only a flight number has been entered - * Then: flight number should be passed in compeltion handler - * And: Additional information string should be nil - * And: Keyboard should resign - */ - func testContinueWithFlightNumber() { - testObject.didChange(text: "123", isValid: true, identifier: AirportFields.flightNumber.rawValue) - testObject.didPressContinue() - - XCTAssertNil(testCallback?.completedValue()?.comments) - XCTAssert(testCallback?.completedValue()?.flightNumber == "123") - XCTAssertTrue(mockFlightDetailsView.unfocusInputCalled) - } - - /** - * Given: User presses continue - * When: a flight number AND additional information has been entered - * Then: flight number and additional information should be passed in compeltion handler - * And: the keyboard should resign - */ - func testContinueWithFlightNumberAndNotes() { - testObject.didChange(text: "123", isValid: true, identifier: AirportFields.flightNumber.rawValue) - testObject.didSet(additionalInformation: "1234") - testObject.didPressContinue() - - XCTAssert(testCallback?.completedValue()?.comments == "1234") - XCTAssert(testCallback?.completedValue()?.flightNumber == "123") - XCTAssertTrue(mockFlightDetailsView.unfocusInputCalled) - } - - private func airportScreenCallback(result: ScreenResult?) { - testCallback = result - } -} diff --git a/KarhooUISDKTests/TestCases/Screens/FlightDetails/FlightNumberValidatorSpec.swift b/KarhooUISDKTests/TestCases/Screens/FlightDetails/FlightNumberValidatorSpec.swift deleted file mode 100644 index 4026a5570..000000000 --- a/KarhooUISDKTests/TestCases/Screens/FlightDetails/FlightNumberValidatorSpec.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// FlightNumberValidatorSpec.swift -// KarhooTests -// -// -// Copyright © 2020 Karhoo. All rights reserved. -// - -import Foundation -import XCTest - -@testable import KarhooUISDK - -final class FlightNumberValidatorSpec: XCTestCase { - - private var testObject: FlightNumberValidator! - private var mockValidatorListener: MockValidatorListener! - - override func setUp() { - super.setUp() - mockValidatorListener = MockValidatorListener() - testObject = FlightNumberValidator() - testObject.set(listener: mockValidatorListener) - } - - /** - * When: Validating an empty string - * Then: No validation should take place - */ - func testEmptyStringValidation() { - testObject.validate(text: "") - XCTAssertFalse(mockValidatorListener.validCalled) - } - - /** - * When: Validating an invalid flight number - * Then: Invalid should be called - * And: No reason should be provided - */ - func testInvalidFlightNumber() { - testObject.validate(text: "1") - XCTAssertTrue(mockValidatorListener.invalidCalled) - XCTAssertTrue(mockValidatorListener.invalidReason!.isEmpty) - } - - /** - * When: Validating a valid flight number - * Then: Valid should be called - */ - func testValidFlightNumber() { - testObject.validate(text: "LH4232") - XCTAssertTrue(mockValidatorListener.validCalled) - } -} diff --git a/KarhooUISDKTests/TestCases/Screens/GuestBookingRequestScreen/KarhooGuestBookingRequestPresenterSpec.swift b/KarhooUISDKTests/TestCases/Screens/GuestCheckoutScreen/KarhooGuestCheckoutPresenterSpec.swift similarity index 92% rename from KarhooUISDKTests/TestCases/Screens/GuestBookingRequestScreen/KarhooGuestBookingRequestPresenterSpec.swift rename to KarhooUISDKTests/TestCases/Screens/GuestCheckoutScreen/KarhooGuestCheckoutPresenterSpec.swift index bca485189..ec242b7f1 100644 --- a/KarhooUISDKTests/TestCases/Screens/GuestBookingRequestScreen/KarhooGuestBookingRequestPresenterSpec.swift +++ b/KarhooUISDKTests/TestCases/Screens/GuestCheckoutScreen/KarhooGuestCheckoutPresenterSpec.swift @@ -9,10 +9,10 @@ import XCTest import KarhooSDK @testable import KarhooUISDK -class KarhooGuestBookingRequestPresenterSpec: XCTestCase { +class KarhooGuestCheckoutPresenterSpec: XCTestCase { - private var testObject: FormBookingRequestPresenter! - private var mockView: MockBookingRequestView = MockBookingRequestView() + private var testObject: KarhooCheckoutPresenter! + private var mockView: MockCheckoutView = MockCheckoutView() private var testQuote: Quote = TestUtil.getRandomQuote(highPrice: 10) private var testCallbackResult: ScreenResult? private var mockThreeDSecureProvider = MockThreeDSecureProvider() @@ -23,8 +23,8 @@ class KarhooGuestBookingRequestPresenterSpec: XCTestCase { override func setUp() { super.setUp() - loadTestObject() KarhooTestConfiguration.authenticationMethod = .guest(settings: KarhooTestConfiguration.guestSettings) + loadTestObject() } /** Given: A user has added details and a nonce @@ -137,7 +137,6 @@ class KarhooGuestBookingRequestPresenterSpec: XCTestCase { KarhooTestConfiguration.authenticationMethod = .tokenExchange(settings: KarhooTestConfiguration.tokenExchangeSettings) mockUserService.currentUserToReturn = TestUtil.getRandomUser(nonce: nil, paymentProvider: "adyen") - testObject.bookTripPressed() let tripBooked = TestUtil.getRandomTrip() @@ -233,13 +232,13 @@ class KarhooGuestBookingRequestPresenterSpec: XCTestCase { mockView.commentsToReturn = "comments" mockView.flightNumberToReturn = "flightNumber" mockUserService.currentUserToReturn = TestUtil.getRandomUser(nonce: nil) - testObject = FormBookingRequestPresenter(quote: testQuote, - bookingDetails: mockBookingDetails, - bookingMetadata: mockBookingMetadata, - threeDSecureProvider: mockThreeDSecureProvider, - tripService: mockTripService, - userService: mockUserService, - callback: guestBookingRequestTrip) + testObject = KarhooCheckoutPresenter(quote: testQuote, + bookingDetails: mockBookingDetails, + bookingMetadata: mockBookingMetadata, + threeDSecureProvider: mockThreeDSecureProvider, + tripService: mockTripService, + userService: mockUserService, + callback: guestBookingRequestTrip) testObject.load(view: mockView) } } diff --git a/KarhooUISDKTests/TestCases/Screens/PassengerDetails/MockPassengerDetailsViewController.swift b/KarhooUISDKTests/TestCases/Screens/PassengerDetails/MockPassengerDetailsViewController.swift new file mode 100644 index 000000000..b35c3a0a3 --- /dev/null +++ b/KarhooUISDKTests/TestCases/Screens/PassengerDetails/MockPassengerDetailsViewController.swift @@ -0,0 +1,46 @@ +// +// MockPassengerDetailsViewController.swift +// KarhooUISDKTests +// +// Created by Diana Petrea on 08.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import UIKit +import KarhooSDK +@testable import KarhooUISDK + +final class MockPassengerDetailsViewController: MockBaseViewController, KarhooInputViewDelegate { + lazy var textField: KarhooTextInputView = { + let textField = KarhooTextInputView(contentType: .firstname, + isOptional: false, + accessibilityIdentifier: KHPassengerDetailsViewID.firstNameInputView) + textField.delegate = self + return textField + }() + + init() { + super.init(nibName: nil, bundle: nil) + self.view = UIView() + self.view.addSubview(textField) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(code:) has not been implemented") + } + + var didBecomeInactiveCalled = false + func didBecomeInactive(identifier: String) { + didBecomeInactiveCalled = true + } + + var didBecomeActiveCalled = false + func didBecomeActive(identifier: String) { + didBecomeActiveCalled = true + } + + var didChangeCharacterInSetCalled = false + func didChangeCharacterInSet(identifier: String) { + didChangeCharacterInSetCalled = true + } +} diff --git a/KarhooUISDKTests/TestCases/Screens/PassengerDetails/PassengerDetailsPresenterSpec.swift b/KarhooUISDKTests/TestCases/Screens/PassengerDetails/PassengerDetailsPresenterSpec.swift new file mode 100644 index 000000000..90dc5c33e --- /dev/null +++ b/KarhooUISDKTests/TestCases/Screens/PassengerDetails/PassengerDetailsPresenterSpec.swift @@ -0,0 +1,81 @@ +// +// PassengerDetailsPresenterSpec.swift +// KarhooUISDKTests +// +// Created by Diana Petrea on 08.09.2021. +// Copyright © 2021 Flit Technologies Ltd. All rights reserved. +// + +import XCTest +import KarhooSDK +@testable import KarhooUISDK + +class PassengerDetailsPresenterSpec: XCTestCase { + + private var testObject: PassengerDetailsPresenter! + private var mockView: MockPassengerDetailsViewController! + private var mockDetails: PassengerDetails! + private var callbackResult: ScreenResult! + + override func setUp() { + super.setUp() + + mockDetails = TestUtil.getRandomPassengerDetails() + testObject = PassengerDetailsPresenter(details: mockDetails, callback: passengerDetailsResult) + mockView = MockPassengerDetailsViewController() + } + + private func passengerDetailsResult(result: ScreenResult) { + callbackResult = result + } + + /** + * When: the user finishes inputting and clicks NEXT + * Then: the details passed are returned in the callback + */ + func testDoneClicked() { + testObject.doneClicked(newDetails: mockDetails, country: KarhooCountryParser.defaultCountry) + XCTAssert(callbackResult != nil) + XCTAssert(callbackResult.isComplete()) + XCTAssert(callbackResult.completedValue()?.details == mockDetails) + } + + /** + * When: the user finishes inputting and clicks NEXT + * Then: the details in the callback are nil + */ + func testBackClicked() { + testObject.backClicked() + XCTAssert(callbackResult != nil) + XCTAssert(callbackResult.isCancelledByUser()) + XCTAssert(callbackResult.completedValue() == nil) + } + + /** + * When: the user begins editing the text field + * Then: didBecomeActive() in called + */ + func testDidBecomeActiveCalled() { + mockView.textField.setActive() + XCTAssertTrue(mockView.didBecomeActiveCalled) + } + + /** + * When: the user ends editing the text field + * Then: didBecomeInactive is called + */ + func testDidBecomeInactiveCalled() { + mockView.textField.setInactive() + XCTAssertTrue(mockView.didBecomeInactiveCalled) + } + + /** + * When: we set the text in the text field + * Then: didChangeCharacterInSet is not called + * didChangeCharacterInSet should be called only when the input field is edited manually by the user + */ + func testDidChangeCharacterInSetCalled() { + mockView.textField.set(text: TestUtil.getRandomString()) + XCTAssertFalse(mockView.didChangeCharacterInSetCalled) + } +} diff --git a/Podfile b/Podfile index 732dc3f63..2c6f38426 100644 --- a/Podfile +++ b/Podfile @@ -6,7 +6,7 @@ source 'https://github.com/CocoaPods/Specs.git' use_frameworks! -# suppress error of duplocate uuids on pod install: https://github.com/ivpusic/react-native-image-crop-picker/issues/680 +# suppress error of duplicate uuids on pod install: https://github.com/ivpusic/react-native-image-crop-picker/issues/680 install! 'cocoapods', :deterministic_uuids => false diff --git a/Podfile.lock b/Podfile.lock index 8a4630620..44021b6bf 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -11,42 +11,42 @@ PODS: - Adyen/Card - Adyen/Core - Adyen3DS2 (2.1.0-rc.6) - - Braintree/Card (4.37.1): + - Braintree/Card (4.38.0): - Braintree/Core - - Braintree/Core (4.37.1) - - Braintree/PaymentFlow (4.37.1): + - Braintree/Core (4.38.0) + - Braintree/PaymentFlow (4.38.0): - Braintree/Card - Braintree/Core - Braintree/PayPalOneTouch - - Braintree/PayPal (4.37.1): + - Braintree/PayPal (4.38.0): - Braintree/Core - Braintree/PayPalOneTouch - - Braintree/PayPalDataCollector (4.37.1): + - Braintree/PayPalDataCollector (4.38.0): - Braintree/Core - Braintree/PayPalUtils - - Braintree/PayPalOneTouch (4.37.1): + - Braintree/PayPalOneTouch (4.38.0): - Braintree/Core - Braintree/PayPalDataCollector - Braintree/PayPalUtils - - Braintree/PayPalUtils (4.37.1) - - Braintree/UnionPay (4.37.1): + - Braintree/PayPalUtils (4.38.0) + - Braintree/UnionPay (4.38.0): - Braintree/Card - Braintree/Core - - BraintreeDropIn (8.1.4): - - BraintreeDropIn/DropIn (= 8.1.4) - - BraintreeDropIn/DropIn (8.1.4): + - BraintreeDropIn (8.2.0): + - BraintreeDropIn/DropIn (= 8.2.0) + - BraintreeDropIn/DropIn (8.2.0): - Braintree/Card (~> 4.32) - Braintree/Core (~> 4.32) - Braintree/PaymentFlow (~> 4.32) - Braintree/PayPal (~> 4.32) - Braintree/UnionPay (~> 4.32) - BraintreeDropIn/UIKit - - BraintreeDropIn/UIKit (8.1.4) + - BraintreeDropIn/UIKit (8.2.0) - FloatingPanel (2.0.1) - KarhooSDK (1.5.3): - KeychainSwift (= 12.0.0) - ReachabilitySwift (= 5.0.0) - - KarhooUISDK (1.6.4): + - KarhooUISDK (1.7.0): - Adyen (= 3.7.0) - Braintree/PaymentFlow (~> 4.37) - BraintreeDropIn (~> 8.1) @@ -61,7 +61,7 @@ PODS: - PhoneNumberKit/UIKit (3.3.1): - PhoneNumberKit/PhoneNumberKitCore - ReachabilitySwift (5.0.0) - - SwiftLint (0.43.1) + - SwiftLint (0.45.0) DEPENDENCIES: - Adyen (= 3.7.0) @@ -93,16 +93,16 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Adyen: 31c52afffea7987e1385da7b66508cd55925b4af Adyen3DS2: 9f7bfb0bd76bd11dcf2599fce2c1d9bbcdc0895a - Braintree: 94a20907b70aeffb29c40380eec583d783a347b6 - BraintreeDropIn: 073ef11637285efc5572b412079a34942c849ef9 + Braintree: 78a33deb6f6ec617c2c4891fbe352854358b3a8d + BraintreeDropIn: b57b653d130981aad7ad9bc97a69d3d7ef86f7a1 FloatingPanel: 579a5ac0154f923a9d7302c4f13dbc0268511c92 KarhooSDK: d02c689599befaeeb3ad5fcc9e8fc6cafa1d7370 - KarhooUISDK: 8abc6309ceddd7d1fa85186e48ecfa5b8996282f + KarhooUISDK: 1f6cacb427de47caddbf69f104c5902d14c6de01 KeychainSwift: d5e776578587ee5958ce36601df22f168f65138a PhoneNumberKit: ff153d5e299f6da566cb73c6aa71e354933b2932 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 - SwiftLint: 99f82d07b837b942dd563c668de129a03fc3fb52 + SwiftLint: e5c7f1fba68eccfc51509d5b2ce1699f5502e0c7 -PODFILE CHECKSUM: ebb692689c5ef9b10c62213bbecea9b0e383f3e1 +PODFILE CHECKSUM: 58c4f81ed1d801d739a3d11932945b29ec986b3c -COCOAPODS: 1.10.1 +COCOAPODS: 1.11.2 diff --git a/README.md b/README.md index 613bdb5a3..5888bba39 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ You can use [CocoaPods](http://cocoapods.org/) to install `KarhooUISDK` by addin use_frameworks! pod 'KarhooSDK', '1.5.3' -pod 'KarhooUISDK', :git => 'git@github.com:karhoo/karhoo-ios-ui-sdk.git', :tag => '1.6.4' +pod 'KarhooUISDK', :git => 'git@github.com:karhoo/karhoo-ios-ui-sdk.git', :tag => '1.7.0' ``` then import `KarhooUISDK` wherever you want to access Karhoo services