@stream-io/video-react-native-sdk 1.28.1 → 1.29.0-beta.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.
Files changed (172) hide show
  1. package/android/src/main/AndroidManifest.xml +8 -1
  2. package/android/src/main/AndroidManifestNew.xml +11 -0
  3. package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +42 -5
  4. package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +83 -0
  5. package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +134 -0
  6. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +235 -0
  7. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
  8. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
  9. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  10. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +60 -97
  11. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  12. package/dist/commonjs/index.js +1 -0
  13. package/dist/commonjs/index.js.map +1 -1
  14. package/dist/commonjs/modules/call-manager/CallManager.js +20 -0
  15. package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
  16. package/dist/commonjs/providers/StreamCall/index.js +6 -6
  17. package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
  18. package/dist/commonjs/utils/StreamVideoRN/index.js +33 -21
  19. package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
  20. package/dist/commonjs/utils/internal/registerSDKGlobals.js +47 -3
  21. package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
  22. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +48 -0
  23. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +1 -0
  24. package/dist/commonjs/utils/push/android.js +145 -200
  25. package/dist/commonjs/utils/push/android.js.map +1 -1
  26. package/dist/commonjs/utils/push/internal/ios.js +16 -34
  27. package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
  28. package/dist/commonjs/utils/push/internal/rxSubjects.js +1 -20
  29. package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
  30. package/dist/commonjs/utils/push/internal/utils.js +17 -1
  31. package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
  32. package/dist/commonjs/utils/push/ios.js.map +1 -1
  33. package/dist/commonjs/utils/push/libs/callingx.js +75 -0
  34. package/dist/commonjs/utils/push/libs/callingx.js.map +1 -0
  35. package/dist/commonjs/utils/push/libs/index.js +8 -19
  36. package/dist/commonjs/utils/push/libs/index.js.map +1 -1
  37. package/dist/commonjs/utils/push/libs/notifee/index.js +0 -19
  38. package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
  39. package/dist/commonjs/utils/push/setupCallingExpEvents.js +75 -0
  40. package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +1 -0
  41. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +7 -6
  42. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
  43. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +228 -0
  44. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
  45. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
  46. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  47. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +62 -99
  48. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  49. package/dist/module/index.js +1 -0
  50. package/dist/module/index.js.map +1 -1
  51. package/dist/module/modules/call-manager/CallManager.js +20 -0
  52. package/dist/module/modules/call-manager/CallManager.js.map +1 -1
  53. package/dist/module/providers/StreamCall/index.js +6 -6
  54. package/dist/module/providers/StreamCall/index.js.map +1 -1
  55. package/dist/module/utils/StreamVideoRN/index.js +33 -21
  56. package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
  57. package/dist/module/utils/internal/registerSDKGlobals.js +48 -4
  58. package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
  59. package/dist/module/utils/keepCallAliveHeadlessTask.js +42 -0
  60. package/dist/module/utils/keepCallAliveHeadlessTask.js.map +1 -0
  61. package/dist/module/utils/push/android.js +147 -202
  62. package/dist/module/utils/push/android.js.map +1 -1
  63. package/dist/module/utils/push/internal/ios.js +16 -34
  64. package/dist/module/utils/push/internal/ios.js.map +1 -1
  65. package/dist/module/utils/push/internal/rxSubjects.js +0 -19
  66. package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
  67. package/dist/module/utils/push/internal/utils.js +14 -0
  68. package/dist/module/utils/push/internal/utils.js.map +1 -1
  69. package/dist/module/utils/push/ios.js.map +1 -1
  70. package/dist/module/utils/push/libs/callingx.js +67 -0
  71. package/dist/module/utils/push/libs/callingx.js.map +1 -0
  72. package/dist/module/utils/push/libs/index.js +1 -2
  73. package/dist/module/utils/push/libs/index.js.map +1 -1
  74. package/dist/module/utils/push/libs/notifee/index.js +0 -18
  75. package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
  76. package/dist/module/utils/push/setupCallingExpEvents.js +69 -0
  77. package/dist/module/utils/push/setupCallingExpEvents.js.map +1 -0
  78. package/dist/module/utils/push/setupIosVoipPushEvents.js +7 -6
  79. package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
  80. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +5 -0
  81. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +1 -0
  82. package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
  83. package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
  84. package/dist/typescript/index.d.ts +1 -0
  85. package/dist/typescript/index.d.ts.map +1 -1
  86. package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
  87. package/dist/typescript/utils/StreamVideoRN/index.d.ts +20 -2
  88. package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
  89. package/dist/typescript/utils/StreamVideoRN/types.d.ts +54 -29
  90. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  91. package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
  92. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts +10 -0
  93. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +1 -0
  94. package/dist/typescript/utils/push/android.d.ts +1 -2
  95. package/dist/typescript/utils/push/android.d.ts.map +1 -1
  96. package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
  97. package/dist/typescript/utils/push/internal/rxSubjects.d.ts +0 -12
  98. package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
  99. package/dist/typescript/utils/push/internal/utils.d.ts +4 -0
  100. package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
  101. package/dist/typescript/utils/push/ios.d.ts +1 -2
  102. package/dist/typescript/utils/push/ios.d.ts.map +1 -1
  103. package/dist/typescript/utils/push/libs/callingx.d.ts +9 -0
  104. package/dist/typescript/utils/push/libs/callingx.d.ts.map +1 -0
  105. package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts +16 -2
  106. package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts.map +1 -1
  107. package/dist/typescript/utils/push/libs/index.d.ts +1 -2
  108. package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
  109. package/dist/typescript/utils/push/libs/notifee/index.d.ts +0 -1
  110. package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
  111. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +8 -0
  112. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +1 -0
  113. package/dist/typescript/utils/push/setupIosVoipPushEvents.d.ts.map +1 -1
  114. package/expo-config-plugin/dist/withAndroidManifest.js +1 -33
  115. package/expo-config-plugin/dist/withAndroidPermissions.js +2 -7
  116. package/expo-config-plugin/dist/withAppDelegate.js +19 -197
  117. package/expo-config-plugin/dist/withMainActivity.js +1 -1
  118. package/expo-config-plugin/dist/withiOSInfoPlist.js +2 -3
  119. package/ios/StreamInCallManager.swift +4 -0
  120. package/ios/StreamVideoReactNative.h +7 -4
  121. package/ios/StreamVideoReactNative.m +191 -82
  122. package/package.json +10 -15
  123. package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +361 -0
  124. package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +21 -34
  125. package/src/hooks/useAndroidKeepCallAliveEffect.ts +95 -120
  126. package/src/index.ts +1 -0
  127. package/src/modules/call-manager/CallManager.ts +30 -0
  128. package/src/providers/StreamCall/index.tsx +6 -6
  129. package/src/utils/StreamVideoRN/index.ts +40 -30
  130. package/src/utils/StreamVideoRN/types.ts +56 -29
  131. package/src/utils/internal/registerSDKGlobals.ts +42 -4
  132. package/src/utils/keepCallAliveHeadlessTask.ts +54 -0
  133. package/src/utils/push/android.ts +223 -308
  134. package/src/utils/push/internal/ios.ts +25 -46
  135. package/src/utils/push/internal/rxSubjects.ts +0 -29
  136. package/src/utils/push/internal/utils.ts +25 -0
  137. package/src/utils/push/ios.ts +1 -6
  138. package/src/utils/push/libs/callingx.ts +90 -0
  139. package/src/utils/push/libs/index.ts +1 -2
  140. package/src/utils/push/libs/notifee/index.ts +0 -27
  141. package/src/utils/push/setupCallingExpEvents.ts +100 -0
  142. package/src/utils/push/setupIosVoipPushEvents.ts +11 -7
  143. package/CHANGELOG.md +0 -3089
  144. package/android/src/main/java/com/streamvideo/reactnative/util/CallAliveServiceChecker.kt +0 -95
  145. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -160
  146. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
  147. package/dist/commonjs/utils/push/libs/callkeep.js +0 -17
  148. package/dist/commonjs/utils/push/libs/callkeep.js.map +0 -1
  149. package/dist/commonjs/utils/push/libs/voipPushNotification.js +0 -17
  150. package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +0 -1
  151. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +0 -205
  152. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +0 -1
  153. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -153
  154. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
  155. package/dist/module/utils/push/libs/callkeep.js +0 -11
  156. package/dist/module/utils/push/libs/callkeep.js.map +0 -1
  157. package/dist/module/utils/push/libs/voipPushNotification.js +0 -11
  158. package/dist/module/utils/push/libs/voipPushNotification.js.map +0 -1
  159. package/dist/module/utils/push/setupIosCallKeepEvents.js +0 -199
  160. package/dist/module/utils/push/setupIosCallKeepEvents.js.map +0 -1
  161. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +0 -5
  162. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +0 -1
  163. package/dist/typescript/utils/push/libs/callkeep.d.ts +0 -3
  164. package/dist/typescript/utils/push/libs/callkeep.d.ts.map +0 -1
  165. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +0 -3
  166. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +0 -1
  167. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +0 -6
  168. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +0 -1
  169. package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +0 -235
  170. package/src/utils/push/libs/callkeep.ts +0 -16
  171. package/src/utils/push/libs/voipPushNotification.ts +0 -17
  172. package/src/utils/push/setupIosCallKeepEvents.ts +0 -252
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-native-sdk",
3
- "version": "1.28.1",
3
+ "version": "1.29.0-beta.0",
4
4
  "description": "Stream Video SDK for React Native",
