react-native-mytatva-rn-sdk 1.2.97 → 1.2.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/android/src/main/java/com/mytatvarnsdk/CgmTrackyLibModule.kt +25 -0
  2. package/android/src/main/java/com/mytatvarnsdk/activity/ConnectSensorActivity.kt +164 -18
  3. package/android/src/main/java/com/mytatvarnsdk/activity/HelpActivity.kt +3 -9
  4. package/android/src/main/java/com/mytatvarnsdk/activity/PermissionActivity.kt +8 -16
  5. package/android/src/main/java/com/mytatvarnsdk/activity/PlaceSensorActivity.kt +12 -13
  6. package/android/src/main/java/com/mytatvarnsdk/activity/PlaceTransmitterActivity.kt +12 -13
  7. package/android/src/main/java/com/mytatvarnsdk/activity/SearchTransmitterActivity.kt +9 -14
  8. package/android/src/main/java/com/mytatvarnsdk/activity/SensorConnectSuccessActivity.kt +12 -16
  9. package/android/src/main/java/com/mytatvarnsdk/activity/StartCGMActivity.kt +9 -15
  10. package/android/src/main/java/com/mytatvarnsdk/activity/VideoActivity.kt +96 -50
  11. package/android/src/main/java/com/mytatvarnsdk/network/AuthenticateSDKService.kt +50 -0
  12. package/android/src/main/java/com/mytatvarnsdk/utils/CustomerSupportConfig.kt +137 -0
  13. package/android/src/main/java/com/mytatvarnsdk/utils/ToolbarSupportHelper.kt +83 -0
  14. package/android/src/main/res/layout/activity_connect_sensor.xml +117 -2
  15. package/ios/Custom/CustomTopUIView.swift +25 -0
  16. package/ios/Database/KLTBluetoothManager.m +69 -14
  17. package/ios/MyReactNativeBridge.m +4 -0
  18. package/ios/Support/API.swift +117 -18
  19. package/ios/Support/CustomTopViewSupportHelper.swift +55 -0
  20. package/ios/Support/CustomerSupportConfig.swift +169 -0
  21. package/ios/Support/Global.swift +2 -2
  22. package/ios/Support/GlobalYouTubePlayerView.swift +102 -11
  23. package/ios/TableViewCell/ImageTVC/ImageTVC.swift +147 -15
  24. package/ios/ViewControllers/AttachTransmitterViewController.swift +16 -21
  25. package/ios/ViewControllers/ChatWithExpertViewController.swift +1 -7
  26. package/ios/ViewControllers/ConnectToSensorViewController.swift +213 -34
  27. package/ios/ViewControllers/ConnectToTransmitterViewController.swift +16 -21
  28. package/ios/ViewControllers/ProvidePermissionViewController.swift +16 -21
  29. package/ios/ViewControllers/PutOnTheSensorViewController.swift +16 -21
  30. package/ios/ViewControllers/StartConnectionViewController.swift +18 -25
  31. package/ios/ViewModel/FinalViewModel.swift +2 -2
  32. package/package.json +1 -1
