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.

611 lines
18 KiB

6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. //
  2. // SplashScreenViewController.swift
  3. // GMERemittance
  4. //
  5. // Created by gme_2 on 10/09/2018.
  6. //Copyright © 2018 Gobal Money Express Co. Ltd. All rights reserved.
  7. //
  8. import UIKit
  9. import Localize_Swift
  10. import DTTJailbreakDetection
  11. import ChannelIO
  12. class SplashScreenViewController: UIViewController {
  13. @IBOutlet private weak var buttonLogin: UIButton!
  14. @IBOutlet private weak var buttonSignUp: UIButton!
  15. @IBOutlet private weak var languageBackGroundView: UIView!
  16. @IBOutlet private weak var languageLabel: UILabel!
  17. @IBOutlet private weak var flagImageView: UIImageView!
  18. @IBOutlet private weak var appVersionLabel: UILabel!
  19. @IBOutlet private weak var senderCountryView: UIView!
  20. @IBOutlet private weak var recipientCountryView: UIView!
  21. @IBOutlet private weak var senderBackground: UIView!
  22. @IBOutlet private weak var recipientBackground: UIView!
  23. @IBOutlet private weak var exchangeRootView: UIView!
  24. @IBOutlet private weak var segmentedControl: ScrollableSegmentedControl!
  25. @IBOutlet private weak var senderTextField: GMENumberTextField!
  26. @IBOutlet private weak var recipientTextField: GMENumberTextField!
  27. @IBOutlet private weak var dropDownImageView: UIImageView!
  28. @IBOutlet private weak var countryImageView: UIImageView!
  29. @IBOutlet private weak var currencyTextField: UILabel!
  30. @IBOutlet private weak var senderTitleLabel: UILabel!
  31. @IBOutlet private weak var recipientTitleLabel: UILabel!
  32. @IBOutlet private weak var calculatedInfoView: UIView!
  33. @IBOutlet private weak var serviceChargeTextField: UILabel!
  34. @IBOutlet private weak var serviceChargeView: UIStackView!
  35. @IBOutlet private weak var exchangeRateTextField: UILabel!
  36. @IBOutlet private weak var exchangeRateView: UIStackView!
  37. @IBOutlet private weak var inAppChatButton: UIButton!
  38. @IBOutlet private weak var logoImageView: UIImageView!
  39. // MARK: Properties
  40. var presenter: SplashScreenModuleInterface?
  41. private var timer: Timer?
  42. lazy private var languageIndex = 0
  43. lazy private var languages = Utility.getLanguages()
  44. lazy private var selectedPaymentModeIndex = 0
  45. lazy private var calcBy = ""
  46. private var selectedLanguage: SendMoneyCountryViewModel? {
  47. didSet {
  48. let code = Language.init(rawValue: selectedLanguage?.code ?? "en")?.code ?? "en"
  49. Localize.setCurrentLanguage(code)
  50. GMEDB.shared.app.set(selectedLanguage?.code ?? "en", .firstTimeLanguageIsSet)
  51. setText()
  52. flagImageView.image = CountryInfo().getFlag(for: selectedLanguage?.code ?? "")
  53. showExchangeRateInfomation(isHidden: true)
  54. presenter?.fetchExchangeRate()
  55. }
  56. }
  57. private var exchangeRateModels: [ExchangeRateModel]? {
  58. didSet {
  59. let countryCode = GMEDB.shared.app.string(.firstTimeLanguageIsSet)
  60. if let defaultExchangeRate = exchangeRateModels?.filter({
  61. ($0.countryCode ?? "").lowercased() == countryCode?.lowercased()
  62. }).first {
  63. selectedExchangeRateModel = defaultExchangeRate
  64. } else {
  65. selectedExchangeRateModel = exchangeRateModels?.filter({
  66. ($0.countryCode ?? "").lowercased() == "np"
  67. }).first
  68. }
  69. }
  70. }
  71. private var selectedExchangeRateModel: ExchangeRateModel? {
  72. didSet {
  73. let code = selectedExchangeRateModel?.countryCode?.lowercased() ?? "np"
  74. let codeEnum = CountryEnum(rawValue: code)
  75. countryImageView.image = codeEnum?.flag
  76. currencyTextField.text = selectedExchangeRateModel?.currency
  77. segmentedControl.segmentItems = selectedExchangeRateModel?.availableServices?.compactMap {
  78. $0.subtitle
  79. } ?? [""]
  80. guard let defaultAmount = codeEnum?.getDefaultRecipientAcount(
  81. currency: selectedExchangeRateModel?.currency ?? ""
  82. ) else {
  83. calcBy = "c"
  84. senderTextField.text = codeEnum?.defaultSenderAmount.likeCommaMoney()
  85. recipientTextField.text = ""
  86. calculateExchangeRate()
  87. return
  88. }
  89. calcBy = "p"
  90. senderTextField.text = ""
  91. recipientTextField.text = defaultAmount.likeCommaMoney()
  92. calculateExchangeRate()
  93. }
  94. }
  95. private var exchangeRateDetailModel: ExchangeRateDetailModel? {
  96. didSet {
  97. guard let model = exchangeRateDetailModel else {
  98. showExchangeRateInfomation(isHidden: true)
  99. return
  100. }
  101. showExchangeRateInfomation(isHidden: false)
  102. recipientTextField.text = Utility.getCommaSeperatedStringWithDecimal(
  103. numberString: model.recipientAmount ?? ""
  104. )
  105. senderTextField.text = Utility.getCommaSeperatedStringWithDecimal(
  106. numberString: model.senderAmount ?? ""
  107. )
  108. let transferFee = model.transferFee ?? ""
  109. let currency = model.senderCurrency ?? ""
  110. serviceChargeTextField.text =
  111. "-\(transferFee) \(currency) (" + "transfer_fee_included_text".localized() + ")"
  112. let exchangeRate = model.exchangeRate ?? ""
  113. exchangeRateTextField.text = "\(exchangeRate) " + "(" + "current_exchange_rate_text".localized() + ")"
  114. calculatedInfoView.isHidden = false
  115. }
  116. }
  117. var messageCount: String? {
  118. didSet {
  119. var appearance = BadgeAppearance()
  120. appearance.backgroundColor = .themeWhite
  121. appearance.textColor = .themeRed
  122. inAppChatButton.badge(text: messageCount, appearance: appearance)
  123. }
  124. }
  125. // MARK: VC's Life cycle
  126. override func viewDidLoad() {
  127. super.viewDidLoad()
  128. checkJailBreak()
  129. setup()
  130. }
  131. override func viewWillAppear(_ animated: Bool) {
  132. super.viewWillAppear(animated)
  133. self.navigationItem.title = ""
  134. hideNavBar()
  135. setLanguageBackgroundView()
  136. timer?.fire()
  137. if selectedLanguage == nil {
  138. presenter?.fetchExchangeRate()
  139. }
  140. }
  141. override func viewWillDisappear(_ animated: Bool) {
  142. super.viewWillDisappear(animated)
  143. navigationItem.title = ""
  144. timer?.invalidate()
  145. }
  146. // MARK: IBActions
  147. private func checkJailBreak() {
  148. if DTTJailbreakDetection.isJailbroken() {
  149. alert(type: .error, message: "Your device is jail broken.", title: "Alert!") {
  150. exit(0)
  151. }
  152. }
  153. }
  154. @IBAction func touchInAppChat(_ sender: UIButton) {
  155. self.alertWithOkCancel(
  156. message: "check_start_chat_text".localized(),
  157. title: "check_start_chat_title_text".localized(),
  158. okTitle: "yes_text".localized(),
  159. cancelTitle: "no_text".localized(),
  160. okAction: {
  161. if !ChannelIO.isBooted {
  162. self.setChannelIO(delegate: self)
  163. } else {
  164. ChannelIO.open(animated: true)
  165. }
  166. }
  167. )
  168. }
  169. @IBAction private func login(_ sender: UIButton) {
  170. presenter?.login()
  171. }
  172. @IBAction private func register(_ sender: UIButton) {
  173. presenter?.register()
  174. }
  175. // MARK: Other Functions
  176. private func hideNavBar() {
  177. navigationController?.isNavigationBarHidden = true
  178. navigationController?.navigationBar.barTintColor = .themeRed
  179. navigationController?.navigationBar.isTranslucent = false
  180. navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
  181. setupNavigationShadow(isUse: false)
  182. }
  183. private func setup() {
  184. // all setup should be done here
  185. hideNavBar()
  186. setUpButtons()
  187. appVersionLabel.text = Utility.getAppVersion()
  188. setExchangeRateUI()
  189. setSegmentedControl()
  190. setupTargets()
  191. showExchangeRateInfomation(isHidden: true)
  192. senderCountryView.backgroundColor = .themeBlue
  193. recipientCountryView.backgroundColor = .themeBlue
  194. logoImageView?.image = logoImageView?.image?.withRenderingMode(.alwaysTemplate)
  195. logoImageView.tintColor = .themeWhiteRed
  196. buttonSignUp.titleLabel?.adjustsFontSizeToFitWidth(true, scale: 0.7)
  197. buttonSignUp.titleLabel?.numberOfLines = 2
  198. buttonLogin.titleLabel?.adjustsFontSizeToFitWidth(true, scale: 0.7)
  199. buttonLogin.titleLabel?.numberOfLines = 2
  200. }
  201. private func setExchangeRateUI() {
  202. [senderCountryView, recipientCountryView]
  203. .forEach { $0?.layer.cornerRadius = 5 }
  204. [recipientBackground, senderBackground]
  205. .forEach {
  206. $0?.layer.borderWidth = 1
  207. $0?.layer.borderColor = UIColor.init(hex: "#E0E0E0").cgColor
  208. $0?.layer.cornerRadius = 5
  209. }
  210. let dropDownImage = #imageLiteral(resourceName: "dropdown_white").withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
  211. let image = dropDownImage
  212. dropDownImageView.image = image
  213. dropDownImageView.tintColor = UIColor.white
  214. exchangeRootView.layer.cornerRadius = 5
  215. exchangeRootView.clipsToBounds = true
  216. exchangeRootView.layer.addShadow(offset: CGSize(width: 2, height: 2))
  217. senderTextField.delegate = self
  218. recipientTextField.delegate = self
  219. }
  220. private func setSegmentedControl() {
  221. segmentedControl.segmentDelegate = self
  222. segmentedControl.itemWidth = 150
  223. segmentedControl.segmentFont = .sanfrancisco(.medium, size: 12)
  224. segmentedControl.segmentTintColor = .themeRed
  225. }
  226. private func setLanguageBackgroundView() {
  227. let languageSelectionGuesture = UITapGestureRecognizer(
  228. target: self,
  229. action: #selector(showCountryPickerview)
  230. )
  231. languageBackGroundView.addGestureRecognizer(languageSelectionGuesture)
  232. languageBackGroundView.layer.cornerRadius = 5
  233. languageBackGroundView.clipsToBounds = true
  234. languageBackGroundView.layer.addShadow(offset: CGSize.init(width: 2, height: 2))
  235. NotificationCenter.default.addObserver(
  236. self,
  237. selector: #selector(setText),
  238. name: NSNotification.Name(LCLLanguageChangeNotification),
  239. object: nil
  240. )
  241. configureLanguage()
  242. if let language = GMEDB.shared.app.string(.firstTimeLanguageIsSet) {
  243. selectedLanguage = languages
  244. .filter {
  245. $0.code?.languageCode == language.languageCode
  246. }
  247. .first
  248. flagImageView.image = CountryEnum(rawValue: selectedLanguage?.code ?? "")?.flag
  249. } else {
  250. configureTimer()
  251. }
  252. }
  253. @objc private func setText() {
  254. timer?.invalidate()
  255. buttonLogin.setTitle("login_text".localized(), for: .normal)
  256. buttonSignUp.setTitle("new_user_text".localized(), for: .normal)
  257. languageLabel.text = selectedLanguage?.title
  258. senderTitleLabel.text = "you_send_text".localized()
  259. recipientTitleLabel.text = "receipient_gets_text".localized()
  260. }
  261. private func configureTimer() {
  262. timer = Timer.scheduledTimer (
  263. timeInterval: 2,
  264. target: self,
  265. selector: #selector(updateLanguage),
  266. userInfo: nil,
  267. repeats: true
  268. )
  269. }
  270. private func configureLanguage() {
  271. buttonLogin.setTitle("login_text".localized(), for: .normal)
  272. buttonSignUp.setTitle("new_user_text".localized(), for: .normal)
  273. }
  274. private func setUpButtons() {
  275. buttonSignUp.layer.cornerRadius = 5
  276. buttonLogin.layer.cornerRadius = 5
  277. buttonLogin.layer.borderWidth = 1
  278. buttonLogin.layer.borderColor = UIColor.white.cgColor
  279. buttonSignUp.layer.borderWidth = 1
  280. buttonSignUp.layer.borderColor = UIColor.white.cgColor
  281. // view.backgroundColor = .themeRed
  282. buttonSignUp.backgroundColor = .themeDarkRed
  283. buttonLogin.backgroundColor = .themeBlue
  284. }
  285. @objc private func updateLanguage() {
  286. guard let element = languages.elementAt(index: languageIndex) else { return }
  287. changeLanguageInfo(
  288. text: element.name ?? "",
  289. flag: CountryEnum(rawValue: element.code ?? "")?.flag
  290. )
  291. if (languageIndex + 1) >= languages.count {
  292. languageIndex = 0
  293. } else {
  294. languageIndex += 1
  295. }
  296. }
  297. private func changeLanguageInfo(text: String, flag: UIImage?) {
  298. let animation = CATransition()
  299. animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
  300. animation.type = CATransitionType.push
  301. animation.subtype = CATransitionSubtype.fromTop
  302. animation.duration = 0.8
  303. languageLabel.layer.add(animation, forKey: convertFromCATransitionType(CATransitionType.push))
  304. languageLabel.text = text
  305. flagImageView.layer.add(animation, forKey: convertFromCATransitionType(CATransitionType.push))
  306. flagImageView.image = flag
  307. }
  308. @objc private func showCountryPickerview() {
  309. TablePresenterWireframe().openWith(
  310. tag: 0,
  311. delegate: self,
  312. model: languages,
  313. source: self
  314. )
  315. }
  316. @objc private func showCurrencyCountryPickerview() {
  317. DispatchQueue.main.async {
  318. self.recipientTextField.resignFirstResponder()
  319. self.senderTextField.resignFirstResponder()
  320. }
  321. TablePresenterWireframe().openWith(
  322. tag: 1,
  323. delegate: self,
  324. model: exchangeRateModels,
  325. source: self
  326. )
  327. }
  328. override func didReceiveMemoryWarning() {
  329. super.didReceiveMemoryWarning()
  330. }
  331. }
  332. // MARK: SplashScreenViewInterface
  333. extension SplashScreenViewController: SplashScreenViewInterface {
  334. func setModel(with model: [ExchangeRateModel]?) {
  335. exchangeRateModels = model
  336. }
  337. func setModel(with model: ExchangeRateDetailModel?) {
  338. exchangeRateDetailModel = model
  339. }
  340. func setError(with error: Error) {
  341. if (error as NSError).code == -99 {
  342. alert(
  343. type: .error,
  344. message: error.localizedDescription,
  345. rightButtomTitle: "retry_text".localized(),
  346. okAction: {
  347. self.presenter?.fetchExchangeRate()
  348. }
  349. )
  350. return
  351. }
  352. alert(type: .error, message: error.localizedDescription)
  353. }
  354. func showLoading() {
  355. showProgressHud()
  356. }
  357. func hideLoading() {
  358. hideProgressHud()
  359. }
  360. }
  361. // MARK: - TablePresenterDelegate
  362. extension SplashScreenViewController: TablePresenterDelegate {
  363. func tablePresenterView(_ viewController: TablePresenterViewController) -> TablePresenterConfiguration {
  364. let title: String
  365. let placeHolder: String
  366. switch viewController.view.tag {
  367. case 0:
  368. title = "select_language_text".localized()
  369. placeHolder = "search_language_text".localized()
  370. case 1:
  371. title = "search_currency_text".localized()
  372. placeHolder = "search_currency_text".localized()
  373. default:
  374. title = "select_language_text".localized()
  375. placeHolder = "search_language_text".localized()
  376. }
  377. return TablePresenterConfiguration(
  378. presenterTitle: title,
  379. closeButtonTitle: "cancel_text".localized(),
  380. notFoundTitle: "no_result_found_text".localized(),
  381. searchBarPlaceHolder: placeHolder
  382. )
  383. }
  384. func tablePresenterView(
  385. _ viewController: TablePresenterViewController,
  386. didSelectModel model: TablePresenterProtocol?
  387. ) {
  388. switch viewController.view.tag {
  389. case 0:
  390. selectedLanguage = (model as? SendMoneyCountryViewModel) ?? selectedLanguage
  391. case 1:
  392. showExchangeRateInfomation(isHidden: true)
  393. selectedExchangeRateModel = (model as? ExchangeRateModel) ?? selectedExchangeRateModel
  394. default: break
  395. }
  396. }
  397. }
  398. // Helper function inserted by Swift 4.2 migrator.
  399. private func convertFromCATransitionType(_ input: CATransitionType) -> String {
  400. return input.rawValue
  401. }
  402. // MARK: - Other Methods
  403. extension SplashScreenViewController {
  404. private func setupTargets() {
  405. let tapGuesture = UITapGestureRecognizer(target: self, action: #selector(showCurrencyCountryPickerview))
  406. recipientCountryView.addGestureRecognizer(tapGuesture)
  407. recipientTextField.addTarget(
  408. self,
  409. action: #selector(self.textChanged(sender:)),
  410. for: UIControl.Event.editingChanged
  411. )
  412. senderTextField.addTarget(
  413. self,
  414. action: #selector(self.textChanged(sender:)),
  415. for: UIControl.Event.editingChanged
  416. )
  417. }
  418. @objc private func textChanged(sender: UITextField) {
  419. switch sender {
  420. case senderTextField:
  421. recipientTextField.text = ""
  422. calcBy = "c"
  423. senderTextField.text = Utility.getCommaSeperatedString(numberString: senderTextField.text!)
  424. case recipientTextField:
  425. senderTextField.text = ""
  426. calcBy = "p"
  427. recipientTextField.text = Utility.getCommaSeperatedString(numberString: recipientTextField.text!)
  428. default:
  429. break
  430. }
  431. }
  432. func calculateExchangeRate() {
  433. let model = ExchangeRateRequestModel(
  434. senderAmount: (senderTextField.text ?? "").stringRemovingComma(),
  435. senderCurrency: "KRW",
  436. senderCountryID: "118",
  437. recipientAmount: (recipientTextField.text ?? "").stringRemovingComma(),
  438. recipientCurrency: selectedExchangeRateModel?.currency ?? "",
  439. recipientCountryID: selectedExchangeRateModel?.countryId ?? "",
  440. recipientCountry: selectedExchangeRateModel?.country ?? "",
  441. serviceType: selectedExchangeRateModel?
  442. .availableServices?
  443. .elementAt(index: selectedPaymentModeIndex)?.id ?? "",
  444. calcBy: calcBy
  445. )
  446. presenter?.exchangeCalculate(use: model)
  447. }
  448. private func showExchangeRateInfomation(isHidden flag: Bool) {
  449. calculatedInfoView.isHidden = flag
  450. calculatedInfoView.alpha = flag ? 0.0 : 1.0
  451. if !flag {
  452. self.serviceChargeView.isHidden = false
  453. self.exchangeRateView.isHidden = false
  454. let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeIn) {
  455. self.serviceChargeView.alpha = 1.0
  456. }
  457. animator.addCompletion { _ in
  458. let subAnimator = UIViewPropertyAnimator(duration: 0.5, curve: .easeIn) {
  459. self.exchangeRateView.alpha = 1.0
  460. }
  461. subAnimator.startAnimation()
  462. }
  463. animator.startAnimation()
  464. } else {
  465. serviceChargeView.isHidden = true
  466. serviceChargeView.alpha = 0.0
  467. exchangeRateView.isHidden = true
  468. exchangeRateView.alpha = 0.0
  469. }
  470. }
  471. }
  472. // MARK: - UITextFieldDelegate
  473. extension SplashScreenViewController: UITextFieldDelegate {
  474. func textFieldDidEndEditing(_ textField: UITextField) {
  475. calculateExchangeRate()
  476. }
  477. }
  478. // MARK: - ScrollableSegmentedControlDelegate
  479. extension SplashScreenViewController: ScrollableSegmentedControlDelegate {
  480. func selectItemAt(
  481. index: Int,
  482. onScrollUISegmentController scrollUISegmentController: ScrollableSegmentedControl
  483. ) {
  484. selectedPaymentModeIndex = index
  485. calculateExchangeRate()
  486. }
  487. }
  488. // MARK: - ChannelPluginDelegate
  489. extension SplashScreenViewController: ChannelPluginDelegate {
  490. func onChangeBadge(count: Int) {
  491. messageCount = count != 0 ? "\(count)" : nil
  492. }
  493. func onReceivePush(event: PushEvent) {
  494. //configure your view with push event data
  495. //and display
  496. print("event: \(event)")
  497. }
  498. }