mobile-ios/CovidSafe/UploadDataStep2VC.swift

209 lines
8.2 KiB
Swift
Raw Normal View History

2020-05-08 07:49:14 +00:00
import Foundation
import UIKit
import Lottie
import CoreData
import KeychainSwift
enum UploadResult {
case Success
case SessionExpired
case Failed
case FailedUpload
case InvalidCode
}
class UploadDataStep2VC: UIViewController, CodeInputViewDelegate {
func codeDidChange(codeInputView: CodeInputView) {
updateUploadButton()
}
func codeDidFinish(codeInputView: CodeInputView) {
updateUploadButton()
}
@IBOutlet weak var codeInputView: CodeInputView!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var uploadErrorMsgLbl: UILabel!
@IBOutlet weak var uploadDataButton: GradientButton!
@IBOutlet weak var uploadingView: UIView!
@IBOutlet weak var uploadAnimatedviewContainer: UIView!
2020-07-03 04:26:13 +00:00
@IBOutlet var animationLeadingConstraint: NSLayoutConstraint!
@IBOutlet var animationTrailingConstraint: NSLayoutConstraint!
@IBOutlet var centredContainerViewBottomConstraint: NSLayoutConstraint!
@IBOutlet var centredContainerViewTopConstraint: NSLayoutConstraint!
2020-05-08 07:49:14 +00:00
var currentKeyboardFrame: CGRect?
var uploadAnimatedView: AnimationView?
2021-02-02 00:04:43 +00:00
var uploadDisplayErrorMsg = ""
2020-07-03 04:26:13 +00:00
let invalidPinErrMsg = "action_verify_invalid_pin".localizedString(comment: "Invalid PIN, please ask health official to send another PIN.")
2020-05-08 07:49:14 +00:00
2020-05-15 07:47:40 +00:00
let verifyEnabledColor = UIColor.covidSafeButtonDarkerColor
2020-05-08 07:49:14 +00:00
let verifyDisabledColor = UIColor(red: 219/255.0, green: 221/255.0, blue: 221.0/255.0, alpha: 1.0)
lazy var countdownFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.minute, .second]
formatter.unitsStyle = .positional
formatter.zeroFormattingBehavior = .pad
return formatter
}()
override func viewDidLoad() {
_ = codeInputView.becomeFirstResponder()
codeInputView.delegate = self
dismissKeyboardOnTap()
updateUploadButton()
2020-07-03 04:26:13 +00:00
updateConstrainstsTo(orientation: UIDevice.current.orientation)
2020-05-08 07:49:14 +00:00
if #available(iOS 13.0, *) {
isModalInPresentation = true
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
setIsLoading(false)
2021-02-02 00:04:43 +00:00
if uploadAnimatedView == nil {
let uploadAnimation = AnimationView(name: "Spinner_upload")
uploadAnimation.loopMode = .loop
uploadAnimation.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: self.uploadAnimatedviewContainer.frame.size)
self.uploadAnimatedviewContainer.addSubview(uploadAnimation)
uploadAnimatedView = uploadAnimation
}
2020-05-08 07:49:14 +00:00
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notif:)), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(notif:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
2020-07-03 04:26:13 +00:00
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
updateConstrainstsTo(orientation: UIDevice.current.orientation)
}
func updateConstrainstsTo(orientation: UIDeviceOrientation) {
if orientation.isLandscape {
centredContainerViewTopConstraint.isActive = true
centredContainerViewBottomConstraint.isActive = true
animationLeadingConstraint.isActive = false
animationTrailingConstraint.isActive = false
} else {
centredContainerViewTopConstraint.isActive = false
centredContainerViewBottomConstraint.isActive = false
animationLeadingConstraint.isActive = true
animationTrailingConstraint.isActive = true
}
}
2020-05-08 07:49:14 +00:00
@objc
func keyboardWillHide(notif: Notification) {
self.currentKeyboardFrame = nil
let contentInset = UIEdgeInsets.zero
scrollView.contentInset = contentInset
scrollView.scrollIndicatorInsets = contentInset
}
@objc
func keyboardWillChangeFrame(notif: Notification) {
let userInfo = notif.userInfo
guard let keyboardFrame = userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else {
return
}
currentKeyboardFrame = keyboardFrame
updateScrollviewContentInset()
}
func updateScrollviewContentInset() {
guard let keyboardFrame = currentKeyboardFrame else {
return
}
// the reason for the view.frame.height - scrollview.frame.height is because the scrollview is not full height of the view
// so we don't need to inset the complete keyboard height
let offsetKeyboardBottom = keyboardFrame.height - (view.frame.height - scrollView.frame.height)
let contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: offsetKeyboardBottom, right: 0.0)
scrollView.contentInset = contentInset
scrollView.scrollIndicatorInsets = contentInset
scrollView.scrollRectToVisible(codeInputView.frame, animated: true)
}
func updateUploadButton() {
if let OTP = codeInputView?.text {
uploadDataButton.isEnabled = OTP.count == 6
uploadDataButton.backgroundColor = OTP.count == 6 ? verifyEnabledColor : verifyDisabledColor
} else {
uploadDataButton.isEnabled = false
uploadDataButton.backgroundColor = verifyDisabledColor
}
}
@IBAction func backBtnTapped(_ sender: UIButton) {
navigationController?.popViewController(animated: true)
}
@IBAction func uploadDataBtnTapped(_ sender: UIButton) {
uploadErrorMsgLbl.isHidden = true
let code = codeInputView.text
guard code.range(of: "^[0-9]{6}$", options: .regularExpression) != nil else {
uploadErrorMsgLbl.isHidden = false
uploadErrorMsgLbl.text = invalidPinErrMsg
return
}
setIsLoading(true)
self.codeInputView.invalidCode = false
2021-02-02 00:04:43 +00:00
UploadHelper.uploadEncounterData(pin: code) { result, errorMessage in
2020-05-08 07:49:14 +00:00
self.setIsLoading(false)
switch result{
case .InvalidCode:
self.codeInputView.invalidCode = true
self.uploadErrorMsgLbl.text = self.invalidPinErrMsg
self.uploadErrorMsgLbl.isHidden = false
case .Success:
UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: "uploadDataDate")
let firstUploadDate = UserDefaults.standard.double(forKey: "firstUploadDataDate")
if(firstUploadDate == 0){
UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: "firstUploadDataDate")
}
Encounter.deleteAll()
self.performSegue(withIdentifier: "showSuccessVCSegue", sender: nil)
2021-02-02 00:04:43 +00:00
case .FailedUpload, .Failed:
self.uploadDisplayErrorMsg = errorMessage ?? "No error code/message available"
2020-05-08 07:49:14 +00:00
self.performSegue(withIdentifier: "uploadErrorSegue", sender: self)
sender.isEnabled = true
case .SessionExpired:
NotificationCenter.default.post(name: .jwtExpired, object: nil)
sender.isEnabled = true
}
}
}
private func setIsLoading(_ isLoading: Bool) {
if isLoading {
uploadAnimatedView?.play()
uploadingView.alpha = 1
uploadingView.isHidden = false
} else {
uploadAnimatedView?.stop()
uploadingView.alpha = 0
uploadingView.isHidden = true
}
}
2021-02-02 00:04:43 +00:00
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let errorViewController = segue.destination as? UploadDataErrorViewController {
errorViewController.uploadErrorMessage = self.uploadDisplayErrorMsg
}
}
2020-05-08 07:49:14 +00:00
}