@stream-io/video-react-native-sdk 1.19.1 → 1.20.1-alpha.1
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/commonjs/components/Call/CallLayout/CallParticipantsGrid.js +10 -1
- package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js +3 -2
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
- package/dist/commonjs/contexts/BackgroundFilters.js +4 -0
- package/dist/commonjs/contexts/BackgroundFilters.js.map +1 -1
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +31 -12
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/commonjs/hooks/useTrackDimensions.js +31 -35
- package/dist/commonjs/hooks/useTrackDimensions.js.map +1 -1
- package/dist/commonjs/providers/StreamCall/DeviceStats.js +19 -8
- package/dist/commonjs/providers/StreamCall/DeviceStats.js.map +1 -1
- package/dist/commonjs/utils/StreamVideoRN/index.js +22 -6
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/commonjs/version.js.map +1 -1
- package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js +10 -1
- package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
- package/dist/module/components/Participant/ParticipantView/VideoRenderer.js +3 -2
- package/dist/module/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
- package/dist/module/contexts/BackgroundFilters.js +4 -0
- package/dist/module/contexts/BackgroundFilters.js.map +1 -1
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +31 -12
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/module/hooks/useTrackDimensions.js +30 -35
- package/dist/module/hooks/useTrackDimensions.js.map +1 -1
- package/dist/module/providers/StreamCall/DeviceStats.js +20 -9
- package/dist/module/providers/StreamCall/DeviceStats.js.map +1 -1
- package/dist/module/utils/StreamVideoRN/index.js +23 -6
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/module/version.js.map +1 -1
- package/dist/typescript/components/Call/CallLayout/CallParticipantsGrid.d.ts.map +1 -1
- package/dist/typescript/components/Participant/ParticipantView/VideoRenderer.d.ts.map +1 -1
- package/dist/typescript/contexts/BackgroundFilters.d.ts.map +1 -1
- package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/useTrackDimensions.d.ts +2 -2
- package/dist/typescript/hooks/useTrackDimensions.d.ts.map +1 -1
- package/dist/typescript/providers/StreamCall/DeviceStats.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts +6 -2
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +6 -1
- package/dist/typescript/utils/StreamVideoRN/types.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/withMainActivity.js +6 -1
- package/ios/RTCViewPip.swift +11 -21
- package/ios/RTCViewPipManager.swift +4 -17
- package/ios/StreamVideoReactNative.xcodeproj/project.xcworkspace/xcuserdata/santhoshvaiyapuri.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/StreamVideoReactNative.xcodeproj/xcuserdata/santhoshvaiyapuri.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/package.json +8 -8
- package/src/components/Call/CallLayout/CallParticipantsGrid.tsx +12 -5
- package/src/components/Participant/ParticipantView/VideoRenderer.tsx +7 -2
- package/src/contexts/BackgroundFilters.tsx +4 -0
- package/src/hooks/useAndroidKeepCallAliveEffect.ts +30 -10
- package/src/hooks/useTrackDimensions.ts +51 -34
- package/src/providers/StreamCall/DeviceStats.tsx +20 -9
- package/src/utils/StreamVideoRN/index.ts +41 -6
- package/src/utils/StreamVideoRN/types.ts +6 -0
- package/src/version.ts +1 -1
- package/CHANGELOG.md +0 -2594
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackgroundFilters.d.ts","sourceRoot":"","sources":["../../../src/contexts/BackgroundFilters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,EAAY,MAAM,cAAc,CAAC;AAoB/C,QAAA,MAAM,sBAAsB,iCAA2B,CAAC;AAGxD,KAAK,eAAe,GAAG,OAAO,CAC5B,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC5C,KAAK,CAAC,GAAG,CAAC,CACX,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,uBAAuB,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC7D;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,0BAA0B,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE;;;;OAIG;IACH,yBAAyB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAClE;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7D;;OAEG;IACH,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AASF;;GAEG;AACH,eAAO,MAAM,oBAAoB,4BAahC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,iBAAiB,
|
|
1
|
+
{"version":3,"file":"BackgroundFilters.d.ts","sourceRoot":"","sources":["../../../src/contexts/BackgroundFilters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,EAAY,MAAM,cAAc,CAAC;AAoB/C,QAAA,MAAM,sBAAsB,iCAA2B,CAAC;AAGxD,KAAK,eAAe,GAAG,OAAO,CAC5B,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC5C,KAAK,CAAC,GAAG,CAAC,CACX,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,uBAAuB,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC7D;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,0BAA0B,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE;;;;OAIG;IACH,yBAAyB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAClE;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7D;;OAEG;IACH,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AASF;;GAEG;AACH,eAAO,MAAM,oBAAoB,4BAahC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,iBAAiB,sBA8HxE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAndroidKeepCallAliveEffect.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAndroidKeepCallAliveEffect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useAndroidKeepCallAliveEffect.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAndroidKeepCallAliveEffect.ts"],"names":[],"mappings":"AAkHA;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,YA+GzC,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type StreamVideoParticipant } from '@stream-io/video-client';
|
|
1
|
+
import { type StreamVideoParticipant, type VideoTrackType } from '@stream-io/video-client';
|
|
2
2
|
/**
|
|
3
3
|
* This is a utility hook to get the dimensions of the video track of the participant.
|
|
4
4
|
* Note: the `tracktype` is used only for local participants.
|
|
5
5
|
* `tracktype` should be 'videoTrack' for video track and 'screenShareTrack' for screen share track.
|
|
6
6
|
*/
|
|
7
|
-
export declare function useTrackDimensions(participant: StreamVideoParticipant): {
|
|
7
|
+
export declare function useTrackDimensions(participant: StreamVideoParticipant, trackType: VideoTrackType): {
|
|
8
8
|
width: number;
|
|
9
9
|
height: number;
|
|
10
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackDimensions.d.ts","sourceRoot":"","sources":["../../../src/hooks/useTrackDimensions.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"useTrackDimensions.d.ts","sourceRoot":"","sources":["../../../src/hooks/useTrackDimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAMjC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,sBAAsB,EACnC,SAAS,EAAE,cAAc;;;EAqD1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceStats.d.ts","sourceRoot":"","sources":["../../../../src/providers/StreamCall/DeviceStats.tsx"],"names":[],"mappings":"AAaA;;GAEG;AACH,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"DeviceStats.d.ts","sourceRoot":"","sources":["../../../../src/providers/StreamCall/DeviceStats.tsx"],"names":[],"mappings":"AAaA;;GAEG;AACH,eAAO,MAAM,WAAW,YAqDvB,CAAC"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import type { StreamVideoConfig } from './types';
|
|
2
2
|
import { type NewCallNotificationCallback } from '../internal/newNotificationCallbacks';
|
|
3
|
+
type DeepPartial<T> = {
|
|
4
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
5
|
+
};
|
|
3
6
|
export declare class StreamVideoRN {
|
|
4
7
|
private static config;
|
|
5
8
|
/**
|
|
6
9
|
* Update the global config for StreamVideoRN except for push config.
|
|
7
10
|
* To set push config use `StreamVideoRN.setPushConfig` instead.
|
|
8
|
-
* This function accepts a partial config object that will be merged with the default config.
|
|
11
|
+
* This function accepts a partial config object that will be deeply merged with the default config.
|
|
9
12
|
*/
|
|
10
|
-
static updateConfig(updateConfig:
|
|
13
|
+
static updateConfig(updateConfig: DeepPartial<Omit<StreamVideoConfig, 'push'>>): void;
|
|
11
14
|
static updateAndroidIncomingCallChannel(updateChannel: Partial<NonNullable<StreamVideoConfig['push']>['android']['incomingCallChannel']>): void;
|
|
12
15
|
/**
|
|
13
16
|
* Set the push config for StreamVideoRN.
|
|
@@ -39,4 +42,5 @@ export declare class StreamVideoRN {
|
|
|
39
42
|
*/
|
|
40
43
|
static addOnNewCallNotificationListener(callback: NewCallNotificationCallback): () => void;
|
|
41
44
|
}
|
|
45
|
+
export {};
|
|
42
46
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAiC,EAC/B,KAAK,2BAA2B,EACjC,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAiC,EAC/B,KAAK,2BAA2B,EACjC,MAAM,sCAAsC,CAAC;AAK9C,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAChE,CAAC;AAmDF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA+B;IAEpD;;;;OAIG;IACH,MAAM,CAAC,YAAY,CACjB,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAK5D,MAAM,CAAC,gCAAgC,CACrC,aAAa,EAAE,OAAO,CACpB,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CACzE;IAWH;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAsBvE,MAAM,CAAC,SAAS;IAIhB;;;OAGG;IACH,MAAM,CAAC,YAAY;IASnB,MAAM,CAAC,wBAAwB;IAI/B;;;;OAIG;IACH,MAAM,CAAC,gCAAgC,CACrC,QAAQ,EAAE,2BAA2B;CAYxC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ClientPublishOptions, StreamVideoClient } from '@stream-io/video-client';
|
|
1
|
+
import { type ClientPublishOptions, StreamVideoClient, type Call } from '@stream-io/video-client';
|
|
2
2
|
import type { AndroidChannel } from '@notifee/react-native';
|
|
3
3
|
export type NonRingingPushEvent = 'call.live_started' | 'call.notification' | 'call.missed';
|
|
4
4
|
export type StreamVideoConfig = {
|
|
@@ -140,6 +140,11 @@ export type StreamVideoConfig = {
|
|
|
140
140
|
title: string;
|
|
141
141
|
body: string;
|
|
142
142
|
};
|
|
143
|
+
/**
|
|
144
|
+
* The task to run in the foreground service
|
|
145
|
+
* The task must resolve a promise once complete
|
|
146
|
+
*/
|
|
147
|
+
taskToRun: (call: Call) => Promise<void>;
|
|
143
148
|
};
|
|
144
149
|
};
|
|
145
150
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,iBAAiB,EACjB,KAAK,IAAI,EACV,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,MAAM,mBAAmB,GAC3B,mBAAmB,GACnB,mBAAmB,GACnB,aAAa,CAAC;AAElB,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB;;;;WAIG;QACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;QACtC,GAAG,EAAE;YACH;;;;eAIG;YACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;SAC3B,CAAC;QACF,OAAO,EAAE;YACP;;;;eAIG;YACH,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB;;;;eAIG;YACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAC1B;;;;;;;;;eASG;YACH,WAAW,CAAC,EAAE,cAAc,CAAC;YAC7B;;;;;;;;;eASG;YACH,mBAAmB,CAAC,EAAE,cAAc,CAAC;YACrC;;;;;;;;;eASG;YACH,mCAAmC,CAAC,EAAE;gBACpC,QAAQ,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;gBAC9C,OAAO,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;gBAC7C,oBAAoB,CAAC,EAAE,MAAM,MAAM,CAAC;gBACpC,qBAAqB,CAAC,EAAE,MAAM,MAAM,CAAC;aACtC,CAAC;YACF;;;;;;;;;;;;;;;;;;;eAmBG;YACH,2BAA2B,CAAC,EAAE;gBAC5B,QAAQ,EAAE,CACR,IAAI,EAAE,mBAAmB,EACzB,eAAe,EAAE,MAAM,KACpB,MAAM,CAAC;gBACZ,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;aACzE,CAAC;SACH,CAAC;QACF;;;;;;;;;;;;;;;;;WAiBG;QACH,uBAAuB,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;QACtE;yJACiJ;QACjJ,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;QAChC;yJACiJ;QACjJ,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;QACpC,8EAA8E;QAC9E,+BAA+B,CAAC,EAAE,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,mBAAmB,KACtB,IAAI,CAAC;KACX,CAAC;IACF,iBAAiB,EAAE;QACjB,OAAO,EAAE;YACP;;eAEG;YACH,OAAO,EAAE,cAAc,CAAC;YACxB;;eAEG;YACH,iBAAiB,EAAE;gBACjB,KAAK,EAAE,MAAM,CAAC;gBACd,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;YACF;;;eAGG;YACH,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;SAC1C,CAAC;KACH,CAAC;CACH,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "1.
|
|
1
|
+
export declare const version = "1.20.1-alpha.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,mBAAmB,CAAC"}
|
|
@@ -37,7 +37,9 @@ function addOnPictureInPictureModeChanged(contents, isJava) {
|
|
|
37
37
|
@Override
|
|
38
38
|
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
|
|
39
39
|
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
|
|
40
|
-
|
|
40
|
+
if (isFinishing()) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
41
43
|
if (lifecycleOwner.getLifecycle().getCurrentState() == Lifecycle.State.CREATED) {
|
|
42
44
|
// When user clicks on Close button of PIP
|
|
43
45
|
finishAndRemoveTask();
|
|
@@ -51,6 +53,9 @@ function addOnPictureInPictureModeChanged(contents, isJava) {
|
|
|
51
53
|
statementToInsert = `
|
|
52
54
|
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
|
|
53
55
|
super.onPictureInPictureModeChanged(isInPictureInPictureMode)
|
|
56
|
+
if (isFinishing) {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
54
59
|
if (lifecycle.currentState === Lifecycle.State.CREATED) {
|
|
55
60
|
// when user clicks on Close button of PIP
|
|
56
61
|
finishAndRemoveTask()
|
package/ios/RTCViewPip.swift
CHANGED
|
@@ -13,17 +13,6 @@ class RTCViewPip: UIView {
|
|
|
13
13
|
private var pictureInPictureController = StreamPictureInPictureController()
|
|
14
14
|
private var webRtcModule: WebRTCModule?
|
|
15
15
|
|
|
16
|
-
override init(frame: CGRect) {
|
|
17
|
-
super.init(frame: frame)
|
|
18
|
-
setupNotificationObserver()
|
|
19
|
-
self.pictureInPictureController?.sourceView = self
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
required init?(coder aDecoder: NSCoder) {
|
|
23
|
-
super.init(coder: aDecoder)
|
|
24
|
-
setupNotificationObserver()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
16
|
private func setupNotificationObserver() {
|
|
28
17
|
NotificationCenter.default.addObserver(
|
|
29
18
|
self,
|
|
@@ -33,10 +22,6 @@ class RTCViewPip: UIView {
|
|
|
33
22
|
)
|
|
34
23
|
}
|
|
35
24
|
|
|
36
|
-
deinit {
|
|
37
|
-
NotificationCenter.default.removeObserver(self)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
25
|
func setWebRtcModule(_ module: WebRTCModule) {
|
|
41
26
|
webRtcModule = module
|
|
42
27
|
}
|
|
@@ -82,16 +67,21 @@ class RTCViewPip: UIView {
|
|
|
82
67
|
self.pictureInPictureController = nil
|
|
83
68
|
}
|
|
84
69
|
|
|
85
|
-
override func
|
|
86
|
-
super.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// taken from: https://github.com/software-mansion/react-native-screens/blob/main/Example/ios/ScreensExample/RNSSampleLifecycleAwareView.m
|
|
70
|
+
override func didMoveToSuperview() {
|
|
71
|
+
super.didMoveToSuperview()
|
|
72
|
+
if self.superview == nil {
|
|
73
|
+
print("PiP - RTCViewPip has been removed from its superview.")
|
|
74
|
+
NotificationCenter.default.removeObserver(self)
|
|
91
75
|
DispatchQueue.main.async {
|
|
92
76
|
NSLog("PiP - onCallClosed called due to view detaching")
|
|
93
77
|
self.onCallClosed()
|
|
94
78
|
}
|
|
79
|
+
} else {
|
|
80
|
+
print("PiP - RTCViewPip has been added to a superview.")
|
|
81
|
+
setupNotificationObserver()
|
|
82
|
+
DispatchQueue.main.async {
|
|
83
|
+
self.pictureInPictureController?.sourceView = self
|
|
84
|
+
}
|
|
95
85
|
}
|
|
96
86
|
}
|
|
97
87
|
}
|
|
@@ -9,34 +9,21 @@ import Foundation
|
|
|
9
9
|
|
|
10
10
|
@objc(RTCViewPipManager)
|
|
11
11
|
class RTCViewPipManager: RCTViewManager {
|
|
12
|
-
|
|
13
|
-
// A cached RTCViewPip reference.
|
|
14
|
-
//
|
|
15
|
-
// Often, the view unmounts before the `onCallClosed` command arrives and as a consequence
|
|
16
|
-
// pipView.onCallClosed() method wasn't called, as the view can't be found in the ViewRegistry
|
|
17
|
-
// causing dangling PiP window with the last video frame frozen.
|
|
18
|
-
// Now, once this happens, instead forwarding the command to the view returned by the registry,
|
|
19
|
-
// we manually apply it to the cached view. The current setup allows only one PipView, so we
|
|
20
|
-
// don't have to introduce more complex view tracking mechanism.
|
|
21
|
-
private var _view: RTCViewPip? = nil
|
|
22
|
-
|
|
12
|
+
|
|
23
13
|
override func view() -> UIView! {
|
|
24
14
|
let view = RTCViewPip()
|
|
25
15
|
view.setWebRtcModule(self.bridge.module(forName: "WebRTCModule") as! WebRTCModule)
|
|
26
|
-
self._view = view
|
|
27
16
|
return view
|
|
28
17
|
}
|
|
29
|
-
|
|
18
|
+
|
|
30
19
|
override static func requiresMainQueueSetup() -> Bool {
|
|
31
20
|
return true
|
|
32
21
|
}
|
|
33
|
-
|
|
22
|
+
|
|
34
23
|
@objc func onCallClosed(_ reactTag: NSNumber) {
|
|
35
24
|
self.bridge!.uiManager.addUIBlock { (_: RCTUIManager?, viewRegistry: [NSNumber: UIView]?) in
|
|
36
25
|
guard let pipView = viewRegistry?[reactTag] as? RTCViewPip else {
|
|
37
|
-
NSLog("PiP - onCallClosed
|
|
38
|
-
self._view?.onCallClosed()
|
|
39
|
-
self._view = nil
|
|
26
|
+
NSLog("PiP - onCallClosed cant be called, Invalid view returned from registry, expecting RTCViewPip")
|
|
40
27
|
return
|
|
41
28
|
}
|
|
42
29
|
DispatchQueue.main.async {
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>SchemeUserState</key>
|
|
6
|
+
<dict>
|
|
7
|
+
<key>StreamVideoReactNative.xcscheme_^#shared#^_</key>
|
|
8
|
+
<dict>
|
|
9
|
+
<key>orderHint</key>
|
|
10
|
+
<integer>0</integer>
|
|
11
|
+
</dict>
|
|
12
|
+
</dict>
|
|
13
|
+
</dict>
|
|
14
|
+
</plist>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-native-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.1-alpha.1",
|
|
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/",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"!**/.*"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@stream-io/video-client": "
|
|
49
|
-
"@stream-io/video-react-bindings": "
|
|
48
|
+
"@stream-io/video-client": "workspace:*",
|
|
49
|
+
"@stream-io/video-react-bindings": "workspace:*",
|
|
50
50
|
"intl-pluralrules": "2.0.1",
|
|
51
51
|
"lodash.merge": "^4.6.2",
|
|
52
52
|
"react-native-url-polyfill": "1.3.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@react-native-firebase/app": ">=17.5.0",
|
|
61
61
|
"@react-native-firebase/messaging": ">=17.5.0",
|
|
62
62
|
"@stream-io/noise-cancellation-react-native": ">=0.1.0",
|
|
63
|
-
"@stream-io/react-native-webrtc": ">=125.
|
|
63
|
+
"@stream-io/react-native-webrtc": ">=125.4.0",
|
|
64
64
|
"@stream-io/video-filters-react-native": ">=0.1.0",
|
|
65
65
|
"expo": ">=47.0.0",
|
|
66
66
|
"expo-build-properties": "*",
|
|
@@ -125,9 +125,9 @@
|
|
|
125
125
|
"@react-native-firebase/app": "^22.1.0",
|
|
126
126
|
"@react-native-firebase/messaging": "^22.1.0",
|
|
127
127
|
"@react-native/babel-preset": "^0.79.2",
|
|
128
|
-
"@stream-io/noise-cancellation-react-native": "
|
|
129
|
-
"@stream-io/react-native-webrtc": "^125.
|
|
130
|
-
"@stream-io/video-filters-react-native": "
|
|
128
|
+
"@stream-io/noise-cancellation-react-native": "workspace:^",
|
|
129
|
+
"@stream-io/react-native-webrtc": "^125.4.0",
|
|
130
|
+
"@stream-io/video-filters-react-native": "workspace:^",
|
|
131
131
|
"@testing-library/jest-native": "^5.4.3",
|
|
132
132
|
"@testing-library/react-native": "13.2.0",
|
|
133
133
|
"@tsconfig/node14": "14.1.3",
|
|
@@ -164,4 +164,4 @@
|
|
|
164
164
|
"typescript"
|
|
165
165
|
]
|
|
166
166
|
}
|
|
167
|
-
}
|
|
167
|
+
}
|
|
@@ -11,6 +11,7 @@ import { useTheme } from '../../../contexts/ThemeContext';
|
|
|
11
11
|
import type { CallContentProps } from '../CallContent';
|
|
12
12
|
import type { ParticipantViewComponentProps } from '../../Participant';
|
|
13
13
|
import { useIsInPiPMode } from '../../../hooks/useIsInPiPMode';
|
|
14
|
+
import { StreamVideoParticipant } from '@stream-io/video-client';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Props for the CallParticipantsGrid component.
|
|
@@ -71,11 +72,17 @@ export const CallParticipantsGrid = ({
|
|
|
71
72
|
remoteParticipants.length > 0 &&
|
|
72
73
|
remoteParticipants.length < 3;
|
|
73
74
|
|
|
74
|
-
let participants
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
let participants: StreamVideoParticipant[];
|
|
76
|
+
|
|
77
|
+
if (showFloatingView) {
|
|
78
|
+
if (showLocalParticipant && localParticipant) {
|
|
79
|
+
participants = [localParticipant];
|
|
80
|
+
} else {
|
|
81
|
+
participants = remoteParticipants;
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
participants = allParticipants;
|
|
85
|
+
}
|
|
79
86
|
|
|
80
87
|
if (isInPiPMode) {
|
|
81
88
|
if (dominantSpeaker && !dominantSpeaker.isLocalParticipant) {
|
|
@@ -73,7 +73,10 @@ export const VideoRenderer = ({
|
|
|
73
73
|
deregister: deregisterIosScreenshot,
|
|
74
74
|
} = useScreenshotIosContext();
|
|
75
75
|
|
|
76
|
-
const videoDimensions = useTrackDimensions(participant);
|
|
76
|
+
const videoDimensions = useTrackDimensions(participant, trackType);
|
|
77
|
+
|
|
78
|
+
const isVideoDimensionsValid =
|
|
79
|
+
videoDimensions.width > 0 && videoDimensions.height > 0;
|
|
77
80
|
|
|
78
81
|
const {
|
|
79
82
|
isLocalParticipant,
|
|
@@ -291,7 +294,9 @@ export const VideoRenderer = ({
|
|
|
291
294
|
onLayout={onLayout}
|
|
292
295
|
style={[styles.container, videoRenderer.container]}
|
|
293
296
|
>
|
|
294
|
-
{canShowVideo &&
|
|
297
|
+
{canShowVideo &&
|
|
298
|
+
videoStreamToRender &&
|
|
299
|
+
(objectFit || isVideoDimensionsValid) ? (
|
|
295
300
|
<RTCView
|
|
296
301
|
style={[styles.videoStream, videoRenderer.videoStream]}
|
|
297
302
|
streamURL={videoStreamToRender.toURL()}
|
|
@@ -139,6 +139,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
139
139
|
} else if (blurIntensity === 'light') {
|
|
140
140
|
filterName = 'BackgroundBlurLight';
|
|
141
141
|
}
|
|
142
|
+
call?.tracer.trace('backgroundFilters.apply', filterName);
|
|
142
143
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
143
144
|
?.getVideoTracks()
|
|
144
145
|
.forEach((track) => {
|
|
@@ -164,6 +165,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
164
165
|
} else if (blurIntensity === 'light') {
|
|
165
166
|
filterName = 'BlurLight';
|
|
166
167
|
}
|
|
168
|
+
call?.tracer.trace('backgroundFilters.apply', filterName);
|
|
167
169
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
168
170
|
?.getVideoTracks()
|
|
169
171
|
.forEach((track) => {
|
|
@@ -187,6 +189,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
187
189
|
registeredImageFiltersSetRef.current.add(imageUri);
|
|
188
190
|
}
|
|
189
191
|
const filterName = `VirtualBackground-${imageUri}`;
|
|
192
|
+
call?.tracer.trace('backgroundFilters.apply', filterName);
|
|
190
193
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
191
194
|
?.getVideoTracks()
|
|
192
195
|
.forEach((track) => {
|
|
@@ -201,6 +204,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
201
204
|
if (!isSupported) {
|
|
202
205
|
return;
|
|
203
206
|
}
|
|
207
|
+
call?.tracer.trace('backgroundFilters.disableAll', null);
|
|
204
208
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
205
209
|
?.getVideoTracks()
|
|
206
210
|
.forEach((track) => {
|
|
@@ -7,13 +7,16 @@ import {
|
|
|
7
7
|
NativeModules,
|
|
8
8
|
Platform,
|
|
9
9
|
} from 'react-native';
|
|
10
|
-
import { CallingState, getLogger } from '@stream-io/video-client';
|
|
10
|
+
import { Call, CallingState, getLogger } from '@stream-io/video-client';
|
|
11
11
|
import {
|
|
12
12
|
getKeepCallAliveForegroundServiceTypes,
|
|
13
13
|
getNotifeeLibNoThrowForKeepCallAlive,
|
|
14
14
|
} from '../utils/push/libs/notifee';
|
|
15
15
|
|
|
16
16
|
const notifeeLib = getNotifeeLibNoThrowForKeepCallAlive();
|
|
17
|
+
const callToPassToForegroundService: { current: Call | undefined } = {
|
|
18
|
+
current: undefined,
|
|
19
|
+
};
|
|
17
20
|
|
|
18
21
|
function setForegroundService() {
|
|
19
22
|
if (Platform.OS === 'ios' || !notifeeLib) return;
|
|
@@ -28,22 +31,29 @@ function setForegroundService() {
|
|
|
28
31
|
return;
|
|
29
32
|
}
|
|
30
33
|
notifeeLib.default.registerForegroundService(() => {
|
|
31
|
-
|
|
34
|
+
const task = new Promise((resolve) => {
|
|
32
35
|
const logger = getLogger(['setForegroundService method']);
|
|
33
36
|
logger('info', 'Foreground service running for call in progress');
|
|
37
|
+
// any task to run from SDK in the foreground service must be added
|
|
38
|
+
resolve(true);
|
|
34
39
|
});
|
|
40
|
+
const videoConfig = StreamVideoRN.getConfig();
|
|
41
|
+
const foregroundServiceConfig = videoConfig.foregroundService;
|
|
42
|
+
const { taskToRun } = foregroundServiceConfig.android;
|
|
43
|
+
const call = callToPassToForegroundService.current;
|
|
44
|
+
if (!call) {
|
|
45
|
+
const logger = getLogger(['setForegroundService method']);
|
|
46
|
+
logger('warn', 'No call to pass to foreground service');
|
|
47
|
+
return task.then(() => new Promise(() => {}));
|
|
48
|
+
}
|
|
49
|
+
callToPassToForegroundService.current = undefined;
|
|
50
|
+
return task.then(() => taskToRun(call));
|
|
35
51
|
});
|
|
36
52
|
},
|
|
37
53
|
);
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
async function startForegroundService(call_cid: string) {
|
|
41
|
-
const videoConfig = StreamVideoRN.getConfig();
|
|
42
|
-
const foregroundServiceConfig = videoConfig.foregroundService;
|
|
43
|
-
const { title, body } = foregroundServiceConfig.android.notificationTexts;
|
|
44
|
-
|
|
45
|
-
// check for notification permission and then start the foreground service
|
|
46
|
-
if (!notifeeLib) return;
|
|
47
57
|
const isCallAliveConfigured =
|
|
48
58
|
await NativeModules.StreamVideoReactNative.isCallAliveConfigured();
|
|
49
59
|
if (!isCallAliveConfigured) {
|
|
@@ -54,6 +64,8 @@ async function startForegroundService(call_cid: string) {
|
|
|
54
64
|
);
|
|
55
65
|
return;
|
|
56
66
|
}
|
|
67
|
+
// check for notification permission and then start the foreground service
|
|
68
|
+
if (!notifeeLib) return;
|
|
57
69
|
const settings = await notifeeLib.default.getNotificationSettings();
|
|
58
70
|
if (
|
|
59
71
|
settings.authorizationStatus !== notifeeLib.AuthorizationStatus.AUTHORIZED
|
|
@@ -65,6 +77,9 @@ async function startForegroundService(call_cid: string) {
|
|
|
65
77
|
);
|
|
66
78
|
return;
|
|
67
79
|
}
|
|
80
|
+
const videoConfig = StreamVideoRN.getConfig();
|
|
81
|
+
const foregroundServiceConfig = videoConfig.foregroundService;
|
|
82
|
+
const notificationTexts = foregroundServiceConfig.android.notificationTexts;
|
|
68
83
|
const channelId = foregroundServiceConfig.android.channel.id;
|
|
69
84
|
await notifeeLib.default.createChannel(
|
|
70
85
|
foregroundServiceConfig.android.channel,
|
|
@@ -76,8 +91,8 @@ async function startForegroundService(call_cid: string) {
|
|
|
76
91
|
requestAnimationFrame(() => {
|
|
77
92
|
notifeeLib.default.displayNotification({
|
|
78
93
|
id: call_cid,
|
|
79
|
-
title,
|
|
80
|
-
body,
|
|
94
|
+
title: notificationTexts.title,
|
|
95
|
+
body: notificationTexts.body,
|
|
81
96
|
android: {
|
|
82
97
|
channelId,
|
|
83
98
|
smallIcon: videoConfig.push?.android.smallIcon,
|
|
@@ -107,6 +122,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
107
122
|
const foregroundServiceStartedRef = useRef(false);
|
|
108
123
|
|
|
109
124
|
const call = useCall();
|
|
125
|
+
callToPassToForegroundService.current = call;
|
|
110
126
|
const activeCallCid = call?.cid;
|
|
111
127
|
const { useCallCallingState } = useCallStateHooks();
|
|
112
128
|
const callingState = useCallCallingState();
|
|
@@ -141,6 +157,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
141
157
|
(notification) => notification.id === activeCallCid,
|
|
142
158
|
);
|
|
143
159
|
if (activeCallNotification) {
|
|
160
|
+
callToPassToForegroundService.current = undefined;
|
|
144
161
|
// this means that we have a incoming call notification shown as foreground service and we must stop it
|
|
145
162
|
notifee.stopForegroundService();
|
|
146
163
|
notifee.cancelDisplayedNotification(activeCallCid);
|
|
@@ -179,6 +196,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
179
196
|
callingState === CallingState.LEFT
|
|
180
197
|
) {
|
|
181
198
|
if (foregroundServiceStartedRef.current) {
|
|
199
|
+
callToPassToForegroundService.current = undefined;
|
|
182
200
|
// stop foreground service when the call is not active
|
|
183
201
|
notifeeLib.default.stopForegroundService();
|
|
184
202
|
foregroundServiceStartedRef.current = false;
|
|
@@ -190,6 +208,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
190
208
|
(notification) => notification.id === activeCallCid,
|
|
191
209
|
);
|
|
192
210
|
if (activeCallNotification) {
|
|
211
|
+
callToPassToForegroundService.current = undefined;
|
|
193
212
|
// this means that we have a incoming call notification shown as foreground service and we must stop it
|
|
194
213
|
notifeeLib.default.stopForegroundService();
|
|
195
214
|
}
|
|
@@ -204,6 +223,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
204
223
|
// stop foreground service when this effect is unmounted
|
|
205
224
|
if (foregroundServiceStartedRef.current) {
|
|
206
225
|
if (!notifeeLib) return;
|
|
226
|
+
callToPassToForegroundService.current = undefined;
|
|
207
227
|
notifeeLib.default.stopForegroundService();
|
|
208
228
|
foregroundServiceStartedRef.current = false;
|
|
209
229
|
}
|
|
@@ -1,53 +1,70 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
type StreamVideoParticipant,
|
|
3
|
+
type VideoTrackType,
|
|
4
|
+
} from '@stream-io/video-client';
|
|
3
5
|
import { useEffect, useState } from 'react';
|
|
6
|
+
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
7
|
+
|
|
8
|
+
const webRTCEventEmitter = new NativeEventEmitter(NativeModules.WebRTCModule);
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* This is a utility hook to get the dimensions of the video track of the participant.
|
|
7
12
|
* Note: the `tracktype` is used only for local participants.
|
|
8
13
|
* `tracktype` should be 'videoTrack' for video track and 'screenShareTrack' for screen share track.
|
|
9
14
|
*/
|
|
10
|
-
export function useTrackDimensions(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
const
|
|
16
|
-
|
|
15
|
+
export function useTrackDimensions(
|
|
16
|
+
participant: StreamVideoParticipant,
|
|
17
|
+
trackType: VideoTrackType,
|
|
18
|
+
) {
|
|
19
|
+
const { videoStream, screenShareStream } = participant;
|
|
20
|
+
const stream =
|
|
21
|
+
trackType === 'screenShareTrack' ? screenShareStream : videoStream;
|
|
22
|
+
const [track] = stream?.getVideoTracks() ?? [];
|
|
23
|
+
const trackId = track?.id;
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
const [trackDimensions, setTrackDimensions] = useState(() => {
|
|
26
|
+
const settings = track?.getSettings();
|
|
27
|
+
const width = settings?.width ?? 0;
|
|
28
|
+
const height = settings?.height ?? 0;
|
|
29
|
+
return {
|
|
30
|
+
width,
|
|
31
|
+
height,
|
|
23
32
|
};
|
|
24
|
-
}
|
|
33
|
+
});
|
|
25
34
|
|
|
26
|
-
//
|
|
27
|
-
// and for local participants we can get from track.getSettings() but it reports the wrong dimensions as it sends the constraints
|
|
28
|
-
// so we need to rely on call stats for all participants to get the dimensions
|
|
35
|
+
// Set up videoTrackDimensionChanged event listener for more direct dimension updates
|
|
29
36
|
useEffect(() => {
|
|
30
|
-
if (!
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
const { frameWidth = 0, frameHeight = 0 } = stat;
|
|
37
|
+
if (!trackId || !NativeModules.WebRTCModule) return;
|
|
38
|
+
|
|
39
|
+
const handleVideoTrackDimensionChanged = (eventData: {
|
|
40
|
+
pcId: string;
|
|
41
|
+
trackId: string;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
}) => {
|
|
45
|
+
// Only handle events for this specific participant
|
|
46
|
+
if (eventData.trackId === trackId) {
|
|
41
47
|
setTrackDimensions((prev) => {
|
|
42
|
-
if (
|
|
43
|
-
|
|
48
|
+
if (
|
|
49
|
+
prev.width !== eventData.width ||
|
|
50
|
+
prev.height !== eventData.height
|
|
51
|
+
) {
|
|
52
|
+
return { width: eventData.width, height: eventData.height };
|
|
44
53
|
}
|
|
45
54
|
return prev;
|
|
46
55
|
});
|
|
47
56
|
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const subscription = webRTCEventEmitter.addListener(
|
|
60
|
+
'videoTrackDimensionChanged',
|
|
61
|
+
handleVideoTrackDimensionChanged,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return () => {
|
|
65
|
+
subscription.remove();
|
|
66
|
+
};
|
|
67
|
+
}, [trackId, track]);
|
|
51
68
|
|
|
52
69
|
return trackDimensions;
|
|
53
70
|
}
|