5
5
  "author": "https://getstream.io",
6
6
  "homepage": "https://getstream.io/video/docs/react-native/",
@@ -65,6 +65,7 @@
65
65
  "@react-native-firebase/app": ">=17.5.0",
66
66
  "@react-native-firebase/messaging": ">=17.5.0",
67
67
  "@stream-io/noise-cancellation-react-native": ">=0.1.0",
68
+ "@stream-io/react-native-callingx": ">=0.1.0",
68
69
  "@stream-io/react-native-webrtc": ">=137.1.0",
69
70
  "@stream-io/video-filters-react-native": ">=0.1.0",
70
71
  "expo": ">=47.0.0",
@@ -72,11 +73,9 @@
72
73
  "expo-notifications": "*",
73
74
  "react": ">=17.0.0",
74
75
  "react-native": ">=0.73.0",
75
- "react-native-callkeep": ">=4.3.11",
76
76
  "react-native-gesture-handler": ">=2.8.0",
77
77
  "react-native-reanimated": ">=2.7.0",
78
- "react-native-svg": ">=13.6.0",
79
- "react-native-voip-push-notification": ">=3.3.1"
78
+ "react-native-svg": ">=13.6.0"
80
79
  },
81
80
  "peerDependenciesMeta": {
82
81
  "@notifee/react-native": {
@@ -94,6 +93,9 @@
94
93
  "@stream-io/noise-cancellation-react-native": {
95
94
  "optional": true
96
95
  },
96
+ "@stream-io/react-native-callingx": {
97
+ "optional": true
98
+ },
97
99
  "@stream-io/video-filters-react-native": {
98
100
  "optional": true
99
101
  },
@@ -106,17 +108,11 @@
106
108
  "expo-notifications": {
107
109
  "optional": true
108
110
  },
109
- "react-native-callkeep": {
110
- "optional": true
111
- },
112
111
  "react-native-gesture-handler": {
113
112
  "optional": true
114
113
  },
115
114
  "react-native-reanimated": {
116
115
  "optional": true
117
- },
118
- "react-native-voip-push-notification": {
119
- "optional": true
120
116
  }
121
117
  },
122
118
  "devDependencies": {
@@ -130,9 +126,10 @@
130
126
  "@react-native-firebase/app": "^23.4.0",
131
127
  "@react-native-firebase/messaging": "^23.4.0",
132
128
  "@react-native/babel-preset": "^0.81.5",
133
- "@stream-io/noise-cancellation-react-native": "^0.5.0",
129
+ "@stream-io/noise-cancellation-react-native": "0.5.0",
130
+ "@stream-io/react-native-callingx": "0.1.0-beta.0",
134
131
  "@stream-io/react-native-webrtc": "137.1.0",
135
- "@stream-io/video-filters-react-native": "^0.10.0",
132
+ "@stream-io/video-filters-react-native": "0.10.0",
136
133
  "@testing-library/jest-native": "^5.4.3",
137
134
  "@testing-library/react-native": "13.3.3",
138
135
  "@tsconfig/node18": "^18.2.4",
@@ -148,11 +145,9 @@
148
145
  "react": "19.1.0",
149
146
  "react-native": "^0.81.5",
150
147
  "react-native-builder-bob": "~0.23",
151
- "react-native-callkeep": "^4.3.16",
152
148
  "react-native-gesture-handler": "^2.28.0",
153
149
  "react-native-reanimated": "~4.1.2",
154
150
  "react-native-svg": "^15.14.0",
155
- "react-native-voip-push-notification": "3.3.3",
156
151
  "react-native-worklets": "^0.5.0",
157
152
  "react-test-renderer": "19.1.0",
158
153
  "rimraf": "^6.0.1",
@@ -167,4 +162,4 @@
167
162
  "typescript"
168
163
  ]
169
164
  }
