@poolse/react-native 2.2.0 → 2.4.0

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.cjs CHANGED
@@ -4942,32 +4942,22 @@ function useAppStateLifecycle() {
4942
4942
  }
4943
4943
 
4944
4944
  // src/voice/webrtc-native.ts
4945
- var cached;
4946
- function loadNativeWebRtc() {
4947
- if (cached !== void 0) return cached;
4948
- try {
4949
- cached = __require("react-native-webrtc");
4950
- } catch {
4951
- cached = null;
4952
- }
4953
- return cached;
4945
+ function isNativeWebRtcAvailable(mod) {
4946
+ return typeof mod?.RTCPeerConnection === "function" && mod?.mediaDevices != null;
4954
4947
  }
4955
- function isNativeWebRtcAvailable() {
4956
- return loadNativeWebRtc() != null;
4957
- }
4958
- function createNativeWebRtcAdapter() {
4959
- const native = loadNativeWebRtc();
4960
- if (!native) {
4948
+ function createNativeWebRtcAdapter(mod) {
4949
+ if (!isNativeWebRtcAvailable(mod)) {
4961
4950
  throw new Error(
4962
- "react-native-webrtc is not installed. Add it to enable poolse voice calls:\n npx expo install react-native-webrtc\nIt contains native code, so it needs a development build \u2014 it will not run in Expo Go."
4951
+ "react-native-webrtc is missing or not linked. Install it and rebuild:\n npx expo install react-native-webrtc\nIt contains native code, so it needs a development build \u2014 it will not run in Expo Go."
4963
4952
  );
4964
4953
  }
4954
+ const rtc = mod;
4965
4955
  return {
4966
4956
  createPeerConnection(iceServers) {
4967
- return new native.RTCPeerConnection({ iceServers });
4957
+ return new rtc.RTCPeerConnection({ iceServers });
4968
4958
  },
4969
4959
  getUserMedia() {
4970
- return native.mediaDevices.getUserMedia({
4960
+ return rtc.mediaDevices.getUserMedia({
4971
4961
  audio: { echoCancellation: true, noiseSuppression: true },
4972
4962
  video: false
4973
4963
  });
@@ -4978,12 +4968,17 @@ function createNativeWebRtcAdapter() {
4978
4968
  }
4979
4969
  };
4980
4970
  }
4981
- function VoiceRoomBar({ conversationId, labelFor, unavailableSlot }) {
4971
+ function VoiceRoomBar({
4972
+ conversationId,
4973
+ labelFor,
4974
+ unavailableSlot,
4975
+ webrtc
4976
+ }) {
4982
4977
  const theme = usePoolseTheme();
4983
- const available = isNativeWebRtcAvailable();
4978
+ const available = isNativeWebRtcAvailable(webrtc);
4984
4979
  const opts = react.useMemo(
4985
- () => available ? { webrtc: createNativeWebRtcAdapter() } : {},
4986
- [available]
4980
+ () => available && webrtc ? { webrtc: createNativeWebRtcAdapter(webrtc) } : {},
4981
+ [available, webrtc]
4987
4982
  );
4988
4983
  const { status, participants, muted, join, leave, toggleMute, error } = react$1.useVoiceRoom(
4989
4984
  available ? conversationId : null,
@@ -5111,14 +5106,14 @@ var styles23 = reactNative.StyleSheet.create({
5111
5106
  hint: { fontSize: 13, flexShrink: 1 },
5112
5107
  error: { fontSize: 12, marginTop: 6 }
5113
5108
  });
5114
- function CallScreen({ userId, labelFor, calls: external }) {
5109
+ function CallScreen({ userId, labelFor, calls: external, webrtc }) {
5115
5110
  const theme = usePoolseTheme();
5116
5111
  const own = react$1.useCalls(external ? null : userId);
5117
5112
  const calls = external ?? own;
5118
- const available = isNativeWebRtcAvailable();
5113
+ const available = isNativeWebRtcAvailable(webrtc);
5119
5114
  const opts = react.useMemo(
5120
- () => available ? { webrtc: createNativeWebRtcAdapter() } : {},
5121
- [available]
5115
+ () => available && webrtc ? { webrtc: createNativeWebRtcAdapter(webrtc) } : {},
5116
+ [available, webrtc]
5122
5117
  );
5123
5118
  const voice = react$1.useVoiceRoom(
5124
5119
  calls.phase === "active" && available ? calls.activeConversationId : null,
@@ -5226,6 +5221,81 @@ var styles24 = reactNative.StyleSheet.create({
5226
5221
  callBtnText: { color: "#ffffff", fontSize: 16, fontWeight: "600" },
5227
5222
  warn: { fontSize: 12, textAlign: "center", marginTop: 12 }
5228
5223
  });
5224
+ function useVoipCalls({
5225
+ voipPush,
5226
+ callKeep,
5227
+ onAnswer,
5228
+ onDecline,
5229
+ appName = "poolse"
5230
+ }) {
5231
+ const poolse = react$1.usePoolse();
5232
+ const pending = react.useRef(/* @__PURE__ */ new Map());
5233
+ const handlers = react.useRef({ onAnswer, onDecline });
5234
+ handlers.current = { onAnswer, onDecline };
5235
+ react.useEffect(() => {
5236
+ let cancelled = false;
5237
+ const reportCall = (payload) => {
5238
+ const callId = payload.call_id;
5239
+ const conversationId = payload.conversation_id;
5240
+ if (!callId || !conversationId) return;
5241
+ const call = {
5242
+ callId,
5243
+ conversationId,
5244
+ callerUserId: payload.caller_user_id ?? "",
5245
+ callerName: payload.caller_name ?? "Incoming call"
5246
+ };
5247
+ pending.current.set(callId, call);
5248
+ callKeep.displayIncomingCall(callId, call.callerUserId, call.callerName, "generic", false);
5249
+ };
5250
+ void callKeep.setup({
5251
+ ios: { appName },
5252
+ android: {
5253
+ alertTitle: "Permissions required",
5254
+ alertDescription: "Allow calls from this app",
5255
+ cancelButton: "Cancel",
5256
+ okButton: "ok",
5257
+ additionalPermissions: []
5258
+ }
5259
+ }).catch(() => {
5260
+ });
5261
+ voipPush.addEventListener("register", ((token) => {
5262
+ if (cancelled || !token) return;
5263
+ void poolse.devices.register({ token, platform: "ios", environment: apnsEnvironment() }).catch(() => {
5264
+ });
5265
+ }));
5266
+ voipPush.addEventListener("notification", ((payload) => {
5267
+ reportCall(payload);
5268
+ }));
5269
+ voipPush.addEventListener("didLoadWithEvents", ((events) => {
5270
+ for (const event of events ?? []) {
5271
+ if (event.name === "RNVoipPushRemoteNotificationReceivedEvent") {
5272
+ reportCall(event.data);
5273
+ }
5274
+ }
5275
+ }));
5276
+ callKeep.addEventListener("answerCall", (({ callUUID }) => {
5277
+ const call = pending.current.get(callUUID);
5278
+ if (call) handlers.current.onAnswer?.(call);
5279
+ }));
5280
+ callKeep.addEventListener("endCall", (({ callUUID }) => {
5281
+ const call = pending.current.get(callUUID);
5282
+ pending.current.delete(callUUID);
5283
+ if (call) handlers.current.onDecline?.(call);
5284
+ }));
5285
+ voipPush.registerVoipToken();
5286
+ return () => {
5287
+ cancelled = true;
5288
+ voipPush.removeEventListener("register");
5289
+ voipPush.removeEventListener("notification");
5290
+ voipPush.removeEventListener("didLoadWithEvents");
5291
+ callKeep.removeEventListener("answerCall");
5292
+ callKeep.removeEventListener("endCall");
5293
+ };
5294
+ }, [poolse, voipPush, callKeep, appName]);
5295
+ }
5296
+ function apnsEnvironment() {
5297
+ return __DEV__ ? "sandbox" : "production";
5298
+ }
5229
5299
 
5230
5300
  exports.AttachmentPicker = AttachmentPicker;
5231
5301
  exports.AttachmentPreview = AttachmentPreview;
@@ -5263,5 +5333,6 @@ exports.isNativeWebRtcAvailable = isNativeWebRtcAvailable;
5263
5333
  exports.useAppStateLifecycle = useAppStateLifecycle;
5264
5334
  exports.useDisplayName = useDisplayName;
5265
5335
  exports.usePoolseTheme = usePoolseTheme;
5336
+ exports.useVoipCalls = useVoipCalls;
5266
5337
  //# sourceMappingURL=index.cjs.map
5267
5338
  //# sourceMappingURL=index.cjs.map