@@ -12,22 +12,113 @@ class WebViewController: UIViewController {
12
12
  var webView: WKWebView!
13
13
  var videoURL: URL?
14
14
 
15
+ private lazy var closeButton: UIButton = {
16
+ let button = UIButton(type: .custom)
17
+ button.translatesAutoresizingMaskIntoConstraints = false
18
+ button.accessibilityLabel = "Close video"
19
+ if let image = loadImage(named: "ic_close") {
20
+ button.setImage(image, for: .normal)
21
+ } else {
22
+ let config = UIImage.SymbolConfiguration(pointSize: 22, weight: .medium)
23
+ button.setImage(UIImage(systemName: "xmark.circle.fill", withConfiguration: config), for: .normal)
24
+ button.tintColor = .white
25
+ }
26
+ button.addTarget(self, action: #selector(closeTapped), for: .touchUpInside)
27
+ return button
28
+ }()
29
+
15
30
  override func viewDidLoad() {
16
31
  super.viewDidLoad()
17
- view.backgroundColor = .white
18
-
19
- // Setup WebView
32
+ view.backgroundColor = .black
33
+
20
34
  let config = WKWebViewConfiguration()
21
35
  config.allowsInlineMediaPlayback = true
22
-
23
- webView = WKWebView(frame: view.bounds, configuration: config)
24
- webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
36
+
37
+ webView = WKWebView(frame: .zero, configuration: config)
38
+ webView.translatesAutoresizingMaskIntoConstraints = false
39
+ webView.backgroundColor = .black
40
+ webView.isOpaque = false
25
41
  view.addSubview(webView)
26
-
27
- // Load video URL
28
- if let url = videoURL {
29
- let request = URLRequest(url: url)
30
- webView.load(request)
42
+
43
+ view.addSubview(closeButton)
44
+
45
+ NSLayoutConstraint.activate([
46
+ closeButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8),
47
+ closeButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8),
48
+ closeButton.widthAnchor.constraint(equalToConstant: 40),
49
+ closeButton.heightAnchor.constraint(equalToConstant: 40),
50
+
51
+ webView.topAnchor.constraint(equalTo: closeButton.bottomAnchor, constant: 8),
52
+ webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
53
+ webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
54
+ webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
55
+ ])
56
+
57
+ view.bringSubviewToFront(closeButton)
58
+
59
+ let videoId = resolveVideoId(from: videoURL?.absoluteString)
60
+ let html = buildYouTubeEmbedHtml(videoId: videoId)
61
+ let baseURL = URL(string: "https://www.mytatva.in/")!
62
+ webView.loadHTMLString(html, baseURL: baseURL)
63
+ }
64
+
65
+ @objc private func closeTapped() {
66
+ dismiss(animated: true)
67
+ }
68
+
69
+ private func resolveVideoId(from raw: String?) -> String {
70
+ let value = raw?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
71
+ if value.isEmpty {
72
+ return "65vl2aE1K_I"
31
73
  }
74
+
75
+ let patterns = [
76
+ #"(?:embed/|/v/|watch\?v=|youtu\.be/)([\w-]{11})"#,
77
+ #"^([\w-]{11})$"#
78
+ ]
79
+
80
+ for pattern in patterns {
81
+ if let regex = try? NSRegularExpression(pattern: pattern),
82
+ let match = regex.firstMatch(in: value, range: NSRange(value.startIndex..., in: value)),
83
+ let range = Range(match.range(at: 1), in: value) {
84
+ return String(value[range])
85
+ }
86
+ }
87
+
88
+ return "65vl2aE1K_I"
89
+ }
90
+
91
+ private func buildYouTubeEmbedHtml(videoId: String) -> String {
92
+ """
93
+ <!DOCTYPE html>
94
+ <html>
95
+ <head>
96
+ <meta name="viewport" content="width=device-width, initial-scale=1">
97
+ <meta name="referrer" content="strict-origin-when-cross-origin">
98
+ <style>
99
+ html, body { margin: 0; padding: 0; background: #000; height: 100%; }
100
+ .video-container { position: relative; width: 100%; height: 100%; }
101
+ iframe {
102
+ position: absolute;
103
+ top: 0;
104
+ left: 0;
105
+ width: 100%;
106
+ height: 100%;
107
+ border: 0;
108
+ }
109
+ </style>
110
+ </head>
111
+ <body>
112
+ <div class="video-container">
113
+ <iframe
114
+ src="https://www.youtube-nocookie.com/embed/\(videoId)?playsinline=1&rel=0&modestbranding=1"
115
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
116
+ allowfullscreen
117
+ referrerpolicy="strict-origin-when-cross-origin">
118
+ </iframe>
119
+ </div>
120
+ </body>
121
+ </html>
122
+ """
32
123
  }
33
124
  }
@@ -7,58 +7,191 @@
7
7
 
8
8
  import UIKit
9
9
  import AVFoundation
