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.
 
 
 
 

741 lines
22 KiB

//
// HomeViewController.swift
// GMERemittance
//
// Created by gme_2 on 21/09/2018.
//Copyright © 2018 Gobal Money Express Co. Ltd. All rights reserved.
//
import UIKit
import Crashlytics
import Localize_Swift
import ChannelIO
import LGSideMenuController
#if DEBUG
import FLEX
#endif
class HomeViewController: UIViewController {
enum Sections: Int {
case balance = 0
case collection
}
struct Constants {
static let verificationNoticeHeight: CGFloat = 100
}
struct StringConstants {
let homeText = "home_text".localized()
let registerProcessText = "complete_your_registration_text".localized()
let registrationApprovalText = "verification_in_aproval_process_text".localized()
let pennyTestPrimaryBankText = "complete_penny_test".localized()
let verifyTitleText = "kyc_fill_text".localized()
let continueRegistrationTitleText = "penny_test_pending_text".localized()
let verificationInProcessTitleText = "kyc_verify_pending_text".localized()
let soonToUseGmeServicesTitle = "verification_in_aproval_process_text".localized()
}
// MARK: IBOutlets
@IBOutlet private weak var tableView: UITableView!
@IBOutlet private weak var messageViewHeightConstraint: NSLayoutConstraint!
@IBOutlet private weak var messageView: UIView!
@IBOutlet private weak var messageLabel: UILabel!
@IBOutlet private weak var messageTitleLabel: UILabel!
@IBOutlet private weak var messageLeftImageview: UIImageView!
@IBOutlet private var tapMessageViewGestrueRecognizer: UITapGestureRecognizer!
@IBOutlet private weak var seperatorView: UIView!
@IBOutlet private weak var supportBarButton: UIBarButtonItem!
// MARK: Properties
lazy var blobView = UIView()
private var isUserVerified: Bool {
return Utility.isVerifiedUser()
}
private var didSubmitKycAndNotVerified: Bool {
return Utility.didSubmitKyc() && !Utility.isVerifiedUser()
}
private var didSubmitKycAndVerified: Bool {
return Utility.didSubmitKyc() && Utility.isVerifiedUser()
}
private var didNotSubmitKycAndNotVerified: Bool {
return !Utility.didSubmitKyc() && !Utility.isVerifiedUser()
}
private var shouldShowPennyTestError: Bool {
return Utility.shouldShowPennyTestError()
}
private var shouldShowUnverifiedNotice: Bool {
return !self.isUserVerified
}
var refreshControl: UIRefreshControl?
var presenter: HomeModuleInterface?
var user: User? {
didSet {
// update
self.save(user: user)
setMessageView()
self.tableView.reloadData()
updateBalance()
self.update()
checkKFTCToken()
}
}
var sections: [Sections] = [.balance, .collection]
var menuHeight: CGFloat? {
didSet {
self.tableView.reloadData()
}
}
// MARK: VC's Life cycle
var hotLines: [HotLine]? {
didSet {
guard let nativeCountry = GMEDB.shared.user.string(.countryCode)?.lowercased() else {
return
}
userHotLine = hotLines?.filter { $0.countryCode == nativeCountry }.first
}
}
var userHotLine: HotLine?
var isShowTokenRenewAlert = false
override func viewDidLoad() {
super.viewDidLoad()
self.setup()
let supportImage = UIImage(named: "ic_support")?.withRenderingMode(.alwaysOriginal)
supportBarButton.image = supportImage
let sideMenuVC = (MainWireframe.shared?.window?.rootViewController as? LGSideMenuController)?
.leftViewController as? SideMenuViewController
sideMenuVC?.sideMenuDelegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tableView.reloadData()
NotificationCenter.default.addObserver(
self,
selector: #selector(updateTabBarTitle),
name: NSNotification.Name(LCLLanguageChangeNotification),
object: nil
)
setNavBar(isUseMenu: false)
presenter?.viewIsReady()
presenter?.fetchHotLines()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationItem.title = ""
blobView.removeFromSuperview()
MainWireframe.shared?.isUseSwipeGesture = false
navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.interactivePopGestureRecognizer?.isEnabled = false
// if kyc is false then,
if self.didNotSubmitKycAndNotVerified {
self.presenter?.showKyc()
} else if shouldShowPennyTestError { // if pennyTestStatus is not completed(2) then,
if Utility.didPennyTestRequested() { // if pennyTestStatus is request(1) then
presenter?.showPennyTestSubmit()
} else { // if pennyTestStatus is no request(0) then
presenter?.showPennyTest()
}
} else {
if KeyChain.shared.get(key: .biometricAuth) == nil {
BiometricNotificationWireframe().openMainView(source: self)
}
}
}
// MARK: IBActions
// MARK: Other Functions
private func setup() {
// all setup should be done here
self.messageViewHeightConstraint.constant = 0
self.messageView.alpha = 0
setupDelegates()
setupNotifications()
addRefreshControlTableView()
addRightCSButton(delegate: self)
}
private func update() {
let platform = self.user?.platforms ?? []
guard let ios = platform.filter({ $0.os ?? "" == "IOS"}).first else {return}
let critical = ios.critical ?? "N"
GMEDB.shared.app.set(critical, .criticalUpdate)
if critical == "Y" {
guard
let serverVersion = ios.version,
let appVersion = Utility.getAppVersion(),
let appVersionInfo = Double(
appVersion
.components(separatedBy: ".")
.compactMap { Int($0) }
.reduce("0.") {"\($0)\($1)"}
),
let serverVersionInfo = Double(serverVersion
.components(separatedBy: ".")
.compactMap { Int($0) }
.reduce("0.") {"\($0)\($1)"}
)
else {
return
}
if appVersionInfo < serverVersionInfo {
self.presenter?.showAppUpdate()
}
}
}
private func updateBalance() {
let balance = user?.availableBalance ?? ""
GMEDB.shared.user.set(balance, .availableBalance)
let userInfo = [SideMenuNavigationNotifications.availableBalance : balance]
NotificationCenter.default.post(
name: self.getAvailableBalanceNotificationName(),
object: nil,
userInfo: userInfo
)
self.tableView.reloadData()
}
private func setupDelegates() {
tableView.delegate = self
tableView.dataSource = self
}
private func addRefreshControlTableView() {
let colorOption = [NSAttributedString.Key.foregroundColor : UIColor.themeWhite]
let title = NSAttributedString(string: "pull to refresh", attributes: colorOption)
let refreshControl = UIRefreshControl()
refreshControl.attributedTitle = title
refreshControl.backgroundColor = .themeBlue
refreshControl.tintColor = .themeWhite
refreshControl.addTarget(self, action: #selector(self.refresh), for: .valueChanged)
self.refreshControl = refreshControl
if #available(iOS 10.0, *) {
tableView.refreshControl = self.refreshControl
} else {
if let control = self.refreshControl {
tableView.addSubview(control)
}
}
}
@objc private func refresh() {
presenter?.refreshData()
}
func startCall(contactNumber: String) {
if let url = URL(string: "tel://\(contactNumber.removeWhitespacesInBetween())"),
UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
private func setupNotifications() {
let center = NotificationCenter.default
center.addObserver(
self,
selector: #selector(self.setupHeight(sender:)),
name: self.getCollectionHeightNotificationName(),
object: nil
)
center.addObserver(
self,
selector: #selector(self.showUnVerifiedMessage),
name: self.getMainControllerNotificationName(),
object: nil
)
}
@objc private func setupHeight(sender: Notification) {
if let height = sender.userInfo?[MenuNotificationName.collectionHeight] as? CGFloat {
self.menuHeight = height
}
}
}
// MARK: - Manage Message View
extension HomeViewController {
private func setMessageView() {
switch GMEDB.shared.user.string(.redirectTo) ?? "" {
case "autodebit":
setNavBar(isUseMenu: false)
showAutoDebitMessage()
default:
setNavBar(isUseMenu: true)
didSubmitKycAndNotVerified ? showWaitVerifyMessage() : removeAllMessage()
}
}
private func showAutoDebitMessage() {
showMessageView(isHidden: false)
messageTitleLabel.text = "add_auto_debit_account_text".localized()
messageLabel.text = "autodebit_account_required_message".localized()
messageLeftImageview.image = #imageLiteral(resourceName: "ic_home_verified")
let offset = messageView.frame(forAlignmentRect: self.view.frame).origin.y
blobView = UIView(
frame: CGRect(x: 0, y: offset + 100, width: view.frame.width, height: view.frame.height)
)
blobView.backgroundColor = .init(white: 0, alpha: 0.5)
tabBarController?.view.addSubview(blobView)
tapMessageViewGestrueRecognizer.addTarget(self, action: #selector(tapMessageView(_:)))
}
@objc private func tapMessageView(_ sender: UITapGestureRecognizer) {
let navigationVC = UINavigationController(rootViewController: AutoDebitWireframe().getMainView())
tabBarController?.present(navigationVC, animated: true, completion: nil)
}
private func showWaitVerifyMessage() {
blobView.removeFromSuperview()
tapMessageViewGestrueRecognizer.removeTarget(self, action: #selector(tapMessageView(_:)))
showMessageView(isHidden: false)
messageTitleLabel.text = StringConstants().verificationInProcessTitleText
messageLabel.text = StringConstants().soonToUseGmeServicesTitle
messageLeftImageview.image = #imageLiteral(resourceName: "ic_home_verified")
}
private func removeAllMessage() {
blobView.removeFromSuperview()
showMessageView(isHidden: true)
}
private func showMessageView(isHidden: Bool) {
UIView.animate(
withDuration: 0.33,
animations: {
self.messageViewHeightConstraint.constant = isHidden ? 0 : 100
self.messageView.alpha = isHidden ? 0 : 1
}
)
}
func setNavBar(isUseMenu: Bool) {
let selector = #selector(self.showSideMenu)
isUseMenu ? setupPicturedNavBar(sideMenuAction: selector) : setupPicturedNavBar(sideMenuAction: nil)
MainWireframe.shared?.isUseSwipeGesture = isUseMenu
}
}
// MARK: - Other functions
extension HomeViewController {
@objc func showSideMenu() {
sideMenuController?.showLeftViewAnimated()
}
private func showSendMoney() {
let kycSubmited = user?.kyc ?? false
let pennyTestComplete = Utility.pennyTestVerified()
if kycSubmited == true && pennyTestComplete == false {
self.show(error: StringConstants().pennyTestPrimaryBankText)
return
}
if isUserVerified {
let recipientsVC = RecipientsWireframe().getMainView()
self.navigationController?.pushViewController(recipientsVC, animated: true)
} else {
self.showUnVerifiedMessage()
}
}
private func showDomesticRemit() {
let kycSubmited = user?.kyc ?? false
let pennyTestComplete = Utility.pennyTestVerified()
if kycSubmited == true && pennyTestComplete == false {
self.show(error: StringConstants().pennyTestPrimaryBankText)
return
}
if isUserVerified {
DomesticRemitWireframe().open(on: self)
} else {
self.showUnVerifiedMessage()
}
}
private func showResendMoney() {
}
private func showMobileRecharge() {
let kycSubmited = user?.kyc ?? false
let pennyTestComplete = Utility.pennyTestVerified()
if kycSubmited == true && pennyTestComplete == false {
self.show(error: StringConstants().pennyTestPrimaryBankText)
return
}
self.alert(type: .error, message: "This feature is coming soon")
}
private func showTodaysRate() {
presenter?.openTodaysRate()
}
private func showTrackYourTransfer() {
let kycSubmited = user?.kyc ?? false
let pennyTestComplete = Utility.pennyTestVerified()
if kycSubmited == true && pennyTestComplete == false {
self.show(error: StringConstants().pennyTestPrimaryBankText)
return
}
isUserVerified ? (presenter?.openTrackYourTransfer()) : (self.showUnVerifiedMessage())
}
private func showTransactionStatement() {
let kycSubmited = user?.kyc ?? false
let pennyTestComplete = Utility.pennyTestVerified()
if kycSubmited == true && pennyTestComplete == false {
self.show(error: StringConstants().pennyTestPrimaryBankText)
return
}
isUserVerified ? (presenter?.openTransactionHistory()) : (self.showUnVerifiedMessage())
}
@objc private func showUnVerifiedMessage() {
if didNotSubmitKycAndNotVerified {
self.alert(type: .error, message: StringConstants().registerProcessText)
} else if Utility.didSubmitKyc() && !Utility.pennyTestVerified() {
self.alert(type: .error, message: StringConstants().pennyTestPrimaryBankText)
} else if didSubmitKycAndNotVerified {
self.alert(type: .error, message: "verification_in_aproval_process_text".localized())
}
}
@objc private func showUnVerifiedPennyTestMessage() {
self.alert(type: .normal, message: "complete_penny_test".localized())
}
@objc private func showWalletToWallet() {
self.alert(type: .error, message: "This feature is coming soon")
}
private func showSideMenuAboutGme() {
guard let viewController = UIStoryboard(name: "SideMenu", bundle: nil)
.instantiateViewController(withIdentifier: "AboutGMEViewController") as? AboutGMEViewController else {
return
}
self.navigationController?.pushViewController(viewController, animated: true)
}
private func showSideMenuSetting() {
guard let viewController = UIStoryboard(name: "Setting", bundle: nil)
.instantiateViewController(withIdentifier: "SettingViewController") as? SettingViewController else {
return
}
self.navigationController?.pushViewController(viewController, animated: true)
}
private func showAutoDebit() {
let wireframe = AutoDebitWireframe()
if let navigation = self.navigationController {
wireframe.pushMainView(in: navigation)
}
}
private func showWithdraw() {
guard let viewController = UIStoryboard(name: "autoRefund", bundle: nil).instantiateViewController(
withIdentifier: "AutoRefundsViewController"
) as? AutoRefundsViewController else {
return
}
self.navigationController?.pushViewController(viewController, animated: true)
}
}
// MARK: HomeViewInterface
extension HomeViewController: HomeViewInterface {
func setHotLine(with model: [HotLine]?) {
hotLines = model
}
func show(model: User) {
self.user = model
}
func show(error: String) {
self.alert(type: .error, message: error)
}
func show(panicError: String) {
self.alert(type: .error, message: panicError, title: "Warning") {
self.presenter?.logout()
}
}
func showLoading() {
self.showProgressHud()
}
func hideLoading() {
self.hideProgressHud()
if self.tableView.refreshControl?.isRefreshing ?? false {
self.tableView.refreshControl?.endRefreshing()
}
}
}
// MARK: - UITableViewDelegate
extension HomeViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let section = Sections.init(rawValue: indexPath.section) else { return 0 }
switch section {
case .balance:
return UITableView.automaticDimension
case .collection:
let totalHeight = view.frame.height
let ramainingBalanceCellHeight: CGFloat = 100
let finalHeight = totalHeight - ramainingBalanceCellHeight
return finalHeight
}
}
}
// MARK: - UITableViewDataSource
extension HomeViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return self.sections.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let section = Sections.init(rawValue: indexPath.section) else {return UITableViewCell()}
switch section {
case .balance:
return configureRemainingLimitCell(tableView: tableView, indexPath: indexPath)
case .collection:
return configureCollectionCell(tableView: tableView, indexPath: indexPath)
}
}
func configureRemainingLimitCell(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(
withIdentifier: "HomeRemainingLimitTableViewCell"
) as? HomeRemainingLimitTableViewCell else {
return UITableViewCell()
}
cell.user = self.user
cell.setup()
return cell
}
func configureCollectionCell(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(
withIdentifier: "HomeCollectionTableViewCell"
) as? HomeCollectionTableViewCell else {
return UITableViewCell()
}
cell.setup()
cell.homeCollectionDelegate = self
return cell
}
override func setupTabItem() {
let image = UIImage.init(named: "ic-home")
self.tabBarItem = UITabBarItem(title: "home_text".localized(), image: image, selectedImage: nil)
self.tabBarItem.titlePositionAdjustment = UIOffset(
horizontal: 0,
vertical: UI_USER_INTERFACE_IDIOM() == .pad ? 2 : -6
)
}
@objc func updateTabBarTitle() {
self.tabBarItem.title = "home_text".localized()
}
}
// MARK: - Notification Name
extension HomeViewController {
func getCollectionHeightNotificationName() -> Notification.Name {
return Notification.Name.init(rawValue: MenuNotificationName.collectionHeight)
}
func getAvailableBalanceNotificationName() -> Notification.Name {
return Notification.Name.init(rawValue: SideMenuNavigationNotifications.availableBalance)
}
func getMainControllerNotificationName() -> Notification.Name {
return Notification.Name.init(rawValue: AppConstants.MainWireFrameNotificationName)
}
}
// MARK: - UIGestureRecognizerDelegate
extension HomeViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return !Utility.didSubmitKyc() ||
Utility.shouldShowPennyTestError() ||
Utility.didPennyTestCancelled() ||
Utility.didPennyTestRequested() ||
Utility.didPennyTestNotInitiated()
}
}
// MARK: - Check KFTC Token, PopUpNotification
extension HomeViewController {
func save(user: User?) {
Utility.save(user: user)
}
private func checkKFTCToken() {
if !GMEDB.shared.app.bool(.isOpenedTokenRenwalAlert) {
guard
let remind = GMEDB.shared.user.string(.remindKFTCTokenDay),
let remindDay = Int(remind) else {
popUpNotification()
return
}
if remindDay <= 30 {
let expiredMessage = "kftc_token_expired_message_text".localized()
let defaultMessage =
remindDay != 0 ? "kftc_token_remind_message_text".localized().replacingOccurrences(
of: "xx",
with: "\(remindDay)"
) : "kftc_token_remind_message_text".localized().replacingOccurrences(of: "xx ", with: "To")
alertWithOkCancel(
message: remindDay >= 0 ? defaultMessage : expiredMessage,
title: "kftc_token_title_message_text".localized(),
okTitle: "renewal_text".localized(),
cancelTitle: "later_text".localized(),
okAction: {
AutoDebitWireframe().pushMainView(on: self)
GMEDB.shared.app.set(true, .isOpenedTokenRenwalAlert)
},
cancelAction : {
self.popUpNotification()
GMEDB.shared.app.set(true, .isOpenedTokenRenwalAlert)
}
)
} else {
popUpNotification()
}
}
}
private func popUpNotification() {
// FIXME: Temporary expire date
let dateformat = DateFormatter()
dateformat.dateFormat = "yyyy-MM-dd"
let expireDate = dateformat.date(from: "2019-08-01")
GMEDB.shared.app.set(expireDate, .dateOfExpireNotification)
PopupNotificationWireframe().show(source: self)
}
}
// MARK: - ChannelPluginDelegate
extension HomeViewController: ChannelPluginDelegate {
func onChangeBadge(count: Int) {
setMessageCount(with: count)
}
func onReceivePush(event: PushEvent) {
//configure your view with push event data
//and display
print("event: \(event)")
}
}
// MARK: - HomeCollectionDelegate
extension HomeViewController: HomeCollectionDelegate {
func didSelect(
_ collectionView: UICollectionView,
didSelectMenu: HomeCollectionTableViewCell.CollectionMenus
) {
switch didSelectMenu {
case .sendMoney: showSendMoney()
case .mobileRecharge: showMobileRecharge()
case .todaysRate: presenter?.openTodaysRate()
case .walletStatement: showTrackYourTransfer()
case .resend: showResendMoney()
case .walletToWallet: showWalletToWallet()
case .demosticRemit: showDomesticRemit()
case .phoneRecharge: ()
case .cardRecharge: ()
}
}
}
// MARK: - SideMenuDelegate
extension HomeViewController: SideMenuDelegate {
func didSelectMenu(_ viewController: UIViewController, didSelectMenu: SideMenuViewController.MenuType) {
switch didSelectMenu {
case .withDraw:
showWithdraw()
case .autoDebit:
showAutoDebit()
case .transferHistory:
showTransactionStatement()
case .about:
showSideMenuAboutGme()
case .setting:
showSideMenuSetting()
}
}
}