@stream-io/video-react-native-sdk 1.13.3 → 1.14.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/gradle.properties +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.js +23 -29
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLivestreamControls.js +187 -29
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLivestreamControls.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js +1 -1
- package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamEnded.js +111 -0
- package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamEnded.js.map +1 -0
- package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamPlayer.js +5 -6
- package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamPlayer.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamTopView/DurationBadge.js +32 -28
- package/dist/commonjs/components/Livestream/LivestreamTopView/DurationBadge.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamTopView/FollowerCount.js +36 -36
- package/dist/commonjs/components/Livestream/LivestreamTopView/FollowerCount.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamTopView/LiveIndicator.js +21 -15
- package/dist/commonjs/components/Livestream/LivestreamTopView/LiveIndicator.js.map +1 -1
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js +70 -4
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js.map +1 -1
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLobby.js +143 -0
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLobby.js.map +1 -0
- package/dist/commonjs/icons/LivestreamControls.js +73 -0
- package/dist/commonjs/icons/LivestreamControls.js.map +1 -0
- package/dist/commonjs/icons/Maximize.js +52 -0
- package/dist/commonjs/icons/Maximize.js.map +1 -0
- package/dist/commonjs/icons/index.js +11 -0
- package/dist/commonjs/icons/index.js.map +1 -1
- package/dist/commonjs/index.js +12 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/providers/NoiseCancellation/NoiseCancellationProvider.js +75 -0
- package/dist/commonjs/providers/NoiseCancellation/NoiseCancellationProvider.js.map +1 -0
- package/dist/commonjs/providers/NoiseCancellation/index.js +17 -0
- package/dist/commonjs/providers/NoiseCancellation/index.js.map +1 -0
- package/dist/commonjs/providers/NoiseCancellation/lib.js +34 -0
- package/dist/commonjs/providers/NoiseCancellation/lib.js.map +1 -0
- package/dist/commonjs/version.js +1 -1
- package/dist/module/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.js +27 -33
- package/dist/module/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/ViewerLivestreamControls.js +187 -30
- package/dist/module/components/Livestream/LivestreamControls/ViewerLivestreamControls.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamLayout/LivestreamLayout.js +1 -1
- package/dist/module/components/Livestream/LivestreamLayout/LivestreamLayout.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamPlayer/LivestreamEnded.js +104 -0
- package/dist/module/components/Livestream/LivestreamPlayer/LivestreamEnded.js.map +1 -0
- package/dist/module/components/Livestream/LivestreamPlayer/LivestreamPlayer.js +5 -6
- package/dist/module/components/Livestream/LivestreamPlayer/LivestreamPlayer.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamTopView/DurationBadge.js +33 -29
- package/dist/module/components/Livestream/LivestreamTopView/DurationBadge.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamTopView/FollowerCount.js +35 -35
- package/dist/module/components/Livestream/LivestreamTopView/FollowerCount.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamTopView/LiveIndicator.js +20 -14
- package/dist/module/components/Livestream/LivestreamTopView/LiveIndicator.js.map +1 -1
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLivestream.js +73 -7
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLivestream.js.map +1 -1
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLobby.js +136 -0
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLobby.js.map +1 -0
- package/dist/module/icons/LivestreamControls.js +62 -0
- package/dist/module/icons/LivestreamControls.js.map +1 -0
- package/dist/module/icons/Maximize.js +43 -0
- package/dist/module/icons/Maximize.js.map +1 -0
- package/dist/module/icons/index.js +1 -0
- package/dist/module/icons/index.js.map +1 -1
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/providers/NoiseCancellation/NoiseCancellationProvider.js +67 -0
- package/dist/module/providers/NoiseCancellation/NoiseCancellationProvider.js.map +1 -0
- package/dist/module/providers/NoiseCancellation/index.js +2 -0
- package/dist/module/providers/NoiseCancellation/index.js.map +1 -0
- package/dist/module/providers/NoiseCancellation/lib.js +26 -0
- package/dist/module/providers/NoiseCancellation/lib.js.map +1 -0
- package/dist/module/version.js +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/ViewerLivestreamControls.d.ts +7 -0
- package/dist/typescript/components/Livestream/LivestreamControls/ViewerLivestreamControls.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamPlayer/LivestreamEnded.d.ts +3 -0
- package/dist/typescript/components/Livestream/LivestreamPlayer/LivestreamEnded.d.ts.map +1 -0
- package/dist/typescript/components/Livestream/LivestreamPlayer/LivestreamPlayer.d.ts +13 -1
- package/dist/typescript/components/Livestream/LivestreamPlayer/LivestreamPlayer.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/DurationBadge.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/FollowerCount.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/LiveIndicator.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLivestream.d.ts +9 -1
- package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLivestream.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLobby.d.ts +8 -0
- package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLobby.d.ts.map +1 -0
- package/dist/typescript/icons/LivestreamControls.d.ts +12 -0
- package/dist/typescript/icons/LivestreamControls.d.ts.map +1 -0
- package/dist/typescript/icons/Maximize.d.ts +10 -0
- package/dist/typescript/icons/Maximize.d.ts.map +1 -0
- package/dist/typescript/icons/index.d.ts +1 -0
- package/dist/typescript/icons/index.d.ts.map +1 -1
- package/dist/typescript/index.d.ts +1 -0
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/providers/NoiseCancellation/NoiseCancellationProvider.d.ts +34 -0
- package/dist/typescript/providers/NoiseCancellation/NoiseCancellationProvider.d.ts.map +1 -0
- package/dist/typescript/providers/NoiseCancellation/index.d.ts +2 -0
- package/dist/typescript/providers/NoiseCancellation/index.d.ts.map +1 -0
- package/dist/typescript/providers/NoiseCancellation/lib.d.ts +8 -0
- package/dist/typescript/providers/NoiseCancellation/lib.d.ts.map +1 -0
- package/dist/typescript/version.d.ts +1 -1
- package/expo-config-plugin/dist/index.js +2 -0
- package/expo-config-plugin/dist/withAndroidPermissions.js +1 -0
- package/expo-config-plugin/dist/withAppDelegate.js +26 -7
- package/expo-config-plugin/dist/withMainApplication.js +24 -0
- package/package.json +10 -5
- package/src/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.tsx +30 -48
- package/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx +260 -43
- package/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx +1 -1
- package/src/components/Livestream/LivestreamPlayer/LivestreamEnded.tsx +130 -0
- package/src/components/Livestream/LivestreamPlayer/LivestreamPlayer.tsx +15 -5
- package/src/components/Livestream/LivestreamTopView/DurationBadge.tsx +35 -38
- package/src/components/Livestream/LivestreamTopView/FollowerCount.tsx +40 -47
- package/src/components/Livestream/LivestreamTopView/LiveIndicator.tsx +22 -14
- package/src/components/Livestream/ViewerLivestream/ViewerLivestream.tsx +107 -10
- package/src/components/Livestream/ViewerLivestream/ViewerLobby.tsx +171 -0
- package/src/icons/LivestreamControls.tsx +51 -0
- package/src/icons/Maximize.tsx +48 -0
- package/src/icons/index.tsx +1 -0
- package/src/index.ts +1 -0
- package/src/providers/NoiseCancellation/NoiseCancellationProvider.tsx +147 -0
- package/src/providers/NoiseCancellation/index.ts +1 -0
- package/src/providers/NoiseCancellation/lib.ts +37 -0
- package/src/version.ts +1 -1
|
@@ -10,13 +10,17 @@ const addToSwiftBridgingHeaderFile_1 = require("./common/addToSwiftBridgingHeade
|
|
|
10
10
|
const withAppDelegate = (configuration, props) => {
|
|
11
11
|
return (0, config_plugins_1.withAppDelegate)(configuration, (config) => {
|
|
12
12
|
if (!props?.ringingPushNotifications &&
|
|
13
|
-
!props?.iOSEnableMultitaskingCameraAccess
|
|
13
|
+
!props?.iOSEnableMultitaskingCameraAccess &&
|
|
14
|
+
!props?.addNoiseCancellation) {
|
|
14
15
|
// quit early if no change is necessary
|
|
15
16
|
return config;
|
|
16
17
|
}
|
|
17
18
|
if (['objc', 'objcpp'].includes(config.modResults.language)) {
|
|
18
19
|
try {
|
|
19
|
-
|
|
20
|
+
if (props?.addNoiseCancellation) {
|
|
21
|
+
config.modResults.contents = (0, codeMod_1.addObjcImports)(config.modResults.contents, ['"NoiseCancellationManagerObjc.h"']);
|
|
22
|
+
}
|
|
23
|
+
config.modResults.contents = addDidFinishLaunchingWithOptionsObjc(config.modResults.contents, props.iOSEnableMultitaskingCameraAccess, props.addNoiseCancellation);
|
|
20
24
|
if (props?.ringingPushNotifications) {
|
|
21
25
|
config.modResults.contents = (0, codeMod_1.addObjcImports)(config.modResults.contents, [
|
|
22
26
|
'"RNCallKeep.h"',
|
|
@@ -68,7 +72,10 @@ const withAppDelegate = (configuration, props) => {
|
|
|
68
72
|
]);
|
|
69
73
|
return headerFileContents;
|
|
70
74
|
});
|
|
71
|
-
|
|
75
|
+
if (props?.addNoiseCancellation) {
|
|
76
|
+
config.modResults.contents = (0, codeMod_1.addObjcImports)(config.modResults.contents, ['stream_io_noise_cancellation_react_native']);
|
|
77
|
+
}
|
|
78
|
+
config.modResults.contents = addDidFinishLaunchingWithOptionsSwift(config.modResults.contents, props.iOSEnableMultitaskingCameraAccess, props.addNoiseCancellation);
|
|
72
79
|
if (props?.ringingPushNotifications) {
|
|
73
80
|
config.modResults.contents = (0, codeMod_1.addSwiftImports)(config.modResults.contents, ['RNCallKeep', 'PushKit', 'RNVoipPushNotification']);
|
|
74
81
|
config.modResults.contents =
|
|
@@ -85,20 +92,26 @@ const withAppDelegate = (configuration, props) => {
|
|
|
85
92
|
}
|
|
86
93
|
});
|
|
87
94
|
};
|
|
88
|
-
function addDidFinishLaunchingWithOptionsSwift(contents, iOSEnableMultitaskingCameraAccess) {
|
|
95
|
+
function addDidFinishLaunchingWithOptionsSwift(contents, iOSEnableMultitaskingCameraAccess, enableNoiseCancellation) {
|
|
96
|
+
const functionSelector = 'application(_:didFinishLaunchingWithOptions:)';
|
|
89
97
|
if (iOSEnableMultitaskingCameraAccess) {
|
|
90
|
-
const functionSelector = 'application(_:didFinishLaunchingWithOptions:)';
|
|
91
98
|
const setupMethod = `let options = WebRTCModuleOptions.sharedInstance()
|
|
92
99
|
options.enableMultitaskingCameraAccess = true`;
|
|
93
100
|
if (!contents.includes('options.enableMultitaskingCameraAccess = true')) {
|
|
94
101
|
contents = (0, codeMod_1.insertContentsInsideSwiftFunctionBlock)(contents, functionSelector, setupMethod, { position: 'head' });
|
|
95
102
|
}
|
|
96
103
|
}
|
|
104
|
+
if (enableNoiseCancellation) {
|
|
105
|
+
const setupMethod = `NoiseCancellationManager.getInstance().registerProcessor()`;
|
|
106
|
+
if (!contents.includes(setupMethod)) {
|
|
107
|
+
contents = (0, codeMod_1.insertContentsInsideSwiftFunctionBlock)(contents, functionSelector, setupMethod, { position: 'head' });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
97
110
|
return contents;
|
|
98
111
|
}
|
|
99
|
-
function addDidFinishLaunchingWithOptionsObjc(contents, iOSEnableMultitaskingCameraAccess) {
|
|
112
|
+
function addDidFinishLaunchingWithOptionsObjc(contents, iOSEnableMultitaskingCameraAccess, enableNoiseCancellation) {
|
|
113
|
+
const functionSelector = 'application:didFinishLaunchingWithOptions:';
|
|
100
114
|
if (iOSEnableMultitaskingCameraAccess) {
|
|
101
|
-
const functionSelector = 'application:didFinishLaunchingWithOptions:';
|
|
102
115
|
contents = (0, codeMod_1.addObjcImports)(contents, ['<WebRTCModuleOptions.h>']);
|
|
103
116
|
const setupMethod = `WebRTCModuleOptions *options = [WebRTCModuleOptions sharedInstance];
|
|
104
117
|
options.enableMultitaskingCameraAccess = YES;`;
|
|
@@ -106,6 +119,12 @@ function addDidFinishLaunchingWithOptionsObjc(contents, iOSEnableMultitaskingCam
|
|
|
106
119
|
contents = (0, codeMod_1.insertContentsInsideObjcFunctionBlock)(contents, functionSelector, setupMethod, { position: 'head' });
|
|
107
120
|
}
|
|
108
121
|
}
|
|
122
|
+
if (enableNoiseCancellation) {
|
|
123
|
+
const setupMethod = `[[NoiseCancellationManagerObjc sharedInstance] registerProcessor];`;
|
|
124
|
+
if (!contents.includes(setupMethod)) {
|
|
125
|
+
contents = (0, codeMod_1.insertContentsInsideObjcFunctionBlock)(contents, functionSelector, setupMethod, { position: 'head' });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
109
128
|
return contents;
|
|
110
129
|
}
|
|
111
130
|
function addDidFinishLaunchingWithOptionsRingingSwift(contents, ringingPushNotifications) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
4
|
+
const codeMod_1 = require("@expo/config-plugins/build/android/codeMod");
|
|
5
|
+
const withStreamVideoReactNativeSDKMainApplication = (configuration, props) => {
|
|
6
|
+
return (0, config_plugins_1.withMainApplication)(configuration, (config) => {
|
|
7
|
+
const isMainActivityJava = config.modResults.language === 'java';
|
|
8
|
+
if (props?.addNoiseCancellation) {
|
|
9
|
+
config.modResults.contents = (0, codeMod_1.addImports)(config.modResults.contents, ['io.getstream.rn.noisecancellation.NoiseCancellationReactNative'], isMainActivityJava);
|
|
10
|
+
config.modResults.contents = addNoiseCancellationInsideOnCreate(config.modResults.contents, isMainActivityJava);
|
|
11
|
+
}
|
|
12
|
+
return config;
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
function addNoiseCancellationInsideOnCreate(contents, isJava) {
|
|
16
|
+
const addBlock = isJava
|
|
17
|
+
? `NoiseCancellationReactNative.registerProcessor(getApplicationContext());`
|
|
18
|
+
: `NoiseCancellationReactNative.registerProcessor(applicationContext)`;
|
|
19
|
+
if (!contents.includes(addBlock)) {
|
|
20
|
+
contents = (0, codeMod_1.appendContentsInsideDeclarationBlock)(contents, 'onCreate', addBlock + '\n');
|
|
21
|
+
}
|
|
22
|
+
return contents;
|
|
23
|
+
}
|
|
24
|
+
exports.default = withStreamVideoReactNativeSDKMainApplication;
|
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.14.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/",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"!**/.*"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@stream-io/video-client": "1.
|
|
49
|
-
"@stream-io/video-react-bindings": "1.6.
|
|
48
|
+
"@stream-io/video-client": "1.23.0",
|
|
49
|
+
"@stream-io/video-react-bindings": "1.6.3",
|
|
50
50
|
"intl-pluralrules": "2.0.1",
|
|
51
51
|
"lodash.merge": "^4.6.2",
|
|
52
52
|
"react-native-url-polyfill": "1.3.0",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"@react-native-community/push-notification-ios": ">=1.11.0",
|
|
60
60
|
"@react-native-firebase/app": ">=17.5.0",
|
|
61
61
|
"@react-native-firebase/messaging": ">=17.5.0",
|
|
62
|
+
"@stream-io/noise-cancellation-react-native": ">=0.1.0",
|
|
62
63
|
"@stream-io/react-native-webrtc": ">=125.2.1",
|
|
63
64
|
"@stream-io/video-filters-react-native": ">=0.1.0",
|
|
64
65
|
"expo": ">=47.0.0",
|
|
@@ -86,6 +87,9 @@
|
|
|
86
87
|
"@react-native-firebase/messaging": {
|
|
87
88
|
"optional": true
|
|
88
89
|
},
|
|
90
|
+
"@stream-io/noise-cancellation-react-native": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
89
93
|
"@stream-io/video-filters-react-native": {
|
|
90
94
|
"optional": true
|
|
91
95
|
},
|
|
@@ -121,8 +125,9 @@
|
|
|
121
125
|
"@react-native-firebase/app": "^22.1.0",
|
|
122
126
|
"@react-native-firebase/messaging": "^22.1.0",
|
|
123
127
|
"@react-native/babel-preset": "^0.79.2",
|
|
124
|
-
"@stream-io/react-native
|
|
125
|
-
"@stream-io/
|
|
128
|
+
"@stream-io/noise-cancellation-react-native": "^0.1.0",
|
|
129
|
+
"@stream-io/react-native-webrtc": "^125.3.0",
|
|
130
|
+
"@stream-io/video-filters-react-native": "^0.4.0",
|
|
126
131
|
"@testing-library/jest-native": "^5.4.3",
|
|
127
132
|
"@testing-library/react-native": "13.2.0",
|
|
128
133
|
"@tsconfig/node14": "14.1.3",
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
ActivityIndicator,
|
|
4
|
-
Pressable,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
Text,
|
|
7
|
-
View,
|
|
8
|
-
} from 'react-native';
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import { ActivityIndicator, Pressable, StyleSheet, View } from 'react-native';
|
|
9
3
|
import { useTheme } from '../../../contexts';
|
|
10
|
-
import {
|
|
11
|
-
import { useCall
|
|
4
|
+
import { PhoneDown } from '../../../icons';
|
|
5
|
+
import { useCall } from '@stream-io/video-react-bindings';
|
|
12
6
|
import { getLogger } from '@stream-io/video-client';
|
|
13
7
|
|
|
14
8
|
/**
|
|
@@ -30,12 +24,11 @@ export const ViewerLeaveStreamButton = ({
|
|
|
30
24
|
}: ViewerLeaveStreamButtonProps) => {
|
|
31
25
|
const [isAwaitingResponse, setIsAwaitingResponse] = useState(false);
|
|
32
26
|
const call = useCall();
|
|
33
|
-
const
|
|
27
|
+
const styles = useStyles();
|
|
34
28
|
const {
|
|
35
29
|
theme: {
|
|
36
30
|
colors,
|
|
37
31
|
variants: { iconSizes },
|
|
38
|
-
typefaces,
|
|
39
32
|
viewerLeaveStreamButton,
|
|
40
33
|
},
|
|
41
34
|
} = useTheme();
|
|
@@ -57,46 +50,35 @@ export const ViewerLeaveStreamButton = ({
|
|
|
57
50
|
|
|
58
51
|
return (
|
|
59
52
|
<Pressable
|
|
60
|
-
style={
|
|
61
|
-
styles.container,
|
|
62
|
-
{ backgroundColor: colors.buttonSecondary },
|
|
63
|
-
viewerLeaveStreamButton.container,
|
|
64
|
-
]}
|
|
53
|
+
style={viewerLeaveStreamButton.container}
|
|
65
54
|
onPress={onLeaveStreamButtonPress}
|
|
66
55
|
>
|
|
67
|
-
<View
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
>
|
|
74
|
-
{isAwaitingResponse ? <ActivityIndicator /> : <LeaveStreamIcon />}
|
|
56
|
+
<View style={[styles.icon, viewerLeaveStreamButton.icon]}>
|
|
57
|
+
{isAwaitingResponse ? (
|
|
58
|
+
<ActivityIndicator />
|
|
59
|
+
) : (
|
|
60
|
+
<PhoneDown color={colors.iconPrimary} size={iconSizes.sm} />
|
|
61
|
+
)}
|
|
75
62
|
</View>
|
|
76
|
-
<Text
|
|
77
|
-
style={[
|
|
78
|
-
styles.text,
|
|
79
|
-
typefaces.subtitleBold,
|
|
80
|
-
{ color: colors.textPrimary },
|
|
81
|
-
viewerLeaveStreamButton.text,
|
|
82
|
-
]}
|
|
83
|
-
>
|
|
84
|
-
{isAwaitingResponse ? t('Loading...') : t('Leave Stream')}
|
|
85
|
-
</Text>
|
|
86
63
|
</Pressable>
|
|
87
64
|
);
|
|
88
65
|
};
|
|
89
66
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
67
|
+
const useStyles = () => {
|
|
68
|
+
const { theme } = useTheme();
|
|
69
|
+
return useMemo(
|
|
70
|
+
() =>
|
|
71
|
+
StyleSheet.create({
|
|
72
|
+
icon: {
|
|
73
|
+
backgroundColor: theme.colors.buttonSecondary,
|
|
74
|
+
height: theme.variants.buttonSizes.xs,
|
|
75
|
+
width: theme.variants.buttonSizes.xs,
|
|
76
|
+
justifyContent: 'center',
|
|
77
|
+
alignItems: 'center',
|
|
78
|
+
borderRadius: theme.variants.borderRadiusSizes.sm,
|
|
79
|
+
zIndex: 2,
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
[theme],
|
|
83
|
+
);
|
|
84
|
+
};
|
|
@@ -1,12 +1,30 @@
|
|
|
1
|
-
import React
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
8
|
+
import { Pressable, StyleSheet, View, type ViewProps } from 'react-native';
|
|
4
9
|
import {
|
|
5
10
|
ViewerLeaveStreamButton as DefaultViewerLeaveStreamButton,
|
|
6
11
|
type ViewerLeaveStreamButtonProps,
|
|
7
12
|
} from './ViewerLeaveStreamButton';
|
|
8
13
|
import { useTheme } from '../../../contexts';
|
|
9
14
|
import { Z_INDEX } from '../../../constants';
|
|
15
|
+
import {
|
|
16
|
+
DurationBadge,
|
|
17
|
+
FollowerCount,
|
|
18
|
+
LiveIndicator,
|
|
19
|
+
} from '../LivestreamTopView';
|
|
20
|
+
import { IconWrapper, Maximize } from '../../../icons';
|
|
21
|
+
import InCallManager from 'react-native-incall-manager';
|
|
22
|
+
import {
|
|
23
|
+
VolumeOff,
|
|
24
|
+
VolumeOn,
|
|
25
|
+
PauseIcon,
|
|
26
|
+
PlayIcon,
|
|
27
|
+
} from '../../../icons/LivestreamControls';
|
|
10
28
|
|
|
11
29
|
/**
|
|
12
30
|
* Props for the ViewerLivestreamControls component.
|
|
@@ -16,6 +34,15 @@ export type ViewerLivestreamControlsProps = ViewerLeaveStreamButtonProps & {
|
|
|
16
34
|
* Component to customize the leave stream button on the viewer's end live stream.
|
|
17
35
|
*/
|
|
18
36
|
ViewerLeaveStreamButton?: React.ComponentType<ViewerLeaveStreamButtonProps> | null;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Handler to be called when the leave stream button is pressed.
|
|
40
|
+
*/
|
|
41
|
+
onLeaveStreamHandler?: () => void;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Handler to be called when the layout of the component changes.
|
|
45
|
+
*/
|
|
19
46
|
onLayout?: ViewProps['onLayout'];
|
|
20
47
|
};
|
|
21
48
|
|
|
@@ -27,50 +54,240 @@ export const ViewerLivestreamControls = ({
|
|
|
27
54
|
onLeaveStreamHandler,
|
|
28
55
|
onLayout,
|
|
29
56
|
}: ViewerLivestreamControlsProps) => {
|
|
57
|
+
const styles = useStyles();
|
|
30
58
|
const {
|
|
31
|
-
theme: { colors, viewerLivestreamControls },
|
|
59
|
+
theme: { colors, viewerLivestreamControls, variants },
|
|
32
60
|
} = useTheme();
|
|
33
61
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
const [showControls, setShowControls] = useState(true);
|
|
63
|
+
const [isMuted, setIsMuted] = useState(false);
|
|
64
|
+
const [isPlaying, setIsPlaying] = useState(true);
|
|
65
|
+
const [showPlayPauseButton, setShowPlayPauseButton] = useState(true);
|
|
66
|
+
const playPauseTimeout = useRef<NodeJS.Timeout | null>(null);
|
|
67
|
+
|
|
68
|
+
const hidePlayPauseButtonAfterDelay = useCallback(() => {
|
|
69
|
+
if (playPauseTimeout.current) {
|
|
70
|
+
clearTimeout(playPauseTimeout.current);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
playPauseTimeout.current = setTimeout(() => {
|
|
74
|
+
setShowPlayPauseButton(false);
|
|
75
|
+
playPauseTimeout.current = null;
|
|
76
|
+
}, 3000);
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
hidePlayPauseButtonAfterDelay();
|
|
81
|
+
return () => {
|
|
82
|
+
if (playPauseTimeout.current) {
|
|
83
|
+
clearTimeout(playPauseTimeout.current);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}, [hidePlayPauseButtonAfterDelay]);
|
|
87
|
+
|
|
88
|
+
const showPlayPauseButtonWithTimeout = () => {
|
|
89
|
+
setShowPlayPauseButton(true);
|
|
90
|
+
hidePlayPauseButtonAfterDelay();
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const showControlsHandler = () => {
|
|
94
|
+
showPlayPauseButtonWithTimeout();
|
|
95
|
+
if (showControls) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setShowControls(true);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const toggleControls = () => {
|
|
103
|
+
setShowControls(!showControls);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const toggleAudio = () => {
|
|
107
|
+
setIsMuted(!isMuted);
|
|
108
|
+
InCallManager.setForceSpeakerphoneOn(isMuted);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const togglePlayPause = () => {
|
|
112
|
+
setIsPlaying(!isPlaying);
|
|
113
|
+
showPlayPauseButtonWithTimeout();
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const VolumeButton = (
|
|
117
|
+
<Pressable onPress={toggleAudio} style={[styles.fullscreenButton]}>
|
|
118
|
+
<View style={[styles.icon]}>
|
|
119
|
+
<IconWrapper>
|
|
120
|
+
{isMuted ? (
|
|
121
|
+
<VolumeOff
|
|
122
|
+
color={colors.iconPrimary}
|
|
123
|
+
size={variants.iconSizes.sm}
|
|
124
|
+
/>
|
|
125
|
+
) : (
|
|
126
|
+
<VolumeOn color={colors.iconPrimary} size={variants.iconSizes.sm} />
|
|
127
|
+
)}
|
|
128
|
+
</IconWrapper>
|
|
129
|
+
</View>
|
|
130
|
+
</Pressable>
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const MaximizeButton = (
|
|
134
|
+
<Pressable onPress={toggleControls} style={[styles.fullscreenButton]}>
|
|
135
|
+
<View style={[styles.icon]}>
|
|
136
|
+
<Maximize
|
|
137
|
+
color={colors.iconPrimary}
|
|
138
|
+
width={variants.iconSizes.sm}
|
|
139
|
+
height={variants.iconSizes.sm}
|
|
140
|
+
/>
|
|
49
141
|
</View>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
142
|
+
</Pressable>
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const PlayPauseButton = (
|
|
146
|
+
<Pressable onPress={togglePlayPause} style={styles.playPauseButton}>
|
|
147
|
+
<View style={styles.playPauseIcon}>
|
|
148
|
+
<IconWrapper>
|
|
149
|
+
{isPlaying ? (
|
|
150
|
+
<PauseIcon
|
|
151
|
+
color={colors.iconPrimary}
|
|
152
|
+
size={variants.iconSizes.lg * 3}
|
|
153
|
+
/>
|
|
154
|
+
) : (
|
|
155
|
+
<PlayIcon
|
|
156
|
+
color={colors.iconPrimary}
|
|
157
|
+
size={variants.iconSizes.lg * 3}
|
|
158
|
+
/>
|
|
159
|
+
)}
|
|
160
|
+
</IconWrapper>
|
|
161
|
+
</View>
|
|
162
|
+
</Pressable>
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<Pressable style={StyleSheet.absoluteFill} onPress={showControlsHandler}>
|
|
167
|
+
{!isPlaying && <View style={styles.blackOverlay} />}
|
|
168
|
+
|
|
169
|
+
{showPlayPauseButton && (
|
|
170
|
+
<View style={styles.centerButtonContainer}>{PlayPauseButton}</View>
|
|
171
|
+
)}
|
|
172
|
+
|
|
173
|
+
{showControls && (
|
|
174
|
+
<View
|
|
175
|
+
style={[styles.container, viewerLivestreamControls.container]}
|
|
176
|
+
onLayout={onLayout}
|
|
177
|
+
>
|
|
178
|
+
<View
|
|
179
|
+
style={[styles.leftElement, viewerLivestreamControls.leftElement]}
|
|
180
|
+
>
|
|
181
|
+
<View style={[styles.leftElement]}>
|
|
182
|
+
<View style={[styles.liveInfo]}>
|
|
183
|
+
<LiveIndicator />
|
|
184
|
+
<FollowerCount />
|
|
185
|
+
</View>
|
|
186
|
+
</View>
|
|
187
|
+
</View>
|
|
188
|
+
<View>
|
|
189
|
+
<DurationBadge mode="viewer" />
|
|
190
|
+
</View>
|
|
191
|
+
|
|
192
|
+
<View
|
|
193
|
+
style={[styles.rightElement, viewerLivestreamControls.rightElement]}
|
|
194
|
+
>
|
|
195
|
+
<View style={styles.buttonContainer}>
|
|
196
|
+
{VolumeButton}
|
|
197
|
+
{MaximizeButton}
|
|
198
|
+
{ViewerLeaveStreamButton && (
|
|
199
|
+
<ViewerLeaveStreamButton
|
|
200
|
+
onLeaveStreamHandler={onLeaveStreamHandler}
|
|
201
|
+
/>
|
|
202
|
+
)}
|
|
203
|
+
</View>
|
|
204
|
+
</View>
|
|
205
|
+
</View>
|
|
206
|
+
)}
|
|
207
|
+
</Pressable>
|
|
54
208
|
);
|
|
55
209
|
};
|
|
56
210
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
211
|
+
const useStyles = () => {
|
|
212
|
+
const { theme } = useTheme();
|
|
213
|
+
return useMemo(
|
|
214
|
+
() =>
|
|
215
|
+
StyleSheet.create({
|
|
216
|
+
container: {
|
|
217
|
+
position: 'absolute',
|
|
218
|
+
bottom: 0,
|
|
219
|
+
flexDirection: 'row',
|
|
220
|
+
alignItems: 'center',
|
|
221
|
+
justifyContent: 'center',
|
|
222
|
+
paddingVertical: 16,
|
|
223
|
+
paddingHorizontal: 8,
|
|
224
|
+
zIndex: Z_INDEX.IN_FRONT,
|
|
225
|
+
backgroundColor: theme.colors.sheetOverlay,
|
|
226
|
+
},
|
|
227
|
+
leftElement: {
|
|
228
|
+
flex: 1,
|
|
229
|
+
alignItems: 'flex-start',
|
|
230
|
+
justifyContent: 'center',
|
|
231
|
+
},
|
|
232
|
+
rightElement: {
|
|
233
|
+
flex: 1,
|
|
234
|
+
alignItems: 'flex-end',
|
|
235
|
+
},
|
|
236
|
+
liveInfo: {
|
|
237
|
+
flexDirection: 'row',
|
|
238
|
+
},
|
|
239
|
+
icon: {
|
|
240
|
+
height: theme.variants.iconSizes.sm,
|
|
241
|
+
width: theme.variants.iconSizes.sm,
|
|
242
|
+
},
|
|
243
|
+
fullscreenButton: {
|
|
244
|
+
backgroundColor: theme.colors.buttonSecondary,
|
|
245
|
+
height: theme.variants.buttonSizes.xs,
|
|
246
|
+
width: theme.variants.buttonSizes.xs,
|
|
247
|
+
justifyContent: 'center',
|
|
248
|
+
alignItems: 'center',
|
|
249
|
+
borderRadius: theme.variants.borderRadiusSizes.sm,
|
|
250
|
+
zIndex: 2,
|
|
251
|
+
},
|
|
252
|
+
buttonContainer: {
|
|
253
|
+
flexDirection: 'row',
|
|
254
|
+
alignItems: 'center',
|
|
255
|
+
justifyContent: 'center',
|
|
256
|
+
gap: theme.variants.spacingSizes.sm,
|
|
257
|
+
},
|
|
258
|
+
centerButtonContainer: {
|
|
259
|
+
position: 'absolute',
|
|
260
|
+
top: 0,
|
|
261
|
+
bottom: 0,
|
|
262
|
+
left: 0,
|
|
263
|
+
right: 0,
|
|
264
|
+
justifyContent: 'center',
|
|
265
|
+
alignItems: 'center',
|
|
266
|
+
zIndex: Z_INDEX.IN_FRONT,
|
|
267
|
+
pointerEvents: 'box-none',
|
|
268
|
+
},
|
|
269
|
+
playPauseButton: {
|
|
270
|
+
height: 200,
|
|
271
|
+
width: 200,
|
|
272
|
+
|
|
273
|
+
justifyContent: 'center',
|
|
274
|
+
alignItems: 'center',
|
|
275
|
+
zIndex: Z_INDEX.IN_FRONT + 1,
|
|
276
|
+
},
|
|
277
|
+
playPauseIcon: {
|
|
278
|
+
height: 200,
|
|
279
|
+
width: 200,
|
|
280
|
+
},
|
|
281
|
+
blackOverlay: {
|
|
282
|
+
position: 'absolute',
|
|
283
|
+
top: 0,
|
|
284
|
+
left: 0,
|
|
285
|
+
right: 0,
|
|
286
|
+
bottom: 0,
|
|
287
|
+
backgroundColor: 'black',
|
|
288
|
+
zIndex: Z_INDEX.IN_FRONT - 1,
|
|
289
|
+
},
|
|
290
|
+
}),
|
|
291
|
+
[theme],
|
|
292
|
+
);
|
|
293
|
+
};
|