@poolse/react-native 2.8.2 → 2.8.3

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/dist/index.d.cts CHANGED
@@ -1171,12 +1171,25 @@ interface VoipPushModule {
1171
1171
  addEventListener(event: string, handler: (payload: unknown) => void): void;
1172
1172
  removeEventListener(event: string): void;
1173
1173
  registerVoipToken(): void;
1174
+ /**
1175
+ * Releases the native PushKit completion handler for a push.
1176
+ *
1177
+ * iOS hands `didReceiveIncomingPushWith` a completion block and expects
1178
+ * it back once the call has been reported. Never calling it leaves the
1179
+ * app looking like it dropped the push, which is one of the ways iOS
1180
+ * stops delivering VoIP pushes to an app entirely.
1181
+ *
1182
+ * Optional because older versions of the module don't expose it.
1183
+ */
1184
+ onVoipNotificationCompleted?(uuid: string): void;
1174
1185
  }
1175
1186
  /** The slice of `react-native-callkeep` used here. */
1176
1187
  interface CallKeepModule {
1177
1188
  setup(options: unknown): Promise<unknown>;
1178
1189
  displayIncomingCall(uuid: string, handle: string, localizedCallerName?: string, handleType?: string, hasVideo?: boolean): unknown;
1179
1190
  endCall(uuid: string): unknown;
1191
+ /** Tell CallKit the call connected. Absent on older versions. */
1192
+ setCurrentCallActive?(uuid: string): unknown;
1180
1193
  addEventListener(event: string, handler: (payload: unknown) => void): void;
1181
1194
  removeEventListener(event: string): void;
1182
1195
  }
@@ -1231,18 +1244,6 @@ interface UseVoipCallsOptions {
1231
1244
  */
1232
1245
  staleAfterMs?: number;
1233
1246
  }
1234
- /**
1235
- * Whether a pushed call is old enough to be dismissed straight after
1236
- * being reported.
1237
- *
1238
- * Exported for testing, because getting this wrong is silent and total:
1239
- * too tight a window and clock skew between the server and the handset
1240
- * suppresses live calls with nothing in the app to explain it.
1241
- *
1242
- * Never dismisses on a missing timestamp, and never on a future one —
1243
- * skew runs both ways, and withholding a real call is far worse than
1244
- * ringing once for a dead one.
1245
- */
1246
1247
  declare function isStalePush(sentAt: number | undefined, now: number, staleAfterMs: number): boolean;
1247
1248
  /**
1248
1249
  * Registers this device for VoIP pushes and drives the native call UI.
package/dist/index.d.ts CHANGED
@@ -1171,12 +1171,25 @@ interface VoipPushModule {
1171
1171
  addEventListener(event: string, handler: (payload: unknown) => void): void;
1172
1172
  removeEventListener(event: string): void;
1173
1173
  registerVoipToken(): void;
1174
+ /**
1175
+ * Releases the native PushKit completion handler for a push.
1176
+ *
1177
+ * iOS hands `didReceiveIncomingPushWith` a completion block and expects
1178
+ * it back once the call has been reported. Never calling it leaves the
1179
+ * app looking like it dropped the push, which is one of the ways iOS
1180
+ * stops delivering VoIP pushes to an app entirely.
1181
+ *
1182
+ * Optional because older versions of the module don't expose it.
1183
+ */
1184
+ onVoipNotificationCompleted?(uuid: string): void;
1174
1185
  }
1175
1186
  /** The slice of `react-native-callkeep` used here. */
1176
1187
  interface CallKeepModule {
1177
1188
  setup(options: unknown): Promise<unknown>;
1178
1189
  displayIncomingCall(uuid: string, handle: string, localizedCallerName?: string, handleType?: string, hasVideo?: boolean): unknown;
1179
1190
  endCall(uuid: string): unknown;
1191
+ /** Tell CallKit the call connected. Absent on older versions. */
1192
+ setCurrentCallActive?(uuid: string): unknown;
1180
1193
  addEventListener(event: string, handler: (payload: unknown) => void): void;
1181
1194
  removeEventListener(event: string): void;
1182
1195
  }
@@ -1231,18 +1244,6 @@ interface UseVoipCallsOptions {
1231
1244
  */
1232
1245
  staleAfterMs?: number;
1233
1246
  }
1234
- /**
1235
- * Whether a pushed call is old enough to be dismissed straight after
1236
- * being reported.
1237
- *
1238
- * Exported for testing, because getting this wrong is silent and total:
1239
- * too tight a window and clock skew between the server and the handset
1240
- * suppresses live calls with nothing in the app to explain it.
1241
- *
1242
- * Never dismisses on a missing timestamp, and never on a future one —
1243
- * skew runs both ways, and withholding a real call is far worse than
1244
- * ringing once for a dead one.
1245
- */
1246
1247
  declare function isStalePush(sentAt: number | undefined, now: number, staleAfterMs: number): boolean;
1247
1248
  /**
1248
1249
  * Registers this device for VoIP pushes and drives the native call UI.
package/dist/index.js CHANGED
@@ -5209,6 +5209,10 @@ var styles24 = StyleSheet.create({
5209
5209
  callBtnText: { color: "#ffffff", fontSize: 16, fontWeight: "600" },
5210
5210
  warn: { fontSize: 12, textAlign: "center", marginTop: 12 }
5211
5211
  });
5212
+ function isCallOver(phase) {
5213
+ if (phase === void 0) return false;
5214
+ return phase !== "ringing-in" && phase !== "ringing-out" && phase !== "active";
5215
+ }
5212
5216
  function isStalePush(sentAt, now, staleAfterMs) {
5213
5217
  if (typeof sentAt !== "number" || !Number.isFinite(sentAt)) return false;
5214
5218
  const age = now - sentAt;
@@ -5254,7 +5258,14 @@ function useVoipCalls({
5254
5258
  } catch {
5255
5259
  }
5256
5260
  };
5257
- void ready.current.then(show, show);
5261
+ const done = () => {
5262
+ show();
5263
+ try {
5264
+ voipPush.onVoipNotificationCompleted?.(call.callId);
5265
+ } catch {
5266
+ }
5267
+ };
5268
+ void ready.current.then(done, done);
5258
5269
  if (isStalePush(sentAt, Date.now(), staleRef.current)) dismiss.current(call.callId);
5259
5270
  });
5260
5271
  useEffect(() => {
@@ -5305,7 +5316,10 @@ function useVoipCalls({
5305
5316
  }));
5306
5317
  callKeep.addEventListener("answerCall", (({ callUUID }) => {
5307
5318
  const call = shown.current.get(callUUID);
5308
- shown.current.delete(callUUID);
5319
+ try {
5320
+ callKeep.setCurrentCallActive?.(callUUID);
5321
+ } catch {
5322
+ }
5309
5323
  if (!call) {
5310
5324
  void handlers.current.calls?.accept();
5311
5325
  return;
@@ -5354,7 +5368,7 @@ function useVoipCalls({
5354
5368
  }
5355
5369
  }, [phase, incoming]);
5356
5370
  useEffect(() => {
5357
- if (phase === "ringing-in" || phase === "ringing-out") return;
5371
+ if (!isCallOver(phase)) return;
5358
5372
  for (const callId of [...shown.current.keys()]) dismiss.current(callId);
5359
5373
  }, [phase]);
5360
5374
  }