@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
- if (packageInfo.firstInstallTime == packageInfo.lastUpdateTime) {
207
- Log.d("StreamCallPlugin", "Fresh install detected, clearing user credentials.")
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 update or existing installation detected")
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 ${ret}")
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-stream-call",
3
- "version": "0.0.90",
3
+ "version": "0.0.92",
4
4
  "description": "Uses the https://getstream.io/ SDK to implement calling in Capacitor",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",