10
+
10
11
  class ImageTVC: UITableViewCell {
11
12
 
12
13
  @IBOutlet weak var bottomConstraint: NSLayoutConstraint!
13
14
  @IBOutlet weak var displayImageView: UIImageView!
14
15
  @IBOutlet weak var topConstraint: NSLayoutConstraint!
15
-
16
+
16
17
  @IBOutlet var gifView: UIImageView!
17
18
  @IBOutlet weak var cameraView: CustomView!
18
19
  @IBOutlet weak var cameraTitleLabel: UILabel!
19
20
  @IBOutlet weak var cameraDescLabel: UILabel!
20
-
21
+
21
22
  @IBOutlet var ic_green_arrow: UIImageView!
22
23
  var scannerView: QRScannerView!
24
+
25
+ var onConnectTapped: ((String) -> Void)?
26
+ var onTextFieldDidBeginEditing: (() -> Void)?
27
+
28
+ private var manualEntryView: UIView?
29
+ private var sensorIdTextField: UITextField?
30
+ private var isManualEntryVisible = false
31
+
32
+ var activeSensorIdTextField: UITextField? {
33
+ isManualEntryVisible ? sensorIdTextField : nil
34
+ }
35
+
23
36
  override func awakeFromNib() {
24
37
  super.awakeFromNib()
25
38
  gifView.isHidden = true
26
39
  ic_green_arrow.image = loadImage(named: "ic_green_arrow")
27
- // Initialization code
28
40
  cameraTitleLabel.text = "GoodFlip requires camera permission to scan the QR and connect with the sensor"
29
-
30
41
  cameraTitleLabel.font = FontManager.font(ofSize: 14, weight: .medium)
31
-
32
42
  cameraTitleLabel.textColor = .white
33
-
34
- let first = "Provide Camera Permissions"
35
43
 
44
+ let first = "Provide Camera Permissions"
36
45
  let attributedString = NSMutableAttributedString(string: first, attributes: [
37
46
  .font: FontManager.font(ofSize: 16, weight: .semibold),
38
47
  .foregroundColor: CustomColor.shared.lightGreen,
39
48
  .underlineStyle: NSUnderlineStyle.single.rawValue,
40
49
  ])
41
-
42
50
  cameraDescLabel.attributedText = attributedString
51
+
52
+ setupManualEntryView()
43
53
  }
44
54
 
45
55
  override func setSelected(_ selected: Bool, animated: Bool) {
46
56
  super.setSelected(selected, animated: animated)
57
+ }
47
58
 
48
- // Configure the view for the selected state
59
+ override func prepareForReuse() {
60
+ super.prepareForReuse()
61
+ onConnectTapped = nil
62
+ onTextFieldDidBeginEditing = nil
63
+ scannerView?.stopScanning()
64
+ scannerView?.removeFromSuperview()
65
+ scannerView = nil
66
+ manualEntryView?.isHidden = true
67
+ sensorIdTextField?.text = nil
68
+ isManualEntryVisible = false
49
69
  }
50
-
70
+
71
+ // MARK: - Manual Entry UI Setup
72
+
73
+ private func setupManualEntryView() {
74
+ let container = UIView()
75
+ container.translatesAutoresizingMaskIntoConstraints = false
76
+ container.backgroundColor = UIColor(red: 16/255, green: 24/255, blue: 40/255, alpha: 1)
77
+ container.layer.cornerRadius = 12
78
+ container.isHidden = true
79
+ contentView.addSubview(container)
80
+
81
+ let textField = UITextField()
82
+ textField.translatesAutoresizingMaskIntoConstraints = false
83
+ textField.placeholder = "Enter Sensor ID"
84
+ textField.autocapitalizationType = .allCharacters
85
+ textField.autocorrectionType = .no
86
+ textField.returnKeyType = .done
87
+ textField.font = FontManager.font(ofSize: 14, weight: .regular)
88
+ textField.textColor = UIColor(red: 16/255, green: 24/255, blue: 40/255, alpha: 1)
89
+ textField.backgroundColor = .white
90
+ textField.layer.cornerRadius = 8
91
+ textField.layer.masksToBounds = true
92
+ textField.delegate = self
93
+ let leftPad = UIView(frame: CGRect(x: 0, y: 0, width: 14, height: 1))
94
+ textField.leftView = leftPad
95
+ textField.leftViewMode = .always
96
+ textField.rightView = UIView(frame: CGRect(x: 0, y: 0, width: 14, height: 1))
97
+ textField.rightViewMode = .always
98
+ container.addSubview(textField)
99
+
100
+ let connectButton = UIButton(type: .custom)
101
+ connectButton.translatesAutoresizingMaskIntoConstraints = false
102
+ connectButton.setTitle("Connect", for: .normal)
103
+ connectButton.setTitleColor(.white, for: .normal)
104
+ connectButton.titleLabel?.font = FontManager.font(ofSize: 16, weight: .semibold)
105
+ connectButton.backgroundColor = CustomColor.shared.lightGreen
106
+ connectButton.layer.cornerRadius = 12
107
+ connectButton.addTarget(self, action: #selector(connectButtonTapped), for: .touchUpInside)
108
+ container.addSubview(connectButton)
109
+
110
+ let hintLabel = UILabel()
111
+ hintLabel.translatesAutoresizingMaskIntoConstraints = false
112
+ hintLabel.text = "Scan the QR with mobile camera to get a sensor ID."
113
+ hintLabel.font = FontManager.font(ofSize: 12, weight: .regular)
114
+ hintLabel.textColor = UIColor(white: 1, alpha: 0.55)
115
+ hintLabel.textAlignment = .center
116
+ hintLabel.numberOfLines = 0
117
+ container.addSubview(hintLabel)
118
+
119
+ NSLayoutConstraint.activate([
120
+ textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 16),
121
+ textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
122
+ textField.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -16),
123
+ textField.heightAnchor.constraint(equalToConstant: 48),
124
+
125
+ connectButton.topAnchor.constraint(equalTo: textField.bottomAnchor, constant: 12),
126
+ connectButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
127
+ connectButton.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -16),
128
+ connectButton.heightAnchor.constraint(equalToConstant: 52),
129
+
130
+ hintLabel.topAnchor.constraint(equalTo: connectButton.bottomAnchor, constant: 10),
131
+ hintLabel.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
132
+ hintLabel.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -16),
133
+ hintLabel.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -16),
134
+
135
+ container.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
136
+ container.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
137
+ container.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
138
+ container.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -8),
139
+ ])
140
+
141
+ manualEntryView = container
142
+ sensorIdTextField = textField
143
+ }
144
+
145
+ // MARK: - Public API
146
+
147
+ func configureAsStaticImage() {
148
+ isManualEntryVisible = false
149
+ manualEntryView?.isHidden = true
150
+ cameraView.isHidden = true
151
+ scannerView?.stopScanning()
152
+ }
153
+
154
+ func configure(isManualEntry: Bool) {
155
+ isManualEntryVisible = isManualEntry
156
+ if isManualEntry {
157
+ cameraView.isHidden = true
158
+ manualEntryView?.isHidden = false
159
+ scannerView?.stopScanning()
160
+ } else {
161
+ cameraView.isHidden = false
162
+ manualEntryView?.isHidden = true
163
+ sensorIdTextField?.text = nil
164
+ sensorIdTextField?.resignFirstResponder()
165
+ }
166
+ }
167
+
51
168
  func setupQRView() {
52
169
  scannerView = QRScannerView(frame: cameraView.bounds)
53
170
  scannerView.onCodeDetected = { code in
54
171
  print("Detected QR Code: \(code)")
55
- // You can stop scanning or navigate
56
172
  self.scannerView.stopScanning()
57
173
  }
58
-
59
174
  cameraView.addSubview(scannerView)
60
175
  }
