@stream-io/video-react-native-sdk 0.7.14 → 0.7.16
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 +18 -0
- package/android/build.gradle +56 -97
- package/android/gradle.properties +5 -3
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +2 -1
- package/dist/commonjs/components/Call/CallControls/index.js +11 -0
- package/dist/commonjs/components/Call/CallControls/index.js.map +1 -1
- package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
- package/dist/commonjs/contexts/BackgroundFilters.js +125 -0
- package/dist/commonjs/contexts/BackgroundFilters.js.map +1 -0
- package/dist/commonjs/contexts/index.js +11 -0
- package/dist/commonjs/contexts/index.js.map +1 -1
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/index.js +5 -4
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/components/Call/CallControls/index.js +1 -0
- package/dist/module/components/Call/CallControls/index.js.map +1 -1
- package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
- package/dist/module/contexts/BackgroundFilters.js +116 -0
- package/dist/module/contexts/BackgroundFilters.js.map +1 -0
- package/dist/module/contexts/index.js +1 -0
- package/dist/module/contexts/index.js.map +1 -1
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/module/index.js +3 -2
- package/dist/module/index.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/components/Call/CallControls/index.d.ts +1 -0
- package/dist/typescript/components/Call/CallControls/index.d.ts.map +1 -1
- package/dist/typescript/contexts/BackgroundFilters.d.ts +49 -0
- package/dist/typescript/contexts/BackgroundFilters.d.ts.map +1 -0
- package/dist/typescript/contexts/index.d.ts +1 -0
- package/dist/typescript/contexts/index.d.ts.map +1 -1
- package/dist/typescript/index.d.ts +2 -1
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/package.json +19 -6
- package/src/components/Call/CallControls/CallControlsButton.tsx +1 -1
- package/src/components/Call/CallControls/ScreenShareToggleButton.tsx +1 -1
- package/src/components/Call/CallControls/index.tsx +1 -0
- package/src/components/Call/CallLayout/CallParticipantsGrid.tsx +2 -2
- package/src/components/Call/CallParticipantsList/CallParticipantsList.tsx +4 -4
- package/src/components/Call/RingingCallContent/UserInfo.tsx +1 -1
- package/src/components/Livestream/LivestreamControls/HostStartStreamButton.tsx +4 -4
- package/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx +1 -1
- package/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx +1 -1
- package/src/components/Livestream/LivestreamTopView/DurationBadge.tsx +1 -1
- package/src/components/Participant/FloatingParticipantView/FloatingView/AnimatedFloatingView.tsx +3 -3
- package/src/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.tsx +5 -5
- package/src/components/Participant/ParticipantView/ParticipantNetworkQualityIndicator.tsx +1 -1
- package/src/components/Participant/ParticipantView/ParticipantReaction.tsx +1 -1
- package/src/components/Participant/ParticipantView/VideoRenderer.tsx +1 -1
- package/src/contexts/BackgroundFilters.tsx +197 -0
- package/src/contexts/StreamVideoContext.tsx +3 -3
- package/src/contexts/ThemeContext.tsx +2 -2
- package/src/contexts/index.ts +1 -0
- package/src/hooks/push/useIosCallKeepEventsSetupEffect.ts +3 -3
- package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +5 -5
- package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +5 -4
- package/src/hooks/push/useProcessPushCallEffect.ts +5 -5
- package/src/hooks/useAndroidKeepCallAliveEffect.ts +2 -2
- package/src/hooks/useIsInPiPMode.tsx +2 -2
- package/src/hooks/useIsIosScreenshareBroadcastStarted.ts +2 -2
- package/src/hooks/usePaginatedLayoutSortPreset.ts +1 -1
- package/src/hooks/usePermissionNotification.tsx +1 -1
- package/src/hooks/usePermissionRequest.tsx +3 -3
- package/src/index.ts +3 -2
- package/src/providers/StreamCall.tsx +2 -2
- package/src/providers/StreamVideo.tsx +1 -1
- package/src/utils/StreamVideoRN/index.ts +3 -3
- package/src/utils/StreamVideoRN/types.ts +2 -2
- package/src/utils/enterPiPAndroid.ts +1 -1
- package/src/utils/hooks/useAppStateListener.ts +2 -2
- package/src/utils/index.ts +2 -2
- package/src/utils/internal/newNotificationCallbacks.ts +3 -3
- package/src/utils/push/android.ts +14 -14
- package/src/utils/push/ios.ts +6 -6
- package/src/utils/push/libs/callkeep.ts +1 -1
- package/src/utils/push/libs/expoNotifications.ts +1 -1
- package/src/utils/push/libs/expoTaskManager.ts +1 -1
- package/src/utils/push/libs/firebaseMessaging.ts +2 -2
- package/src/utils/push/libs/iosPushNotification.ts +1 -1
- package/src/utils/push/libs/voipPushNotification.ts +1 -1
- package/src/utils/push/utils.ts +5 -5
- package/src/version.ts +1 -1
- package/dist/commonjs/providers/index.js +0 -28
- package/dist/commonjs/providers/index.js.map +0 -1
- package/dist/module/providers/index.js +0 -3
- package/dist/module/providers/index.js.map +0 -1
- package/dist/typescript/providers/index.d.ts +0 -3
- package/dist/typescript/providers/index.d.ts.map +0 -1
- package/src/providers/index.ts +0 -2
package/src/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.tsx
CHANGED
|
@@ -13,7 +13,7 @@ type ReanimatedExportsType = typeof import('react-native-reanimated');
|
|
|
13
13
|
|
|
14
14
|
let ReanimatedFloatingView: React.FC<FloatingViewProps> = () => {
|
|
15
15
|
throw new Error(
|
|
16
|
-
'ReanimatedFloatingView component must not be used without the react-native-reanimated library and react-native-gesture-handler library installed'
|
|
16
|
+
'ReanimatedFloatingView component must not be used without the react-native-reanimated library and react-native-gesture-handler library installed'
|
|
17
17
|
);
|
|
18
18
|
};
|
|
19
19
|
|
|
@@ -90,15 +90,15 @@ try {
|
|
|
90
90
|
0,
|
|
91
91
|
Math.min(
|
|
92
92
|
e.translationX + (start.value.x ?? 0),
|
|
93
|
-
snapAlignments[FloatingViewAlignment.bottomRight].x
|
|
94
|
-
)
|
|
93
|
+
snapAlignments[FloatingViewAlignment.bottomRight].x
|
|
94
|
+
)
|
|
95
95
|
);
|
|
96
96
|
translationY.value = Math.max(
|
|
97
97
|
0,
|
|
98
98
|
Math.min(
|
|
99
99
|
e.translationY + (start.value.y ?? 0),
|
|
100
|
-
snapAlignments[FloatingViewAlignment.bottomRight].y
|
|
101
|
-
)
|
|
100
|
+
snapAlignments[FloatingViewAlignment.bottomRight].y
|
|
101
|
+
)
|
|
102
102
|
);
|
|
103
103
|
})
|
|
104
104
|
.onEnd(() => {
|
|
@@ -15,7 +15,7 @@ export type ParticipantNetworkQualityIndicatorProps = Pick<
|
|
|
15
15
|
>;
|
|
16
16
|
|
|
17
17
|
const useConnectionQualitySignalColors = (
|
|
18
|
-
participant: ParticipantViewProps['participant']
|
|
18
|
+
participant: ParticipantViewProps['participant']
|
|
19
19
|
) => {
|
|
20
20
|
const {
|
|
21
21
|
theme: { colors },
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
PropsWithChildren,
|
|
3
|
+
createContext,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useMemo,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
} from 'react';
|
|
10
|
+
import { MediaStream } from '@stream-io/react-native-webrtc';
|
|
11
|
+
import { useCall } from '@stream-io/video-react-bindings';
|
|
12
|
+
import { Platform } from 'react-native';
|
|
13
|
+
|
|
14
|
+
type VideoFiltersModuleType =
|
|
15
|
+
typeof import('@stream-io/video-filters-react-native');
|
|
16
|
+
|
|
17
|
+
let videoFiltersModule: VideoFiltersModuleType | undefined;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
videoFiltersModule = require('@stream-io/video-filters-react-native');
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.log(e);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
import { Image } from 'react-native';
|
|
26
|
+
|
|
27
|
+
const resolveAssetSourceFunc = Image.resolveAssetSource;
|
|
28
|
+
|
|
29
|
+
// excluding array of images and only allow one image
|
|
30
|
+
type ImageSourceType = Exclude<
|
|
31
|
+
Parameters<typeof resolveAssetSourceFunc>[0],
|
|
32
|
+
Array<any>
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
export type BlurIntensity = 'light' | 'medium' | 'heavy';
|
|
36
|
+
|
|
37
|
+
export type BackgroundFilterType = 'blur' | 'image';
|
|
38
|
+
|
|
39
|
+
export type CurrentBackgroundFilter = {
|
|
40
|
+
blur?: BlurIntensity;
|
|
41
|
+
image?: ImageSourceType;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type BackgroundFiltersAPI = {
|
|
45
|
+
/**
|
|
46
|
+
* The currently applied background filter. Undefined value indicates that no filter is applied.
|
|
47
|
+
*/
|
|
48
|
+
currentBackgroundFilter: CurrentBackgroundFilter | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Whether the current device supports the background filters.
|
|
51
|
+
*/
|
|
52
|
+
isSupported: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Applies a background image filter to the video.
|
|
55
|
+
*
|
|
56
|
+
* @param imageSource the URL of the image to use as the background.
|
|
57
|
+
*/
|
|
58
|
+
applyBackgroundImageFilter: (imageSource: ImageSourceType) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Applies a background blur filter to the video.
|
|
61
|
+
*
|
|
62
|
+
* @param blurLevel the level of blur to apply to the background.
|
|
63
|
+
*/
|
|
64
|
+
applyBackgroundBlurFilter: (blurIntensity: BlurIntensity) => void;
|
|
65
|
+
/**
|
|
66
|
+
* Disables all filters applied to the video.
|
|
67
|
+
*/
|
|
68
|
+
disableAllFilters: () => void;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The context for the background filters.
|
|
73
|
+
*/
|
|
74
|
+
const BackgroundFiltersContext = createContext<
|
|
75
|
+
BackgroundFiltersAPI | undefined
|
|
76
|
+
>(undefined);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* A hook to access the background filters context API.
|
|
80
|
+
*/
|
|
81
|
+
export const useBackgroundFilters = () => {
|
|
82
|
+
const context = useContext(BackgroundFiltersContext);
|
|
83
|
+
if (!context) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
'useBackgroundFilters must be used within a BackgroundFiltersProvider'
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
if (!videoFiltersModule) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"Install the '@stream-io/video-filters-react-native' library to use background filters"
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return context;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const isSupported = Platform.OS === 'android';
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A provider component that enables the use of background filters in your app.
|
|
100
|
+
*
|
|
101
|
+
* Please make sure you have the `@stream-io/video-filters-react-native` package installed
|
|
102
|
+
* in your project before using this component.
|
|
103
|
+
*/
|
|
104
|
+
export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
105
|
+
if (!videoFiltersModule) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
"Install the '@stream-io/video-filters-react-native' library to use background filters"
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
const call = useCall();
|
|
111
|
+
const isBlurRegisteredRef = useRef(false);
|
|
112
|
+
const registeredImageFiltersSetRef = useRef(new Set<string>());
|
|
113
|
+
const [currentBackgroundFilter, setCurrentBackgroundFilter] =
|
|
114
|
+
useState<CurrentBackgroundFilter>();
|
|
115
|
+
|
|
116
|
+
const applyBackgroundBlurFilter = useCallback(
|
|
117
|
+
(blurIntensity: BlurIntensity) => {
|
|
118
|
+
if (!isSupported) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (!isBlurRegisteredRef.current) {
|
|
122
|
+
videoFiltersModule?.registerBackgroundBlurVideoFilters();
|
|
123
|
+
}
|
|
124
|
+
let filterName = 'BackgroundBlurMedium';
|
|
125
|
+
if (blurIntensity === 'heavy') {
|
|
126
|
+
filterName = 'BackgroundBlurHeavy';
|
|
127
|
+
} else if (blurIntensity === 'light') {
|
|
128
|
+
filterName = 'BackgroundBlurLight';
|
|
129
|
+
}
|
|
130
|
+
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
131
|
+
?.getVideoTracks()
|
|
132
|
+
.forEach((track) => {
|
|
133
|
+
track._setVideoEffect(filterName);
|
|
134
|
+
});
|
|
135
|
+
setCurrentBackgroundFilter({ blur: blurIntensity });
|
|
136
|
+
},
|
|
137
|
+
[call]
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const applyBackgroundImageFilter = useCallback(
|
|
141
|
+
(imageSource: ImageSourceType) => {
|
|
142
|
+
if (!isSupported) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const source = resolveAssetSourceFunc(imageSource);
|
|
146
|
+
const imageUri = source.uri;
|
|
147
|
+
const registeredImageFiltersSet = registeredImageFiltersSetRef.current;
|
|
148
|
+
if (!registeredImageFiltersSet.has(imageUri)) {
|
|
149
|
+
videoFiltersModule?.registerVirtualBackgroundFilter(imageUri);
|
|
150
|
+
registeredImageFiltersSetRef.current.add(imageUri);
|
|
151
|
+
}
|
|
152
|
+
const filterName = `VirtualBackground-${imageUri}`;
|
|
153
|
+
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
154
|
+
?.getVideoTracks()
|
|
155
|
+
.forEach((track) => {
|
|
156
|
+
track._setVideoEffect(filterName);
|
|
157
|
+
});
|
|
158
|
+
setCurrentBackgroundFilter({ image: imageSource });
|
|
159
|
+
},
|
|
160
|
+
[call]
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const disableAllFilters = useCallback(() => {
|
|
164
|
+
if (!isSupported) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
168
|
+
?.getVideoTracks()
|
|
169
|
+
.forEach((track) => {
|
|
170
|
+
// @ts-expect-error - webrtc typing is wrong, null is supported
|
|
171
|
+
track._setVideoEffect(null);
|
|
172
|
+
});
|
|
173
|
+
setCurrentBackgroundFilter(undefined);
|
|
174
|
+
}, [call]);
|
|
175
|
+
|
|
176
|
+
const value = useMemo(
|
|
177
|
+
() => ({
|
|
178
|
+
currentBackgroundFilter,
|
|
179
|
+
isSupported,
|
|
180
|
+
applyBackgroundImageFilter,
|
|
181
|
+
applyBackgroundBlurFilter,
|
|
182
|
+
disableAllFilters,
|
|
183
|
+
}),
|
|
184
|
+
[
|
|
185
|
+
applyBackgroundBlurFilter,
|
|
186
|
+
applyBackgroundImageFilter,
|
|
187
|
+
currentBackgroundFilter,
|
|
188
|
+
disableAllFilters,
|
|
189
|
+
]
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<BackgroundFiltersContext.Provider value={value}>
|
|
194
|
+
{children}
|
|
195
|
+
</BackgroundFiltersContext.Provider>
|
|
196
|
+
);
|
|
197
|
+
};
|
|
@@ -17,7 +17,7 @@ function createStoreContext<StoreType extends object>(initialState: StoreType) {
|
|
|
17
17
|
type SetStateFuncType = (
|
|
18
18
|
partialStateOrFunc:
|
|
19
19
|
| Partial<StoreType>
|
|
20
|
-
| ((prevState: StoreType) => Partial<StoreType>)
|
|
20
|
+
| ((prevState: StoreType) => Partial<StoreType>)
|
|
21
21
|
) => void;
|
|
22
22
|
|
|
23
23
|
// returns unsubscribe function
|
|
@@ -79,7 +79,7 @@ function createStoreContext<StoreType extends object>(initialState: StoreType) {
|
|
|
79
79
|
* @category Client State
|
|
80
80
|
*/
|
|
81
81
|
function useStoreValue<SelectorOutput extends StoreType[keyof StoreType]>(
|
|
82
|
-
selector: (store: StoreType) => SelectorOutput
|
|
82
|
+
selector: (store: StoreType) => SelectorOutput
|
|
83
83
|
): SelectorOutput {
|
|
84
84
|
const store = useContext(StoreContext);
|
|
85
85
|
if (!store) {
|
|
@@ -89,7 +89,7 @@ function createStoreContext<StoreType extends object>(initialState: StoreType) {
|
|
|
89
89
|
const [state, setState] = useState(selector(store.getSnapshot()));
|
|
90
90
|
useEffect(
|
|
91
91
|
() => store.subscribe(() => setState(selector(store.getSnapshot()))),
|
|
92
|
-
[selector, store]
|
|
92
|
+
[selector, store]
|
|
93
93
|
);
|
|
94
94
|
|
|
95
95
|
return state;
|
|
@@ -45,7 +45,7 @@ export const mergeThemes = (params: MergedThemesParams) => {
|
|
|
45
45
|
const DEFAULT_BASE_CONTEXT_VALUE = {};
|
|
46
46
|
|
|
47
47
|
export const ThemeContext = createContext<Theme>(
|
|
48
|
-
DEFAULT_BASE_CONTEXT_VALUE as Theme
|
|
48
|
+
DEFAULT_BASE_CONTEXT_VALUE as Theme
|
|
49
49
|
);
|
|
50
50
|
|
|
51
51
|
export const ThemeProvider: React.FC<
|
|
@@ -73,7 +73,7 @@ export const useTheme = () => {
|
|
|
73
73
|
|
|
74
74
|
if (theme === DEFAULT_BASE_CONTEXT_VALUE) {
|
|
75
75
|
throw new Error(
|
|
76
|
-
'The useThemeContext hook was called outside the ThemeContext Provider. Make sure you have configured OverlayProvider component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#overlay-provider'
|
|
76
|
+
'The useThemeContext hook was called outside the ThemeContext Provider. Make sure you have configured OverlayProvider component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#overlay-provider'
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
79
|
return { theme };
|
package/src/contexts/index.ts
CHANGED
|
@@ -28,14 +28,14 @@ export const useIosCallKeepEventsSetupEffect = () => {
|
|
|
28
28
|
({ callUUID }) => {
|
|
29
29
|
const call_cid = RxUtils.getCurrentValue(voipPushNotificationCallCId$);
|
|
30
30
|
iosCallkeepAcceptCall(call_cid, callUUID);
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
32
|
);
|
|
33
33
|
const { remove: removeEndCall } = callkeep.addEventListener(
|
|
34
34
|
'endCall',
|
|
35
35
|
({ callUUID }) => {
|
|
36
36
|
const call_cid = RxUtils.getCurrentValue(voipPushNotificationCallCId$);
|
|
37
37
|
iosCallkeepRejectCall(call_cid, callUUID, pushConfig);
|
|
38
|
-
}
|
|
38
|
+
}
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
const { remove: removeDisplayIncomingCall } = callkeep.addEventListener(
|
|
@@ -52,7 +52,7 @@ export const useIosCallKeepEventsSetupEffect = () => {
|
|
|
52
52
|
uuid: callUUID,
|
|
53
53
|
cid: call_cid,
|
|
54
54
|
});
|
|
55
|
-
}
|
|
55
|
+
}
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
return () => {
|
|
@@ -61,10 +61,10 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
63
|
const nativeDialerAcceptedCallMap = RxUtils.getCurrentValue(
|
|
64
|
-
voipCallkeepAcceptedCallOnNativeDialerMap
|
|
64
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$
|
|
65
65
|
);
|
|
66
66
|
const foregroundIncomingCallkeepMap = RxUtils.getCurrentValue(
|
|
67
|
-
voipCallkeepCallOnForegroundMap
|
|
67
|
+
voipCallkeepCallOnForegroundMap$
|
|
68
68
|
);
|
|
69
69
|
const callkeep = getCallKeepLib();
|
|
70
70
|
if (activeCallCid === nativeDialerAcceptedCallMap?.cid) {
|
|
@@ -95,7 +95,7 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
95
95
|
// push notification was displayed
|
|
96
96
|
// but the call has been accepted through the app and not through the native dialer
|
|
97
97
|
const foregroundCallkeepMap = RxUtils.getCurrentValue(
|
|
98
|
-
voipCallkeepCallOnForegroundMap
|
|
98
|
+
voipCallkeepCallOnForegroundMap$
|
|
99
99
|
);
|
|
100
100
|
if (foregroundCallkeepMap && foregroundCallkeepMap.cid === activeCallCid) {
|
|
101
101
|
// this call should be accepted in callkeep
|
|
@@ -122,7 +122,7 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
122
122
|
// this was a call which had push notification displayed but never joined
|
|
123
123
|
// the user rejected in the app and not from native dialer
|
|
124
124
|
const foregroundIncomingCallkeepMap = RxUtils.getCurrentValue(
|
|
125
|
-
voipCallkeepCallOnForegroundMap
|
|
125
|
+
voipCallkeepCallOnForegroundMap$
|
|
126
126
|
);
|
|
127
127
|
if (activeCallCid === foregroundIncomingCallkeepMap?.cid) {
|
|
128
128
|
callkeep.endCall(foregroundIncomingCallkeepMap.uuid);
|
|
@@ -134,7 +134,7 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
134
134
|
// it was an accepted call from native dialer and not from the app
|
|
135
135
|
// the user left using the leave button in the app
|
|
136
136
|
const nativeDialerAcceptedCallMap = RxUtils.getCurrentValue(
|
|
137
|
-
voipCallkeepAcceptedCallOnNativeDialerMap
|
|
137
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$
|
|
138
138
|
);
|
|
139
139
|
if (activeCallCid === nativeDialerAcceptedCallMap?.cid) {
|
|
140
140
|
callkeep.endCall(nativeDialerAcceptedCallMap.uuid);
|
|
@@ -146,9 +146,10 @@ const onNotificationReceived = async (notification: any) => {
|
|
|
146
146
|
const callFromPush = await client.onRingingCall(call_cid);
|
|
147
147
|
let uuid = '';
|
|
148
148
|
try {
|
|
149
|
-
uuid =
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
uuid =
|
|
150
|
+
await NativeModules?.StreamVideoReactNative?.getIncomingCallUUid(
|
|
151
|
+
call_cid
|
|
152
|
+
);
|
|
152
153
|
} catch (error) {
|
|
153
154
|
console.log('Error in getting call uuid', error);
|
|
154
155
|
}
|
|
@@ -161,7 +162,7 @@ const onNotificationReceived = async (notification: any) => {
|
|
|
161
162
|
const { mustEndCall, callkeepReason } = shouldCallBeEnded(
|
|
162
163
|
callFromPush,
|
|
163
164
|
created_by_id,
|
|
164
|
-
receiver_id
|
|
165
|
+
receiver_id
|
|
165
166
|
);
|
|
166
167
|
if (mustEndCall) {
|
|
167
168
|
const callkeep = getCallKeepLib();
|
|
@@ -37,7 +37,7 @@ export const useProcessPushCallEffect = () => {
|
|
|
37
37
|
pushAcceptedIncomingCallCId$,
|
|
38
38
|
client,
|
|
39
39
|
pushConfig,
|
|
40
|
-
'accept'
|
|
40
|
+
'accept'
|
|
41
41
|
);
|
|
42
42
|
|
|
43
43
|
// if the user rejects the call from push notification we leave the call
|
|
@@ -45,7 +45,7 @@ export const useProcessPushCallEffect = () => {
|
|
|
45
45
|
pushRejectedIncomingCallCId$,
|
|
46
46
|
client,
|
|
47
47
|
pushConfig,
|
|
48
|
-
'decline'
|
|
48
|
+
'decline'
|
|
49
49
|
);
|
|
50
50
|
|
|
51
51
|
// if the user taps the call from push notification we do nothing as the only thing is to get the call which adds it to the client
|
|
@@ -53,14 +53,14 @@ export const useProcessPushCallEffect = () => {
|
|
|
53
53
|
pushTappedIncomingCallCId$,
|
|
54
54
|
client,
|
|
55
55
|
pushConfig,
|
|
56
|
-
'pressed'
|
|
56
|
+
'pressed'
|
|
57
57
|
);
|
|
58
58
|
|
|
59
59
|
const backgroundIncomingDeliveredCallSubscription = createCallSubscription(
|
|
60
60
|
pushAndroidBackgroundDeliveredIncomingCallCId$,
|
|
61
61
|
client,
|
|
62
62
|
pushConfig,
|
|
63
|
-
'backgroundDelivered'
|
|
63
|
+
'backgroundDelivered'
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
return () => {
|
|
@@ -86,7 +86,7 @@ const createCallSubscription = (
|
|
|
86
86
|
behaviourSubjectWithCallCid: BehaviorSubject<string | undefined>,
|
|
87
87
|
client: StreamVideoClient,
|
|
88
88
|
pushConfig: NonNullable<StreamVideoConfig['push']>,
|
|
89
|
-
action: 'accept' | 'decline' | 'pressed' | 'backgroundDelivered'
|
|
89
|
+
action: 'accept' | 'decline' | 'pressed' | 'backgroundDelivered'
|
|
90
90
|
) => {
|
|
91
91
|
return behaviourSubjectWithCallCid
|
|
92
92
|
.pipe(filter(cidIsNotUndefined))
|
|
@@ -28,7 +28,7 @@ async function startForegroundService(call_cid: string) {
|
|
|
28
28
|
const settings = await notifee.getNotificationSettings();
|
|
29
29
|
if (settings.authorizationStatus !== AuthorizationStatus.AUTHORIZED) {
|
|
30
30
|
console.warn(
|
|
31
|
-
'Notification permission not granted, can not start foreground service to keep the call alive'
|
|
31
|
+
'Notification permission not granted, can not start foreground service to keep the call alive'
|
|
32
32
|
);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
@@ -110,7 +110,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
110
110
|
} else {
|
|
111
111
|
notifee.getDisplayedNotifications().then((displayedNotifications) => {
|
|
112
112
|
const activeCallNotification = displayedNotifications.find(
|
|
113
|
-
(notification) => notification.id === activeCallCid
|
|
113
|
+
(notification) => notification.id === activeCallCid
|
|
114
114
|
);
|
|
115
115
|
if (activeCallNotification) {
|
|
116
116
|
// this means that we have a incoming call notification shown as foreground service and we must stop it
|
|
@@ -10,14 +10,14 @@ export function useIsInPiPMode() {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const eventEmitter = new NativeEventEmitter(
|
|
13
|
-
NativeModules.StreamVideoReactNative
|
|
13
|
+
NativeModules.StreamVideoReactNative
|
|
14
14
|
);
|
|
15
15
|
|
|
16
16
|
const subscription = eventEmitter.addListener(
|
|
17
17
|
'StreamVideoReactNative_PIP_CHANGE_EVENT',
|
|
18
18
|
(isPiPEnabled: boolean) => {
|
|
19
19
|
setIsInPiPMode(isPiPEnabled);
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
return () => {
|
|
@@ -14,14 +14,14 @@ export function useIsIosScreenshareBroadcastStarted() {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const eventEmitter = new NativeEventEmitter(
|
|
17
|
-
NativeModules.StreamVideoReactNative
|
|
17
|
+
NativeModules.StreamVideoReactNative
|
|
18
18
|
);
|
|
19
19
|
|
|
20
20
|
const subscription = eventEmitter.addListener(
|
|
21
21
|
'StreamVideoReactNative_Ios_Screenshare_Event',
|
|
22
22
|
(event: Event) => {
|
|
23
23
|
setHasStarted(event.name === 'iOS_BroadcastStarted');
|
|
24
|
-
}
|
|
24
|
+
}
|
|
25
25
|
);
|
|
26
26
|
|
|
27
27
|
return () => {
|
|
@@ -10,7 +10,7 @@ const resetSortPreset = (call: Call) => {
|
|
|
10
10
|
// reset the sorting to the default for the call type
|
|
11
11
|
const callConfig = CallTypes.get(call.type);
|
|
12
12
|
call.setSortParticipantsBy(
|
|
13
|
-
callConfig.options.sortParticipantsBy || defaultSortPreset
|
|
13
|
+
callConfig.options.sortParticipantsBy || defaultSortPreset
|
|
14
14
|
);
|
|
15
15
|
};
|
|
16
16
|
|
|
@@ -24,7 +24,7 @@ export type PermissionNotificationProps = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export const usePermissionNotification = (
|
|
27
|
-
props: PermissionNotificationProps
|
|
27
|
+
props: PermissionNotificationProps
|
|
28
28
|
) => {
|
|
29
29
|
const { permission, messageApproved, messageRevoked } = props;
|
|
30
30
|
const { useCallCallingState, useHasPermissions } = useCallStateHooks();
|
|
@@ -8,7 +8,7 @@ export const usePermissionRequest = () => {
|
|
|
8
8
|
|
|
9
9
|
const { useHasPermissions } = useCallStateHooks();
|
|
10
10
|
const userHasUpdateCallPermissionsCapability = useHasPermissions(
|
|
11
|
-
OwnCapability.UPDATE_CALL_PERMISSIONS
|
|
11
|
+
OwnCapability.UPDATE_CALL_PERMISSIONS
|
|
12
12
|
);
|
|
13
13
|
|
|
14
14
|
const messageForPermission = (userName: string, permission: string) => {
|
|
@@ -39,7 +39,7 @@ export const usePermissionRequest = () => {
|
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
},
|
|
42
|
-
[call]
|
|
42
|
+
[call]
|
|
43
43
|
);
|
|
44
44
|
|
|
45
45
|
useEffect(() => {
|
|
@@ -64,7 +64,7 @@ export const usePermissionRequest = () => {
|
|
|
64
64
|
text: 'Allow',
|
|
65
65
|
onPress: handleUpdatePermission(event, true),
|
|
66
66
|
},
|
|
67
|
-
]
|
|
67
|
+
]
|
|
68
68
|
);
|
|
69
69
|
});
|
|
70
70
|
});
|
package/src/index.ts
CHANGED
|
@@ -28,8 +28,9 @@ export * from './theme';
|
|
|
28
28
|
export * from './utils';
|
|
29
29
|
export * from './translations';
|
|
30
30
|
|
|
31
|
-
// Overriding 'StreamVideo' from '@stream-io/video-react-bindings'
|
|
31
|
+
// Overriding 'StreamVideo' and 'StreamCall' from '@stream-io/video-react-bindings'
|
|
32
32
|
// Explicitly re-exporting to resolve ambiguity.
|
|
33
|
-
export { StreamVideo
|
|
33
|
+
export { StreamVideo } from './providers/StreamVideo';
|
|
34
|
+
export { StreamCall } from './providers/StreamCall';
|
|
34
35
|
|
|
35
36
|
setClientDetails();
|
|
@@ -43,7 +43,7 @@ export class StreamVideoRN {
|
|
|
43
43
|
static updateAndroidIncomingCallChannel(
|
|
44
44
|
updateChannel: Partial<
|
|
45
45
|
NonNullable<StreamVideoConfig['push']>['android']['incomingCallChannel']
|
|
46
|
-
|
|
46
|
+
>
|
|
47
47
|
) {
|
|
48
48
|
const prevChannel = this.config.push?.android?.incomingCallChannel;
|
|
49
49
|
if (prevChannel) {
|
|
@@ -92,7 +92,7 @@ export class StreamVideoRN {
|
|
|
92
92
|
static onPushLogout() {
|
|
93
93
|
if (pushLogoutCallbacks.current) {
|
|
94
94
|
return Promise.all(
|
|
95
|
-
pushLogoutCallbacks.current.map((callback) => callback())
|
|
95
|
+
pushLogoutCallbacks.current.map((callback) => callback())
|
|
96
96
|
).then(() => {});
|
|
97
97
|
}
|
|
98
98
|
return Promise.resolve();
|
|
@@ -104,7 +104,7 @@ export class StreamVideoRN {
|
|
|
104
104
|
* @returns Unsubscribe function
|
|
105
105
|
*/
|
|
106
106
|
static addOnNewCallNotificationListener(
|
|
107
|
-
callback: NewCallNotificationCallback
|
|
107
|
+
callback: NewCallNotificationCallback
|
|
108
108
|
) {
|
|
109
109
|
if (!newNotificationCallbacks.current) {
|
|
110
110
|
newNotificationCallbacks.current = [callback];
|
|
@@ -77,7 +77,7 @@ export type StreamVideoConfig = {
|
|
|
77
77
|
callNotificationTextGetters?: {
|
|
78
78
|
getTitle: (
|
|
79
79
|
type: NonRingingPushEvent,
|
|
80
|
-
createdUserName: string
|
|
80
|
+
createdUserName: string
|
|
81
81
|
) => string;
|
|
82
82
|
getBody: (type: NonRingingPushEvent, createdUserName: string) => string;
|
|
83
83
|
};
|
|
@@ -107,7 +107,7 @@ export type StreamVideoConfig = {
|
|
|
107
107
|
/** Callback that is called when a non ringing push notification was tapped */
|
|
108
108
|
onTapNonRingingCallNotification?: (
|
|
109
109
|
call_cid: string,
|
|
110
|
-
type: NonRingingPushEvent
|
|
110
|
+
type: NonRingingPushEvent
|
|
111
111
|
) => void;
|
|
112
112
|
};
|
|
113
113
|
foregroundService: {
|
|
@@ -3,7 +3,7 @@ import { AppState, AppStateStatus } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
export const useAppStateListener = (
|
|
5
5
|
onForeground?: () => void,
|
|
6
|
-
onBackground?: () => void
|
|
6
|
+
onBackground?: () => void
|
|
7
7
|
) => {
|
|
8
8
|
const appStateRef = useRef(AppState.currentState);
|
|
9
9
|
const onForegroundRef = useRef(onForeground);
|
|
@@ -31,7 +31,7 @@ export const useAppStateListener = (
|
|
|
31
31
|
};
|
|
32
32
|
const subscription = AppState.addEventListener(
|
|
33
33
|
'change',
|
|
34
|
-
handleAppStateChange
|
|
34
|
+
handleAppStateChange
|
|
35
35
|
);
|
|
36
36
|
|
|
37
37
|
return () => {
|
package/src/utils/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Utility to join strings with commas and 'and'
|
|
2
2
|
export const generateCallTitle = (
|
|
3
3
|
memberUserIds: string[],
|
|
4
|
-
totalMembersToShow?: number
|
|
4
|
+
totalMembersToShow?: number
|
|
5
5
|
) => {
|
|
6
6
|
const supportedAmountOfMemberUserIds = memberUserIds.slice(
|
|
7
7
|
0,
|
|
8
|
-
totalMembersToShow
|
|
8
|
+
totalMembersToShow
|
|
9
9
|
);
|
|
10
10
|
if (
|
|
11
11
|
totalMembersToShow &&
|