170
- }
165
+ }
@@ -0,0 +1,361 @@
1
+ import {
2
+ CallingState,
3
+ MemberResponse,
4
+ StreamVideoParticipant,
5
+ videoLoggerSystem,
6
+ } from '@stream-io/video-client';
7
+ import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
8
+ import { useEffect, useMemo, useRef } from 'react';
9
+ import { getCallingxLibIfAvailable } from '../../utils/push/libs/callingx';
10
+
11
+ const logger = videoLoggerSystem.getLogger(
12
+ 'useCallingExpWithCallingStateEffect',
13
+ );
14
+
15
+ //calling state methods are not exhaustive, so we need to add more methods to cover different cases
16
+ const canAcceptIncomingCall = (
17
+ prevState: CallingState | undefined,
18
+ currentState: CallingState | undefined,
19
+ ) => {
20
+ if (!prevState && !currentState) {
21
+ return false;
22
+ }
23
+
24
+ const isJoined = (state: CallingState | undefined) => {
25
+ if (!state) {
26
+ return false;
27
+ }
28
+
29
+ return state === CallingState.JOINING || state === CallingState.JOINED;
30
+ };
31
+
32
+ return (
33
+ (!isJoined(prevState) && isJoined(currentState)) ||
34
+ (prevState === CallingState.JOINING && currentState === CallingState.JOINED)
35
+ );
36
+ };
37
+
38
+ const canEndCall = (
39
+ prevState: CallingState | undefined,
40
+ currentState: CallingState | undefined,
41
+ ) => {
42
+ if (!prevState && !currentState) {
43
+ return false;
44
+ }
45
+
46
+ return (
47
+ (prevState === CallingState.JOINED ||
48
+ prevState === CallingState.JOINING ||
49
+ prevState === CallingState.RINGING ||
50
+ prevState === CallingState.RECONNECTING ||
51
+ prevState === CallingState.MIGRATING ||
52
+ prevState === CallingState.OFFLINE) &&
53
+ (currentState === CallingState.LEFT ||
54
+ currentState === CallingState.RECONNECTING_FAILED ||
55
+ currentState === CallingState.IDLE)
56
+ );
57
+ };
58
+
59
+ const canStartCall = (
60
+ prevState: CallingState | undefined,
61
+ currentState: CallingState | undefined,
62
+ ) => {
63
+ if (!prevState && !currentState) {
64
+ return false;
65
+ }
66
+
67
+ return (
68
+ (!prevState ||
69
+ prevState === CallingState.IDLE ||
70
+ prevState === CallingState.UNKNOWN) &&
71
+ (currentState === CallingState.JOINED ||
72
+ currentState === CallingState.JOINING ||
73
+ currentState === CallingState.RINGING)
74
+ );
75
+ };
76
+
77
+ function getCallDisplayName(
78
+ callMembers: MemberResponse[] | undefined,
79
+ participants: StreamVideoParticipant[] | undefined,
80
+ currentUserId: string | undefined,
81
+ ) {
82
+ if (!callMembers || !participants || !currentUserId) {
83
+ return 'Call';
84
+ }
85
+
86
+ let names: string[] = [];
87
+
88
+ if (callMembers.length > 0) {
89
+ names = callMembers
90
+ .filter((member) => member.user.id !== currentUserId)
91
+ .map((member) => member.user.name)
92
+ .filter((name): name is string => name !== undefined);
93
+ } else if (participants.length > 0) {
94
+ names = participants
95
+ .filter((participant) => participant.userId !== currentUserId)
96
+ .map((participant) => participant.name)
97
+ .filter(Boolean);
98
+ }
99
+
100
+ return names.length > 0 ? names.sort().join(', ') : 'Call';
101
+ }
102
+
103
+ /**
104
+ * This hook is used to inform sync call state with CallKit/Telecom (i.e. start call, end call, mute/unmute call).
105
+ */
106
+ export const useCallingExpWithCallingStateEffect = () => {
107
+ const {
108
+ useCallCallingState,
109
+ // useMicrophoneState,
110
+ useParticipants,
111
+ useCallMembers,
112
+ } = useCallStateHooks();
113
+
114
+ const activeCall = useCall();
115
+ const callingState = useCallCallingState();
116
+ // const { isMute, microphone } = useMicrophoneState();
117
+ const callMembers = useCallMembers();
118
+ const participants = useParticipants();
119
+
120
+ const prevState = useRef<CallingState | undefined>(undefined);
121
+
122
+ const activeCallCid = activeCall?.cid;
123
+ const isIncomingCall = activeCall?.ringing && !activeCall?.isCreatedByMe;
124
+ const isOutcomingCall = activeCall?.ringing && activeCall?.isCreatedByMe;
125
+ const currentUserId = activeCall?.currentUserId;
126
+ const isVideoCall = activeCall?.state.settings?.video?.enabled ?? false;
127
+
128
+ const callDisplayName = useMemo(
129
+ () => getCallDisplayName(callMembers, participants, currentUserId),
130
+ [callMembers, participants, currentUserId],
131
+ );
132
+
133
+ useEffect(() => {
134
+ return () => {
135
+ const callingx = getCallingxLibIfAvailable();
136
+ if (!callingx?.isSetup || !activeCallCid) {
137
+ return;
138
+ }
139
+
140
+ const isCallRegistered = callingx.isCallRegistered(activeCallCid);
141
+ if (!isCallRegistered) {
142
+ logger.debug(
143
+ `No active call cid to end in calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`,
144
+ );
145
+ return;
146
+ }
147
+ //if incoming stream call was unmounted, we need to end the call in CallKit/Telecom
148
+ logger.debug(`Ending call in calling exp: ${activeCallCid}`);
149
+ callingx
150
+ .endCallWithReason(activeCallCid, 'local')
151
+ .catch((error: unknown) => {
152
+ logger.error(
153
+ `Error ending call in calling exp: ${activeCallCid}`,
154
+ error,
155
+ );
156
+ });
157
+ };
158
+ }, [activeCallCid]);
159
+
160
+ useEffect(() => {
161
+ const callingx = getCallingxLibIfAvailable();
162
+ if (
163
+ !callingx?.isSetup ||
164
+ !activeCallCid ||
165
+ prevState.current === callingState
166
+ ) {
167
+ return;
168
+ }
169
+
170
+ //tells if call is registered in CallKit/Telecom
171
+ const isCallRegistered = callingx.isCallRegistered(activeCallCid);
172
+ logger.debug(
173
+ `useEffect: ${activeCallCid} isCallRegistered: ${isCallRegistered}
174
+ isIncomingCall: ${isIncomingCall} isOutcomingCall: ${isOutcomingCall}
175
+ prevState: ${prevState.current}, currentState: ${callingState}
176
+ isOngoingCallsEnabled: ${callingx.isOngoingCallsEnabled}`,
177
+ );
178
+
179
+ if (
180
+ isIncomingCall &&
181
+ isCallRegistered &&
182
+ canAcceptIncomingCall(prevState.current, callingState)
183
+ ) {
184
+ logger.debug(`Should accept call in callkeep: ${activeCallCid}`);
185
+ callingx.answerIncomingCall(activeCallCid).catch((error: unknown) => {
186
+ logger.error(
187
+ `Error answering call in calling exp: ${activeCallCid}`,
188
+ error,
189
+ );
190
+ });
191
+ } else if (
192
+ (isOutcomingCall ||
193
+ (!isIncomingCall && callingx.isOngoingCallsEnabled)) && //we register call in case if is outcoming ringing call or it is non-ringing call and ongoing calls are enabled
194
+ !isCallRegistered &&
195
+ canStartCall(prevState.current, callingState)
196
+ ) {
197
+ logger.debug(`Should register call in callkeep: ${activeCallCid}`);
198
+ //we request start call action from CallKit/Telecom, next step is to make call active when we receive call started event
199
+ callingx
200
+ .startCall(activeCallCid, activeCallCid, callDisplayName, isVideoCall)
201
+ .catch((error: unknown) => {
202
+ logger.error(
203
+ `Error starting call in calling exp: ${activeCallCid}`,
204
+ error,
205
+ );
206
+ });
207
+ } else if (
208
+ isCallRegistered &&
209
+ canEndCall(prevState.current, callingState)
210
+ ) {
211
+ //in case call was registered as incoming and state changed to "not joined", we need to end the call and clear rxjs subject
212
+ logger.debug(`Should end call in callkeep: ${activeCallCid}`);
213
+ //TODO: think about sending appropriate reason for end call
214
+ callingx
215
+ .endCallWithReason(activeCallCid, 'local')
216
+ .catch((error: unknown) => {
217
+ logger.error(
218
+ `Error ending call in calling exp: ${activeCallCid}`,
219
+ error,
220
+ );
221
+ });
222
+ }
223
+
224
+ prevState.current = callingState;
225
+ }, [
226
+ activeCallCid,
227
+ callingState,
228
+ callDisplayName,
229
+ isIncomingCall,
230
+ isOutcomingCall,
231
+ isVideoCall,
232
+ ]);
233
+
234
+ useEffect(() => {
235
+ const callingx = getCallingxLibIfAvailable();
236
+ if (!callingx?.isSetup || !activeCallCid) {
237
+ logger.debug(
238
+ `No active call cid to listen to start call action in calling exp: ${activeCallCid} callingx is not setup`,
239
+ );
240
+ return;
241
+ }
242
+
243
+ if (
244
+ !isOutcomingCall &&
245
+ !(!isIncomingCall && callingx.isOngoingCallsEnabled)
246
+ ) {
247
+ logger.debug(
248
+ `Call is not outcoming or ongoing calls are not enabled for non-ringing calls`,
249
+ );
250
+ return;
251
+ }
252
+
253
+ //listen to start call action from CallKit/Telecom and set the current call active
254
+ const subscription = callingx.addEventListener(
255
+ 'didReceiveStartCallAction',
256
+ ({ callId }: { callId: string }) => {
257
+ if (callId === activeCallCid) {
258
+ logger.debug(`Received start call action for call: ${activeCallCid}`);
259
+ callingx
260
+ .setCurrentCallActive(activeCallCid)
261
+ .catch((error: unknown) => {
262
+ logger.error(
263
+ `Error answering call in calling exp: ${activeCallCid}`,
264
+ error,
265
+ );
266
+ });
267
+ }
268
+ },
269
+ );
270
+
271
+ return () => {
272
+ subscription.remove();
273
+ };
274
+ }, [activeCallCid, isOutcomingCall, isIncomingCall]);
275
+
276
+ useEffect(() => {
277
+ const callingx = getCallingxLibIfAvailable();
278
+ if (!callingx?.isSetup || !activeCallCid) {
279
+ return;
280
+ }
281
+
282
+ const isCallRegistered = callingx.isCallRegistered(activeCallCid);
283
+ if (!isCallRegistered) {
284
+ logger.debug(
285
+ `No active call cid to update calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`,
286
+ );
287
+ return;
288
+ }
289
+
290
+ callingx.updateDisplay(activeCallCid, activeCallCid, callDisplayName);
291
+ }, [activeCallCid, callDisplayName]);
292
+
293
+ // useEffect(() => {
294
+ // const callingx = getCallingxLibIfAvailable();
295
+ // if (!callingx?.isSetup || !activeCallCid) {
296
+ // return;
297
+ // }
298
+
299
+ // const isCallRegistered = callingx.isCallRegistered(activeCallCid);
300
+ // if (!isCallRegistered) {
301
+ // logger.debug(
302
+ // `No active call cid to set muted in calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`,
303
+ // );
304
+ // return;
305
+ // }
306
+
307
+ // callingx.setMutedCall(activeCallCid, isMute);
308
+ // }, [activeCallCid, isMute]);
309
+
310
+ // useEffect(() => {
311
+ // const callingx = getCallingxLibIfAvailable();
312
+ // if (!callingx?.isSetup || !activeCallCid) {
313
+ // return;
314
+ // }
315
+
316
+ // const isCallRegistered = callingx.isCallRegistered(activeCallCid);
317
+ // if (!isCallRegistered) {
318
+ // logger.debug(
319
+ // `No active call cid to set muted in calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`,
320
+ // );
321
+ // return;
322
+ // }
323
+
324
+ // //listen to mic toggle events from CallKit/Telecom and update stream call microphone state
325
+ // const subscription = callingx.addEventListener(
326
+ // 'didPerformSetMutedCallAction',
327
+ // async (event: { callId: string; muted: boolean }) => {
328
+ // const { callId, muted } = event;
329
+
330
+ // if (callId === activeCallCid) {
331
+ // const isCurrentlyMuted =
332
+ // RxUtils.getCurrentValue(microphone.state.status$) === 'disabled';
333
+ // if (isCurrentlyMuted === muted) {
334
+ // logger.debug(
335
+ // `Mic toggle is already in the desired state: ${muted} for call: ${activeCallCid}`,
336
+ // );
337
+ // //this check prevents mic toggle when state change was initiated from client and not from CallKit/Telecom
338
+ // return;
339
+ // }
340
+
341
+ // try {
342
+ // if (muted) {
343
+ // await microphone.disable();
344
+ // } else {
345
+ // await microphone.enable();
346
+ // }
347
+ // } catch (error: unknown) {
348
+ // logger.error(
349
+ // `Error toggling mic in calling exp: ${activeCallCid}`,
350
+ // error,
351
+ // );
352
+ // }
353
+ // }
354
+ // },
355
+ // );
356
+
357
+ // return () => {
358
+ // subscription.remove();
359
+ // };
360
+ // }, [activeCallCid, microphone, isOutcomingCall, isIncomingCall]);
361
+ };
@@ -1,6 +1,4 @@
1
1
  import { type MutableRefObject, useEffect, useRef, useState } from 'react';