61
-
176
+
177
+ // MARK: - Actions
178
+
179
+ @objc private func connectButtonTapped() {
180
+ sensorIdTextField?.resignFirstResponder()
181
+ let sensorId = (sensorIdTextField?.text ?? "").trimmingCharacters(in: .whitespaces).uppercased()
182
+ onConnectTapped?(sensorId)
183
+ }
184
+ }
185
+
186
+ extension ImageTVC: UITextFieldDelegate {
187
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
188
+ textField.resignFirstResponder()
189
+ return true
190
+ }
191
+
192
+ func textFieldDidBeginEditing(_ textField: UITextField) {
193
+ onTextFieldDidBeginEditing?()
194
+ }
62
195
  }
63
196
 
64
197
  class QRScannerView: UIView {
@@ -90,7 +223,6 @@ class QRScannerView: UIView {
90
223
  let metadataOutput = AVCaptureMetadataOutput()
91
224
  if captureSession.canAddOutput(metadataOutput) {
92
225
  captureSession.addOutput(metadataOutput)
93
-
94
226
  metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
95
227
  metadataOutput.metadataObjectTypes = [.qr]
96
228
  }
@@ -100,7 +232,7 @@ class QRScannerView: UIView {
100
232
  previewLayer.videoGravity = .resizeAspectFill
101
233
  layer.addSublayer(previewLayer)
102
234
 
103
- self.captureSession.startRunning()
235
+ captureSession.startRunning()
104
236
  }
105
237
 
106
238
  func stopScanning() {
@@ -28,6 +28,11 @@ class AttachTransmitterViewController: UIViewController {
28
28
  setupLayout()
29
29
  viewModel.initialize()
30
30
  }
31
+
32
+ override func viewWillAppear(_ animated: Bool) {
33
+ super.viewWillAppear(animated)
34
+ CustomTopViewSupportHelper.configureWhatsapp(customTopView: customTopView)
35
+ }
31
36
 
32
37
  func setupLayout() {
33
38
  tableView.delegate = self
@@ -102,32 +107,22 @@ class AttachTransmitterViewController: UIViewController {
102
107
  //self.navigationController?.pushViewController(vc, animated: true)
103
108
  }
104
109
 
105
- customTopView.onDemoTapped = {
106
- let isForReconnect = UserDefaults.standard.bool(forKey: "isForReconnect")
107
- let payload = [
108
- "status": "cgm_watch_demo_clicked"
109
- ]
110
-
111
- NotificationCenter.default.post(
112
- name: Notification.Name("cgmwatchdemoclicked"),
113
- object: nil,
114
- userInfo: payload
115
- )
116
-
117
- let webVC = WebViewController()
118
- webVC.modalPresentationStyle = .formSheet
119
- webVC.videoURL = URL(string: isForReconnect == true ? reconnectionwatchCGMVideo : watchCGMVideo)
120
- self.present(webVC, animated: true, completion: nil)
121
- }
110
+ CustomTopViewSupportHelper.configureWhatsapp(customTopView: customTopView)
111
+ CustomTopViewSupportHelper.bindDemoAction(
112
+ customTopView: customTopView,
113
+ isForReconnect: UserDefaults.standard.bool(forKey: "isForReconnect"),
114
+ presenter: self
115
+ )
116
+ CustomTopViewSupportHelper.bindWhatsappAction(
117
+ customTopView: customTopView,
118
+ navigationController: navigationController
119
+ )
120
+
122
121
  customTopView.onCloseTapped = {
123
122
  let vc = ExitJourneyViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
124
123
  vc.modalPresentationStyle = .overFullScreen
125
124
  self.present(vc, animated: true, completion: nil)
126
125
  }
127
- customTopView.onWhatsAppTapped = {
128
- let vc = ChatWithExpertViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
129
- self.navigationController?.pushViewController(vc, animated: false)
130
- }
131
126
  }
132
127
 
133
128
  }
@@ -79,13 +79,7 @@ class ChatWithExpertViewController: UIViewController {
79
79
  )
80
80
 
81
81
 
82
- if let url = URL(string: "https://wa.aisensy.com/aaa1qv") {
83
- if UIApplication.shared.canOpenURL(url) {
84
- UIApplication.shared.open(url, options: [:], completionHandler: nil)
85
- } else {
86
- print("Cannot open URL")
87
- }
88
- }
82
+ CustomerSupportConfig.shared.openWhatsApp()
89
83
  //let vc = ConnectToTransmitterViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
90
84
  //self.navigationController?.pushViewController(vc, animated: false)
91
85
  }