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.
- package/CuoralIonic.podspec +17 -0
- package/README.md +22 -0
- package/android/build/.transforms/bb54161301273cf9b5b94a21c0fb3f23/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$4.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$5.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin$6.dex +0 -0
- package/android/build/.transforms/f1aabffcd8b03aa664e77a79b3e1de5d/transformed/debug/debug_dex/com/cuoral/ionic/CuoralPlugin.dex +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$4.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$5.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$6.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$4.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$5.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin$6.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/cuoral/ionic/CuoralPlugin.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/{CuoralPlugin$1.class.uniqueId1 → CuoralPlugin$1.class.uniqueId2} +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/{CuoralPlugin$2.class.uniqueId2 → CuoralPlugin$2.class.uniqueId5} +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$3.class.uniqueId3 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$4.class.uniqueId6 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$5.class.uniqueId4 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$6.class.uniqueId8 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$InitiateCallback.class.uniqueId0 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin$UploadCallback.class.uniqueId7 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/CuoralPlugin.class.uniqueId1 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/src/main/java/com/cuoral/ionic/CuoralPlugin.java +38 -35
- package/dist/bridge.d.ts.map +1 -1
- package/dist/cuoral.d.ts.map +1 -1
- package/dist/cuoral.js +31 -6
- package/dist/index.esm.js +75 -43
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +75 -43
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +43 -39
- package/ios/Plugin/CuoralPlugin.swift +3 -3
- package/package.json +3 -2
- package/src/bridge.ts +1 -0
- package/src/cuoral.ts +33 -6
- package/src/plugin.ts +43 -38
- 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)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$4.class
CHANGED
|
Binary file
|
package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$5.class
CHANGED
|
Binary file
|
package/android/build/intermediates/javac/debug/classes/com/cuoral/ionic/CuoralPlugin$6.class
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
647
|
-
|
|
648
|
-
);
|
|
650
|
+
json.toString(),
|
|
651
|
+
MediaType.parse("application/json"));
|
|
649
652
|
|
|
650
653
|
Request request = new Request.Builder()
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
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
|
-
|
|
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
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
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
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
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
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
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 {
|
package/dist/bridge.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/cuoral.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
447
|
-
|
|
448
|
-
|
|
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,
|
|
486
|
+
// Video was automatically uploaded, notify widget with RECORDING_STOPPED
|
|
463
487
|
this.bridge.sendToWidget({
|
|
464
|
-
type: CuoralMessageType.
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
//
|
|
117
|
-
if (
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
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,
|
|
1911
|
+
// Video was automatically uploaded, notify widget with RECORDING_STOPPED
|
|
1881
1912
|
this.bridge.sendToWidget({
|
|
1882
|
-
type: CuoralMessageType.
|
|
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
|
});
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|