react-native-mytatva-rn-sdk 1.2.45 → 1.2.46

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.
@@ -262,7 +262,7 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
262
262
  put("transmitterName", device?.name ?: "")
263
263
  put("SensorId", sensorId ?: "")
264
264
  put("Sensor", sensorId ?: "")
265
- put("timeInMillis", Date().time)
265
+ put("timeInMillis", System.currentTimeMillis())
266
266
  }
267
267
 
268
268
  val obj = JSONObject().apply {
@@ -368,10 +368,22 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
368
368
  Handler(Looper.getMainLooper()).postDelayed({
369
369
  // Create new observer with explicit nullable parameter type
370
370
  glucoseObserver = Observer<PocGlucose?> { pocGlucose ->
371
- if (pocGlucose != null) {
371
+ val currentTime = System.currentTimeMillis()
372
+ var dataAge = System.currentTimeMillis()
373
+
374
+ if (prefsHelper.lastSyncData != null) {
375
+ dataAge = currentTime - prefsHelper.lastSyncData.timeInMillis
376
+ }
377
+
378
+ if ((pocGlucose != null && prefsHelper.lastSyncData == null) || (pocGlucose != null && prefsHelper.lastSyncData != null && dataAge <= 4 * 60 * 1000L)) {
372
379
  handleGlucoseData(pocGlucose)
380
+ Log.d(
381
+ "observeGlucoseData",
382
+ "Received glucose data - processing"
383
+ )
373
384
  } else {
374
- Log.w(
385
+ observeAllGlucoseData(userToken)
386
+ Log.d(
375
387
  "observeGlucoseData",
376
388
  "Received null glucose data - skipping processing"
377
389
  )
@@ -517,6 +529,11 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
517
529
  if (lastSyncData != null) {
518
530
  CoroutineScope(Dispatchers.IO).launch {
519
531
  val glucoseData = mModel.getGlucoseBetweenTime(lastSyncData.lastSyncTime)
532
+
533
+ Log.d("observeAllGlucoseData: ", glucoseData.toString())
534
+ Log.d("Last sync time: ", lastSyncData.lastSyncTime.toString())
535
+ Log.d("current time: ", System.currentTimeMillis().toString())
536
+
520
537
  if (glucoseData != null && glucoseData.isNotEmpty()) {
521
538
  processBatchDataAndStartObserver(glucoseData)
522
539
  } else {
@@ -778,7 +795,7 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
778
795
  lastRecord?.let {
779
796
  try {
780
797
  val syncData = SyncMeta(
781
- Date().time,
798
+ System.currentTimeMillis(),
782
799
  it.timeInMillis,
783
800
  it.deviceId,
784
801
  it.glucoseId
@@ -99,7 +99,7 @@ public class BaseViewModel extends AndroidViewModel {
99
99
  }
100
100
 
101
101
  public List<PocGlucose> getGlucoseBetweenTime(long startTime) {
102
- return mRepositoryGlucose.getGlucoseByTimeMillis(startTime, new Date().getTime());
102
+ return mRepositoryGlucose.getGlucoseByTimeMillis(startTime, System.currentTimeMillis());
103
103
  }
104
104
 
105
105
  public PocDevice getDeviceInfo(int deviceId) {
@@ -20,7 +20,7 @@ RCT_EXPORT_MODULE();
20
20
 
21
21
  // Define the supported events
22
22
  - (NSArray<NSString *> *)supportedEvents {
23
- return @[@"cgmDeviceEvent"]; // Event names to listen to in JS
23
+ return @[@"cgmDeviceEvent", @"cgmwatchdemoclicked", @"cgmWAsupportclicked"]; // Event names to listen to in JS
24
24
  }
25
25
 
26
26
  // Example method to emit an event from native to JS
@@ -39,7 +39,7 @@ RCT_EXPORT_MODULE();
39
39
  // This method returns the list of events the module supports
40
40
  - (NSArray<NSString *> *)supportedEvents
41
41
  {
42
- return @[@"cgmDeviceEvent"];
42
+ return @[@"cgmDeviceEvent", @"cgmwatchdemoclicked", @"cgmWAsupportclicked"];
43
43
  }
44
44
 
45
45
  // Start listening for notifications
@@ -51,6 +51,17 @@ RCT_EXPORT_MODULE();
51
51
  selector:@selector(handleNotification:)
52
52
  name:@"cgmDeviceEvent"
53
53
  object:nil];
54
+
55
+ [[NSNotificationCenter defaultCenter] addObserver:self
56
+ selector:@selector(handleNotification:)
57
+ name:@"cgmwatchdemoclicked"
58
+ object:nil];
59
+
60
+
61
+ [[NSNotificationCenter defaultCenter] addObserver:self
62
+ selector:@selector(handleNotification:)
63
+ name:@"cgmWAsupportclicked"
64
+ object:nil];
54
65
  }
55
66
  return self;
56
67
  }
@@ -64,6 +75,9 @@ RCT_EXPORT_MODULE();
64
75
 
65
76
  // Send the data to React Native via event emitter
66
77
  [self sendEventWithName:@"cgmDeviceEvent" body:@{@"status": @"WARM_PERIOD_STARTED"}];
78
+ [self sendEventWithName:@"cgmwatchdemoclicked" body:@{@"status": @"cgm_watch_demo_clicked"}];
79
+ [self sendEventWithName:@"cgmWAsupportclicked" body:@{@"status": @"cgm_WA_support_clicked"}];
80
+
67
81
  }
68
82
 
69
83
  // Private helper
@@ -259,68 +273,59 @@ RCT_EXPORT_METHOD(observeAllGlucoseData:(NSString *)token)
259
273
  });
260
274
  }
261
275
 
262
- // Internal method — can be kept private using a class extension
263
- - (void)observeTransmitterUnbindStatus:(NSString *)token
264
- response:(NSDictionary *)responseDict
265
- completion:(void (^)(NSDictionary *response, NSError *error))completion
276
+ //--------------OLD FUNCTION-----------------
277
+ //RCT_EXPORT_METHOD(observeTransmitterUnbindStatus:(NSString *)token)
278
+ //{
279
+ // NSLog(@"Received token: %@", token);
280
+ // [[NSUserDefaults standardUserDefaults] setObject:token forKey:@"authToken"];
281
+ // [[NSUserDefaults standardUserDefaults] synchronize];
282
+ // FinalViewModelManager *manager = [FinalViewModelManager shared];
283
+ // [manager callForObserveTransmitterUnbindStatus];
284
+ //}
285
+
286
+
287
+
288
+ RCT_EXPORT_METHOD(observeTransmitterUnbindStatus:(NSString *)token
289
+ response:(NSString *)responseJsonString
290
+ resolver:(RCTPromiseResolveBlock)resolve
291
+ rejecter:(RCTPromiseRejectBlock)reject)
266
292
  {
293
+ if (responseJsonString == nil || ![responseJsonString isKindOfClass:[NSString class]]) {
294
+ NSError *error = [NSError errorWithDomain:@"CgmTrackyLib"
295
+ code:1001
296
+ userInfo:@{NSLocalizedDescriptionKey: @"Invalid or nil JSON string passed from JS"}];
297
+ reject(@"invalid_params", @"Response JSON string is nil or invalid", error);
298
+ return;
299
+ }
300
+
301
+ // Parse JSON string to NSDictionary
302
+ NSData *data = [responseJsonString dataUsingEncoding:NSUTF8StringEncoding];
303
+ NSError *parseError = nil;
304
+ NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
305
+
306
+ if (parseError || ![responseDict isKindOfClass:[NSDictionary class]]) {
307
+ reject(@"json_parse_error", @"Failed to parse JSON string to dictionary", parseError);
308
+ return;
309
+ }
310
+
267
311
  // Save token
268
312
  [[NSUserDefaults standardUserDefaults] setObject:token forKey:@"authToken"];
269
- [[NSUserDefaults standardUserDefaults] synchronize];
270
313
 
271
- // Save CGM status item to UserDefaults (if needed by Swift)
272
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseDict options:0 error:nil];
273
- if (jsonData) {
274
- [[NSUserDefaults standardUserDefaults] setObject:jsonData forKey:@"CGMStatusItem"];
275
- [[NSUserDefaults standardUserDefaults] synchronize];
276
- }
314
+ // Save response data
315
+ [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"CGMStatusItem"];
316
+ [[NSUserDefaults standardUserDefaults] synchronize];
277
317
 
278
- // Call Swift method which reads CGMStatusItem from UserDefaults
318
+ // Call manager logic
279
319
  FinalViewModelManager *manager = [FinalViewModelManager shared];
280
320
  [manager callForObserveTransmitterUnbindStatusWithCompletion:^(NSDictionary *response, NSError *error) {
281
- if (completion) {
282
- completion(response, error);
321
+ if (error) {
322
+ reject([NSString stringWithFormat:@"%ld", (long)error.code], error.localizedDescription, error);
323
+ } else {
324
+ dispatch_async(dispatch_get_main_queue(), ^{
325
+ resolve(response ?: @{});
326
+ });
283
327
  }
284
328
  }];
285
329
  }
286
330
 
287
- //RCT_EXPORT_METHOD(observeTransmitterUnbindStatus:(NSString *)token response:(NSString *)responseJsonString)
288
- //{
289
- // // Optional: Parse the JSON string if needed
290
- // NSData *jsonData = [responseJsonString dataUsingEncoding:NSUTF8StringEncoding];
291
- // NSError *jsonError;
292
- // NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&jsonError];
293
- //
294
- // if (jsonError) {
295
- // NSLog(@"Failed to parse JSON: %@", jsonError.localizedDescription);
296
- // [self sendEventWithName:@"observeTransmitterUnbindStatusHandler" body:@{
297
- // @"token": token ?: @"",
298
- // @"success": @NO,
299
- // @"error": @"Invalid JSON response from JS"
300
- // }];
301
- // return;
302
- // }
303
- //
304
- // // Now you have responseDict, you can use it
305
- // [self observeTransmitterUnbindStatusInternal:token response:responseDict completion:^(NSDictionary *response, NSError *error) {
306
- // if (error) {
307
- // NSDictionary *errorPayload = @{
308
- // @"token": token ?: @"",
309
- // @"success": @NO,
310
- // @"error": error.localizedDescription ?: @"Unknown error"
311
- // };
312
- // [self sendEventWithName:@"observeTransmitterUnbindStatusHandler" body:errorPayload];
313
- // } else {
314
- // NSDictionary *successPayload = @{
315
- // @"token": token ?: @"",
316
- // @"responseFromBackend": response ?: @{},
317
- // @"responseFromJS": responseDict ?: @{},
318
- // @"success": @YES
319
- // };
320
- // [self sendEventWithName:@"observeTransmitterUnbindStatusHandler" body:successPayload];
321
- // }
322
- // }];
323
- //
324
- //}
325
-
326
331
  @end
@@ -188,7 +188,7 @@ class API {
188
188
  // Set request body
189
189
  let json: [String: Any] = [
190
190
  "sensorId": sensorId,
191
- "sensorName": sensorId,
191
+ // "sensorName": sensorId,
192
192
  "status": status.rawValue,
193
193
  "rawData": [
194
194
  "transmitterName": transmitterName,
@@ -72,6 +72,7 @@ class AttachTransmitterViewController: UIViewController {
72
72
  }
73
73
 
74
74
  customTopView.onDemoTapped = {
75
+ NotificationCenter.default.post(name: Notification.Name("cgmwatchdemoclicked"), object: nil, userInfo: ["a":"a"])
75
76
  let webVC = WebViewController()
76
77
  webVC.modalPresentationStyle = .formSheet
77
78
  webVC.videoURL = URL(string: watchCGMVideo)
@@ -27,6 +27,7 @@ class ChatWithExpertViewController: UIViewController {
27
27
  super.viewDidLoad()
28
28
  // Do any additional setup after loading the view.
29
29
  setupLayout()
30
+
30
31
  }
31
32
 
32
33
  func setupLayout() {
@@ -43,6 +44,9 @@ class ChatWithExpertViewController: UIViewController {
43
44
  buttonBack.titleLabel?.font = FontManager.font(ofSize: 16, weight: .medium)
44
45
  bottomButton.labelText = "Proceed"
45
46
  bottomButton.showLeftWhatsappImage()
47
+
48
+ NotificationCenter.default.post(name: Notification.Name("cgmWAsupportclicked"), object: nil, userInfo: ["a":"a"])
49
+
46
50
  bottomButton.buttonTapCallback = {
47
51
 
48
52
  if let url = URL(string: "https://wa.aisensy.com/aaa1qv") {
@@ -99,6 +99,7 @@ class ConnectToSensorViewController: UIViewController {
99
99
  }
100
100
 
101
101
  customTopView.onDemoTapped = {
102
+ NotificationCenter.default.post(name: Notification.Name("cgmwatchdemoclicked"), object: nil, userInfo: ["a":"a"])
102
103
  let webVC = WebViewController()
103
104
  webVC.modalPresentationStyle = .formSheet
104
105
  webVC.videoURL = URL(string: watchCGMVideo)
@@ -96,12 +96,21 @@ class ConnectToTransmitterViewController: UIViewController, KLTBluetoothDelegate
96
96
  }
97
97
  bottomButton.buttonTapCallback = {
98
98
  if self.isForReconnect {
99
- let vc = ConnectToSensorViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
100
- vc.connected = {
101
- //self.showConfirmInsulinUser()
99
+ if self.bottomButton.labelText == "Retry" {
100
+ self.manager?.bluetoothDelegate = self
101
+ self.manager?.startScan()
102
+ self.screenType = .searching
103
+ self.tableView.reloadData()
104
+ self.bottomButton.hideRightArrow()
105
+ } else {
106
+ let vc = ConnectToSensorViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
107
+ vc.connected = {
108
+ //self.showConfirmInsulinUser()
109
+ }
110
+ vc.isFromReconnect = true
111
+ self.navigationController?.pushViewController(vc, animated: false)
102
112
  }
103
- vc.isFromReconnect = true
104
- self.navigationController?.pushViewController(vc, animated: false)
113
+
105
114
  // NotificationCenter.default.post(name: Notification.Name("cgmDeviceEvent"), object: nil, userInfo: ["a":"a"])
106
115
  // if let rootVC = UIApplication.shared.connectedScenes
107
116
  // .compactMap({ ($0 as? UIWindowScene)?.windows.first?.rootViewController })
@@ -112,6 +121,8 @@ class ConnectToTransmitterViewController: UIViewController, KLTBluetoothDelegate
112
121
  // }
113
122
  } else {
114
123
  if self.screenType == .error {
124
+ self.manager?.bluetoothDelegate = self
125
+ self.manager?.startScan()
115
126
  self.bottomButton.disable()
116
127
  self.screenType = .searching
117
128
  self.tableView.reloadData()
@@ -126,6 +137,7 @@ class ConnectToTransmitterViewController: UIViewController, KLTBluetoothDelegate
126
137
  }
127
138
 
128
139
  customTopView.onDemoTapped = {
140
+ NotificationCenter.default.post(name: Notification.Name("cgmwatchdemoclicked"), object: nil, userInfo: ["a":"a"])
129
141
  let webVC = WebViewController()
130
142
  webVC.modalPresentationStyle = .formSheet
131
143
  webVC.videoURL = URL(string: watchCGMVideo)
@@ -297,6 +309,7 @@ extension ConnectToTransmitterViewController: UITableViewDelegate, UITableViewDa
297
309
 
298
310
  //cell.labelDesc.text = "Sno:\(devices[indexPath.row].name)"
299
311
  cell.button.buttonTapCallback = {
312
+
300
313
  if self.isForReconnect {
301
314
  self.sensorForceEnd()
302
315
  }
@@ -304,7 +317,7 @@ extension ConnectToTransmitterViewController: UITableViewDelegate, UITableViewDa
304
317
  if !KLTLocalSettingManager.shareInstance().canConnectOtherDevice {
305
318
  return
306
319
  }
307
-
320
+
308
321
  self.manager?.stopScan()
309
322
  if self.foundDevices.count > indexPath.row {
310
323
  let peripheral = self.foundDevices[indexPath.row] as! CBPeripheral
@@ -45,11 +45,14 @@ class ProvidePermissionViewController: UIViewController {
45
45
 
46
46
  bottomButton.labelText = "Proceed"
47
47
  bottomButton.buttonTapCallback = {
48
+ let isForReconnect = UserDefaults.standard.bool(forKey: "isForReconnect")
48
49
  let vc = ConnectToTransmitterViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
50
+ vc.isForReconnect = isForReconnect
49
51
  self.navigationController?.pushViewController(vc, animated: false)
50
52
  }
51
53
 
52
54
  customTopView.onDemoTapped = {
55
+ NotificationCenter.default.post(name: Notification.Name("cgmwatchdemoclicked"), object: nil, userInfo: ["a":"a"])
53
56
  let webVC = WebViewController()
54
57
  webVC.modalPresentationStyle = .formSheet
55
58
  webVC.videoURL = URL(string: watchCGMVideo)
@@ -42,6 +42,7 @@ class PutOnTheSensorViewController: UIViewController {
42
42
  }
43
43
 
44
44
  customTopView.onDemoTapped = {
45
+ NotificationCenter.default.post(name: Notification.Name("cgmwatchdemoclicked"), object: nil, userInfo: ["a":"a"])
45
46
  let webVC = WebViewController()
46
47
  webVC.modalPresentationStyle = .formSheet
47
48
  webVC.videoURL = URL(string: watchCGMVideo)
@@ -51,8 +51,7 @@ class StartConnectionViewController: UIViewController {
51
51
  ImageTVC.self,
52
52
  ChargingIndicatorTVC.self])
53
53
  tableView.reloadData()
54
- // UserDefaults.standard.set(isLocationEnabled, forKey: "isForReconnect")
55
-
54
+
56
55
  let isForReconnect = UserDefaults.standard.bool(forKey: "isForReconnect")
57
56
  if isForReconnect{
58
57
  checkLocationPermission()
@@ -74,6 +73,7 @@ class StartConnectionViewController: UIViewController {
74
73
  }
75
74
 
76
75
  customTopView.onDemoTapped = {
76
+ NotificationCenter.default.post(name: Notification.Name("cgmwatchdemoclicked"), object: nil, userInfo: ["a":"a"])
77
77
  let webVC = WebViewController()
78
78
  webVC.modalPresentationStyle = .formSheet // or .pageSheet, .fullScreen
79
79
  webVC.videoURL = URL(string: watchCGMVideo)
@@ -95,7 +95,9 @@ class StartConnectionViewController: UIViewController {
95
95
 
96
96
  private func updateBottomButtonState() {
97
97
  if isBluetoothEnabled && isLocationEnabled {
98
+ let isForReconnect = UserDefaults.standard.bool(forKey: "isForReconnect")
98
99
  let vc = ConnectToTransmitterViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
100
+ vc.isForReconnect = isForReconnect
99
101
  self.navigationController?.pushViewController(vc, animated: false)
100
102
  } else {
101
103
  let vc = ProvidePermissionViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
@@ -105,29 +105,25 @@ import Foundation
105
105
  startDate: String,
106
106
  endDate: String
107
107
  ) -> [String: Any] {
108
- let updatedResponse = response
108
+ var updatedResponse = response
109
109
 
110
110
  if viewModel.isCurrentDateInRange(startDate: startDate, endDate: endDate) {
111
111
  print("Current date is in range")
112
- if ((viewModel.manager.connectedPeripheral == nil) && !KLTLocalSettingManager.shareInstance().canConnectOtherDevice) {
112
+
113
+ let canConnectOther = KLTLocalSettingManager.shareInstance().canConnectOtherDevice
114
+ let connectedPeripheral = viewModel.manager.connectedPeripheral
115
+
116
+ if connectedPeripheral == nil && !canConnectOther {
113
117
  viewModel.manager.startScan()
114
118
  viewModel.debouncer.update(with: .transmitterDisconnect)
115
- } else {
116
- print("here")
117
- //debouncer.update(with: .connected)
118
- //API.shared.sendStatus(status: .connected) 计算 算法入参
119
- if let last = viewModel.manager.currentDevice {
120
-
121
- }
122
- else {
123
-
124
- //self.manager.closeBleSensor()
125
- //manager.startScan()
126
- //self.debouncer.update(with: .disconnected)
127
- //debouncer.update(with: .transmitterDisconnectBox)
128
- }
129
-
130
- if KLTBluetoothManager.shared().currentDevice.connectedDateTime == nil && KLTBluetoothManager.shared().currentDevice.disconnectedDateTime == nil {
119
+ } else {
120
+ if let device = KLTBluetoothManager.shared().currentDevice {
121
+ if device.connectedDateTime == nil && device.disconnectedDateTime == nil {
122
+ viewModel.manager.startScan()
123
+ viewModel.debouncer.update(with: .transmitterDisconnect)
124
+ }
125
+ } else {
126
+ print("⚠️ currentDevice is nil")
131
127
  viewModel.manager.startScan()
132
128
  viewModel.debouncer.update(with: .transmitterDisconnect)
133
129
  }
@@ -136,9 +132,6 @@ import Foundation
136
132
 
137
133
  return updatedResponse
138
134
  }
139
-
140
-
141
-
142
135
  }
143
136
 
144
137
  class FinalViewModel: NSObject {
@@ -335,7 +328,7 @@ class FinalViewModel: NSObject {
335
328
  let batches = stride(from: 0, to: data.count, by: batchSize).map {
336
329
  Array(data[$0..<min($0 + batchSize, data.count)])
337
330
  }
338
-
331
+
339
332
  uploadBatch(batches: batches, index: 0)
340
333
  }
341
334
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mytatva-rn-sdk",
3
- "version": "1.2.45",
3
+ "version": "1.2.46",
4
4
  "description": "a package to inject data into visit health pwa",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",