agora-appbuilder-core 2.0.1 → 2.0.3-rc2
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/Readme.md +2 -1
- package/package.json +1 -1
- package/template/_package-lock.json +8853 -8806
- package/template/agora-rn-uikit/.git/index +0 -0
- package/template/agora-rn-uikit/.git/logs/HEAD +2 -2
- package/template/agora-rn-uikit/.git/logs/refs/heads/ab-dev-auto +1 -1
- package/template/agora-rn-uikit/.git/logs/refs/heads/master +1 -1
- package/template/agora-rn-uikit/.git/logs/refs/remotes/origin/HEAD +1 -1
- package/template/agora-rn-uikit/.git/objects/pack/pack-2a0122bf5a3199f941e5a52535f43881623f752c.idx +0 -0
- package/template/agora-rn-uikit/.git/objects/pack/{pack-f379286d0537eb68377220b4929979324b8d5d1c.pack → pack-2a0122bf5a3199f941e5a52535f43881623f752c.pack} +0 -0
- package/template/agora-rn-uikit/.git/packed-refs +4 -2
- package/template/agora-rn-uikit/.git/refs/heads/ab-dev-auto +1 -1
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +21 -0
- package/template/agora-rn-uikit/src/Controls/BtnTemplate.tsx +22 -14
- package/template/agora-rn-uikit/src/Controls/ImageIcon.tsx +17 -13
- package/template/agora-rn-uikit/src/Controls/types.ts +4 -0
- package/template/agora-rn-uikit/src/Rtc/Create.tsx +117 -19
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +24 -13
- package/template/{src/utils/isSafariBrowser.tsx → agora-rn-uikit/src/Utils/isSafariBrowser.ts} +3 -0
- package/template/{src → agora-rn-uikit/src}/hooks/useImageDelay.tsx +5 -2
- package/template/agora-rn-uikit/src/index.ts +2 -0
- package/template/bridge/rtc/webNg/RtcEngine.ts +73 -70
- package/template/bridge/rtc/webNg/Types.ts +59 -5
- package/template/bridge/rtm/web/Types.ts +13 -0
- package/template/bridge/rtm/web/index.ts +78 -1
- package/template/global.d.ts +2 -0
- package/template/package-lock.json +8853 -8806
- package/template/package.json +3 -4
- package/template/react-native-toast-message/src/components/base/styles.js +4 -2
- package/template/src/assets/icons.ts +41 -28
- package/template/src/components/Chat.tsx +70 -184
- package/template/src/components/ChatContext.ts +13 -2
- package/template/src/components/Controls.native.tsx +37 -76
- package/template/src/components/Controls.tsx +50 -158
- package/template/src/components/DeviceConfigure.native.tsx +5 -1
- package/template/src/components/DeviceConfigure.tsx +38 -20
- package/template/src/components/Navbar.tsx +185 -226
- package/template/src/components/ParticipantsView.tsx +176 -184
- package/template/src/components/Precall.native.tsx +83 -69
- package/template/src/components/Precall.tsx +174 -191
- package/template/src/components/RTMConfigure.tsx +264 -78
- package/template/src/components/SettingsView.tsx +9 -19
- package/template/src/components/livestream/LiveStreamContext.tsx +411 -0
- package/template/src/components/livestream/Types.ts +69 -0
- package/template/src/components/livestream/index.ts +9 -0
- package/template/src/components/livestream/views/LiveStreamControls.tsx +27 -0
- package/template/src/components/participants/AllAudienceParticipants.tsx +53 -0
- package/template/src/components/participants/AllHostParticipants.tsx +65 -0
- package/template/src/components/participants/MeParticipant.tsx +37 -0
- package/template/src/components/participants/ParticipantName.tsx +47 -0
- package/template/src/components/participants/ParticipantSectionTitle.tsx +29 -0
- package/template/src/components/participants/RemoteParticipants.tsx +69 -0
- package/template/src/components/participants/ScreenshareParticipants.tsx +28 -0
- package/template/src/components/participants/context/ParticipantContext.tsx +97 -0
- package/template/src/components/styles.ts +13 -0
- package/template/src/pages/Create.tsx +25 -14
- package/template/src/pages/VideoCall.tsx +197 -159
- package/template/src/subComponents/ChatBubble.tsx +4 -1
- package/template/src/subComponents/ChatContainer.tsx +44 -20
- package/template/src/subComponents/ChatInput.tsx +4 -12
- package/template/src/subComponents/Checkbox.native.tsx +6 -5
- package/template/src/subComponents/Checkbox.tsx +1 -0
- package/template/src/subComponents/Recording.tsx +23 -9
- package/template/src/subComponents/RemoteVideoMute.tsx +2 -3
- package/template/src/subComponents/SelectDevice.tsx +70 -35
- package/template/src/subComponents/chat/ChatParticipants.tsx +121 -0
- package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +23 -0
- package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +70 -0
- package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +57 -0
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx +24 -0
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestApprove.tsx +38 -0
- package/template/src/subComponents/livestream/controls/RemoteLiveStreamRequestReject.tsx +37 -0
- package/template/src/subComponents/livestream/index.ts +18 -0
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +80 -0
- package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +24 -0
- package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +200 -0
- package/template/src/subComponents/screenshare/ScreenshareContext.tsx +21 -0
- package/template/src/utils/index.tsx +48 -0
- package/template/agora-rn-uikit/.git/objects/pack/pack-f379286d0537eb68377220b4929979324b8d5d1c.idx +0 -0
|
@@ -22,6 +22,7 @@ const Checkbox = (props: any) => {
|
|
|
22
22
|
const setUrlCheckbox = props.onValueChange;
|
|
23
23
|
return (
|
|
24
24
|
<CheckBox
|
|
25
|
+
disabled={props?.disabled}
|
|
25
26
|
value={urlCheckbox}
|
|
26
27
|
onValueChange={setUrlCheckbox}
|
|
27
28
|
//@ts-ignore Color prop exists on react-native-web but it not present in @react-native-community/checkbox
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
information visit https://appbuilder.agora.io.
|
|
10
10
|
*********************************************
|
|
11
11
|
*/
|
|
12
|
-
import React, {useContext, useEffect} from 'react';
|
|
13
|
-
import {
|
|
14
|
-
import icons from '../assets/icons';
|
|
12
|
+
import React, {useContext, useEffect, useRef} from 'react';
|
|
13
|
+
import {TouchableOpacity, StyleSheet, View, Text} from 'react-native';
|
|
15
14
|
import ChatContext, {controlMessageEnum} from '../components/ChatContext';
|
|
16
15
|
import ColorContext from '../components/ColorContext';
|
|
17
16
|
import {gql, useMutation} from '@apollo/client';
|
|
@@ -37,6 +36,14 @@ const STOP_RECORDING = gql`
|
|
|
37
36
|
* Sends a control message to all users in the channel over RTM to indicate that
|
|
38
37
|
* Cloud recording has started/stopped.
|
|
39
38
|
*/
|
|
39
|
+
function usePrevious(value: any) {
|
|
40
|
+
const ref = useRef();
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
ref.current = value;
|
|
43
|
+
});
|
|
44
|
+
return ref.current;
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
const Recording = (props: any) => {
|
|
41
48
|
const {rtcProps} = useContext(PropsContext);
|
|
42
49
|
const {primaryColor} = useContext(ColorContext);
|
|
@@ -46,12 +53,19 @@ const Recording = (props: any) => {
|
|
|
46
53
|
const [startRecordingQuery] = useMutation(START_RECORDING);
|
|
47
54
|
const [stopRecordingQuery] = useMutation(STOP_RECORDING);
|
|
48
55
|
const {sendControlMessage} = useContext(ChatContext);
|
|
56
|
+
const prevRecordingState = usePrevious({recordingActive});
|
|
49
57
|
|
|
50
58
|
useEffect(() => {
|
|
51
|
-
|
|
59
|
+
/**
|
|
60
|
+
* The below check makes sure the notification is triggered
|
|
61
|
+
* only once. In native apps, this componenet is mounted everytime
|
|
62
|
+
* when chat icon is toggle, as Controls component is hidden and
|
|
63
|
+
* shown
|
|
64
|
+
*/
|
|
65
|
+
if (prevRecordingState && recordingActive) {
|
|
66
|
+
if (prevRecordingState?.recordingActive === recordingActive) return;
|
|
52
67
|
Toast.show({text1: 'Recording Started', visibilityTime: 1000});
|
|
53
|
-
|
|
54
|
-
// Toast.show({text1: 'Recording Finished', visibilityTime: 1000})
|
|
68
|
+
}
|
|
55
69
|
}, [recordingActive]);
|
|
56
70
|
|
|
57
71
|
return (
|
|
@@ -103,7 +117,7 @@ const Recording = (props: any) => {
|
|
|
103
117
|
<ImageIcon
|
|
104
118
|
name={recordingActive ? 'recordingActiveIcon' : 'recordingIcon'}
|
|
105
119
|
style={[style.buttonIcon]}
|
|
106
|
-
color={recordingActive ? '#FD0845': $config.PRIMARY_COLOR}
|
|
120
|
+
color={recordingActive ? '#FD0845' : $config.PRIMARY_COLOR}
|
|
107
121
|
/>
|
|
108
122
|
</View>
|
|
109
123
|
<Text
|
|
@@ -132,8 +146,8 @@ const style = StyleSheet.create({
|
|
|
132
146
|
justifyContent: 'center',
|
|
133
147
|
},
|
|
134
148
|
buttonIcon: {
|
|
135
|
-
width: '
|
|
136
|
-
height: '
|
|
149
|
+
width: '90%',
|
|
150
|
+
height: '90%',
|
|
137
151
|
},
|
|
138
152
|
});
|
|
139
153
|
|
|
@@ -24,9 +24,9 @@ const RemoteVideoMute = (props: {
|
|
|
24
24
|
video: boolean;
|
|
25
25
|
isHost: boolean;
|
|
26
26
|
}) => {
|
|
27
|
-
const {primaryColor} = useContext(ColorContext);
|
|
28
27
|
const {isHost = false} = props;
|
|
29
28
|
const {sendControlMessageToUid} = useContext(ChatContext);
|
|
29
|
+
|
|
30
30
|
return String(props.uid)[0] !== '1' ? (
|
|
31
31
|
<BtnTemplate
|
|
32
32
|
disabled={!isHost}
|
|
@@ -43,9 +43,8 @@ const RemoteVideoMute = (props: {
|
|
|
43
43
|
|
|
44
44
|
const style = StyleSheet.create({
|
|
45
45
|
buttonIconCam: {
|
|
46
|
-
width:
|
|
46
|
+
width: 25,
|
|
47
47
|
height: 25,
|
|
48
|
-
marginHorizontal: 2,
|
|
49
48
|
},
|
|
50
49
|
});
|
|
51
50
|
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
*********************************************
|
|
11
11
|
*/
|
|
12
12
|
import React, {useContext} from 'react';
|
|
13
|
-
import {Picker, StyleSheet} from 'react-native';
|
|
13
|
+
import {Picker, StyleSheet, View, Text} from 'react-native';
|
|
14
|
+
import {PropsContext, ClientRole} from '../../agora-rn-uikit';
|
|
14
15
|
import DeviceContext from '../components/DeviceContext';
|
|
15
16
|
import ColorContext from '../components/ColorContext';
|
|
16
17
|
// import {dropdown} from '../../theme.json';
|
|
@@ -19,45 +20,74 @@ import ColorContext from '../components/ColorContext';
|
|
|
19
20
|
* It will add the selected device to the device context.
|
|
20
21
|
*/
|
|
21
22
|
const SelectDevice = () => {
|
|
23
|
+
// Contexts
|
|
24
|
+
const {rtcProps} = useContext(PropsContext);
|
|
22
25
|
const {primaryColor} = useContext(ColorContext);
|
|
23
26
|
const {selectedCam, setSelectedCam, selectedMic, setSelectedMic, deviceList} =
|
|
24
27
|
useContext(DeviceContext);
|
|
28
|
+
// States
|
|
29
|
+
const [isPickerDisabled, setPickerDisabled] = React.useState<boolean>(false);
|
|
30
|
+
const [btnTheme, setBtnTheme] = React.useState<string>(primaryColor);
|
|
31
|
+
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
if ($config.EVENT_MODE && rtcProps.role === ClientRole.Audience) {
|
|
34
|
+
setPickerDisabled(true);
|
|
35
|
+
setBtnTheme('rgba(16, 16, 16, 0.3)');
|
|
36
|
+
} else {
|
|
37
|
+
setPickerDisabled(false);
|
|
38
|
+
setBtnTheme(primaryColor);
|
|
39
|
+
}
|
|
40
|
+
}, [rtcProps?.role]);
|
|
25
41
|
|
|
26
42
|
return (
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
<View>
|
|
44
|
+
<View style={{marginTop: 15}}></View>
|
|
45
|
+
<View>
|
|
46
|
+
<Picker
|
|
47
|
+
enabled={!isPickerDisabled}
|
|
48
|
+
selectedValue={selectedCam}
|
|
49
|
+
style={[{borderColor: btnTheme}, style.popupPicker]}
|
|
50
|
+
onValueChange={(itemValue) => setSelectedCam(itemValue)}>
|
|
51
|
+
{deviceList.map((device: any) => {
|
|
52
|
+
if (device.kind === 'videoinput') {
|
|
53
|
+
return (
|
|
54
|
+
<Picker.Item
|
|
55
|
+
label={device.label}
|
|
56
|
+
value={device.deviceId}
|
|
57
|
+
key={device.deviceId}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
})}
|
|
62
|
+
</Picker>
|
|
63
|
+
<Picker
|
|
64
|
+
enabled={!isPickerDisabled}
|
|
65
|
+
selectedValue={selectedMic}
|
|
66
|
+
style={[{borderColor: btnTheme}, style.popupPicker]}
|
|
67
|
+
onValueChange={(itemValue) => setSelectedMic(itemValue)}>
|
|
68
|
+
{deviceList.map((device: any) => {
|
|
69
|
+
if (device.kind === 'audioinput') {
|
|
70
|
+
return (
|
|
71
|
+
<Picker.Item
|
|
72
|
+
label={device.label}
|
|
73
|
+
value={device.deviceId}
|
|
74
|
+
key={device.deviceId}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
})}
|
|
79
|
+
</Picker>
|
|
80
|
+
</View>
|
|
81
|
+
<View style={{marginTop: 15}}></View>
|
|
82
|
+
{$config.EVENT_MODE && isPickerDisabled && (
|
|
83
|
+
<View>
|
|
84
|
+
<Text style={style.infoTxt}>
|
|
85
|
+
Video and Audio sharing is disabled for attendees. Raise hand to
|
|
86
|
+
request permission to share
|
|
87
|
+
</Text>
|
|
88
|
+
</View>
|
|
89
|
+
)}
|
|
90
|
+
</View>
|
|
61
91
|
);
|
|
62
92
|
};
|
|
63
93
|
|
|
@@ -70,6 +100,11 @@ const style = StyleSheet.create({
|
|
|
70
100
|
fontSize: 15,
|
|
71
101
|
minHeight: 35,
|
|
72
102
|
},
|
|
103
|
+
infoTxt: {
|
|
104
|
+
textAlign: 'center',
|
|
105
|
+
fontSize: 12,
|
|
106
|
+
color: '#FF0000',
|
|
107
|
+
},
|
|
73
108
|
});
|
|
74
109
|
|
|
75
110
|
export default SelectDevice;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
ScrollView,
|
|
7
|
+
useWindowDimensions,
|
|
8
|
+
StyleSheet,
|
|
9
|
+
Platform,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
import {RFValue} from 'react-native-responsive-fontsize';
|
|
12
|
+
import {UserType} from '../../components/RTMConfigure';
|
|
13
|
+
import TextWithTooltip from '../TextWithTooltip';
|
|
14
|
+
import chatContext from '../../components/ChatContext';
|
|
15
|
+
|
|
16
|
+
const ChatParticipants = (props: any) => {
|
|
17
|
+
const {
|
|
18
|
+
selectUser,
|
|
19
|
+
setPrivateMessageLastSeen,
|
|
20
|
+
privateMessageCountMap,
|
|
21
|
+
lastCheckedPrivateState,
|
|
22
|
+
} = props;
|
|
23
|
+
const {height, width} = useWindowDimensions();
|
|
24
|
+
const {userList, localUid} = useContext(chatContext);
|
|
25
|
+
|
|
26
|
+
const isChatUser = (userId: string, userInfo: any) => {
|
|
27
|
+
return (
|
|
28
|
+
userId !== localUid &&
|
|
29
|
+
parseInt(userId) !== 1 &&
|
|
30
|
+
userInfo?.type !== UserType.ScreenShare &&
|
|
31
|
+
!userInfo?.offline
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<ScrollView>
|
|
37
|
+
{Object.entries(userList).map(([uid, value]) => {
|
|
38
|
+
if (isChatUser(uid, value)) {
|
|
39
|
+
return (
|
|
40
|
+
<TouchableOpacity
|
|
41
|
+
style={style.participantContainer}
|
|
42
|
+
key={uid}
|
|
43
|
+
onPress={() => {
|
|
44
|
+
selectUser(uid);
|
|
45
|
+
setPrivateMessageLastSeen({
|
|
46
|
+
userId: uid,
|
|
47
|
+
lastSeenCount: privateMessageCountMap[uid],
|
|
48
|
+
});
|
|
49
|
+
}}>
|
|
50
|
+
{(privateMessageCountMap[uid] || 0) -
|
|
51
|
+
(lastCheckedPrivateState[uid] || 0) !==
|
|
52
|
+
0 ? (
|
|
53
|
+
<View style={style.chatNotificationPrivate}>
|
|
54
|
+
<Text>
|
|
55
|
+
{(privateMessageCountMap[uid] || 0) -
|
|
56
|
+
(lastCheckedPrivateState[uid] || 0)}
|
|
57
|
+
</Text>
|
|
58
|
+
</View>
|
|
59
|
+
) : null}
|
|
60
|
+
<View style={{flex: 1}}>
|
|
61
|
+
<TextWithTooltip
|
|
62
|
+
touchable={false}
|
|
63
|
+
style={[
|
|
64
|
+
style.participantText,
|
|
65
|
+
{
|
|
66
|
+
fontSize: RFValue(16, height > width ? height : width),
|
|
67
|
+
},
|
|
68
|
+
]}
|
|
69
|
+
value={userList[uid] ? userList[uid].name + ' ' : 'User '}
|
|
70
|
+
/>
|
|
71
|
+
</View>
|
|
72
|
+
<View>
|
|
73
|
+
<Text
|
|
74
|
+
style={{
|
|
75
|
+
color: $config.PRIMARY_FONT_COLOR,
|
|
76
|
+
fontSize: 18,
|
|
77
|
+
}}>{`>`}</Text>
|
|
78
|
+
</View>
|
|
79
|
+
</TouchableOpacity>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
})}
|
|
83
|
+
</ScrollView>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const style = StyleSheet.create({
|
|
88
|
+
participantContainer: {
|
|
89
|
+
flexDirection: 'row',
|
|
90
|
+
flex: 1,
|
|
91
|
+
height: 20,
|
|
92
|
+
marginTop: 10,
|
|
93
|
+
backgroundColor: $config.SECONDARY_FONT_COLOR,
|
|
94
|
+
overflow: 'hidden',
|
|
95
|
+
marginHorizontal: 10,
|
|
96
|
+
},
|
|
97
|
+
participantText: {
|
|
98
|
+
flex: 1,
|
|
99
|
+
fontWeight: Platform.OS === 'web' ? '500' : '700',
|
|
100
|
+
flexDirection: 'row',
|
|
101
|
+
color: $config.PRIMARY_FONT_COLOR,
|
|
102
|
+
textAlign: 'left',
|
|
103
|
+
flexShrink: 1,
|
|
104
|
+
marginRight: 30,
|
|
105
|
+
},
|
|
106
|
+
chatNotificationPrivate: {
|
|
107
|
+
width: 20,
|
|
108
|
+
height: 20,
|
|
109
|
+
display: 'flex',
|
|
110
|
+
alignItems: 'center',
|
|
111
|
+
justifyContent: 'center',
|
|
112
|
+
backgroundColor: $config.PRIMARY_COLOR,
|
|
113
|
+
color: $config.SECONDARY_FONT_COLOR,
|
|
114
|
+
fontFamily: Platform.OS === 'ios' ? 'Helvetica' : 'sans-serif',
|
|
115
|
+
borderRadius: 10,
|
|
116
|
+
position: 'absolute',
|
|
117
|
+
right: 20,
|
|
118
|
+
top: 0,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
export default ChatParticipants;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import RemoteLiveStreamApprovedRequestRecall from './controls/RemoteLiveStreamApprovedRequestRecall';
|
|
4
|
+
import LiveStreamContext, {requestStatus} from '../../components/livestream';
|
|
5
|
+
|
|
6
|
+
const ApprovedLiveStreamControlsView = (props: {
|
|
7
|
+
uid: number;
|
|
8
|
+
p_styles: any;
|
|
9
|
+
}) => {
|
|
10
|
+
const {uid, p_styles} = props;
|
|
11
|
+
const {currLiveStreamRequest} = useContext(LiveStreamContext);
|
|
12
|
+
|
|
13
|
+
if (currLiveStreamRequest[uid]?.status === requestStatus.Approved) {
|
|
14
|
+
return (
|
|
15
|
+
<View style={[p_styles.actionBtnIcon, {marginRight: 10}]}>
|
|
16
|
+
<RemoteLiveStreamApprovedRequestRecall uid={uid} />
|
|
17
|
+
</View>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return <></>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default ApprovedLiveStreamControlsView;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React, {useContext, useEffect, useState} from 'react';
|
|
2
|
+
import {View, Text} from 'react-native';
|
|
3
|
+
import RemoteLiveStreamRequestApprove from './controls/RemoteLiveStreamRequestApprove';
|
|
4
|
+
import RemoteLiveStreamRequestReject from './controls/RemoteLiveStreamRequestReject';
|
|
5
|
+
import ParticipantName from '../../components/participants/ParticipantName';
|
|
6
|
+
import LiveStreamContext, {requestStatus} from '../../components/livestream';
|
|
7
|
+
import {filterObject} from '../../utils/index';
|
|
8
|
+
import ParticipantSectionTitle from '../../components/participants/ParticipantSectionTitle';
|
|
9
|
+
|
|
10
|
+
const CurrentLiveStreamRequestsView = (props: any) => {
|
|
11
|
+
const {userList, p_style} = props;
|
|
12
|
+
const {currLiveStreamRequest, setLastCheckedRequestTimestamp} =
|
|
13
|
+
useContext(LiveStreamContext);
|
|
14
|
+
const [activeLiveStreamRequests, setActiveLiveStreamRequests] =
|
|
15
|
+
React.useState({});
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setActiveLiveStreamRequests(
|
|
19
|
+
filterObject(
|
|
20
|
+
currLiveStreamRequest,
|
|
21
|
+
([k, v]) => v?.status === requestStatus.AwaitingAction,
|
|
22
|
+
),
|
|
23
|
+
);
|
|
24
|
+
}, [currLiveStreamRequest]);
|
|
25
|
+
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
// On unmount update the timestamp, if the user was already active in this view
|
|
28
|
+
return () => {
|
|
29
|
+
setLastCheckedRequestTimestamp(new Date().getTime());
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<ParticipantSectionTitle
|
|
36
|
+
title="Streaming Request "
|
|
37
|
+
count={Object.keys(activeLiveStreamRequests).length}
|
|
38
|
+
/>
|
|
39
|
+
<View style={p_style.participantContainer}>
|
|
40
|
+
{Object.keys(currLiveStreamRequest).length == 0 ||
|
|
41
|
+
Object.keys(activeLiveStreamRequests).length == 0 ? (
|
|
42
|
+
<Text style={p_style.infoText}>No streaming request(s)</Text>
|
|
43
|
+
) : (
|
|
44
|
+
Object.keys(activeLiveStreamRequests).map(
|
|
45
|
+
(userUID: any, index: number) =>
|
|
46
|
+
userList[userUID] ? (
|
|
47
|
+
<View style={p_style.participantRow} key={index}>
|
|
48
|
+
<ParticipantName value={userList[userUID]?.name || 'User'} />
|
|
49
|
+
<View style={p_style.participantActionContainer}>
|
|
50
|
+
<RemoteLiveStreamRequestApprove
|
|
51
|
+
user={{...userList[userUID], uid: userUID}}
|
|
52
|
+
/>
|
|
53
|
+
<RemoteLiveStreamRequestReject
|
|
54
|
+
user={{...userList[userUID], uid: userUID}}
|
|
55
|
+
/>
|
|
56
|
+
</View>
|
|
57
|
+
</View>
|
|
58
|
+
) : (
|
|
59
|
+
<View style={p_style.participantRow} key={index}>
|
|
60
|
+
<ParticipantName value={'User not found'} />
|
|
61
|
+
</View>
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
)}
|
|
65
|
+
</View>
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default CurrentLiveStreamRequestsView;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
********************************************
|
|
3
|
+
Copyright © 2021 Agora Lab, Inc., all rights reserved.
|
|
4
|
+
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
+
(the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
+
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
+
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
+
any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
|
|
9
|
+
information visit https://appbuilder.agora.io.
|
|
10
|
+
*********************************************
|
|
11
|
+
*/
|
|
12
|
+
import React, {useContext} from 'react';
|
|
13
|
+
import {StyleSheet} from 'react-native';
|
|
14
|
+
import LiveStreamContext from '../../../components/livestream';
|
|
15
|
+
import {PropsContext} from '../../../../agora-rn-uikit';
|
|
16
|
+
import {BtnTemplate} from '../../../../agora-rn-uikit';
|
|
17
|
+
import icons from '../../../assets/icons';
|
|
18
|
+
|
|
19
|
+
const LocalRaiseHand = () => {
|
|
20
|
+
const {styleProps} = useContext(PropsContext);
|
|
21
|
+
const {audienceSendsRequest, audienceRecallsRequest, raiseHandRequestActive} =
|
|
22
|
+
useContext(LiveStreamContext);
|
|
23
|
+
const {localBtnStyles} = styleProps || {};
|
|
24
|
+
const {theme} = styleProps || {};
|
|
25
|
+
const {muteLocalAudio} = localBtnStyles || {};
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<BtnTemplate
|
|
29
|
+
icon={icons['raiseHandIcon']}
|
|
30
|
+
btnText={raiseHandRequestActive ? 'Lower hand' : 'Raise Hand'}
|
|
31
|
+
color={raiseHandRequestActive ? '#FD0845' : theme}
|
|
32
|
+
style={{
|
|
33
|
+
...style.localBtn,
|
|
34
|
+
...(localBtnStyles as object),
|
|
35
|
+
...(muteLocalAudio as object),
|
|
36
|
+
}}
|
|
37
|
+
onPress={() => {
|
|
38
|
+
if (!raiseHandRequestActive) {
|
|
39
|
+
audienceSendsRequest();
|
|
40
|
+
} else {
|
|
41
|
+
audienceRecallsRequest();
|
|
42
|
+
}
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const style = StyleSheet.create({
|
|
49
|
+
localBtn: {
|
|
50
|
+
borderRadius: 23,
|
|
51
|
+
borderWidth: 4 * StyleSheet.hairlineWidth,
|
|
52
|
+
borderColor: '#007aff',
|
|
53
|
+
backgroundColor: '#007aff',
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export default LocalRaiseHand;
|
package/template/src/subComponents/livestream/controls/RemoteLiveStreamApprovedRequestRecall.tsx
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import ChatContext from '../../../components/ChatContext';
|
|
3
|
+
import {BtnTemplate} from '../../../../agora-rn-uikit';
|
|
4
|
+
import {LiveStreamControlMessageEnum} from '../../../components/livestream';
|
|
5
|
+
import icons from '../../../assets/icons';
|
|
6
|
+
|
|
7
|
+
const RemoteLiveStreamApprovedRequestRecall = (props: {uid: number}) => {
|
|
8
|
+
const {sendControlMessageToUid} = useContext(ChatContext);
|
|
9
|
+
return (
|
|
10
|
+
<BtnTemplate
|
|
11
|
+
style={{width: 24, height: 22}}
|
|
12
|
+
onPress={() => {
|
|
13
|
+
sendControlMessageToUid(
|
|
14
|
+
LiveStreamControlMessageEnum.raiseHandApprovedRequestRecall,
|
|
15
|
+
props.uid,
|
|
16
|
+
);
|
|
17
|
+
}}
|
|
18
|
+
color="#FD0845"
|
|
19
|
+
icon={icons['demoteIcon']}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default RemoteLiveStreamApprovedRequestRecall;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
BtnTemplate,
|
|
5
|
+
PropsContext,
|
|
6
|
+
UidInterface,
|
|
7
|
+
} from '../../../../agora-rn-uikit';
|
|
8
|
+
import LiveStreamContext from '../../../components/livestream';
|
|
9
|
+
import icons from '../../../assets/icons';
|
|
10
|
+
|
|
11
|
+
interface RemoteLiveStreamControlInterface {
|
|
12
|
+
user: UidInterface;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const RemoteLiveStreamRequestApprove: React.FC<RemoteLiveStreamControlInterface> =
|
|
16
|
+
(props) => {
|
|
17
|
+
const {user} = props;
|
|
18
|
+
const {hostApprovesRequestOfUID} = useContext(LiveStreamContext);
|
|
19
|
+
const {styleProps} = useContext(PropsContext);
|
|
20
|
+
const {remoteBtnStyles} = styleProps || {};
|
|
21
|
+
|
|
22
|
+
const {liveStreamHostControlBtns} = remoteBtnStyles || {};
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<View style={{...(liveStreamHostControlBtns as object), marginRight: 15}}>
|
|
26
|
+
<BtnTemplate
|
|
27
|
+
disabled={!user?.uid}
|
|
28
|
+
icon={icons['checkCircleIcon']}
|
|
29
|
+
style={{...(liveStreamHostControlBtns as object)}}
|
|
30
|
+
onPress={() => {
|
|
31
|
+
hostApprovesRequestOfUID(user?.uid);
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
34
|
+
</View>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default RemoteLiveStreamRequestApprove;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
BtnTemplate,
|
|
5
|
+
PropsContext,
|
|
6
|
+
UidInterface,
|
|
7
|
+
} from '../../../../agora-rn-uikit';
|
|
8
|
+
import LiveStreamContext from '../../../components/livestream';
|
|
9
|
+
import icons from '../../../assets/icons';
|
|
10
|
+
|
|
11
|
+
interface RemoteLiveStreamControlInterface {
|
|
12
|
+
user: UidInterface;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const RemoteLiveStreamRequestReject: React.FC<RemoteLiveStreamControlInterface> =
|
|
16
|
+
(props) => {
|
|
17
|
+
const {user} = props;
|
|
18
|
+
const {hostRejectsRequestOfUID} = useContext(LiveStreamContext);
|
|
19
|
+
const {styleProps} = useContext(PropsContext);
|
|
20
|
+
const {remoteBtnStyles} = styleProps || {};
|
|
21
|
+
const {liveStreamHostControlBtns} = remoteBtnStyles || {};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<View style={{...(liveStreamHostControlBtns as object)}}>
|
|
25
|
+
<BtnTemplate
|
|
26
|
+
disabled={!user?.uid}
|
|
27
|
+
icon={icons['crossCircleIcon']}
|
|
28
|
+
style={{...(liveStreamHostControlBtns as object)}}
|
|
29
|
+
onPress={() => {
|
|
30
|
+
hostRejectsRequestOfUID(user.uid);
|
|
31
|
+
}}
|
|
32
|
+
/>
|
|
33
|
+
</View>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default RemoteLiveStreamRequestReject;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Remote controls
|
|
2
|
+
import RemoteLiveStreamApprovedRequestRecall from './controls/RemoteLiveStreamApprovedRequestRecall';
|
|
3
|
+
import RemoteLiveStreamRequestApprove from './controls/RemoteLiveStreamRequestApprove';
|
|
4
|
+
import RemoteLiveStreamRequestReject from './controls/RemoteLiveStreamRequestReject';
|
|
5
|
+
// Local controls
|
|
6
|
+
import LocalRaiseHand from './controls/LocalRaiseHand';
|
|
7
|
+
// Views
|
|
8
|
+
import CurrentLiveStreamRequestsView from './CurrentLiveStreamRequestsView';
|
|
9
|
+
import ApprovedLiveStreamControlsView from './ApprovedLiveStreamControlsView';
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
RemoteLiveStreamApprovedRequestRecall,
|
|
13
|
+
RemoteLiveStreamRequestApprove,
|
|
14
|
+
RemoteLiveStreamRequestReject,
|
|
15
|
+
LocalRaiseHand,
|
|
16
|
+
CurrentLiveStreamRequestsView,
|
|
17
|
+
ApprovedLiveStreamControlsView,
|
|
18
|
+
};
|