2
- import { getVoipPushNotificationLib } from '../../utils/push/libs';
3
-
4
2
  import { Platform } from 'react-native';
5
3
  import { StreamVideoRN } from '../../utils';
6
4
  import { onVoipNotificationReceived } from '../../utils/push/internal/ios';
@@ -10,6 +8,7 @@ import {
10
8
  } from '@stream-io/video-react-bindings';
11
9
  import { setPushLogoutCallback } from '../../utils/internal/pushLogoutCallback';
12
10
  import { StreamVideoClient, videoLoggerSystem } from '@stream-io/video-client';
11
+ import { getCallingxLibIfAvailable } from '../../utils/push/libs';
13
12
 
14
13
  const logger = videoLoggerSystem.getLogger('useIosVoipPushEventsSetupEffect');
15
14
 
@@ -28,6 +27,7 @@ function setLogoutCallback(
28
27
  lastVoipTokenRef.current = { token: '', userId: '' };
29
28
  try {
30
29
  await client.removeDevice(token);
30
+ logger.debug('PushLogoutCallback - Removed voip token', token);
31
31
  } catch (err) {
32
32
  logger.warn('PushLogoutCallback - Failed to remove voip token', err);
33
33
  }
@@ -89,24 +89,12 @@ export const useIosVoipPushEventsSetupEffect = () => {
89
89
  useEffect(() => {
90
90
  const pushConfig = StreamVideoRN.getConfig().push;
91
91
  const pushProviderName = pushConfig?.ios.pushProviderName;
92
- if (Platform.OS !== 'ios' || !client || !pushProviderName) {
93
- return;
94
- }
95
- if (!pushConfig.android.incomingCallChannel) {
96
- // TODO: remove this check and find a better way once we have telecom integration for android
97
- logger.debug(
98
- 'android incomingCallChannel is not defined, so skipping the useIosVoipPushEventsSetupEffect',
99
- );
92
+ const callingx = getCallingxLibIfAvailable();
93
+
94
+ if (Platform.OS !== 'ios' || !client || !pushProviderName || !callingx) {
100
95
  return;
101
96
  }
102
97
 
103
- const voipPushNotification = getVoipPushNotificationLib();
104
-
105
- // even though we do this natively, we have to still register here again
106
- // natively this will make sure "register" event for JS is sent with the last push token
107
- // Necessary if client changed before we got the event here or user logged out and logged in again
108
- voipPushNotification.registerVoipToken();
109
-
110
98
  const onTokenReceived = (token: string) => {
111
99
  const userId = client.streamClient._user?.id ?? '';
112
100
  if (client.streamClient.anonymous || !token || !userId) {
@@ -145,24 +133,24 @@ export const useIosVoipPushEventsSetupEffect = () => {
145
133
  });
146
134
  };
147
135
  // fired when PushKit give us the latest token
148
- voipPushNotification.addEventListener('register', (token) => {
149
- onTokenReceived(token);
150
- });
136
+ const voipRegisterListener = callingx.addEventListener(
137
+ 'voipNotificationsRegistered',
138
+ ({ token }) => {
139
+ onTokenReceived(token);
140
+ },
141
+ );
151
142
 
152
- // this will fire when there are events occured before js bridge initialized
153
- voipPushNotification.addEventListener('didLoadWithEvents', (events) => {
154
- if (!events || !Array.isArray(events) || events.length < 1) {
155
- return;
156
- }
157
- for (const voipPushEvent of events) {
158
- const { name, data } = voipPushEvent;
159
- if (name === 'RNVoipPushRemoteNotificationsRegisteredEvent') {
160
- onTokenReceived(data);
161
- } else if (name === 'RNVoipPushRemoteNotificationReceivedEvent') {
162
- onVoipNotificationReceived(data, pushConfig);
163
- }
143
+ // this will return events that were fired before js bridge initialized
144
+ callingx.getInitialVoipEvents().forEach(({ eventName, params }) => {
145
+ if (eventName === 'voipNotificationsRegistered' && 'token' in params) {
146
+ onTokenReceived(params.token);
147
+ } else if (eventName === 'voipNotificationReceived') {
148
+ onVoipNotificationReceived(params, pushConfig);
164
149
  }
165
150
  });
151
+
152
+ callingx.registerVoipToken();
153
+
166
154
  lastListener.count += 1;
167
155
  const currentListenerCount = lastListener.count;
168
156
 
@@ -175,8 +163,7 @@ export const useIosVoipPushEventsSetupEffect = () => {
175
163
  return;
176
164
  }
177
165
  logger.debug(`Voip event listeners are removed for user: ${userId}`);
178
- voipPushNotification.removeEventListener('didLoadWithEvents');
179
- voipPushNotification.removeEventListener('register');
166
+ voipRegisterListener.remove();
180
167
  };
181
168
  }, [client]);
182
169
  };