@poolse/react-native 2.3.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.d.cts CHANGED
@@ -1098,4 +1098,81 @@ interface CallScreenProps {
1098
1098
  */
1099
1099
  declare function CallScreen({ userId, labelFor, calls: external, webrtc }: CallScreenProps): react_jsx_runtime.JSX.Element;
1100
1100
 
1101
- export { AttachmentPicker, type AttachmentPickerProps, AttachmentPreview, type AttachmentPreviewProps, Avatar, type AvatarProps, CallScreen, type CallScreenProps, ChatHeader, type ChatHeaderProps, ConversationList, type ConversationListProps, ConversationView, type ConversationViewProps, DaySeparator, type DaySeparatorProps, GroupDetailsSheet, type GroupDetailsSheetProps, type IconName, ImageMosaic, type ImageMosaicProps, type InboxUser, MemberList, type MemberListProps, MentionInput, type MentionInputProps, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerProps, MessageList, type MessageListItem, type MessageListProps, MessageRow, type MessageRowProps, type NativeWebRtcModule, PoolseIcon, type PoolseIconProps, PoolseInbox, type PoolseInboxHandle, type PoolseInboxProps, PoolseLogo, type PoolseLogoProps, type PoolseLogoVariant, type PoolseRNTheme, type PoolseRNThemeOverrides, PoolseTheme, type PoolseThemeProps, primitives as Primitives, ReactionPicker, type ReactionPickerProps, ReactionStrip, type ReactionStripProps, type ThemeColors, type ThemeRadii, type ThemeShadows, type ThemeSpacing, type ThemeType, ThreadView, type ThreadViewProps, TypingIndicator, type TypingIndicatorProps, UploadQueueStrip, UserName, type UserNameProps, VoiceRoomBar, type VoiceRoomBarProps, createNativeWebRtcAdapter, defaultDarkTheme, defaultLightTheme, isNativeWebRtcAvailable, useAppStateLifecycle, useDisplayName, usePoolseTheme };
1101
+ /**
1102
+ * Bridges iOS PushKit + CallKit to poolse calls, so a call rings a
1103
+ * backgrounded or closed app.
1104
+ *
1105
+ * ## Why this is needed at all
1106
+ *
1107
+ * `call:incoming` travels over the WebSocket, which only exists while
1108
+ * the app is foregrounded — iOS suspends sockets on background and
1109
+ * drops them on close. Reaching a sleeping phone requires the OS to wake
1110
+ * the app, which means a VoIP push against a PushKit token.
1111
+ *
1112
+ * ## The rule Apple enforces
1113
+ *
1114
+ * Every delivered VoIP push MUST report an incoming call to CallKit,
1115
+ * essentially immediately. Miss it and iOS terminates the app; do it
1116
+ * repeatedly and the system stops delivering VoIP pushes to you at all.
1117
+ * `reportCall` below is not optional politeness — it is the contract.
1118
+ *
1119
+ * ## Dependencies
1120
+ *
1121
+ * `react-native-voip-push-notification` and `react-native-callkeep`,
1122
+ * both native, both requiring a development build. Like
1123
+ * `react-native-webrtc`, Metro only bundles what it can see statically,
1124
+ * so YOUR APP imports them and passes them in:
1125
+ *
1126
+ * import VoipPushNotification from 'react-native-voip-push-notification';
1127
+ * import RNCallKeep from 'react-native-callkeep';
1128
+ *
1129
+ * useVoipCalls({
1130
+ * voipPush: VoipPushNotification,
1131
+ * callKeep: RNCallKeep,
1132
+ * onAnswer: (call) => { ... },
1133
+ * });
1134
+ */
1135
+ /** The slice of `react-native-voip-push-notification` used here. */
1136
+ interface VoipPushModule {
1137
+ addEventListener(event: 'register' | 'notification' | 'didLoadWithEvents', handler: (payload: never) => void): void;
1138
+ removeEventListener(event: string): void;
1139
+ registerVoipToken(): void;
1140
+ }
1141
+ /** The slice of `react-native-callkeep` used here. */
1142
+ interface CallKeepModule {
1143
+ setup(options: unknown): Promise<void>;
1144
+ displayIncomingCall(uuid: string, handle: string, localizedCallerName?: string, handleType?: string, hasVideo?: boolean): void;
1145
+ endCall(uuid: string): void;
1146
+ addEventListener(event: string, handler: (payload: never) => void): void;
1147
+ removeEventListener(event: string): void;
1148
+ }
1149
+ /** An inbound call, as it arrives inside a VoIP push payload. */
1150
+ interface VoipIncomingCall {
1151
+ callId: string;
1152
+ conversationId: string;
1153
+ callerUserId: string;
1154
+ callerName: string;
1155
+ }
1156
+ interface UseVoipCallsOptions {
1157
+ voipPush: VoipPushModule;
1158
+ callKeep: CallKeepModule;
1159
+ /**
1160
+ * Fired when the user answers from the native call UI. Accept the
1161
+ * call and join the room here — the app may have been launched cold,
1162
+ * so don't assume any prior state.
1163
+ */
1164
+ onAnswer?: (call: VoipIncomingCall) => void;
1165
+ /** Fired when the user declines from the native call UI. */
1166
+ onDecline?: (call: VoipIncomingCall) => void;
1167
+ /** CallKit display name for your app. Shown on the lock screen. */
1168
+ appName?: string;
1169
+ }
1170
+ /**
1171
+ * Registers this device for VoIP pushes and wires the native call UI.
1172
+ *
1173
+ * Safe to mount once at the app root. Does nothing on Android, which
1174
+ * needs a separate FCM + ConnectionService integration.
1175
+ */
1176
+ declare function useVoipCalls({ voipPush, callKeep, onAnswer, onDecline, appName, }: UseVoipCallsOptions): void;
1177
+
1178
+ export { AttachmentPicker, type AttachmentPickerProps, AttachmentPreview, type AttachmentPreviewProps, Avatar, type AvatarProps, type CallKeepModule, CallScreen, type CallScreenProps, ChatHeader, type ChatHeaderProps, ConversationList, type ConversationListProps, ConversationView, type ConversationViewProps, DaySeparator, type DaySeparatorProps, GroupDetailsSheet, type GroupDetailsSheetProps, type IconName, ImageMosaic, type ImageMosaicProps, type InboxUser, MemberList, type MemberListProps, MentionInput, type MentionInputProps, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerProps, MessageList, type MessageListItem, type MessageListProps, MessageRow, type MessageRowProps, type NativeWebRtcModule, PoolseIcon, type PoolseIconProps, PoolseInbox, type PoolseInboxHandle, type PoolseInboxProps, PoolseLogo, type PoolseLogoProps, type PoolseLogoVariant, type PoolseRNTheme, type PoolseRNThemeOverrides, PoolseTheme, type PoolseThemeProps, primitives as Primitives, ReactionPicker, type ReactionPickerProps, ReactionStrip, type ReactionStripProps, type ThemeColors, type ThemeRadii, type ThemeShadows, type ThemeSpacing, type ThemeType, ThreadView, type ThreadViewProps, TypingIndicator, type TypingIndicatorProps, UploadQueueStrip, type UseVoipCallsOptions, UserName, type UserNameProps, VoiceRoomBar, type VoiceRoomBarProps, type VoipIncomingCall, type VoipPushModule, createNativeWebRtcAdapter, defaultDarkTheme, defaultLightTheme, isNativeWebRtcAvailable, useAppStateLifecycle, useDisplayName, usePoolseTheme, useVoipCalls };
package/dist/index.d.ts CHANGED
@@ -1098,4 +1098,81 @@ interface CallScreenProps {
1098
1098
  */
1099
1099
  declare function CallScreen({ userId, labelFor, calls: external, webrtc }: CallScreenProps): react_jsx_runtime.JSX.Element;
1100
1100
 
1101
- export { AttachmentPicker, type AttachmentPickerProps, AttachmentPreview, type AttachmentPreviewProps, Avatar, type AvatarProps, CallScreen, type CallScreenProps, ChatHeader, type ChatHeaderProps, ConversationList, type ConversationListProps, ConversationView, type ConversationViewProps, DaySeparator, type DaySeparatorProps, GroupDetailsSheet, type GroupDetailsSheetProps, type IconName, ImageMosaic, type ImageMosaicProps, type InboxUser, MemberList, type MemberListProps, MentionInput, type MentionInputProps, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerProps, MessageList, type MessageListItem, type MessageListProps, MessageRow, type MessageRowProps, type NativeWebRtcModule, PoolseIcon, type PoolseIconProps, PoolseInbox, type PoolseInboxHandle, type PoolseInboxProps, PoolseLogo, type PoolseLogoProps, type PoolseLogoVariant, type PoolseRNTheme, type PoolseRNThemeOverrides, PoolseTheme, type PoolseThemeProps, primitives as Primitives, ReactionPicker, type ReactionPickerProps, ReactionStrip, type ReactionStripProps, type ThemeColors, type ThemeRadii, type ThemeShadows, type ThemeSpacing, type ThemeType, ThreadView, type ThreadViewProps, TypingIndicator, type TypingIndicatorProps, UploadQueueStrip, UserName, type UserNameProps, VoiceRoomBar, type VoiceRoomBarProps, createNativeWebRtcAdapter, defaultDarkTheme, defaultLightTheme, isNativeWebRtcAvailable, useAppStateLifecycle, useDisplayName, usePoolseTheme };
1101
+ /**
1102
+ * Bridges iOS PushKit + CallKit to poolse calls, so a call rings a
1103
+ * backgrounded or closed app.
1104
+ *
1105
+ * ## Why this is needed at all
1106
+ *
1107
+ * `call:incoming` travels over the WebSocket, which only exists while
1108
+ * the app is foregrounded — iOS suspends sockets on background and
1109
+ * drops them on close. Reaching a sleeping phone requires the OS to wake
1110
+ * the app, which means a VoIP push against a PushKit token.
1111
+ *
1112
+ * ## The rule Apple enforces
1113
+ *
1114
+ * Every delivered VoIP push MUST report an incoming call to CallKit,
1115
+ * essentially immediately. Miss it and iOS terminates the app; do it
1116
+ * repeatedly and the system stops delivering VoIP pushes to you at all.
1117
+ * `reportCall` below is not optional politeness — it is the contract.
1118
+ *
1119
+ * ## Dependencies
1120
+ *
1121
+ * `react-native-voip-push-notification` and `react-native-callkeep`,
1122
+ * both native, both requiring a development build. Like
1123
+ * `react-native-webrtc`, Metro only bundles what it can see statically,
1124
+ * so YOUR APP imports them and passes them in:
1125
+ *
1126
+ * import VoipPushNotification from 'react-native-voip-push-notification';
1127
+ * import RNCallKeep from 'react-native-callkeep';
1128
+ *
1129
+ * useVoipCalls({
1130
+ * voipPush: VoipPushNotification,
1131
+ * callKeep: RNCallKeep,
1132
+ * onAnswer: (call) => { ... },
1133
+ * });
1134
+ */
1135
+ /** The slice of `react-native-voip-push-notification` used here. */
1136
+ interface VoipPushModule {
1137
+ addEventListener(event: 'register' | 'notification' | 'didLoadWithEvents', handler: (payload: never) => void): void;
1138
+ removeEventListener(event: string): void;
1139
+ registerVoipToken(): void;
1140
+ }
1141
+ /** The slice of `react-native-callkeep` used here. */
1142
+ interface CallKeepModule {
1143
+ setup(options: unknown): Promise<void>;
1144
+ displayIncomingCall(uuid: string, handle: string, localizedCallerName?: string, handleType?: string, hasVideo?: boolean): void;
1145
+ endCall(uuid: string): void;
1146
+ addEventListener(event: string, handler: (payload: never) => void): void;
1147
+ removeEventListener(event: string): void;
1148
+ }
1149
+ /** An inbound call, as it arrives inside a VoIP push payload. */
1150
+ interface VoipIncomingCall {
1151
+ callId: string;
1152
+ conversationId: string;
1153
+ callerUserId: string;
1154
+ callerName: string;
1155
+ }
1156
+ interface UseVoipCallsOptions {
1157
+ voipPush: VoipPushModule;
1158
+ callKeep: CallKeepModule;
1159
+ /**
1160
+ * Fired when the user answers from the native call UI. Accept the
1161
+ * call and join the room here — the app may have been launched cold,
1162
+ * so don't assume any prior state.
1163
+ */
1164
+ onAnswer?: (call: VoipIncomingCall) => void;
1165
+ /** Fired when the user declines from the native call UI. */
1166
+ onDecline?: (call: VoipIncomingCall) => void;
1167
+ /** CallKit display name for your app. Shown on the lock screen. */
1168
+ appName?: string;
1169
+ }
1170
+ /**
1171
+ * Registers this device for VoIP pushes and wires the native call UI.
1172
+ *
1173
+ * Safe to mount once at the app root. Does nothing on Android, which
1174
+ * needs a separate FCM + ConnectionService integration.
1175
+ */
1176
+ declare function useVoipCalls({ voipPush, callKeep, onAnswer, onDecline, appName, }: UseVoipCallsOptions): void;
1177
+
1178
+ export { AttachmentPicker, type AttachmentPickerProps, AttachmentPreview, type AttachmentPreviewProps, Avatar, type AvatarProps, type CallKeepModule, CallScreen, type CallScreenProps, ChatHeader, type ChatHeaderProps, ConversationList, type ConversationListProps, ConversationView, type ConversationViewProps, DaySeparator, type DaySeparatorProps, GroupDetailsSheet, type GroupDetailsSheetProps, type IconName, ImageMosaic, type ImageMosaicProps, type InboxUser, MemberList, type MemberListProps, MentionInput, type MentionInputProps, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerProps, MessageList, type MessageListItem, type MessageListProps, MessageRow, type MessageRowProps, type NativeWebRtcModule, PoolseIcon, type PoolseIconProps, PoolseInbox, type PoolseInboxHandle, type PoolseInboxProps, PoolseLogo, type PoolseLogoProps, type PoolseLogoVariant, type PoolseRNTheme, type PoolseRNThemeOverrides, PoolseTheme, type PoolseThemeProps, primitives as Primitives, ReactionPicker, type ReactionPickerProps, ReactionStrip, type ReactionStripProps, type ThemeColors, type ThemeRadii, type ThemeShadows, type ThemeSpacing, type ThemeType, ThreadView, type ThreadViewProps, TypingIndicator, type TypingIndicatorProps, UploadQueueStrip, type UseVoipCallsOptions, UserName, type UserNameProps, VoiceRoomBar, type VoiceRoomBarProps, type VoipIncomingCall, type VoipPushModule, createNativeWebRtcAdapter, defaultDarkTheme, defaultLightTheme, isNativeWebRtcAvailable, useAppStateLifecycle, useDisplayName, usePoolseTheme, useVoipCalls };
package/dist/index.js CHANGED
@@ -5194,7 +5194,82 @@ var styles24 = StyleSheet.create({
5194
5194
  callBtnText: { color: "#ffffff", fontSize: 16, fontWeight: "600" },
5195
5195
  warn: { fontSize: 12, textAlign: "center", marginTop: 12 }
5196
5196
  });
5197
+ function useVoipCalls({
5198
+ voipPush,
5199
+ callKeep,
5200
+ onAnswer,
5201
+ onDecline,
5202
+ appName = "poolse"
5203
+ }) {
5204
+ const poolse = usePoolse();
5205
+ const pending = useRef(/* @__PURE__ */ new Map());
5206
+ const handlers = useRef({ onAnswer, onDecline });
5207
+ handlers.current = { onAnswer, onDecline };
5208
+ useEffect(() => {
5209
+ let cancelled = false;
5210
+ const reportCall = (payload) => {
5211
+ const callId = payload.call_id;
5212
+ const conversationId = payload.conversation_id;
5213
+ if (!callId || !conversationId) return;
5214
+ const call = {
5215
+ callId,
5216
+ conversationId,
5217
+ callerUserId: payload.caller_user_id ?? "",
5218
+ callerName: payload.caller_name ?? "Incoming call"
5219
+ };
5220
+ pending.current.set(callId, call);
5221
+ callKeep.displayIncomingCall(callId, call.callerUserId, call.callerName, "generic", false);
5222
+ };
5223
+ void callKeep.setup({
5224
+ ios: { appName },
5225
+ android: {
5226
+ alertTitle: "Permissions required",
5227
+ alertDescription: "Allow calls from this app",
5228
+ cancelButton: "Cancel",
5229
+ okButton: "ok",
5230
+ additionalPermissions: []
5231
+ }
5232
+ }).catch(() => {
5233
+ });
5234
+ voipPush.addEventListener("register", ((token) => {
5235
+ if (cancelled || !token) return;
5236
+ void poolse.devices.register({ token, platform: "ios", environment: apnsEnvironment() }).catch(() => {
5237
+ });
5238
+ }));
5239
+ voipPush.addEventListener("notification", ((payload) => {
5240
+ reportCall(payload);
5241
+ }));
5242
+ voipPush.addEventListener("didLoadWithEvents", ((events) => {
5243
+ for (const event of events ?? []) {
5244
+ if (event.name === "RNVoipPushRemoteNotificationReceivedEvent") {
5245
+ reportCall(event.data);
5246
+ }
5247
+ }
5248
+ }));
5249
+ callKeep.addEventListener("answerCall", (({ callUUID }) => {
5250
+ const call = pending.current.get(callUUID);
5251
+ if (call) handlers.current.onAnswer?.(call);
5252
+ }));
5253
+ callKeep.addEventListener("endCall", (({ callUUID }) => {
5254
+ const call = pending.current.get(callUUID);
5255
+ pending.current.delete(callUUID);
5256
+ if (call) handlers.current.onDecline?.(call);
5257
+ }));
5258
+ voipPush.registerVoipToken();
5259
+ return () => {
5260
+ cancelled = true;
5261
+ voipPush.removeEventListener("register");
5262
+ voipPush.removeEventListener("notification");
5263
+ voipPush.removeEventListener("didLoadWithEvents");
5264
+ callKeep.removeEventListener("answerCall");
5265
+ callKeep.removeEventListener("endCall");
5266
+ };
5267
+ }, [poolse, voipPush, callKeep, appName]);
5268
+ }
5269
+ function apnsEnvironment() {
5270
+ return __DEV__ ? "sandbox" : "production";
5271
+ }
5197
5272
 
5198
- export { AttachmentPicker, AttachmentPreview, Avatar, CallScreen, ChatHeader, ConversationList, ConversationView, DaySeparator, GroupDetailsSheet, ImageMosaic, MemberList, MentionInput, MessageActions, MessageBubble, MessageComposer, MessageList, MessageRow, PoolseIcon, PoolseInbox, PoolseLogo, PoolseTheme, primitives as Primitives, ReactionPicker, ReactionStrip, ThreadView, TypingIndicator, UploadQueueStrip, UserName, VoiceRoomBar, createNativeWebRtcAdapter, defaultDarkTheme, defaultLightTheme, isNativeWebRtcAvailable, useAppStateLifecycle, useDisplayName, usePoolseTheme };
5273
+ export { AttachmentPicker, AttachmentPreview, Avatar, CallScreen, ChatHeader, ConversationList, ConversationView, DaySeparator, GroupDetailsSheet, ImageMosaic, MemberList, MentionInput, MessageActions, MessageBubble, MessageComposer, MessageList, MessageRow, PoolseIcon, PoolseInbox, PoolseLogo, PoolseTheme, primitives as Primitives, ReactionPicker, ReactionStrip, ThreadView, TypingIndicator, UploadQueueStrip, UserName, VoiceRoomBar, createNativeWebRtcAdapter, defaultDarkTheme, defaultLightTheme, isNativeWebRtcAvailable, useAppStateLifecycle, useDisplayName, usePoolseTheme, useVoipCalls };
5199
5274
  //# sourceMappingURL=index.js.map
5200
5275
  //# sourceMappingURL=index.js.map