You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

601 lines
18 KiB

//
// 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
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 csManager: CSManagement?
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: { [weak self] in
if !(self?.csManager?.chatIsBooted ?? false) {
self?.csManager?.setChannelIO()
} else {
self?.csManager?.openChat(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)
setupNavigationShadow(isUse: false)
}
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
buttonSignUp.titleLabel?.adjustsFontSizeToFitWidth(true, scale: 0.7)
buttonSignUp.titleLabel?.numberOfLines = 2
buttonLogin.titleLabel?.adjustsFontSizeToFitWidth(true, scale: 0.7)
buttonLogin.titleLabel?.numberOfLines = 2
csManager = CSManagement(self, badgeTarget: inAppChatButton)
}
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
switch viewController.view.tag {
case 0:
title = "select_language_text".localized()
placeHolder = "search_language_text".localized()
case 1:
title = "search_currency_text".localized()
placeHolder = "search_currency_text".localized()
default:
title = "select_language_text".localized()
placeHolder = "search_language_text".localized()
}
return TablePresenterConfiguration(
presenterTitle: title,
closeButtonTitle: "cancel_text".localized(),
notFoundTitle: "no_result_found_text".localized(),
searchBarPlaceHolder: placeHolder
)
}
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()
}
}