@stream-io/video-react-native-sdk 1.36.2 → 1.37.1-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.
- package/CHANGELOG.md +15 -0
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +81 -0
- package/android/src/main/java/com/streamvideo/reactnative/recorder/AudioPipeline.kt +436 -0
- package/android/src/main/java/com/streamvideo/reactnative/recorder/EncoderConstants.kt +17 -0
- package/android/src/main/java/com/streamvideo/reactnative/recorder/PipelineHost.kt +36 -0
- package/android/src/main/java/com/streamvideo/reactnative/recorder/RecorderPlaybackSamplesSink.kt +60 -0
- package/android/src/main/java/com/streamvideo/reactnative/recorder/RecorderVideoSink.kt +31 -0
- package/android/src/main/java/com/streamvideo/reactnative/recorder/TracksRecorderManager.kt +329 -0
- package/android/src/main/java/com/streamvideo/reactnative/recorder/VideoPipeline.kt +472 -0
- package/dist/commonjs/hooks/index.js +11 -0
- package/dist/commonjs/hooks/index.js.map +1 -1
- package/dist/commonjs/hooks/useLoopbackRecording.js +243 -0
- package/dist/commonjs/hooks/useLoopbackRecording.js.map +1 -0
- package/dist/commonjs/utils/internal/callingx/callingx.js +18 -38
- package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -1
- package/dist/commonjs/utils/push/internal/ios.js +4 -3
- package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/commonjs/version.js.map +1 -1
- package/dist/module/hooks/index.js +1 -0
- package/dist/module/hooks/index.js.map +1 -1
- package/dist/module/hooks/useLoopbackRecording.js +238 -0
- package/dist/module/hooks/useLoopbackRecording.js.map +1 -0
- package/dist/module/utils/internal/callingx/callingx.js +19 -39
- package/dist/module/utils/internal/callingx/callingx.js.map +1 -1
- package/dist/module/utils/push/internal/ios.js +4 -3
- package/dist/module/utils/push/internal/ios.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/module/version.js.map +1 -1
- package/dist/typescript/hooks/index.d.ts +1 -0
- package/dist/typescript/hooks/index.d.ts.map +1 -1
- package/dist/typescript/hooks/useLoopbackRecording.d.ts +85 -0
- package/dist/typescript/hooks/useLoopbackRecording.d.ts.map +1 -0
- package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/dist/typescript/version.d.ts.map +1 -1
- package/expo-config-plugin/dist/withAppDelegate.js +14 -177
- package/ios/RTCViewPip.swift +6 -6
- package/ios/RTCViewPipManager.swift +47 -10
- package/ios/StreamInCallManager.swift +2 -6
- package/ios/StreamVideoReactNative-Bridging-Header.h +2 -0
- package/ios/StreamVideoReactNative.h +5 -18
- package/ios/StreamVideoReactNative.m +83 -296
- package/ios/TracksRecorder/AudioPipeline.swift +270 -0
- package/ios/TracksRecorder/PipelineHost.swift +56 -0
- package/ios/TracksRecorder/RecorderAudioRenderTap.swift +154 -0
- package/ios/TracksRecorder/RecorderVideoSink.swift +137 -0
- package/ios/TracksRecorder/TracksRecorderManager.swift +327 -0
- package/ios/TracksRecorder/VideoPipeline.swift +297 -0
- package/package.json +8 -8
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useLoopbackRecording.ts +438 -0
- package/src/utils/internal/callingx/callingx.ts +19 -44
- package/src/utils/push/internal/ios.ts +4 -3
- package/src/version.ts +1 -1
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
7
4
|
const codeMod_1 = require("@expo/config-plugins/build/ios/codeMod");
|
|
8
|
-
const addNewLinesToAppDelegateObjc_1 = __importDefault(require("./common/addNewLinesToAppDelegateObjc"));
|
|
9
5
|
const addToSwiftBridgingHeaderFile_1 = require("./common/addToSwiftBridgingHeaderFile");
|
|
10
6
|
const withAppDelegate = (configuration, props) => {
|
|
11
7
|
return (0, config_plugins_1.withAppDelegate)(configuration, (config) => {
|
|
@@ -22,13 +18,9 @@ const withAppDelegate = (configuration, props) => {
|
|
|
22
18
|
}
|
|
23
19
|
config.modResults.contents = addDidFinishLaunchingWithOptionsObjc(config.modResults.contents, props.iOSEnableMultitaskingCameraAccess, props.addNoiseCancellation);
|
|
24
20
|
if (props?.ringing) {
|
|
25
|
-
config.modResults.contents = (0, codeMod_1.addObjcImports)(config.modResults.contents, ['
|
|
21
|
+
config.modResults.contents = (0, codeMod_1.addObjcImports)(config.modResults.contents, ['"StreamVideoReactNative.h"']);
|
|
26
22
|
config.modResults.contents =
|
|
27
23
|
addDidFinishLaunchingWithOptionsRingingObjc(config.modResults.contents);
|
|
28
|
-
config.modResults.contents = addDidUpdatePushCredentialsObjc(config.modResults.contents);
|
|
29
|
-
config.modResults.contents = addDidReceiveIncomingPushCallbackObjc(config.modResults.contents);
|
|
30
|
-
config.modResults.contents =
|
|
31
|
-
addDidReceiveIncomingVoIPPushMetadataCallbackObjc(config.modResults.contents);
|
|
32
24
|
}
|
|
33
25
|
return config;
|
|
34
26
|
}
|
|
@@ -38,26 +30,6 @@ const withAppDelegate = (configuration, props) => {
|
|
|
38
30
|
}
|
|
39
31
|
else {
|
|
40
32
|
try {
|
|
41
|
-
if (props?.ringing) {
|
|
42
|
-
// make it public class AppDelegate: ExpoAppDelegate, PKPushRegistryDelegate {
|
|
43
|
-
const regex = /(class\s+AppDelegate[^{]*)(\s*\{)/;
|
|
44
|
-
config.modResults.contents = config.modResults.contents.replace(regex, (match, declarationPart, openBrace) => {
|
|
45
|
-
// Check if PKPushRegistryDelegate is already in the declaration part
|
|
46
|
-
if (declarationPart.includes('PKPushRegistryDelegate')) {
|
|
47
|
-
return match; // Already present, no change needed
|
|
48
|
-
}
|
|
49
|
-
const trimmedDecl = declarationPart.trimRight();
|
|
50
|
-
// If the declaration already has a colon (superclass or other protocols)
|
|
51
|
-
if (trimmedDecl.includes(':')) {
|
|
52
|
-
return `${trimmedDecl}, PKPushRegistryDelegate${openBrace}`;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// No colon, so AppDelegate is the first thing to be listed after :
|
|
56
|
-
// This means the class declaration was like "class AppDelegate {"
|
|
57
|
-
return `${trimmedDecl}: PKPushRegistryDelegate${openBrace}`;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
33
|
config.modResults.contents = (0, codeMod_1.addSwiftImports)(config.modResults.contents, ['WebRTC']);
|
|
62
34
|
(0, addToSwiftBridgingHeaderFile_1.addToSwiftBridgingHeaderFile)(config.modRequest.projectRoot, (headerFileContents) => {
|
|
63
35
|
headerFileContents = (0, codeMod_1.addObjcImports)(headerFileContents, [
|
|
@@ -72,13 +44,9 @@ const withAppDelegate = (configuration, props) => {
|
|
|
72
44
|
}
|
|
73
45
|
config.modResults.contents = addDidFinishLaunchingWithOptionsSwift(config.modResults.contents, props.iOSEnableMultitaskingCameraAccess, props.addNoiseCancellation);
|
|
74
46
|
if (props?.ringing) {
|
|
75
|
-
config.modResults.contents = (0, codeMod_1.addSwiftImports)(config.modResults.contents, ['
|
|
47
|
+
config.modResults.contents = (0, codeMod_1.addSwiftImports)(config.modResults.contents, ['stream_video_react_native']);
|
|
76
48
|
config.modResults.contents =
|
|
77
49
|
addDidFinishLaunchingWithOptionsRingingSwift(config.modResults.contents);
|
|
78
|
-
config.modResults.contents = addDidUpdatePushCredentialsSwift(config.modResults.contents);
|
|
79
|
-
config.modResults.contents = addDidReceiveIncomingPushCallbackSwift(config.modResults.contents);
|
|
80
|
-
config.modResults.contents =
|
|
81
|
-
addDidReceiveIncomingVoIPPushMetadataCallbackSwift(config.modResults.contents);
|
|
82
50
|
}
|
|
83
51
|
return config;
|
|
84
52
|
}
|
|
@@ -125,157 +93,26 @@ function addDidFinishLaunchingWithOptionsObjc(contents, iOSEnableMultitaskingCam
|
|
|
125
93
|
}
|
|
126
94
|
function addDidFinishLaunchingWithOptionsRingingSwift(contents) {
|
|
127
95
|
const functionSelector = 'application(_:didFinishLaunchingWithOptions:)';
|
|
128
|
-
// call the setup of voip push notification
|
|
129
96
|
const voipSetupMethod = 'StreamVideoReactNative.voipRegistration()';
|
|
130
|
-
if (
|
|
131
|
-
|
|
97
|
+
if (contents.includes(voipSetupMethod)) {
|
|
98
|
+
return contents;
|
|
132
99
|
}
|
|
133
|
-
|
|
100
|
+
const updated = (0, codeMod_1.insertContentsInsideSwiftFunctionBlock)(contents, functionSelector, ' ' + voipSetupMethod, { position: 'head' });
|
|
101
|
+
if (!updated.includes(voipSetupMethod)) {
|
|
102
|
+
throw new Error(`Could not find ${functionSelector} in AppDelegate to inject ${voipSetupMethod}`);
|
|
103
|
+
}
|
|
104
|
+
return updated;
|
|
134
105
|
}
|
|
135
106
|
function addDidFinishLaunchingWithOptionsRingingObjc(contents) {
|
|
136
107
|
const functionSelector = 'application:didFinishLaunchingWithOptions:';
|
|
137
|
-
// call the setup of voip push notification
|
|
138
108
|
const voipSetupMethod = '[StreamVideoReactNative voipRegistration];';
|
|
139
|
-
if (
|
|
140
|
-
contents = (0, codeMod_1.insertContentsInsideObjcFunctionBlock)(contents, functionSelector, voipSetupMethod, { position: 'head' });
|
|
141
|
-
}
|
|
142
|
-
return contents;
|
|
143
|
-
}
|
|
144
|
-
function addDidUpdatePushCredentialsSwift(contents) {
|
|
145
|
-
const updatedPushCredentialsMethod = 'StreamVideoReactNative.didUpdate(credentials, forType: type.rawValue)';
|
|
146
|
-
if (!contents.includes(updatedPushCredentialsMethod)) {
|
|
147
|
-
const functionSelector = 'pushRegistry(_:didUpdate:for:)';
|
|
148
|
-
const codeblock = (0, codeMod_1.findSwiftFunctionCodeBlock)(contents, functionSelector);
|
|
149
|
-
if (!codeblock) {
|
|
150
|
-
return (0, codeMod_1.insertContentsInsideSwiftClassBlock)(contents, 'class AppDelegate', `
|
|
151
|
-
public func pushRegistry(
|
|
152
|
-
_ registry: PKPushRegistry,
|
|
153
|
-
didUpdate credentials: PKPushCredentials,
|
|
154
|
-
for type: PKPushType
|
|
155
|
-
) {
|
|
156
|
-
${updatedPushCredentialsMethod}
|
|
157
|
-
}
|
|
158
|
-
`, { position: 'tail' });
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
return (0, codeMod_1.insertContentsInsideSwiftFunctionBlock)(contents, functionSelector, updatedPushCredentialsMethod, { position: 'tail' });
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return contents;
|
|
165
|
-
}
|
|
166
|
-
function addDidUpdatePushCredentialsObjc(contents) {
|
|
167
|
-
const updatedPushCredentialsMethod = '[StreamVideoReactNative didUpdatePushCredentials:credentials forType: (NSString *) type];';
|
|
168
|
-
if (!contents.includes(updatedPushCredentialsMethod)) {
|
|
169
|
-
const functionSelector = 'pushRegistry:didUpdatePushCredentials:forType:';
|
|
170
|
-
const codeblock = (0, codeMod_1.findObjcFunctionCodeBlock)(contents, functionSelector);
|
|
171
|
-
if (!codeblock) {
|
|
172
|
-
return (0, addNewLinesToAppDelegateObjc_1.default)(contents, [
|
|
173
|
-
'- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {',
|
|
174
|
-
' ' /* indentation */ + updatedPushCredentialsMethod,
|
|
175
|
-
'}',
|
|
176
|
-
]);
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
return (0, codeMod_1.insertContentsInsideObjcFunctionBlock)(contents, functionSelector, updatedPushCredentialsMethod, { position: 'tail' });
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return contents;
|
|
183
|
-
}
|
|
184
|
-
function addDidReceiveIncomingPushCallbackSwift(contents) {
|
|
185
|
-
const onIncomingPush = `
|
|
186
|
-
StreamVideoReactNative.didReceiveIncomingPush(payload, forType: type.rawValue, completionHandler: completion)`;
|
|
187
|
-
if (!contents.includes('StreamVideoReactNative.didReceiveIncomingPush')) {
|
|
188
|
-
const functionSelector = 'pushRegistry(_:didReceiveIncomingPushWith:for:completion:)';
|
|
189
|
-
const codeblock = (0, codeMod_1.findSwiftFunctionCodeBlock)(contents, functionSelector);
|
|
190
|
-
if (!codeblock) {
|
|
191
|
-
return (0, codeMod_1.insertContentsInsideSwiftClassBlock)(contents, 'class AppDelegate', `
|
|
192
|
-
public func pushRegistry(
|
|
193
|
-
_ registry: PKPushRegistry,
|
|
194
|
-
didReceiveIncomingPushWith payload: PKPushPayload,
|
|
195
|
-
for type: PKPushType,
|
|
196
|
-
completion: @escaping () -> Void
|
|
197
|
-
) {
|
|
198
|
-
${onIncomingPush}
|
|
199
|
-
}
|
|
200
|
-
`, { position: 'tail' });
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
return (0, codeMod_1.insertContentsInsideSwiftFunctionBlock)(contents, functionSelector, onIncomingPush, { position: 'tail' });
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return contents;
|
|
207
|
-
}
|
|
208
|
-
function addDidReceiveIncomingPushCallbackObjc(contents) {
|
|
209
|
-
const onIncomingPush = `
|
|
210
|
-
// process the payload and display the incoming call notification
|
|
211
|
-
[StreamVideoReactNative didReceiveIncomingPush:payload forType: (NSString *)type completionHandler:completion];
|
|
212
|
-
`;
|
|
213
|
-
if (!contents.includes('[StreamVideoReactNative didReceiveIncomingPush')) {
|
|
214
|
-
const functionSelector = 'pushRegistry:didReceiveIncomingPushWithPayload:forType:withCompletionHandler:';
|
|
215
|
-
const codeblock = (0, codeMod_1.findObjcFunctionCodeBlock)(contents, functionSelector);
|
|
216
|
-
if (!codeblock) {
|
|
217
|
-
return (0, addNewLinesToAppDelegateObjc_1.default)(contents, [
|
|
218
|
-
'- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {',
|
|
219
|
-
...onIncomingPush.trim().split('\n'),
|
|
220
|
-
'}',
|
|
221
|
-
]);
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
return (0, codeMod_1.insertContentsInsideObjcFunctionBlock)(contents, functionSelector, onIncomingPush, { position: 'tail' });
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
return contents;
|
|
228
|
-
}
|
|
229
|
-
// Injects the iOS 26.4+ VoIP push delegate.
|
|
230
|
-
// - AnyObject for metadata: builds on Xcode older than the iOS 26.4 SDK.
|
|
231
|
-
// - Swift label `didReceiveIncomingVoIPPushWith` (no "Payload") matches the
|
|
232
|
-
// protocol's optional requirement on the iOS 26.4 SDK; combined with
|
|
233
|
-
// `private`, the method is excluded from protocol-conformance checking and
|
|
234
|
-
// Swift auto-derives the same ObjC selector PushKit dispatches on.
|
|
235
|
-
function addDidReceiveIncomingVoIPPushMetadataCallbackSwift(contents) {
|
|
236
|
-
// Match the unique signature, not just the function name: the legacy and
|
|
237
|
-
// new delegates are both 4-arg `pushRegistry(...)` methods, so
|
|
238
|
-
// findSwiftFunctionCodeBlock would confuse them.
|
|
239
|
-
const idempotencyMarker = 'didReceiveIncomingVoIPPushWith payload: PKPushPayload';
|
|
240
|
-
if (contents.includes(idempotencyMarker)) {
|
|
109
|
+
if (contents.includes(voipSetupMethod)) {
|
|
241
110
|
return contents;
|
|
242
111
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
didReceiveIncomingVoIPPushWith payload: PKPushPayload,
|
|
247
|
-
metadata: AnyObject,
|
|
248
|
-
withCompletionHandler completion: @escaping () -> Void
|
|
249
|
-
) {
|
|
250
|
-
StreamVideoReactNative.didReceiveIncomingVoIPPush(
|
|
251
|
-
payload,
|
|
252
|
-
metadata: metadata,
|
|
253
|
-
completionHandler: completion
|
|
254
|
-
)
|
|
255
|
-
}
|
|
256
|
-
`, { position: 'tail' });
|
|
257
|
-
}
|
|
258
|
-
// ObjC counterpart of the Swift helper. Uses `id` for the metadata so it
|
|
259
|
-
// builds on Xcode older than the iOS 26.4 SDK. The new selector is different
|
|
260
|
-
// from the legacy one, so findObjcFunctionCodeBlock is safe to use here.
|
|
261
|
-
function addDidReceiveIncomingVoIPPushMetadataCallbackObjc(contents) {
|
|
262
|
-
const onIncomingPush = `
|
|
263
|
-
[StreamVideoReactNative didReceiveIncomingVoIPPush:payload metadata:metadata completionHandler:completion];
|
|
264
|
-
`;
|
|
265
|
-
if (!contents.includes('[StreamVideoReactNative didReceiveIncomingVoIPPush:payload')) {
|
|
266
|
-
const functionSelector = 'pushRegistry:didReceiveIncomingVoIPPushWithPayload:metadata:withCompletionHandler:';
|
|
267
|
-
const codeblock = (0, codeMod_1.findObjcFunctionCodeBlock)(contents, functionSelector);
|
|
268
|
-
if (!codeblock) {
|
|
269
|
-
return (0, addNewLinesToAppDelegateObjc_1.default)(contents, [
|
|
270
|
-
'- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingVoIPPushWithPayload:(PKPushPayload *)payload metadata:(id)metadata withCompletionHandler:(void (^)(void))completion {',
|
|
271
|
-
...onIncomingPush.trim().split('\n'),
|
|
272
|
-
'}',
|
|
273
|
-
]);
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
return (0, codeMod_1.insertContentsInsideObjcFunctionBlock)(contents, functionSelector, onIncomingPush, { position: 'tail' });
|
|
277
|
-
}
|
|
112
|
+
const updated = (0, codeMod_1.insertContentsInsideObjcFunctionBlock)(contents, functionSelector, voipSetupMethod, { position: 'head' });
|
|
113
|
+
if (!updated.includes(voipSetupMethod)) {
|
|
114
|
+
throw new Error(`Could not find ${functionSelector} in AppDelegate to inject ${voipSetupMethod}`);
|
|
278
115
|
}
|
|
279
|
-
return
|
|
116
|
+
return updated;
|
|
280
117
|
}
|
|
281
118
|
exports.default = withAppDelegate;
|
package/ios/RTCViewPip.swift
CHANGED
|
@@ -13,6 +13,8 @@ class RTCViewPip: UIView {
|
|
|
13
13
|
|
|
14
14
|
private var pictureInPictureController: StreamPictureInPictureController? = StreamPictureInPictureController()
|
|
15
15
|
private var webRtcModule: WebRTCModule?
|
|
16
|
+
// Back-reference set by RTCViewPipManager
|
|
17
|
+
weak var manager: RTCViewPipManager?
|
|
16
18
|
|
|
17
19
|
@objc var onPiPChange: RCTBubblingEventBlock?
|
|
18
20
|
|
|
@@ -193,12 +195,10 @@ class RTCViewPip: UIView {
|
|
|
193
195
|
self.pictureInPictureController?.onPiPStateChange = { [weak self] isActive in
|
|
194
196
|
self?.sendPiPChangeEvent(isActive: isActive)
|
|
195
197
|
}
|
|
196
|
-
if let reactTag = self.reactTag,
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
self.setPreferredContentSize(size)
|
|
201
|
-
}
|
|
198
|
+
if let reactTag = self.reactTag,
|
|
199
|
+
let size = self.manager?.getCachedSize(for: reactTag) {
|
|
200
|
+
PictureInPictureLogger.log("Applying cached size \(size) for reactTag \(reactTag)")
|
|
201
|
+
self.setPreferredContentSize(size)
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
}
|
|
@@ -9,25 +9,62 @@ import Foundation
|
|
|
9
9
|
|
|
10
10
|
@objc(RTCViewPipManager)
|
|
11
11
|
class RTCViewPipManager: RCTViewManager {
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
private var cachedSizes: [NSNumber: CGSize] = [:]
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
// Swift equivalent of Obj-C `@synthesize moduleRegistry/viewRegistry_DEPRECATED`.
|
|
16
|
+
private weak var injectedModuleRegistry: RCTModuleRegistry?
|
|
17
|
+
@objc override var moduleRegistry: RCTModuleRegistry! {
|
|
18
|
+
get { injectedModuleRegistry }
|
|
19
|
+
set { injectedModuleRegistry = newValue }
|
|
20
|
+
}
|
|
21
|
+
private weak var injectedViewRegistry: RCTViewRegistry?
|
|
22
|
+
@objc override var viewRegistry_DEPRECATED: RCTViewRegistry! {
|
|
23
|
+
get { injectedViewRegistry }
|
|
24
|
+
set { injectedViewRegistry = newValue }
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
override func view() -> UIView! {
|
|
16
28
|
let view = RTCViewPip()
|
|
17
|
-
view.
|
|
29
|
+
view.manager = self
|
|
30
|
+
view.setWebRtcModule(moduleRegistry.module(forName: "WebRTCModule") as! WebRTCModule)
|
|
18
31
|
return view
|
|
19
32
|
}
|
|
20
|
-
|
|
33
|
+
|
|
21
34
|
override static func requiresMainQueueSetup() -> Bool {
|
|
22
35
|
return true
|
|
23
36
|
}
|
|
37
|
+
|
|
38
|
+
// Resolves the `RTCViewPip` backing a registry lookup, across both RN architectures.
|
|
39
|
+
// Legacy interop stores the backing view in `contentView` since RN 0.73,
|
|
40
|
+
// and newer RN versions also expose it via `paperView`.
|
|
41
|
+
// Taken from https://github.com/rnmapbox/maps/blob/ab2a6dc183dff3a88527803c41edab7d29-2df9cb/ios/RNMBX/Utils/RNMBXViewResolver.mm#L110-L126
|
|
42
|
+
private func resolvePipView(_ view: UIView?) -> RTCViewPip? {
|
|
43
|
+
guard let view else { return nil }
|
|
44
|
+
|
|
45
|
+
if let pipView = view as? RTCViewPip {
|
|
46
|
+
return pipView
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for selectorName in ["paperView", "contentView"] {
|
|
50
|
+
let selector = NSSelectorFromString(selectorName)
|
|
51
|
+
|
|
52
|
+
if view.responds(to: selector),
|
|
53
|
+
let wrappedView = view.perform(selector)?.takeUnretainedValue() as? UIView,
|
|
54
|
+
let pipView = wrappedView as? RTCViewPip {
|
|
55
|
+
return pipView
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return nil
|
|
60
|
+
}
|
|
24
61
|
|
|
25
62
|
@objc(onCallClosed:)
|
|
26
63
|
func onCallClosed(_ reactTag: NSNumber) {
|
|
27
64
|
|
|
28
|
-
|
|
29
|
-
let view =
|
|
30
|
-
if let pipView = view
|
|
65
|
+
viewRegistry_DEPRECATED.addUIBlock({ viewRegistry in
|
|
66
|
+
let view = viewRegistry?.view(forReactTag: reactTag)
|
|
67
|
+
if let pipView = self.resolvePipView(view) {
|
|
31
68
|
DispatchQueue.main.async {
|
|
32
69
|
pipView.onCallClosed()
|
|
33
70
|
}
|
|
@@ -42,9 +79,9 @@ class RTCViewPipManager: RCTViewManager {
|
|
|
42
79
|
func setPreferredContentSize(_ reactTag: NSNumber, width: CGFloat, height: CGFloat) {
|
|
43
80
|
let size = CGSize(width: width, height: height)
|
|
44
81
|
|
|
45
|
-
|
|
46
|
-
let view =
|
|
47
|
-
if let pipView = view
|
|
82
|
+
viewRegistry_DEPRECATED.addUIBlock({ viewRegistry in
|
|
83
|
+
let view = viewRegistry?.view(forReactTag: reactTag)
|
|
84
|
+
if let pipView = self.resolvePipView(view) {
|
|
48
85
|
DispatchQueue.main.async {
|
|
49
86
|
pipView.setPreferredContentSize(size)
|
|
50
87
|
}
|
|
@@ -470,12 +470,8 @@ class StreamInCallManager: RCTEventEmitter {
|
|
|
470
470
|
|
|
471
471
|
// MARK: - Helper Methods
|
|
472
472
|
private func getAudioDeviceModule() -> AudioDeviceModule {
|
|
473
|
-
guard let
|
|
474
|
-
fatalError("
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
guard let webrtcModule = bridge.module(forName: "WebRTCModule") as? WebRTCModule else {
|
|
478
|
-
fatalError("WebRTCModule is required but not registered with the bridge")
|
|
473
|
+
guard let webrtcModule = moduleRegistry?.module(forName: "WebRTCModule") as? WebRTCModule else {
|
|
474
|
+
fatalError("WebRTCModule is required but not registered with the module registry")
|
|
479
475
|
}
|
|
480
476
|
|
|
481
477
|
return webrtcModule.audioDeviceModule
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#import <React/RCTEventEmitter.h>
|
|
2
2
|
#import <React/RCTBridge.h>
|
|
3
|
-
#import <PushKit/PushKit.h>
|
|
4
3
|
|
|
5
4
|
@interface StreamVideoReactNative : RCTEventEmitter <RCTBridgeModule>
|
|
6
5
|
|
|
@@ -10,24 +9,12 @@
|
|
|
10
9
|
|
|
11
10
|
+ (BOOL)hasAnyActiveCall;
|
|
12
11
|
|
|
13
|
-
+ (void)voipRegistration;
|
|
14
|
-
|
|
15
|
-
+ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type;
|
|
16
|
-
|
|
17
|
-
+ (void)didReceiveIncomingPush:(PKPushPayload *)payload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion;
|
|
18
|
-
|
|
19
12
|
/**
|
|
20
|
-
* VoIP push
|
|
21
|
-
* `
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* configured options.
|
|
25
|
-
*
|
|
26
|
-
* `metadata` is typed `id` (not `PKVoIPPushMetadata *`) so the call site
|
|
27
|
-
* compiles on Xcode older than the iOS 26.4 SDK.
|
|
13
|
+
* Registers for VoIP push notifications. The SDK owns the `PKPushRegistry` and
|
|
14
|
+
* its delegate internally, so your `AppDelegate` does not need to conform to
|
|
15
|
+
* `PKPushRegistryDelegate` or implement any `pushRegistry(...)` methods. Call
|
|
16
|
+
* once from `application:didFinishLaunchingWithOptions:`.
|
|
28
17
|
*/
|
|
29
|
-
+ (void)
|
|
30
|
-
metadata:(id _Nullable)metadata
|
|
31
|
-
completionHandler:(void (^_Nullable)(void))completion;
|
|
18
|
+
+ (void)voipRegistration;
|
|
32
19
|
|
|
33
20
|
@end
|