cuoral-ionic 0.0.7 → 0.0.9

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 (44) hide show
  1. package/CuoralIonic.podspec +17 -0
  2. package/README.md +22 -0
  3. package/android/build/.transforms/bb54161301273cf9b5b94a21c0fb3f23/transformed/classes/classes_dex/classes.dex +0 -0
  4. package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$4.dex +0 -0
  5. package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$5.dex +0 -0
  6. package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$6.dex +0 -0
  7. package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin.dex +0 -0
  8. package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
  9. package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$4.class +0 -0
  10. package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$5.class +0 -0
  11. package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$6.class +0 -0
  12. package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin.class +0 -0
  13. package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$4.class +0 -0
  14. package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$5.class +0 -0
  15. package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$6.class +0 -0
  16. package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin.class +0 -0
  17. package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
  18. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/{CuoralPlugin$1.class.uniqueId1 → CuoralPlugin$1.class.uniqueId2} +0 -0
  19. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/{CuoralPlugin$2.class.uniqueId2 → CuoralPlugin$2.class.uniqueId5} +0 -0
  20. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$3.class.uniqueId3 +0 -0
  21. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$4.class.uniqueId6 +0 -0
  22. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$5.class.uniqueId4 +0 -0
  23. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$6.class.uniqueId8 +0 -0
  24. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$InitiateCallback.class.uniqueId0 +0 -0
  25. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$UploadCallback.class.uniqueId7 +0 -0
  26. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin.class.uniqueId1 +0 -0
  27. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  28. package/android/src/main/java/com/cuoral/ionic/CuoralPlugin.java +38 -35
  29. package/dist/bridge.d.ts.map +1 -1
  30. package/dist/cuoral.d.ts.map +1 -1
  31. package/dist/cuoral.js +31 -6
  32. package/dist/index.esm.js +75 -43
  33. package/dist/index.esm.js.map +1 -1
  34. package/dist/index.js +75 -43
  35. package/dist/index.js.map +1 -1
  36. package/dist/plugin.d.ts +2 -2
  37. package/dist/plugin.d.ts.map +1 -1
  38. package/dist/plugin.js +43 -39
  39. package/ios/Plugin/CuoralPlugin.swift +3 -3
  40. package/package.json +3 -2
  41. package/src/bridge.ts +1 -0
  42. package/src/cuoral.ts +33 -6
  43. package/src/plugin.ts +43 -38
  44. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin.class.uniqueId0 +0 -0
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CuoralIonic'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '13.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/README.md CHANGED
@@ -57,6 +57,28 @@ Add to your `Info.plist`:
57
57
 
58
58
  **Note:** Screen recording permission is requested automatically by iOS when recording starts. No additional permissions are needed for crash tracking or intelligence features.
59
59
 
60
+ ### 📱 Google Play Store Declaration (Android Only)
61
+
62
+ **IMPORTANT:** When submitting your app to Google Play Store, you'll be asked to declare why your app uses `FOREGROUND_SERVICE_MEDIA_PROJECTION` (screen recording permission).
63
+
64
+ **Quick Action:**
65
+ 1. Go to Play Console → **Policy** → **App Content** → **Foreground Service Types**
66
+ 2. Find `FOREGROUND_SERVICE_MEDIA_PROJECTION` → Click **Manage**
67
+ 3. Select category: **Customer Support / Bug Reporting**
68
+ 4. Use the justification text from [PLAY_STORE_QUICK_GUIDE.md](PLAY_STORE_QUICK_GUIDE.md)
69
+
70
+ **Why This is Required:**
71
+ - Screen recording is a "sensitive permission" that requires declaration
72
+ - Google wants to ensure it's used appropriately (which it is - user-initiated support)
73
+ - This is a simple form, not a special approval process
74
+ - No code changes needed - your app is already configured correctly
75
+
76
+ **📄 Documentation:**
77
+ - **Quick Guide:** [PLAY_STORE_QUICK_GUIDE.md](PLAY_STORE_QUICK_GUIDE.md) - Copy-paste justification text
78
+ - **Full Guide:** [PLAY_STORE_DECLARATION.md](PLAY_STORE_DECLARATION.md) - Complete information and privacy policy updates
79
+
80
+ **Note:** iOS App Store does not require this declaration.
81
+
60
82
  ## Quick Start
