@capgo/capacitor-stream-call 0.0.90 → 0.0.92
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.
|
@@ -203,11 +203,15 @@ class StreamCallPlugin : Plugin() {
|
|
|
203
203
|
Log.d("StreamCallPlugin", "Plugin load() called")
|
|
204
204
|
try {
|
|
205
205
|
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
// More robust fresh install detection - only clear credentials if:
|
|
207
|
+
// 1. It's actually a fresh install (first == last install time)
|
|
208
|
+
// 2. AND we don't already have stored credentials (to avoid clearing on restart)
|
|
209
|
+
val savedCredentials = SecureUserRepository.getInstance(context).loadCurrentUser()
|
|
210
|
+
if (packageInfo.firstInstallTime == packageInfo.lastUpdateTime && savedCredentials == null) {
|
|
211
|
+
Log.d("StreamCallPlugin", "True fresh install detected (no existing credentials), clearing any residual user credentials.")
|
|
208
212
|
SecureUserRepository.getInstance(context).removeCurrentUser()
|
|
209
213
|
} else {
|
|
210
|
-
Log.d("StreamCallPlugin", "App
|
|
214
|
+
Log.d("StreamCallPlugin", "App restart or existing installation detected, preserving credentials")
|
|
211
215
|
}
|
|
212
216
|
} catch (e: Exception) {
|
|
213
217
|
Log.e("StreamCallPlugin", "Error checking for fresh install", e)
|
|
@@ -2524,7 +2528,7 @@ class StreamCallPlugin : Plugin() {
|
|
|
2524
2528
|
ret.put("isLoggedIn", false)
|
|
2525
2529
|
}
|
|
2526
2530
|
|
|
2527
|
-
Log.d("StreamCallPlugin", "getCurrentUser: Returning $
|
|
2531
|
+
Log.d("StreamCallPlugin", "getCurrentUser: Returning $ret")
|
|
2528
2532
|
call.resolve(ret)
|
|
2529
2533
|
} catch (e: Exception) {
|
|
2530
2534
|
Log.e("StreamCallPlugin", "getCurrentUser: Failed to get current user", e)
|
|
@@ -2539,6 +2543,39 @@ class StreamCallPlugin : Plugin() {
|
|
|
2539
2543
|
p.savedContext = ctx
|
|
2540
2544
|
p.initializeStreamVideo(ctx, app)
|
|
2541
2545
|
holder = p
|
|
2546
|
+
|
|
2547
|
+
// Register lifecycle callback to clean up when all activities are destroyed
|
|
2548
|
+
app.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
|
|
2549
|
+
private var activityCount = 0
|
|
2550
|
+
|
|
2551
|
+
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
|
2552
|
+
activityCount++
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
override fun onActivityDestroyed(activity: Activity) {
|
|
2556
|
+
activityCount--
|
|
2557
|
+
// Only clear holder when no activities remain AND no active/ringing calls
|
|
2558
|
+
if (activityCount <= 0) {
|
|
2559
|
+
val hasActiveCalls = holder?.let { plugin ->
|
|
2560
|
+
val client = plugin.streamVideoClient
|
|
2561
|
+
val hasActive = client?.state?.activeCall?.value != null
|
|
2562
|
+
val hasRinging = client?.state?.ringingCall?.value != null
|
|
2563
|
+
hasActive || hasRinging
|
|
2564
|
+
} ?: false
|
|
2565
|
+
|
|
2566
|
+
if (!hasActiveCalls) {
|
|
2567
|
+
holder = null
|
|
2568
|
+
app.unregisterActivityLifecycleCallbacks(this)
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
|
|
2573
|
+
override fun onActivityStarted(activity: Activity) {}
|
|
2574
|
+
override fun onActivityResumed(activity: Activity) {}
|
|
2575
|
+
override fun onActivityPaused(activity: Activity) {}
|
|
2576
|
+
override fun onActivityStopped(activity: Activity) {}
|
|
2577
|
+
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
|
2578
|
+
})
|
|
2542
2579
|
}
|
|
2543
2580
|
}
|
|
2544
2581
|
private var holder: StreamCallPlugin? = null
|
|
@@ -80,6 +80,14 @@ class TouchInterceptView: UIView {
|
|
|
80
80
|
const x = \(x); const y = \(y);
|
|
81
81
|
const el = document.elementFromPoint(x, y);
|
|
82
82
|
if (!el) return 'NO_ELEM';
|
|
83
|
+
|
|
84
|
+
// iPad fix: Force active state since iPad Safari doesn't handle :active properly
|
|
85
|
+
const isIPad = navigator.userAgent.includes('iPad');
|
|
86
|
+
if (isIPad) {
|
|
87
|
+
el.classList.add('active');
|
|
88
|
+
if (el.style.setProperty) el.style.setProperty('opacity', '0.8', 'important');
|
|
89
|
+
}
|
|
90
|
+
|
|
83
91
|
const eventInit = { bubbles: true, cancelable: true, clientX: x, clientY: y };
|
|
84
92
|
const touchInit = { bubbles: true, cancelable: true, touches: [{ clientX: x, clientY: y }], targetTouches: [], changedTouches: [], shiftKey: false };
|
|
85
93
|
const seq = [];
|
|
@@ -95,6 +103,15 @@ class TouchInterceptView: UIView {
|
|
|
95
103
|
seq.push(new MouseEvent('mouseup', eventInit));
|
|
96
104
|
seq.push(new MouseEvent('click', eventInit));
|
|
97
105
|
seq.forEach(evt => el.dispatchEvent(evt));
|
|
106
|
+
|
|
107
|
+
// iPad cleanup
|
|
108
|
+
if (isIPad) {
|
|
109
|
+
setTimeout(() => {
|
|
110
|
+
el.classList.remove('active');
|
|
111
|
+
el.style.removeProperty('opacity');
|
|
112
|
+
}, 100);
|
|
113
|
+
}
|
|
114
|
+
|
|
98
115
|
console.log('SyntheticClick seq on', el);
|
|
99
116
|
return el.tagName;
|
|
100
117
|
})();
|
package/package.json
CHANGED