@poolse/react-native 2.6.0 → 2.7.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 +74 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -36
- package/dist/index.d.ts +59 -36
- package/dist/index.js +74 -22
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1095,6 +1095,16 @@ interface CallScreenProps {
|
|
|
1095
1095
|
* {@link VoiceRoomBarProps.onStatusChange}.
|
|
1096
1096
|
*/
|
|
1097
1097
|
onStatusChange?: (status: VoiceStatus) => void;
|
|
1098
|
+
/**
|
|
1099
|
+
* Hide this screen while a call is merely ringing in.
|
|
1100
|
+
*
|
|
1101
|
+
* Set it when `useVoipCalls` is wired: CallKit already shows the
|
|
1102
|
+
* system call UI on the lock screen and in the Dynamic Island, and a
|
|
1103
|
+
* second in-app sheet on top of it means one tap of Call produces two
|
|
1104
|
+
* competing rings. The screen still appears once the call connects, to
|
|
1105
|
+
* carry the in-call controls.
|
|
1106
|
+
*/
|
|
1107
|
+
nativeIncomingUi?: boolean;
|
|
1098
1108
|
}
|
|
1099
1109
|
/**
|
|
1100
1110
|
* WhatsApp-style call UI: a full-screen sheet that covers the app while
|
|
@@ -1111,58 +1121,58 @@ interface CallScreenProps {
|
|
|
1111
1121
|
* to whatever button your UI wants. Pass the same instance in via
|
|
1112
1122
|
* `calls` so both halves share one state machine.
|
|
1113
1123
|
*/
|
|
1114
|
-
declare function CallScreen({ userId, labelFor, calls: external, webrtc, onStatusChange, }: CallScreenProps): react_jsx_runtime.JSX.Element;
|
|
1124
|
+
declare function CallScreen({ userId, labelFor, calls: external, webrtc, onStatusChange, nativeIncomingUi, }: CallScreenProps): react_jsx_runtime.JSX.Element;
|
|
1115
1125
|
|
|
1116
1126
|
/**
|
|
1117
|
-
* Bridges iOS PushKit + CallKit to poolse calls,
|
|
1118
|
-
*
|
|
1127
|
+
* Bridges iOS PushKit + CallKit to poolse calls, and owns the incoming
|
|
1128
|
+
* call UI end to end.
|
|
1129
|
+
*
|
|
1130
|
+
* ## Why this coordinates rather than just forwards
|
|
1119
1131
|
*
|
|
1120
|
-
*
|
|
1132
|
+
* A call arrives by two routes: `call:incoming` over the WebSocket when
|
|
1133
|
+
* the app is foregrounded, and a VoIP push when it isn't. The server
|
|
1134
|
+
* fires both, always — deciding server-side whether a socket is really
|
|
1135
|
+
* alive is a race it would lose.
|
|
1121
1136
|
*
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1124
|
-
*
|
|
1125
|
-
*
|
|
1137
|
+
* Reconciling them is therefore the client's job, and doing it badly is
|
|
1138
|
+
* very visible: forward each route to its own UI and one tap of Call
|
|
1139
|
+
* shows the callee two rings, an in-app sheet fighting a system call
|
|
1140
|
+
* screen.
|
|
1141
|
+
*
|
|
1142
|
+
* So this hook is the single place a call becomes visible. Both routes
|
|
1143
|
+
* feed one map keyed by `callId`, CallKit is the only ring UI, and the
|
|
1144
|
+
* native call is torn down whenever the call reaches a terminal state —
|
|
1145
|
+
* declined, cancelled, timed out, answered. Pass the same `calls` object
|
|
1146
|
+
* to `<CallScreen>` and it stays out of the way while a ring is up.
|
|
1126
1147
|
*
|
|
1127
1148
|
* ## The rule Apple enforces
|
|
1128
1149
|
*
|
|
1129
1150
|
* Every delivered VoIP push MUST report an incoming call to CallKit,
|
|
1130
1151
|
* essentially immediately. Miss it and iOS terminates the app; do it
|
|
1131
|
-
* repeatedly and the system stops delivering VoIP pushes
|
|
1132
|
-
* `reportCall` below is not optional politeness — it is the contract.
|
|
1152
|
+
* repeatedly and the system stops delivering VoIP pushes at all.
|
|
1133
1153
|
*
|
|
1134
1154
|
* ## Dependencies
|
|
1135
1155
|
*
|
|
1136
1156
|
* `react-native-voip-push-notification` and `react-native-callkeep`,
|
|
1137
|
-
* both native
|
|
1138
|
-
*
|
|
1139
|
-
*
|
|
1140
|
-
*
|
|
1141
|
-
* import VoipPushNotification from 'react-native-voip-push-notification';
|
|
1142
|
-
* import RNCallKeep from 'react-native-callkeep';
|
|
1157
|
+
* both native and both requiring a development build. Metro only bundles
|
|
1158
|
+
* what it can see statically, so YOUR APP imports them and passes them
|
|
1159
|
+
* in. The iOS AppDelegate also needs PushKit delegate methods, which
|
|
1160
|
+
* Expo does not generate — see the sample's `plugins/withVoipPush.js`.
|
|
1143
1161
|
*
|
|
1144
1162
|
* useVoipCalls({
|
|
1145
1163
|
* voipPush: VoipPushNotification,
|
|
1146
1164
|
* callKeep: RNCallKeep,
|
|
1147
|
-
*
|
|
1165
|
+
* calls, // the same useCalls() the UI uses
|
|
1166
|
+
* apnsEnvironment: 'sandbox',
|
|
1148
1167
|
* });
|
|
1149
1168
|
*/
|
|
1150
|
-
/**
|
|
1151
|
-
* The slice of `react-native-voip-push-notification` used here.
|
|
1152
|
-
*
|
|
1153
|
-
* Loose on purpose. The real module types `addEventListener` as a
|
|
1154
|
-
* generic whose handler payload varies per event, and pinning exact
|
|
1155
|
-
* signatures here makes `voipPush={VoipPushNotification}` fail to
|
|
1156
|
-
* compile — the prop becomes unusable, which is the whole point of it.
|
|
1157
|
-
* Method syntax (not property arrow syntax) keeps the check bivariant.
|
|
1158
|
-
*/
|
|
1169
|
+
/** The slice of `react-native-voip-push-notification` used here. */
|
|
1159
1170
|
interface VoipPushModule {
|
|
1160
1171
|
addEventListener(event: string, handler: (payload: unknown) => void): void;
|
|
1161
1172
|
removeEventListener(event: string): void;
|
|
1162
1173
|
registerVoipToken(): void;
|
|
1163
1174
|
}
|
|
1164
|
-
/** The slice of `react-native-callkeep` used here.
|
|
1165
|
-
* reason — `setup` resolves to a boolean in the real module. */
|
|
1175
|
+
/** The slice of `react-native-callkeep` used here. */
|
|
1166
1176
|
interface CallKeepModule {
|
|
1167
1177
|
setup(options: unknown): Promise<unknown>;
|
|
1168
1178
|
displayIncomingCall(uuid: string, handle: string, localizedCallerName?: string, handleType?: string, hasVideo?: boolean): unknown;
|
|
@@ -1181,12 +1191,15 @@ interface UseVoipCallsOptions {
|
|
|
1181
1191
|
voipPush: VoipPushModule;
|
|
1182
1192
|
callKeep: CallKeepModule;
|
|
1183
1193
|
/**
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1194
|
+
* The `useCalls(...)` instance driving this screen. Supplying it lets
|
|
1195
|
+
* the hook answer, decline and dismiss through the same state machine
|
|
1196
|
+
* the UI uses, rather than two halves disagreeing about what is
|
|
1197
|
+
* happening.
|
|
1187
1198
|
*/
|
|
1199
|
+
calls?: UseCalls;
|
|
1200
|
+
/** Called when the user answers from the native call UI. */
|
|
1188
1201
|
onAnswer?: (call: VoipIncomingCall) => void;
|
|
1189
|
-
/**
|
|
1202
|
+
/** Called when the user declines from the native call UI. */
|
|
1190
1203
|
onDecline?: (call: VoipIncomingCall) => void;
|
|
1191
1204
|
/** CallKit display name for your app. Shown on the lock screen. */
|
|
1192
1205
|
appName?: string;
|
|
@@ -1203,13 +1216,23 @@ interface UseVoipCallsOptions {
|
|
|
1203
1216
|
* rings — with nothing in the app to suggest why.
|
|
1204
1217
|
*/
|
|
1205
1218
|
apnsEnvironment?: 'production' | 'sandbox';
|
|
1219
|
+
/**
|
|
1220
|
+
* How old a pushed call may be before it is ignored, in ms. Defaults
|
|
1221
|
+
* to 45s, matching `useCalls`' ring timeout — past that the caller has
|
|
1222
|
+
* already given up, so there is nothing live to answer.
|
|
1223
|
+
*
|
|
1224
|
+
* PushKit holds a push that lands before the JS bundle is up and
|
|
1225
|
+
* replays it on launch, so opening the app can ring you for a call the
|
|
1226
|
+
* caller hung up on minutes ago — a ring with nothing live to accept.
|
|
1227
|
+
*/
|
|
1228
|
+
staleAfterMs?: number;
|
|
1206
1229
|
}
|
|
1207
1230
|
/**
|
|
1208
|
-
* Registers this device for VoIP pushes and
|
|
1231
|
+
* Registers this device for VoIP pushes and drives the native call UI.
|
|
1209
1232
|
*
|
|
1210
|
-
*
|
|
1211
|
-
* needs a separate FCM + ConnectionService integration.
|
|
1233
|
+
* Mount once, as high in the signed-in tree as possible. Does nothing on
|
|
1234
|
+
* Android, which needs a separate FCM + ConnectionService integration.
|
|
1212
1235
|
*/
|
|
1213
|
-
declare function useVoipCalls({ voipPush, callKeep, onAnswer, onDecline, appName, apnsEnvironment, }: UseVoipCallsOptions): void;
|
|
1236
|
+
declare function useVoipCalls({ voipPush, callKeep, calls, onAnswer, onDecline, appName, apnsEnvironment, staleAfterMs, }: UseVoipCallsOptions): void;
|
|
1214
1237
|
|
|
1215
1238
|
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
|
@@ -1095,6 +1095,16 @@ interface CallScreenProps {
|
|
|
1095
1095
|
* {@link VoiceRoomBarProps.onStatusChange}.
|
|
1096
1096
|
*/
|
|
1097
1097
|
onStatusChange?: (status: VoiceStatus) => void;
|
|
1098
|
+
/**
|
|
1099
|
+
* Hide this screen while a call is merely ringing in.
|
|
1100
|
+
*
|
|
1101
|
+
* Set it when `useVoipCalls` is wired: CallKit already shows the
|
|
1102
|
+
* system call UI on the lock screen and in the Dynamic Island, and a
|
|
1103
|
+
* second in-app sheet on top of it means one tap of Call produces two
|
|
1104
|
+
* competing rings. The screen still appears once the call connects, to
|
|
1105
|
+
* carry the in-call controls.
|
|
1106
|
+
*/
|
|
1107
|
+
nativeIncomingUi?: boolean;
|
|
1098
1108
|
}
|
|
1099
1109
|
/**
|
|
1100
1110
|
* WhatsApp-style call UI: a full-screen sheet that covers the app while
|
|
@@ -1111,58 +1121,58 @@ interface CallScreenProps {
|
|
|
1111
1121
|
* to whatever button your UI wants. Pass the same instance in via
|
|
1112
1122
|
* `calls` so both halves share one state machine.
|
|
1113
1123
|
*/
|
|
1114
|
-
declare function CallScreen({ userId, labelFor, calls: external, webrtc, onStatusChange, }: CallScreenProps): react_jsx_runtime.JSX.Element;
|
|
1124
|
+
declare function CallScreen({ userId, labelFor, calls: external, webrtc, onStatusChange, nativeIncomingUi, }: CallScreenProps): react_jsx_runtime.JSX.Element;
|
|
1115
1125
|
|
|
1116
1126
|
/**
|
|
1117
|
-
* Bridges iOS PushKit + CallKit to poolse calls,
|
|
1118
|
-
*
|
|
1127
|
+
* Bridges iOS PushKit + CallKit to poolse calls, and owns the incoming
|
|
1128
|
+
* call UI end to end.
|
|
1129
|
+
*
|
|
1130
|
+
* ## Why this coordinates rather than just forwards
|
|
1119
1131
|
*
|
|
1120
|
-
*
|
|
1132
|
+
* A call arrives by two routes: `call:incoming` over the WebSocket when
|
|
1133
|
+
* the app is foregrounded, and a VoIP push when it isn't. The server
|
|
1134
|
+
* fires both, always — deciding server-side whether a socket is really
|
|
1135
|
+
* alive is a race it would lose.
|
|
1121
1136
|
*
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1124
|
-
*
|
|
1125
|
-
*
|
|
1137
|
+
* Reconciling them is therefore the client's job, and doing it badly is
|
|
1138
|
+
* very visible: forward each route to its own UI and one tap of Call
|
|
1139
|
+
* shows the callee two rings, an in-app sheet fighting a system call
|
|
1140
|
+
* screen.
|
|
1141
|
+
*
|
|
1142
|
+
* So this hook is the single place a call becomes visible. Both routes
|
|
1143
|
+
* feed one map keyed by `callId`, CallKit is the only ring UI, and the
|
|
1144
|
+
* native call is torn down whenever the call reaches a terminal state —
|
|
1145
|
+
* declined, cancelled, timed out, answered. Pass the same `calls` object
|
|
1146
|
+
* to `<CallScreen>` and it stays out of the way while a ring is up.
|
|
1126
1147
|
*
|
|
1127
1148
|
* ## The rule Apple enforces
|
|
1128
1149
|
*
|
|
1129
1150
|
* Every delivered VoIP push MUST report an incoming call to CallKit,
|
|
1130
1151
|
* essentially immediately. Miss it and iOS terminates the app; do it
|
|
1131
|
-
* repeatedly and the system stops delivering VoIP pushes
|
|
1132
|
-
* `reportCall` below is not optional politeness — it is the contract.
|
|
1152
|
+
* repeatedly and the system stops delivering VoIP pushes at all.
|
|
1133
1153
|
*
|
|
1134
1154
|
* ## Dependencies
|
|
1135
1155
|
*
|
|
1136
1156
|
* `react-native-voip-push-notification` and `react-native-callkeep`,
|
|
1137
|
-
* both native
|
|
1138
|
-
*
|
|
1139
|
-
*
|
|
1140
|
-
*
|
|
1141
|
-
* import VoipPushNotification from 'react-native-voip-push-notification';
|
|
1142
|
-
* import RNCallKeep from 'react-native-callkeep';
|
|
1157
|
+
* both native and both requiring a development build. Metro only bundles
|
|
1158
|
+
* what it can see statically, so YOUR APP imports them and passes them
|
|
1159
|
+
* in. The iOS AppDelegate also needs PushKit delegate methods, which
|
|
1160
|
+
* Expo does not generate — see the sample's `plugins/withVoipPush.js`.
|
|
1143
1161
|
*
|
|
1144
1162
|
* useVoipCalls({
|
|
1145
1163
|
* voipPush: VoipPushNotification,
|
|
1146
1164
|
* callKeep: RNCallKeep,
|
|
1147
|
-
*
|
|
1165
|
+
* calls, // the same useCalls() the UI uses
|
|
1166
|
+
* apnsEnvironment: 'sandbox',
|
|
1148
1167
|
* });
|
|
1149
1168
|
*/
|
|
1150
|
-
/**
|
|
1151
|
-
* The slice of `react-native-voip-push-notification` used here.
|
|
1152
|
-
*
|
|
1153
|
-
* Loose on purpose. The real module types `addEventListener` as a
|
|
1154
|
-
* generic whose handler payload varies per event, and pinning exact
|
|
1155
|
-
* signatures here makes `voipPush={VoipPushNotification}` fail to
|
|
1156
|
-
* compile — the prop becomes unusable, which is the whole point of it.
|
|
1157
|
-
* Method syntax (not property arrow syntax) keeps the check bivariant.
|
|
1158
|
-
*/
|
|
1169
|
+
/** The slice of `react-native-voip-push-notification` used here. */
|
|
1159
1170
|
interface VoipPushModule {
|
|
1160
1171
|
addEventListener(event: string, handler: (payload: unknown) => void): void;
|
|
1161
1172
|
removeEventListener(event: string): void;
|
|
1162
1173
|
registerVoipToken(): void;
|
|
1163
1174
|
}
|
|
1164
|
-
/** The slice of `react-native-callkeep` used here.
|
|
1165
|
-
* reason — `setup` resolves to a boolean in the real module. */
|
|
1175
|
+
/** The slice of `react-native-callkeep` used here. */
|
|
1166
1176
|
interface CallKeepModule {
|
|
1167
1177
|
setup(options: unknown): Promise<unknown>;
|
|
1168
1178
|
displayIncomingCall(uuid: string, handle: string, localizedCallerName?: string, handleType?: string, hasVideo?: boolean): unknown;
|
|
@@ -1181,12 +1191,15 @@ interface UseVoipCallsOptions {
|
|
|
1181
1191
|
voipPush: VoipPushModule;
|
|
1182
1192
|
callKeep: CallKeepModule;
|
|
1183
1193
|
/**
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1194
|
+
* The `useCalls(...)` instance driving this screen. Supplying it lets
|
|
1195
|
+
* the hook answer, decline and dismiss through the same state machine
|
|
1196
|
+
* the UI uses, rather than two halves disagreeing about what is
|
|
1197
|
+
* happening.
|
|
1187
1198
|
*/
|
|
1199
|
+
calls?: UseCalls;
|
|
1200
|
+
/** Called when the user answers from the native call UI. */
|
|
1188
1201
|
onAnswer?: (call: VoipIncomingCall) => void;
|
|
1189
|
-
/**
|
|
1202
|
+
/** Called when the user declines from the native call UI. */
|
|
1190
1203
|
onDecline?: (call: VoipIncomingCall) => void;
|
|
1191
1204
|
/** CallKit display name for your app. Shown on the lock screen. */
|
|
1192
1205
|
appName?: string;
|
|
@@ -1203,13 +1216,23 @@ interface UseVoipCallsOptions {
|
|
|
1203
1216
|
* rings — with nothing in the app to suggest why.
|
|
1204
1217
|
*/
|
|
1205
1218
|
apnsEnvironment?: 'production' | 'sandbox';
|
|
1219
|
+
/**
|
|
1220
|
+
* How old a pushed call may be before it is ignored, in ms. Defaults
|
|
1221
|
+
* to 45s, matching `useCalls`' ring timeout — past that the caller has
|
|
1222
|
+
* already given up, so there is nothing live to answer.
|
|
1223
|
+
*
|
|
1224
|
+
* PushKit holds a push that lands before the JS bundle is up and
|
|
1225
|
+
* replays it on launch, so opening the app can ring you for a call the
|
|
1226
|
+
* caller hung up on minutes ago — a ring with nothing live to accept.
|
|
1227
|
+
*/
|
|
1228
|
+
staleAfterMs?: number;
|
|
1206
1229
|
}
|
|
1207
1230
|
/**
|
|
1208
|
-
* Registers this device for VoIP pushes and
|
|
1231
|
+
* Registers this device for VoIP pushes and drives the native call UI.
|
|
1209
1232
|
*
|
|
1210
|
-
*
|
|
1211
|
-
* needs a separate FCM + ConnectionService integration.
|
|
1233
|
+
* Mount once, as high in the signed-in tree as possible. Does nothing on
|
|
1234
|
+
* Android, which needs a separate FCM + ConnectionService integration.
|
|
1212
1235
|
*/
|
|
1213
|
-
declare function useVoipCalls({ voipPush, callKeep, onAnswer, onDecline, appName, apnsEnvironment, }: UseVoipCallsOptions): void;
|
|
1236
|
+
declare function useVoipCalls({ voipPush, callKeep, calls, onAnswer, onDecline, appName, apnsEnvironment, staleAfterMs, }: UseVoipCallsOptions): void;
|
|
1214
1237
|
|
|
1215
1238
|
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
|
@@ -5088,7 +5088,8 @@ function CallScreen({
|
|
|
5088
5088
|
labelFor,
|
|
5089
5089
|
calls: external,
|
|
5090
5090
|
webrtc,
|
|
5091
|
-
onStatusChange
|
|
5091
|
+
onStatusChange,
|
|
5092
|
+
nativeIncomingUi = false
|
|
5092
5093
|
}) {
|
|
5093
5094
|
const theme = usePoolseTheme();
|
|
5094
5095
|
const own = useCalls(external ? null : userId);
|
|
@@ -5109,7 +5110,8 @@ function CallScreen({
|
|
|
5109
5110
|
onStatusChange?.(voice.status);
|
|
5110
5111
|
}, [voice.status, onStatusChange]);
|
|
5111
5112
|
const label = labelFor ?? ((id) => `User ${id.slice(0, 6)}`);
|
|
5112
|
-
const
|
|
5113
|
+
const ringingIn = calls.phase === "ringing-in";
|
|
5114
|
+
const visible = calls.phase !== "idle" && !(nativeIncomingUi && ringingIn);
|
|
5113
5115
|
const hangUp = () => {
|
|
5114
5116
|
voice.leave();
|
|
5115
5117
|
calls.reset();
|
|
@@ -5210,29 +5212,50 @@ var styles24 = StyleSheet.create({
|
|
|
5210
5212
|
function useVoipCalls({
|
|
5211
5213
|
voipPush,
|
|
5212
5214
|
callKeep,
|
|
5215
|
+
calls,
|
|
5213
5216
|
onAnswer,
|
|
5214
5217
|
onDecline,
|
|
5215
5218
|
appName = "poolse",
|
|
5216
|
-
apnsEnvironment
|
|
5219
|
+
apnsEnvironment,
|
|
5220
|
+
staleAfterMs = 45e3
|
|
5217
5221
|
}) {
|
|
5218
5222
|
const poolse = usePoolse();
|
|
5219
|
-
const
|
|
5220
|
-
const
|
|
5221
|
-
handlers
|
|
5223
|
+
const shown = useRef(/* @__PURE__ */ new Map());
|
|
5224
|
+
const seen = useRef(/* @__PURE__ */ new Set());
|
|
5225
|
+
const handlers = useRef({ onAnswer, onDecline, calls });
|
|
5226
|
+
handlers.current = { onAnswer, onDecline, calls };
|
|
5227
|
+
const staleRef = useRef(staleAfterMs);
|
|
5228
|
+
staleRef.current = staleAfterMs;
|
|
5229
|
+
const dismiss = useRef((callId) => {
|
|
5230
|
+
if (!shown.current.has(callId)) return;
|
|
5231
|
+
shown.current.delete(callId);
|
|
5232
|
+
try {
|
|
5233
|
+
callKeep.endCall(callId);
|
|
5234
|
+
} catch {
|
|
5235
|
+
}
|
|
5236
|
+
});
|
|
5237
|
+
const present = useRef((call, sentAt) => {
|
|
5238
|
+
if (seen.current.has(call.callId)) return;
|
|
5239
|
+
if (typeof sentAt === "number" && Date.now() - sentAt > staleRef.current) return;
|
|
5240
|
+
seen.current.add(call.callId);
|
|
5241
|
+
shown.current.set(call.callId, call);
|
|
5242
|
+
callKeep.displayIncomingCall(call.callId, call.callerUserId, call.callerName, "generic", false);
|
|
5243
|
+
});
|
|
5222
5244
|
useEffect(() => {
|
|
5223
5245
|
let cancelled = false;
|
|
5224
|
-
const
|
|
5246
|
+
const fromPush = (payload) => {
|
|
5225
5247
|
const callId = payload.call_id;
|
|
5226
5248
|
const conversationId = payload.conversation_id;
|
|
5227
5249
|
if (!callId || !conversationId) return;
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5250
|
+
present.current(
|
|
5251
|
+
{
|
|
5252
|
+
callId,
|
|
5253
|
+
conversationId,
|
|
5254
|
+
callerUserId: payload.caller_user_id ?? "",
|
|
5255
|
+
callerName: payload.caller_name ?? "Incoming call"
|
|
5256
|
+
},
|
|
5257
|
+
payload.sent_at
|
|
5258
|
+
);
|
|
5236
5259
|
};
|
|
5237
5260
|
void callKeep.setup({
|
|
5238
5261
|
ios: { appName },
|
|
@@ -5255,23 +5278,36 @@ function useVoipCalls({
|
|
|
5255
5278
|
});
|
|
5256
5279
|
}));
|
|
5257
5280
|
voipPush.addEventListener("notification", ((payload) => {
|
|
5258
|
-
|
|
5281
|
+
fromPush(payload);
|
|
5259
5282
|
}));
|
|
5260
5283
|
voipPush.addEventListener("didLoadWithEvents", ((events) => {
|
|
5261
5284
|
for (const event of events ?? []) {
|
|
5262
5285
|
if (event.name === "RNVoipPushRemoteNotificationReceivedEvent") {
|
|
5263
|
-
|
|
5286
|
+
fromPush(event.data);
|
|
5264
5287
|
}
|
|
5265
5288
|
}
|
|
5266
5289
|
}));
|
|
5267
5290
|
callKeep.addEventListener("answerCall", (({ callUUID }) => {
|
|
5268
|
-
const call =
|
|
5269
|
-
if (call)
|
|
5291
|
+
const call = shown.current.get(callUUID);
|
|
5292
|
+
if (!call) return;
|
|
5293
|
+
shown.current.delete(callUUID);
|
|
5294
|
+
void handlers.current.calls?.accept({
|
|
5295
|
+
callId: call.callId,
|
|
5296
|
+
conversationId: call.conversationId,
|
|
5297
|
+
callerUserId: call.callerUserId
|
|
5298
|
+
});
|
|
5299
|
+
handlers.current.onAnswer?.(call);
|
|
5270
5300
|
}));
|
|
5271
5301
|
callKeep.addEventListener("endCall", (({ callUUID }) => {
|
|
5272
|
-
const call =
|
|
5273
|
-
|
|
5274
|
-
if (call)
|
|
5302
|
+
const call = shown.current.get(callUUID);
|
|
5303
|
+
shown.current.delete(callUUID);
|
|
5304
|
+
if (!call) return;
|
|
5305
|
+
void handlers.current.calls?.decline({
|
|
5306
|
+
callId: call.callId,
|
|
5307
|
+
conversationId: call.conversationId,
|
|
5308
|
+
callerUserId: call.callerUserId
|
|
5309
|
+
});
|
|
5310
|
+
handlers.current.onDecline?.(call);
|
|
5275
5311
|
}));
|
|
5276
5312
|
voipPush.registerVoipToken();
|
|
5277
5313
|
return () => {
|
|
@@ -5283,6 +5319,22 @@ function useVoipCalls({
|
|
|
5283
5319
|
callKeep.removeEventListener("endCall");
|
|
5284
5320
|
};
|
|
5285
5321
|
}, [poolse, voipPush, callKeep, appName, apnsEnvironment]);
|
|
5322
|
+
const incoming = calls?.incoming ?? null;
|
|
5323
|
+
const phase = calls?.phase;
|
|
5324
|
+
useEffect(() => {
|
|
5325
|
+
if (phase === "ringing-in" && incoming) {
|
|
5326
|
+
present.current({
|
|
5327
|
+
callId: incoming.callId,
|
|
5328
|
+
conversationId: incoming.conversationId,
|
|
5329
|
+
callerUserId: incoming.callerUserId,
|
|
5330
|
+
callerName: incoming.callerUserId
|
|
5331
|
+
});
|
|
5332
|
+
}
|
|
5333
|
+
}, [phase, incoming]);
|
|
5334
|
+
useEffect(() => {
|
|
5335
|
+
if (phase === "ringing-in" || phase === "ringing-out") return;
|
|
5336
|
+
for (const callId of [...shown.current.keys()]) dismiss.current(callId);
|
|
5337
|
+
}, [phase]);
|
|
5286
5338
|
}
|
|
5287
5339
|
function guessApnsEnvironment() {
|
|
5288
5340
|
return __DEV__ ? "sandbox" : "production";
|