61
83
 
62
84
  ### Option 1: Modal with Floating Button (Recommended)
@@ -409,7 +409,7 @@ public class CuoralPlugin extends Plugin {
409
409
  if (autoUpload && !sessionId.isEmpty() && !publicKey.isEmpty()) {
410
410
  final String filePath = videoFilePath;
411
411
  final long finalDuration = duration;
412
-
412
+
413
413
  uploadRecording(filePath, sessionId, publicKey, customerId, (int) finalDuration, new UploadCallback() {
414
414
  @Override
415
415
  public void onSuccess() {
@@ -551,7 +551,9 @@ public class CuoralPlugin extends Plugin {
551
551
  mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
552
552
  mediaRecorder.setOutputFile(videoFilePath);
553
553
 
554
- int bitRate = (int) (6000000 * quality); // Base bitrate 6Mbps
554
+ // Optimized bitrate for screen recordings - 1.5 Mbps = ~11MB per minute
555
+ // 5 minutes = ~54MB (good quality, small size)
556
+ int bitRate = 1500000; // 1.5 Mbps (matches iOS settings)
555
557
  mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
556
558
  mediaRecorder.setVideoSize(metrics.widthPixels, metrics.heightPixels);
557
559
  mediaRecorder.setVideoFrameRate(30);
@@ -596,14 +598,15 @@ public class CuoralPlugin extends Plugin {
596
598
  // Upload callback interface
597
599
  private interface UploadCallback {
598
600
  void onSuccess();
601
+
599
602
  void onFailure(String error);
600
603
  }
601
604
 
602
605
  /**
603
606
  * Upload recording to Cuoral backend
604
607
  */
605
- private void uploadRecording(String filePath, String sessionId, String publicKey,
606
- String customerId, int duration, UploadCallback callback) {
608
+ private void uploadRecording(String filePath, String sessionId, String publicKey,
609
+ String customerId, int duration, UploadCallback callback) {
607
610
  File videoFile = new File(filePath);
608
611
  if (!videoFile.exists()) {
609
612
  callback.onFailure("File not found");
@@ -627,14 +630,15 @@ public class CuoralPlugin extends Plugin {
627
630
 
628
631
  private interface InitiateCallback {
629
632
  void onSuccess(String recordId);
633
+
630
634
  void onFailure(String error);
631
635
  }
632
636
 
633
637
  /**
634
638
  * Step 1: Initiate recording session
635
639
  */
636
- private void initiateRecording(String sessionId, String customerId, String publicKey,
637
- InitiateCallback callback) {
640
+ private void initiateRecording(String sessionId, String customerId, String publicKey,
641
+ InitiateCallback callback) {
638
642
  OkHttpClient client = new OkHttpClient();
639
643
 
640
644
  try {
@@ -643,17 +647,16 @@ public class CuoralPlugin extends Plugin {
643
647
  json.put("customer_id", customerId);
644
648
 
645
649
  RequestBody body = RequestBody.create(
646
- json.toString(),
647
- MediaType.parse("application/json")
648
- );
650
+ json.toString(),
651
+ MediaType.parse("application/json"));
649
652
 
650
653
  Request request = new Request.Builder()
651
- .url("https://api.cuoral.com/customer-intelligence/initiate/record")
652
- .post(body)
653
- .addHeader("Content-Type", "application/json")
654
- .addHeader("Accept", "*/*")
655
- .addHeader("x-org-id", publicKey)
656
- .build();
654
+ .url("https://api.cuoral.com/customer-intelligence/initiate/record")
655
+ .post(body)
656
+ .addHeader("Content-Type", "application/json")
657
+ .addHeader("Accept", "*/*")
658
+ .addHeader("x-org-id", publicKey)
659
+ .build();
657
660
 
658
661
  client.newCall(request).enqueue(new Callback() {
659
662
  @Override
@@ -672,7 +675,7 @@ public class CuoralPlugin extends Plugin {
672
675
  String responseBody = response.body().string();
673
676
  JSONObject json = new JSONObject(responseBody);
674
677
  String status = json.getString("status");
675
-
678
+
676
679
  if ("success".equals(status)) {
677
680
  String recordId = json.getString("record_id");
678
681
  callback.onSuccess(recordId);
@@ -692,29 +695,29 @@ public class CuoralPlugin extends Plugin {
692
695
  /**
693
696
  * Step 2: Upload video to the initiated recording
694
697
  */
695
- private void uploadVideo(File videoFile, String recordId, String publicKey,
696
- String customerId, int duration, UploadCallback callback) {
698
+ private void uploadVideo(File videoFile, String recordId, String publicKey,
699
+ String customerId, int duration, UploadCallback callback) {
697
700
  OkHttpClient client = new OkHttpClient.Builder()
698
- .connectTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
699
- .writeTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
700
- .readTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
701
- .build();
701
+ .connectTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
702
+ .writeTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
703
+ .readTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
704
+ .build();
702
705
 
703
706
  RequestBody requestBody = new MultipartBody.Builder()
704
- .setType(MultipartBody.FORM)
705
- .addFormDataPart("record_id", recordId)
706
- .addFormDataPart("console_error", "[]")
707
- .addFormDataPart("api_response_log", "[]")
708
- .addFormDataPart("page_view", "[]")
709
- .addFormDataPart("record_media", "recording.mp4",
710
- RequestBody.create(videoFile, MediaType.parse("video/mp4")))
711
- .build();
707
+ .setType(MultipartBody.FORM)
708
+ .addFormDataPart("record_id", recordId)
709
+ .addFormDataPart("console_error", "[]")
710
+ .addFormDataPart("api_response_log", "[]")
711
+ .addFormDataPart("page_view", "[]")
712
+ .addFormDataPart("record_media", "recording.mp4",
713
+ RequestBody.create(videoFile, MediaType.parse("video/mp4")))
714
+ .build();
712
715
 
713
716
  Request request = new Request.Builder()
714
- .url("https://api.cuoral.com/customer-intelligence/update/record")
715
- .post(requestBody)
716
- .addHeader("Accept", "*/*")
717
- .build();
717
+ .url("https://api.cuoral.com/customer-intelligence/update/record")
718
+ .post(requestBody)
719
+ .addHeader("Accept", "*/*")
720
+ .build();
718
721
 
719
722
  client.newCall(request).enqueue(new Callback() {
720
723
  @Override
@@ -733,7 +736,7 @@ public class CuoralPlugin extends Plugin {
733
736
  String responseBody = response.body().string();
734
737
  JSONObject json = new JSONObject(responseBody);
735
738
  String status = json.getString("status");
736
-
739
+
737
740
  if ("success".equals(status)) {
738
741
  callback.onSuccess();
739
742
  } else {
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzE;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,eAAe,CAAoE;IAC3F,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,YAAY,CAAkC;gBAE1C,MAAM,EAAE,YAAY;IAKhC;;OAEG;IACI,UAAU,IAAI,IAAI;IAgBzB;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAoBjD;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAyCjD;;OAEG;IACI,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAmB/E;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqC5B;;OAEG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;IACI,OAAO,IAAI,IAAI;CAKvB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,MAAM,CAAC,EAAE;YACP,eAAe,CAAC,EAAE;gBAChB,MAAM,CAAC,EAAE;oBACP,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;iBACrC,CAAC;aACH,CAAC;SACH,CAAC;KACH;CACF"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzE;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,eAAe,CAAoE;IAC3F,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,YAAY,CAAkC;gBAE1C,MAAM,EAAE,YAAY;IAKhC;;OAEG;IACI,UAAU,IAAI,IAAI;IAgBzB;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAoBjD;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAyCjD;;OAEG;IACI,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAmB/E;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAsC5B;;OAEG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;IACI,OAAO,IAAI,IAAI;CAKvB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,MAAM,CAAC,EAAE;YACP,eAAe,CAAC,EAAE;gBAChB,MAAM,CAAC,EAAE;oBACP,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;iBACrC,CAAC;aACH,CAAC;SACH,CAAC;KACH;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"cuoral.d.ts","sourceRoot":"","sources":["../src/cuoral.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAeD;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,KAAK,CAAC,CAAc;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAqB;IAC1C,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAuC;IACpF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAwB;gBAElD,OAAO,EAAE,aAAa;IAiDlC;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBxC;;OAEG;YACW,sBAAsB;IA2CpC;;OAEG;YACW,yBAAyB;IAoCvC;;OAEG;IACI,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAM1D;;OAEG;IACI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAM7E;;;;;OAKG;IACU,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA0C7E;;;OAGG;IACU,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/C;;;;OAIG;IACU,aAAa,IAAI,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,GAAG,IAAI,CAAC;IAiBxG;;OAEG;IACI,SAAS,IAAI,IAAI;IASxB;;OAEG;IACI,UAAU,IAAI,IAAI;IAMzB;;OAEG;IACI,WAAW,IAAI,OAAO;IAI7B;;OAEG;IACI,YAAY,IAAI,MAAM;IAuB7B;;OAEG;IACU,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA6C1C;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAsB5B;;OAEG;IACI,OAAO,IAAI,IAAI;IActB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;YACW,eAAe;IAkC7B;;OAEG;YACW,UAAU;IAmBxB;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAyF7B"}
1
+ {"version":3,"file":"cuoral.d.ts","sourceRoot":"","sources":["../src/cuoral.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAeD;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,KAAK,CAAC,CAAc;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAqB;IAC1C,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAuC;IACpF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAwB;gBAElD,OAAO,EAAE,aAAa;IA4DlC;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBxC;;OAEG;YACW,sBAAsB;IA2CpC;;OAEG;YACW,yBAAyB;IAoCvC;;OAEG;IACI,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAM1D;;OAEG;IACI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAM7E;;;;;OAKG;IACU,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA0C7E;;;OAGG;IACU,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/C;;;;OAIG;IACU,aAAa,IAAI,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,GAAG,IAAI,CAAC;IAiBxG;;OAEG;IACI,SAAS,IAAI,IAAI;IASxB;;OAEG;IACI,UAAU,IAAI,IAAI;IAMzB;;OAEG;IACI,WAAW,IAAI,OAAO;IAI7B;;OAEG;IACI,YAAY,IAAI,MAAM;IAuB7B;;OAEG;IACU,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA6C1C;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAsB5B;;OAEG;IACI,OAAO,IAAI,IAAI;IActB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;YACW,eAAe;IAkC7B;;OAEG;YACW,UAAU;IAmBxB;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAyG7B"}
package/dist/cuoral.js CHANGED
@@ -9,6 +9,7 @@ import { Capacitor } from '@capacitor/core';
9
9
  */
10
10
  export class Cuoral {
11
11
  constructor(options) {
12
+ console.log('[Cuoral] Constructor called with options:', options);
12
13
  // Check if running on a mobile platform
13
14
  if (!Capacitor.isNativePlatform()) {
14
15
  throw new Error('Cuoral Ionic library only works on native mobile platforms (iOS/Android). Web is not supported.');
@@ -18,6 +19,7 @@ export class Cuoral {
18
19
  useModal: true,
19
20
  ...options
20
21
  };
22
+ console.log('[Cuoral] Merged options:', this.options);
21
23
  // Determine widget base URL
22
24
  const baseUrl = options.widgetBaseUrl || Cuoral.PRODUCTION_WIDGET_URL;
23
25
  const params = new URLSearchParams({
@@ -47,8 +49,14 @@ export class Cuoral {
47
49
  debug: options.debug || false
48
50
  });
49
51
  this.recorder = new CuoralRecorder();
52
+ // Expose bridge on window for widget detection and debugging
53
+ window.CuoralCapacitorBridge = true;
54
+ window.__cuoralBridge = this.bridge; // For debugging
55
+ window.__cuoralRecorder = this.recorder; // For debugging
56
+ console.log('[Cuoral] Bridge and recorder created, exposed on window');
50
57
  // Setup automatic message handlers
51
58
  this.setupMessageHandlers();
59
+ console.log('[Cuoral] Constructor complete');
52
60
  }
53
61
  /**
54
62
  * Initialize Cuoral
@@ -443,28 +451,45 @@ export class Cuoral {
443
451
  setupMessageHandlers() {
444
452
  // Handle start recording requests from widget
445
453
  this.bridge.on(CuoralMessageType.START_RECORDING, async () => {
446
- const success = await this.recorder.startRecording();
447
- if (!success) {
448
- // Error already handled by recorder
454
+ // Pass sendMessages: false to prevent duplicate messages
455
+ const success = await this.recorder.startRecording(undefined, false);
456
+ if (success) {
457
+ // Send RECORDING_STARTED back to widget
458
+ this.bridge.sendToWidget({
459
+ type: CuoralMessageType.RECORDING_STARTED,
460
+ payload: {
461
+ timestamp: Date.now()
462
+ }
463
+ });
464
+ }
465
+ else {
466
+ this.bridge.sendToWidget({
467
+ type: CuoralMessageType.RECORDING_ERROR,
468
+ payload: {
469
+ error: 'Failed to start recording'
470
+ }
471
+ });
449
472
  }
450
473
  });
451
474
  // Handle stop recording requests from widget
452
475
  this.bridge.on(CuoralMessageType.STOP_RECORDING, async () => {
453
476
  const sessionId = localStorage.getItem('__x_loadID');
454
477
  const customerId = localStorage.getItem('cuoralCustomerId');
478
+ // Pass sendMessages: false to prevent duplicate messages
455
479
  const result = await this.recorder.stopRecording({
456
480
  autoUpload: true,
457
481
  sessionId: sessionId || undefined,
458
482
  publicKey: this.options.publicKey,
459
483
  customerId: customerId || undefined,
460
- });
484
+ }, false);
461
485
  if (result && result.uploaded) {
462
- // Video was automatically uploaded, just notify widget
486
+ // Video was automatically uploaded, notify widget with RECORDING_STOPPED
463
487
  this.bridge.sendToWidget({
464
- type: CuoralMessageType.RECORDING_UPLOADED,
488
+ type: CuoralMessageType.RECORDING_STOPPED,
465
489
  payload: {
466
490
  duration: result.duration,
467
491
  uploaded: true,
492
+ uploadedToBackend: true,
468
493
  timestamp: Date.now()
469
494
  }
470
495
  });
package/dist/index.esm.js CHANGED
@@ -44,7 +44,7 @@ class CuoralRecorder {
44
44
  /**
45
45
  * Start recording with automatic permission handling
46
46
  */
47
- async startRecording(options) {
47
+ async startRecording(options, sendMessages = true) {
48
48
  try {
49
49
  // Check if already recording
50
50
  if (this.isRecording) {
@@ -66,20 +66,24 @@ class CuoralRecorder {
66
66
  if (result.success) {
67
67
  this.isRecording = true;
68
68
  this.recordingStartTime = Date.now();
69
- // Post message to widget
70
- this.postMessage({
71
- type: CuoralMessageType.RECORDING_STARTED,
72
- payload: { timestamp: this.recordingStartTime },
73
- });
69
+ // Post message to widget only if enabled (disabled when called from widget handler)
70
+ if (sendMessages) {
71
+ this.postMessage({
72
+ type: CuoralMessageType.RECORDING_STARTED,
73
+ payload: { timestamp: this.recordingStartTime },
74
+ });
75
+ }
74
76
  }
75
77
  else {
76
78
  // Recording failed - reset state and notify widget
77
79
  this.isRecording = false;
78
80
  this.recordingStartTime = undefined;
79
- this.postMessage({
80
- type: CuoralMessageType.RECORDING_ERROR,
81
- payload: { error: 'Failed to start recording' },
82
- });
81
+ if (sendMessages) {
82
+ this.postMessage({
83
+ type: CuoralMessageType.RECORDING_ERROR,
84
+ payload: { error: 'Failed to start recording' },
85
+ });
86
+ }
83
87
  }
84
88
  return result.success;
85
89
  }
@@ -87,24 +91,28 @@ class CuoralRecorder {
87
91
  // Exception occurred - reset state and notify widget
88
92
  this.isRecording = false;
89
93
  this.recordingStartTime = undefined;
90
- this.postMessage({
91
- type: CuoralMessageType.RECORDING_ERROR,
92
- payload: { error: error.message },
93
- });
94
+ if (sendMessages) {
95
+ this.postMessage({
96
+ type: CuoralMessageType.RECORDING_ERROR,
97
+ payload: { error: error.message },
98
+ });
99
+ }
94
100
  return false;
95
101
  }
96
102
  }
97
103
  /**
98
104
  * Stop recording
99
105
  */
100
- async stopRecording(options) {
106
+ async stopRecording(options, sendMessages = true) {
101
107
  try {
102
108
  if (!this.isRecording) {
103
109
  // Send error message to widget so it can exit "stopping" state
104
- this.postMessage({
105
- type: CuoralMessageType.RECORDING_ERROR,
106
- payload: { error: 'Not recording' },
107
- });
110
+ if (sendMessages) {
111
+ this.postMessage({
112
+ type: CuoralMessageType.RECORDING_ERROR,
113
+ payload: { error: 'Not recording' },
114
+ });
115
+ }
108
116
  return null;
109
117
  }
110
118
  const result = await CuoralPlugin$1.stopRecording(options);
@@ -113,23 +121,15 @@ class CuoralRecorder {
113
121
  const duration = this.recordingStartTime
114
122
  ? Math.floor((Date.now() - this.recordingStartTime) / 1000)
115
123
  : 0;
116
- // If uploaded, notify widget differently
117
- if (result.uploaded) {
118
- this.postMessage({
119
- type: CuoralMessageType.RECORDING_UPLOADED,
120
- payload: {
121
- duration: result.duration || duration,
122
- uploaded: true
123
- },
124
- });
125
- }
126
- else {
127
- // Post message to widget (old behavior)
124
+ // Send RECORDING_STOPPED message only if enabled
125
+ if (sendMessages) {
128
126
  this.postMessage({
129
127
  type: CuoralMessageType.RECORDING_STOPPED,
130
128
  payload: {
131
129
  filePath: result.filePath,
132
130
  duration: result.duration || duration,
131
+ uploaded: result.uploaded,
132
+ uploadedToBackend: result.uploaded,
133
133
  },
134
134
  });
135
135
  }
@@ -140,18 +140,22 @@ class CuoralRecorder {
140
140
  };
141
141
  }
142
142
  // If result.success is false, send error to widget
143
- this.postMessage({
144
- type: CuoralMessageType.RECORDING_ERROR,
145
- payload: { error: 'Failed to stop recording' },
146
- });
143
+ if (sendMessages) {
144
+ this.postMessage({
145
+ type: CuoralMessageType.RECORDING_ERROR,
146
+ payload: { error: 'Failed to stop recording' },
147
+ });
148
+ }
147
149
  return null;
148
150
  }
149
151
  catch (error) {
150
152
  console.error('[Cuoral] Failed to stop recording:', error);
151
- this.postMessage({
152
- type: CuoralMessageType.RECORDING_ERROR,
153
- payload: { error: error.message },
154
- });
153
+ if (sendMessages) {
154
+ this.postMessage({
155
+ type: CuoralMessageType.RECORDING_ERROR,
156
+ payload: { error: error.message },
157
+ });
158
+ }
155
159
  return null;
156
160
  }
157
161
  }
@@ -1430,6 +1434,7 @@ class CuoralIntelligence {
1430
1434
  */
1431
1435
  class Cuoral {
1432
1436
  constructor(options) {
1437
+ console.log('[Cuoral] Constructor called with options:', options);
1433
1438
  // Check if running on a mobile platform
1434
1439
  if (!Capacitor.isNativePlatform()) {
1435
1440
  throw new Error('Cuoral Ionic library only works on native mobile platforms (iOS/Android). Web is not supported.');
@@ -1439,6 +1444,7 @@ class Cuoral {
1439
1444
  useModal: true,
1440
1445
  ...options
1441
1446
  };
1447
+ console.log('[Cuoral] Merged options:', this.options);
1442
1448
  // Determine widget base URL
1443
1449
  const baseUrl = options.widgetBaseUrl || Cuoral.PRODUCTION_WIDGET_URL;
1444
1450
  const params = new URLSearchParams({
@@ -1468,8 +1474,14 @@ class Cuoral {
1468
1474
  debug: options.debug || false
1469
1475
  });
1470
1476
  this.recorder = new CuoralRecorder();
1477
+ // Expose bridge on window for widget detection and debugging
1478
+ window.CuoralCapacitorBridge = true;
1479
+ window.__cuoralBridge = this.bridge; // For debugging
1480
+ window.__cuoralRecorder = this.recorder; // For debugging
1481
+ console.log('[Cuoral] Bridge and recorder created, exposed on window');
1471
1482
  // Setup automatic message handlers
1472
1483
  this.setupMessageHandlers();
1484
+ console.log('[Cuoral] Constructor complete');
1473
1485
  }
1474
1486
  /**
1475
1487
  * Initialize Cuoral
@@ -1864,25 +1876,45 @@ class Cuoral {
1864
1876
  setupMessageHandlers() {
1865
1877
  // Handle start recording requests from widget
1866
1878
  this.bridge.on(CuoralMessageType.START_RECORDING, async () => {
1867
- await this.recorder.startRecording();
1879
+ // Pass sendMessages: false to prevent duplicate messages
1880
+ const success = await this.recorder.startRecording(undefined, false);
1881
+ if (success) {
1882
+ // Send RECORDING_STARTED back to widget
1883
+ this.bridge.sendToWidget({
1884
+ type: CuoralMessageType.RECORDING_STARTED,
1885
+ payload: {
1886
+ timestamp: Date.now()
1887
+ }
1888
+ });
1889
+ }
1890
+ else {
1891
+ this.bridge.sendToWidget({
1892
+ type: CuoralMessageType.RECORDING_ERROR,
1893
+ payload: {
1894
+ error: 'Failed to start recording'
1895
+ }
1896
+ });
1897
+ }
1868
1898
  });
1869
1899
  // Handle stop recording requests from widget
1870
1900
  this.bridge.on(CuoralMessageType.STOP_RECORDING, async () => {
1871
1901
  const sessionId = localStorage.getItem('__x_loadID');
1872
1902
  const customerId = localStorage.getItem('cuoralCustomerId');
1903
+ // Pass sendMessages: false to prevent duplicate messages
1873
1904
  const result = await this.recorder.stopRecording({
1874
1905
  autoUpload: true,
1875
1906
  sessionId: sessionId || undefined,
1876
1907
  publicKey: this.options.publicKey,
1877
1908
  customerId: customerId || undefined,
1878
- });
1909
+ }, false);
1879
1910
  if (result && result.uploaded) {
1880
- // Video was automatically uploaded, just notify widget
1911
+ // Video was automatically uploaded, notify widget with RECORDING_STOPPED
1881
1912
  this.bridge.sendToWidget({
1882
- type: CuoralMessageType.RECORDING_UPLOADED,
1913
+ type: CuoralMessageType.RECORDING_STOPPED,
1883
1914
  payload: {
1884
1915
  duration: result.duration,
1885
1916
  uploaded: true,
1917
+ uploadedToBackend: true,
1886
1918
  timestamp: Date.now()
1887
1919
  }
1888
1920
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}