// // SplashScreenViewController.swift // GMERemittance // // Created by gme_2 on 10/09/2018. //Copyright © 2018 Gobal Money Express Co. Ltd. All rights reserved. // import UIKit import Localize_Swift import DTTJailbreakDetection import ChannelIO class SplashScreenViewController: UIViewController { @IBOutlet private weak var buttonLogin: UIButton! @IBOutlet private weak var buttonSignUp: UIButton! @IBOutlet private weak var languageBackGroundView: UIView! @IBOutlet private weak var languageLabel: UILabel! @IBOutlet private weak var flagImageView: UIImageView! @IBOutlet private weak var appVersionLabel: UILabel! @IBOutlet private weak var senderCountryView: UIView! @IBOutlet private weak var recipientCountryView: UIView! @IBOutlet private weak var senderBackground: UIView! @IBOutlet private weak var recipientBackground: UIView! @IBOutlet private weak var exchangeRootView: UIView! @IBOutlet private weak var segmentedControl: ScrollableSegmentedControl! @IBOutlet private weak var senderTextField: GMENumberTextField! @IBOutlet private weak var recipientTextField: GMENumberTextField! @IBOutlet private weak var dropDownImageView: UIImageView! @IBOutlet private weak var countryImageView: UIImageView! @IBOutlet private weak var currencyTextField: UILabel! @IBOutlet private weak var senderTitleLabel: UILabel! @IBOutlet private weak var recipientTitleLabel: UILabel! @IBOutlet private weak var calculatedInfoView: UIView! @IBOutlet private weak var serviceChargeTextField: UILabel! @IBOutlet private weak var serviceChargeView: UIStackView! @IBOutlet private weak var exchangeRateTextField: UILabel! @IBOutlet private weak var exchangeRateView: UIStackView! @IBOutlet private weak var inAppChatButton: UIButton! @IBOutlet private weak var logoImageView: UIImageView! // MARK: Properties var presenter: SplashScreenModuleInterface? private var timer: Timer? lazy private var languageIndex = 0 lazy private var languages = Utility.getLanguages() lazy private var selectedPaymentModeIndex = 0 lazy private var calcBy = "" private var selectedLanguage: SendMoneyCountryViewModel? { didSet { let code = Language.init(rawValue: selectedLanguage?.code ?? "en")?.code ?? "en" Localize.setCurrentLanguage(code) GMEDB.shared.app.set(selectedLanguage?.code ?? "en", .firstTimeLanguageIsSet) setText() flagImageView.image = CountryInfo().getFlag(for: selectedLanguage?.code ?? "") showExchangeRateInfomation(isHidden: true) presenter?.fetchExchangeRate() } } private var exchangeRateModels: [ExchangeRateModel]? { didSet { let countryCode = GMEDB.shared.app.string(.firstTimeLanguageIsSet) if let defaultExchangeRate = exchangeRateModels?.filter({ ($0.countryCode ?? "").lowercased() == countryCode?.lowercased() }).first { selectedExchangeRateModel = defaultExchangeRate } else { selectedExchangeRateModel = exchangeRateModels?.filter({ ($0.countryCode ?? "").lowercased() == "np" }).first } } } private var selectedExchangeRateModel: ExchangeRateModel? { didSet { let code = selectedExchangeRateModel?.countryCode?.lowercased() ?? "np" let codeEnum = CountryEnum(rawValue: code) countryImageView.image = codeEnum?.flag currencyTextField.text = selectedExchangeRateModel?.currency segmentedControl.segmentItems = selectedExchangeRateModel?.availableServices?.compactMap { $0.subtitle } ?? [""] guard let defaultAmount = codeEnum?.getDefaultRecipientAcount( currency: selectedExchangeRateModel?.currency ?? "" ) else { calcBy = "c" senderTextField.text = codeEnum?.defaultSenderAmount.likeCommaMoney() recipientTextField.text = "" calculateExchangeRate() return } calcBy = "p" senderTextField.text = "" recipientTextField.text = defaultAmount.likeCommaMoney() calculateExchangeRate() } } private var exchangeRateDetailModel: ExchangeRateDetailModel? { didSet { guard let model = exchangeRateDetailModel else { showExchangeRateInfomation(isHidden: true) return } showExchangeRateInfomation(isHidden: false) recipientTextField.text = Utility.getCommaSeperatedStringWithDecimal( numberString: model.recipientAmount ?? "" ) senderTextField.text = Utility.getCommaSeperatedStringWithDecimal( numberString: model.senderAmount ?? "" ) let transferFee = model.transferFee ?? "" let currency = model.senderCurrency ?? "" serviceChargeTextField.text = "-\(transferFee) \(currency) (" + "transfer_fee_included_text".localized() + ")" let exchangeRate = model.exchangeRate ?? "" exchangeRateTextField.text = "\(exchangeRate) " + "(" + "current_exchange_rate_text".localized() + ")" calculatedInfoView.isHidden = false } } var messageCount: String? { didSet { var appearance = BadgeAppearance() appearance.backgroundColor = .themeWhite appearance.textColor = .themeRed inAppChatButton.badge(text: messageCount, appearance: appearance) } } // MARK: VC's Life cycle override func viewDidLoad() { super.viewDidLoad() checkJailBreak() setup() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationItem.title = "" hideNavBar() setLanguageBackgroundView() timer?.fire() if selectedLanguage == nil { presenter?.fetchExchangeRate() } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) navigationItem.title = "" timer?.invalidate() } // MARK: IBActions private func checkJailBreak() { if DTTJailbreakDetection.isJailbroken() { alert(type: .error, message: "Your device is jail broken.", title: "Alert!") { exit(0) } } } @IBAction func touchInAppChat(_ sender: UIButton) { self.alertWithOkCancel( message: "check_start_chat_text".localized(), title: "check_start_chat_title_text".localized(), okTitle: "yes_text".localized(), cancelTitle: "no_text".localized(), okAction: { if !ChannelIO.isBooted { self.setChannelIO() } else { ChannelIO.open(animated: true) } } ) } @IBAction private func login(_ sender: UIButton) { presenter?.login() } @IBAction private func register(_ sender: UIButton) { presenter?.register() } // MARK: Other Functions private func hideNavBar() { navigationController?.isNavigationBarHidden = true navigationController?.navigationBar.barTintColor = .themeRed navigationController?.navigationBar.isTranslucent = false navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) navigationController?.navigationBar.shadowImage = UIImage() } private func setup() { // all setup should be done here hideNavBar() setUpButtons() appVersionLabel.text = Utility.getAppVersion() setExchangeRateUI() setSegmentedControl() setupTargets() showExchangeRateInfomation(isHidden: true) senderCountryView.backgroundColor = .themeBlue recipientCountryView.backgroundColor = .themeBlue logoImageView?.image = logoImageView?.image?.withRenderingMode(.alwaysTemplate) logoImageView.tintColor = .themeWhiteRed } private func setExchangeRateUI() { [senderCountryView, recipientCountryView] .forEach { $0?.layer.cornerRadius = 5 } [recipientBackground, senderBackground] .forEach { $0?.layer.borderWidth = 1 $0?.layer.borderColor = UIColor.init(hex: "#E0E0E0").cgColor $0?.layer.cornerRadius = 5 } let dropDownImage = #imageLiteral(resourceName: "dropdown_white").withRenderingMode(UIImage.RenderingMode.alwaysTemplate) let image = dropDownImage dropDownImageView.image = image dropDownImageView.tintColor = UIColor.white exchangeRootView.layer.cornerRadius = 5 exchangeRootView.clipsToBounds = true exchangeRootView.layer.addShadow(offset: CGSize(width: 2, height: 2)) senderTextField.delegate = self recipientTextField.delegate = self } private func setSegmentedControl() { segmentedControl.segmentDelegate = self segmentedControl.itemWidth = 150 segmentedControl.segmentFont = .sanfrancisco(.medium, size: 12) segmentedControl.segmentTintColor = .themeRed } private func setLanguageBackgroundView() { let languageSelectionGuesture = UITapGestureRecognizer( target: self, action: #selector(showCountryPickerview) ) languageBackGroundView.addGestureRecognizer(languageSelectionGuesture) languageBackGroundView.layer.cornerRadius = 5 languageBackGroundView.clipsToBounds = true languageBackGroundView.layer.addShadow(offset: CGSize.init(width: 2, height: 2)) NotificationCenter.default.addObserver( self, selector: #selector(setText), name: NSNotification.Name(LCLLanguageChangeNotification), object: nil ) configureLanguage() if let language = GMEDB.shared.app.string(.firstTimeLanguageIsSet) { selectedLanguage = languages .filter { $0.code?.languageCode == language.languageCode } .first flagImageView.image = CountryEnum(rawValue: selectedLanguage?.code ?? "")?.flag } else { configureTimer() } } @objc private func setText() { timer?.invalidate() buttonLogin.setTitle("login_text".localized(), for: .normal) buttonSignUp.setTitle("new_user_text".localized(), for: .normal) languageLabel.text = selectedLanguage?.title senderTitleLabel.text = "you_send_text".localized() recipientTitleLabel.text = "receipient_gets_text".localized() } private func configureTimer() { timer = Timer.scheduledTimer ( timeInterval: 2, target: self, selector: #selector(updateLanguage), userInfo: nil, repeats: true ) } private func configureLanguage() { buttonLogin.setTitle("login_text".localized(), for: .normal) buttonSignUp.setTitle("new_user_text".localized(), for: .normal) } private func setUpButtons() { buttonSignUp.layer.cornerRadius = 5 buttonLogin.layer.cornerRadius = 5 buttonLogin.layer.borderWidth = 1 buttonLogin.layer.borderColor = UIColor.white.cgColor buttonSignUp.layer.borderWidth = 1 buttonSignUp.layer.borderColor = UIColor.white.cgColor // view.backgroundColor = .themeRed buttonSignUp.backgroundColor = .themeDarkRed buttonLogin.backgroundColor = .themeBlue } @objc private func updateLanguage() { guard let element = languages.elementAt(index: languageIndex) else { return } changeLanguageInfo( text: element.name ?? "", flag: CountryEnum(rawValue: element.code ?? "")?.flag ) if (languageIndex + 1) >= languages.count { languageIndex = 0 } else { languageIndex += 1 } } private func changeLanguageInfo(text: String, flag: UIImage?) { let animation = CATransition() animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) animation.type = CATransitionType.push animation.subtype = CATransitionSubtype.fromTop animation.duration = 0.8 languageLabel.layer.add(animation, forKey: convertFromCATransitionType(CATransitionType.push)) languageLabel.text = text flagImageView.layer.add(animation, forKey: convertFromCATransitionType(CATransitionType.push)) flagImageView.image = flag } @objc private func showCountryPickerview() { TablePresenterWireframe().openWith( tag: 0, delegate: self, model: languages, source: self ) } @objc private func showCurrencyCountryPickerview() { DispatchQueue.main.async { self.recipientTextField.resignFirstResponder() self.senderTextField.resignFirstResponder() } TablePresenterWireframe().openWith( tag: 1, delegate: self, model: exchangeRateModels, source: self ) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } // MARK: SplashScreenViewInterface extension SplashScreenViewController: SplashScreenViewInterface { func setModel(with model: [ExchangeRateModel]?) { exchangeRateModels = model } func setModel(with model: ExchangeRateDetailModel?) { exchangeRateDetailModel = model } func setError(with error: Error) { if (error as NSError).code == -99 { alert( type: .error, message: error.localizedDescription, rightButtomTitle: "retry_text".localized(), okAction: { self.presenter?.fetchExchangeRate() } ) return } alert(type: .error, message: error.localizedDescription) } func showLoading() { showProgressHud() } func hideLoading() { hideProgressHud() } } // MARK: - TablePresenterDelegate extension SplashScreenViewController: TablePresenterDelegate { func tablePresenterView(_ viewController: TablePresenterViewController) -> TablePresenterConfiguration { let title: String let placeHolder: String let isUse: Bool switch viewController.view.tag { case 0: title = "select_language_text".localized() placeHolder = "search_language_text".localized() isUse = false case 1: title = "search_currency_text".localized() placeHolder = "search_currency_text".localized() isUse = true default: title = "select_language_text".localized() placeHolder = "search_language_text".localized() isUse = false } return TablePresenterConfiguration( presenterTitle: title, closeButtonTitle: "cancel_text".localized(), notFoundTitle: "no_result_found_text".localized(), searchBarPlaceHolder: placeHolder, isUseSearchBar: isUse ) } func tablePresenterView( _ viewController: TablePresenterViewController, didSelectModel model: TablePresenterProtocol? ) { switch viewController.view.tag { case 0: selectedLanguage = (model as? SendMoneyCountryViewModel) ?? selectedLanguage case 1: showExchangeRateInfomation(isHidden: true) selectedExchangeRateModel = (model as? ExchangeRateModel) ?? selectedExchangeRateModel default: break } } } // Helper function inserted by Swift 4.2 migrator. private func convertFromCATransitionType(_ input: CATransitionType) -> String { return input.rawValue } // MARK: - Other Methods extension SplashScreenViewController { private func setupTargets() { let tapGuesture = UITapGestureRecognizer(target: self, action: #selector(showCurrencyCountryPickerview)) recipientCountryView.addGestureRecognizer(tapGuesture) recipientTextField.addTarget( self, action: #selector(self.textChanged(sender:)), for: UIControl.Event.editingChanged ) senderTextField.addTarget( self, action: #selector(self.textChanged(sender:)), for: UIControl.Event.editingChanged ) } @objc private func textChanged(sender: UITextField) { switch sender { case senderTextField: recipientTextField.text = "" calcBy = "c" senderTextField.text = Utility.getCommaSeperatedString(numberString: senderTextField.text!) case recipientTextField: senderTextField.text = "" calcBy = "p" recipientTextField.text = Utility.getCommaSeperatedString(numberString: recipientTextField.text!) default: break } } func calculateExchangeRate() { let model = ExchangeRateRequestModel( senderAmount: (senderTextField.text ?? "").stringRemovingComma(), senderCurrency: "KRW", senderCountryID: "118", recipientAmount: (recipientTextField.text ?? "").stringRemovingComma(), recipientCurrency: selectedExchangeRateModel?.currency ?? "", recipientCountryID: selectedExchangeRateModel?.countryId ?? "", recipientCountry: selectedExchangeRateModel?.country ?? "", serviceType: selectedExchangeRateModel? .availableServices? .elementAt(index: selectedPaymentModeIndex)?.id ?? "", calcBy: calcBy ) presenter?.exchangeCalculate(use: model) } private func showExchangeRateInfomation(isHidden flag: Bool) { calculatedInfoView.isHidden = flag calculatedInfoView.alpha = flag ? 0.0 : 1.0 if !flag { self.serviceChargeView.isHidden = false self.exchangeRateView.isHidden = false let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeIn) { self.serviceChargeView.alpha = 1.0 } animator.addCompletion { _ in let subAnimator = UIViewPropertyAnimator(duration: 0.5, curve: .easeIn) { self.exchangeRateView.alpha = 1.0 } subAnimator.startAnimation() } animator.startAnimation() } else { serviceChargeView.isHidden = true serviceChargeView.alpha = 0.0 exchangeRateView.isHidden = true exchangeRateView.alpha = 0.0 } } } // MARK: - UITextFieldDelegate extension SplashScreenViewController: UITextFieldDelegate { func textFieldDidEndEditing(_ textField: UITextField) { calculateExchangeRate() } } // MARK: - ScrollableSegmentedControlDelegate extension SplashScreenViewController: ScrollableSegmentedControlDelegate { func selectItemAt( index: Int, onScrollUISegmentController scrollUISegmentController: ScrollableSegmentedControl ) { selectedPaymentModeIndex = index calculateExchangeRate() } } extension SplashScreenViewController { private func setChannelIO() { let settings = ChannelPluginSettings() settings.pluginKey = "24dc2dfd-3ed1-4953-b395-a2255ed41dae" // settings.userId = GMEDB.shared.user.string(.email) ChannelIO.delegate = self ChannelIO.boot(with:settings) {(completion, _) in var message = "channelIO_error_message_text".localized() switch completion { case .success: ChannelIO.open(animated: true) return case .notInitialized: message += "(1)" case .networkTimeout: message += "(2)" case .notAvailableVersion: message += "(3)" case .serviceUnderConstruction: message += "(4)" case .requirePayment: message += "(5)" case .accessDenied: message += "(6)" case .unknown: message += "(7)" @unknown default: message += "(8)" } self.alert(type: .error, message: message) } } } // MARK: - ChannelPluginDelegate extension SplashScreenViewController: ChannelPluginDelegate { func onChangeBadge(count: Int) { messageCount = count != 0 ? "\(count)" : nil } func onReceivePush(event: PushEvent) { //configure your view with push event data //and display print("event: \(event)") } }