浏览代码

feat(native-participants-pane) implemented review remarks pt. 1

master
Calin Chitu 4 年前
父节点
当前提交
c6e50ad439

+ 9
- 1
react/features/base/config/functions.any.js 查看文件

60
     return state['features/base/config'].recordingSharingUrl;
60
     return state['features/base/config'].recordingSharingUrl;
61
 }
61
 }
62
 
62
 
63
-/* eslint-disable max-params, no-shadow */
63
+/**
64
+ * Selector used to get if the new participant is starting silent.
65
+ *
66
+ * @param {Object} state - The global state.
67
+ * @returns {string}
68
+ */
69
+export function getIsStartingSilent(state: Object) {
70
+    return Boolean(state['features/base/config'].startSilent);
71
+}
64
 
72
 
65
 /**
73
 /**
66
  * Overrides JSON properties in {@code config} and
74
  * Overrides JSON properties in {@code config} and

+ 1
- 5
react/features/base/react/components/native/HeaderWithNavigation.js 查看文件

56
         const { hideHeaderWithNavigation, onPressBack, onPressForward } = this.props;
56
         const { hideHeaderWithNavigation, onPressBack, onPressForward } = this.props;
57
 
57
 
58
         return (
58
         return (
59
-            <>
60
-                {
61
-                    !hideHeaderWithNavigation
59
+            !{ hideHeaderWithNavigation }
62
                     && <Header>
60
                     && <Header>
63
                         { onPressBack && <BackButton onPress = { onPressBack } /> }
61
                         { onPressBack && <BackButton onPress = { onPressBack } /> }
64
                         <HeaderLabel labelKey = { this.props.headerLabelKey } />
62
                         <HeaderLabel labelKey = { this.props.headerLabelKey } />
67
                             labelKey = { this.props.forwardLabelKey }
65
                             labelKey = { this.props.forwardLabelKey }
68
                             onPress = { onPressForward } /> }
66
                             onPress = { onPressForward } /> }
69
                     </Header>
67
                     </Header>
70
-                }
71
-            </>
72
         );
68
         );
73
     }
69
     }
74
 }
70
 }

+ 4
- 4
react/features/conference/components/native/Conference.js 查看文件

75
     /**
75
     /**
76
      * The indicator which determines if the participants pane is open.
76
      * The indicator which determines if the participants pane is open.
77
      */
77
      */
78
-    _isOpen: boolean,
78
+    _isParticipantsPaneOpen: boolean,
79
 
79
 
80
     /**
80
     /**
81
      * The ID of the participant currently on stage (if any)
81
      * The ID of the participant currently on stage (if any)
243
     _renderContent() {
243
     _renderContent() {
244
         const {
244
         const {
245
             _connecting,
245
             _connecting,
246
-            _isOpen,
246
+            _isParticipantsPaneOpen,
247
             _largeVideoParticipantId,
247
             _largeVideoParticipantId,
248
             _reducedUI,
248
             _reducedUI,
249
             _shouldDisplayTileView
249
             _shouldDisplayTileView
309
 
309
 
310
                 {_shouldDisplayTileView && <Toolbox />}
310
                 {_shouldDisplayTileView && <Toolbox />}
311
 
311
 
312
-                { _isOpen && <ParticipantsPane /> }
312
+                { _isParticipantsPaneOpen && <ParticipantsPane /> }
313
 
313
 
314
             </>
314
             </>
315
         );
315
         );
423
         _connecting: Boolean(connecting_),
423
         _connecting: Boolean(connecting_),
424
         _filmstripVisible: isFilmstripVisible(state),
424
         _filmstripVisible: isFilmstripVisible(state),
425
         _fullscreenEnabled: getFeatureFlag(state, FULLSCREEN_ENABLED, true),
425
         _fullscreenEnabled: getFeatureFlag(state, FULLSCREEN_ENABLED, true),
426
-        _isOpen: isOpen,
426
+        _isParticipantsPaneOpen: isOpen,
427
         _largeVideoParticipantId: state['features/large-video'].participantId,
427
         _largeVideoParticipantId: state['features/large-video'].participantId,
428
         _pictureInPictureEnabled: getFeatureFlag(state, PIP_ENABLED),
428
         _pictureInPictureEnabled: getFeatureFlag(state, PIP_ENABLED),
429
         _reducedUI: reducedUI,
429
         _reducedUI: reducedUI,

+ 6
- 5
react/features/participants-pane/components/native/ContextMenuMeetingParticipantDetails.js 查看文件

4
 import { useTranslation } from 'react-i18next';
4
 import { useTranslation } from 'react-i18next';
5
 import { TouchableOpacity, View } from 'react-native';
5
 import { TouchableOpacity, View } from 'react-native';
6
 import { Divider, Text } from 'react-native-paper';
6
 import { Divider, Text } from 'react-native-paper';
7
-import { useDispatch, useSelector, useStore } from 'react-redux';
7
+import { useDispatch, useSelector } from 'react-redux';
8
 
8
 
9
 import { Avatar } from '../../../base/avatar';
9
 import { Avatar } from '../../../base/avatar';
10
+import { getIsStartingSilent } from '../../../base/config';
10
 import { hideDialog, openDialog } from '../../../base/dialog/actions';
11
 import { hideDialog, openDialog } from '../../../base/dialog/actions';
11
 import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
12
 import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
12
 import {
13
 import {
37
 
38
 
38
 export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props) => {
39
 export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props) => {
39
     const [ volume, setVolume ] = useState(undefined);
40
     const [ volume, setVolume ] = useState(undefined);
40
-    const store = useStore();
41
-    const startSilent = store.getState['features/base/config'];
42
     const dispatch = useDispatch();
41
     const dispatch = useDispatch();
43
     const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
42
     const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
44
-    const changeVolume = useCallback(() => setVolume(volume), [ volume ]);
43
+    const changeVolume = useCallback(() => setVolume(volume), [ setVolume, volume ]);
45
     const displayName = p.name;
44
     const displayName = p.name;
46
     const isLocalModerator = useSelector(isLocalParticipantModerator);
45
     const isLocalModerator = useSelector(isLocalParticipantModerator);
47
     const isParticipantVideoMuted = useSelector(getIsParticipantVideoMuted(p));
46
     const isParticipantVideoMuted = useSelector(getIsParticipantVideoMuted(p));
47
+    const isStartingSilent = useSelector(getIsStartingSilent);
48
+
48
     const kickRemoteParticipant = useCallback(() => {
49
     const kickRemoteParticipant = useCallback(() => {
49
         dispatch(openDialog(KickRemoteParticipantDialog, {
50
         dispatch(openDialog(KickRemoteParticipantDialog, {
50
             participantID: p.id
51
             participantID: p.id
65
             participantID: p.id
66
             participantID: p.id
66
         }));
67
         }));
67
     }, [ dispatch, p ]);
68
     }, [ dispatch, p ]);
68
-    const onVolumeChange = startSilent ? undefined : changeVolume;
69
+    const onVolumeChange = isStartingSilent ? undefined : changeVolume;
69
     const sendPrivateMessage = useCallback(() => {
70
     const sendPrivateMessage = useCallback(() => {
70
         dispatch(hideDialog());
71
         dispatch(hideDialog());
71
         dispatch(openChat(p));
72
         dispatch(openChat(p));

+ 11
- 15
react/features/participants-pane/components/native/ContextMenuMore.js 查看文件

4
 import { useTranslation } from 'react-i18next';
4
 import { useTranslation } from 'react-i18next';
5
 import { TouchableOpacity } from 'react-native';
5
 import { TouchableOpacity } from 'react-native';
6
 import { Text } from 'react-native-paper';
6
 import { Text } from 'react-native-paper';
7
-import { useDispatch } from 'react-redux';
7
+import { useDispatch, useSelector } from 'react-redux';
8
 
8
 
9
 import { openDialog, hideDialog } from '../../../base/dialog/actions';
9
 import { openDialog, hideDialog } from '../../../base/dialog/actions';
10
 import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
10
 import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
12
     Icon, IconMicDisabledHollow,
12
     Icon, IconMicDisabledHollow,
13
     IconVideoOff
13
     IconVideoOff
14
 } from '../../../base/icons';
14
 } from '../../../base/icons';
15
-import { MEDIA_TYPE } from '../../../base/media';
15
+import { getLocalParticipant } from '../../../base/participants';
16
 import { BlockAudioVideoDialog } from '../../../video-menu';
16
 import { BlockAudioVideoDialog } from '../../../video-menu';
17
-import {
18
-    muteAllParticipants
19
-} from '../../../video-menu/actions.any';
17
+import MuteEveryonesVideoDialog
18
+    from '../../../video-menu/components/native/MuteEveryonesVideoDialog';
20
 
19
 
21
 import styles from './styles';
20
 import styles from './styles';
22
-type Props = {
23
-
24
-    /**
25
-     * Array of participant IDs to not mute
26
-     */
27
-    exclude: Array<string>
28
-};
29
 
21
 
30
-export const ContextMenuMore = ({ exclude }: Props) => {
22
+export const ContextMenuMore = () => {
31
     const dispatch = useDispatch();
23
     const dispatch = useDispatch();
32
     const blockAudioVideo = useCallback(() => dispatch(openDialog(BlockAudioVideoDialog)), [ dispatch ]);
24
     const blockAudioVideo = useCallback(() => dispatch(openDialog(BlockAudioVideoDialog)), [ dispatch ]);
33
     const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
25
     const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
34
-    const muteEveryoneVideo = useCallback(() => dispatch(muteAllParticipants(exclude, MEDIA_TYPE.VIDEO)), [ dispatch ]);
26
+    const { id } = useSelector(getLocalParticipant);
27
+    const muteAllVideo = useCallback(() =>
28
+        dispatch(openDialog(MuteEveryonesVideoDialog,
29
+            { exclude: [ id ] })),
30
+        [ dispatch ]);
35
     const { t } = useTranslation();
31
     const { t } = useTranslation();
36
 
32
 
37
     return (
33
     return (
39
             onCancel = { cancel }
35
             onCancel = { cancel }
40
             style = { styles.contextMenuMore }>
36
             style = { styles.contextMenuMore }>
41
             <TouchableOpacity
37
             <TouchableOpacity
42
-                onPress = { muteEveryoneVideo }
38
+                onPress = { muteAllVideo }
43
                 style = { styles.contextMenuItem }>
39
                 style = { styles.contextMenuItem }>
44
                 <Icon
40
                 <Icon
45
                     size = { 20 }
41
                     size = { 20 }

+ 5
- 5
react/features/participants-pane/components/native/LobbyParticipantItem.js 查看文件

5
 import { Button } from 'react-native-paper';
5
 import { Button } from 'react-native-paper';
6
 import { useDispatch } from 'react-redux';
6
 import { useDispatch } from 'react-redux';
7
 
7
 
8
-import { setKnockingParticipantApproval } from '../../../lobby/actions.native';
8
+import { approveKnockingParticipant } from '../../../lobby/actions.native';
9
 import { showContextMenuReject } from '../../actions.native';
9
 import { showContextMenuReject } from '../../actions.native';
10
-import { MediaState } from '../../constants';
10
+import { MEDIA_STATE } from '../../constants';
11
 
11
 
12
 import ParticipantItem from './ParticipantItem';
12
 import ParticipantItem from './ParticipantItem';
13
 import styles from './styles';
13
 import styles from './styles';
22
 
22
 
23
 export const LobbyParticipantItem = ({ participant: p }: Props) => {
23
 export const LobbyParticipantItem = ({ participant: p }: Props) => {
24
     const dispatch = useDispatch();
24
     const dispatch = useDispatch();
25
-    const admit = useCallback(() => dispatch(setKnockingParticipantApproval(p.id, true), [ dispatch ]));
25
+    const admit = useCallback(() => dispatch(approveKnockingParticipant(p.id), [ dispatch ]));
26
     const openContextMenuReject = useCallback(() => dispatch(showContextMenuReject(p), [ dispatch ]));
26
     const openContextMenuReject = useCallback(() => dispatch(showContextMenuReject(p), [ dispatch ]));
27
     const { t } = useTranslation();
27
     const { t } = useTranslation();
28
 
28
 
29
     return (
29
     return (
30
         <ParticipantItem
30
         <ParticipantItem
31
-            audioMuteState = { MediaState.Muted }
31
+            audioMediaState = { MEDIA_STATE.NONE }
32
             isKnockingParticipant = { true }
32
             isKnockingParticipant = { true }
33
             name = { p.name }
33
             name = { p.name }
34
             onPress = { openContextMenuReject }
34
             onPress = { openContextMenuReject }
35
             participant = { p }
35
             participant = { p }
36
-            videoMuteState = { MediaState.ForceMuted }>
36
+            videoMediaState = { MEDIA_STATE.NONE }>
37
             <Button
37
             <Button
38
                 children = { t('lobby.admit') }
38
                 children = { t('lobby.admit') }
39
                 contentStyle = { styles.participantActionsButtonContent }
39
                 contentStyle = { styles.participantActionsButtonContent }

+ 2
- 2
react/features/participants-pane/components/native/LobbyParticipantList.js 查看文件

6
 import { Button } from 'react-native-paper';
6
 import { Button } from 'react-native-paper';
7
 import { useDispatch, useSelector } from 'react-redux';
7
 import { useDispatch, useSelector } from 'react-redux';
8
 
8
 
9
+import { admitMultiple } from '../../../lobby/actions.native';
9
 import { getLobbyState } from '../../../lobby/functions';
10
 import { getLobbyState } from '../../../lobby/functions';
10
-import { admitAllKnockingParticipants } from '../../../video-menu/actions.any';
11
 
11
 
12
 import { LobbyParticipantItem } from './LobbyParticipantItem';
12
 import { LobbyParticipantItem } from './LobbyParticipantItem';
13
 import styles from './styles';
13
 import styles from './styles';
20
 
20
 
21
     const dispatch = useDispatch();
21
     const dispatch = useDispatch();
22
     const admitAll = useCallback(() =>
22
     const admitAll = useCallback(() =>
23
-        dispatch(admitAllKnockingParticipants(participants, lobbyEnabled)),
23
+        dispatch(admitMultiple(participants)),
24
         [ dispatch ]);
24
         [ dispatch ]);
25
     const { t } = useTranslation();
25
     const { t } = useTranslation();
26
 
26
 

+ 5
- 2
react/features/participants-pane/components/native/MeetingParticipantItem.js 查看文件

9
 } from '../../../base/tracks';
9
 } from '../../../base/tracks';
10
 import { showContextMenuDetails } from '../../actions.native';
10
 import { showContextMenuDetails } from '../../actions.native';
11
 import { MEDIA_STATE } from '../../constants';
11
 import { MEDIA_STATE } from '../../constants';
12
+import { getParticipantAudioMediaState } from '../../functions';
12
 
13
 
13
 import ParticipantItem from './ParticipantItem';
14
 import ParticipantItem from './ParticipantItem';
14
 
15
 
25
     const dispatch = useDispatch();
26
     const dispatch = useDispatch();
26
     const isAudioMuted = useSelector(getIsParticipantAudioMuted(p));
27
     const isAudioMuted = useSelector(getIsParticipantAudioMuted(p));
27
     const isVideoMuted = useSelector(getIsParticipantVideoMuted(p));
28
     const isVideoMuted = useSelector(getIsParticipantVideoMuted(p));
29
+    const audioMediaState = useSelector(getParticipantAudioMediaState(p, isAudioMuted));
28
     const openContextMenuDetails = useCallback(() => !p.local && dispatch(showContextMenuDetails(p), [ dispatch ]));
30
     const openContextMenuDetails = useCallback(() => !p.local && dispatch(showContextMenuDetails(p), [ dispatch ]));
29
 
31
 
30
     return (
32
     return (
31
         <ParticipantItem
33
         <ParticipantItem
32
-            audioMuteState = { isAudioMuted ? MEDIA_STATE.MUTED : MEDIA_STATE.UNMUTED }
34
+            audioMediaState = { audioMediaState }
33
             isKnockingParticipant = { false }
35
             isKnockingParticipant = { false }
34
             name = { p.name }
36
             name = { p.name }
35
             onPress = { openContextMenuDetails }
37
             onPress = { openContextMenuDetails }
36
             participant = { p }
38
             participant = { p }
37
-            videoMuteState = { isVideoMuted ? MEDIA_STATE.Muted : MEDIA_STATE.Unmuted } />
39
+            videoMediaState = { isVideoMuted ? MEDIA_STATE.MUTED : MEDIA_STATE.UNMUTED } />
38
     );
40
     );
39
 };
41
 };
42
+

+ 2
- 4
react/features/participants-pane/components/native/MeetingParticipantList.js 查看文件

4
 import { useTranslation } from 'react-i18next';
4
 import { useTranslation } from 'react-i18next';
5
 import { Text, View } from 'react-native';
5
 import { Text, View } from 'react-native';
6
 import { Button } from 'react-native-paper';
6
 import { Button } from 'react-native-paper';
7
-import { useDispatch, useSelector, useStore } from 'react-redux';
7
+import { useDispatch, useSelector } from 'react-redux';
8
 
8
 
9
 import { Icon, IconInviteMore } from '../../../base/icons';
9
 import { Icon, IconInviteMore } from '../../../base/icons';
10
 import { getParticipants } from '../../../base/participants';
10
 import { getParticipants } from '../../../base/participants';
18
     const dispatch = useDispatch();
18
     const dispatch = useDispatch();
19
     const onInvite = useCallback(() => dispatch(doInvitePeople()), [ dispatch ]);
19
     const onInvite = useCallback(() => dispatch(doInvitePeople()), [ dispatch ]);
20
     const showInviteButton = useSelector(shouldRenderInviteButton);
20
     const showInviteButton = useSelector(shouldRenderInviteButton);
21
-    const store = useStore();
22
-    const state = store.getState();
23
-    const participants = getParticipants(state);
21
+    const participants = useSelector(getParticipants);
24
     const { t } = useTranslation();
22
     const { t } = useTranslation();
25
 
23
 
26
     return (
24
     return (

+ 3
- 13
react/features/participants-pane/components/native/ParticipantItem.js 查看文件

9
 
9
 
10
 import { Avatar } from '../../../base/avatar';
10
 import { Avatar } from '../../../base/avatar';
11
 import { getParticipantDisplayNameWithId } from '../../../base/participants';
11
 import { getParticipantDisplayNameWithId } from '../../../base/participants';
12
-import {
13
-    AudioStateIcons,
14
-    MediaState,
15
-    VideoStateIcons
16
-} from '../../constants';
12
+import { MEDIA_STATE, type MediaState, AudioStateIcons, VideoStateIcons } from '../../constants';
17
 
13
 
18
 import { RaisedHandIndicator } from './RaisedHandIndicator';
14
 import { RaisedHandIndicator } from './RaisedHandIndicator';
19
 import styles from './styles';
15
 import styles from './styles';
40
      */
36
      */
41
     name?: string,
37
     name?: string,
42
 
38
 
43
-    /**
44
-     * Callback for when the mouse leaves this component
45
-     */
46
-    onLeave?: Function,
47
-
48
     /**
39
     /**
49
      * Callback to be invoked on pressing the participant item.
40
      * Callback to be invoked on pressing the participant item.
50
      */
41
      */
72
     name,
63
     name,
73
     onPress,
64
     onPress,
74
     participant: p,
65
     participant: p,
75
-    audioMediaState = MediaState.None,
76
-    videoMediaState = MediaState.None
66
+    audioMediaState = MEDIA_STATE.NONE,
67
+    videoMediaState = MEDIA_STATE.NONE
77
 }: Props) {
68
 }: Props) {
78
 
69
 
79
     const displayName = name || useSelector(getParticipantDisplayNameWithId(p.id));
70
     const displayName = name || useSelector(getParticipantDisplayNameWithId(p.id));
82
     return (
73
     return (
83
         <View style = { styles.participantContainer } >
74
         <View style = { styles.participantContainer } >
84
             <TouchableOpacity
75
             <TouchableOpacity
85
-                /* eslint-disable-next-line react/jsx-no-bind */
86
                 onPress = { onPress }
76
                 onPress = { onPress }
87
                 style = { styles.participantContent }>
77
                 style = { styles.participantContent }>
88
                 <Avatar
78
                 <Avatar

+ 20
- 13
react/features/participants-pane/components/native/ParticipantsPane.js 查看文件

10
 import { Icon, IconClose, IconHorizontalPoints } from '../../../base/icons';
10
 import { Icon, IconClose, IconHorizontalPoints } from '../../../base/icons';
11
 import { JitsiModal } from '../../../base/modal';
11
 import { JitsiModal } from '../../../base/modal';
12
 import {
12
 import {
13
+    getParticipantCount, isEveryoneModerator,
13
     isLocalParticipantModerator
14
     isLocalParticipantModerator
14
 } from '../../../base/participants';
15
 } from '../../../base/participants';
15
 import MuteEveryoneDialog
16
 import MuteEveryoneDialog
19
 import { ContextMenuMore } from './ContextMenuMore';
20
 import { ContextMenuMore } from './ContextMenuMore';
20
 import { LobbyParticipantList } from './LobbyParticipantList';
21
 import { LobbyParticipantList } from './LobbyParticipantList';
21
 import { MeetingParticipantList } from './MeetingParticipantList';
22
 import { MeetingParticipantList } from './MeetingParticipantList';
22
-import styles from './styles';
23
+import styles, { button } from './styles';
23
 
24
 
24
 /**
25
 /**
25
  * Participant pane.
26
  * Participant pane.
31
     const openMoreMenu = useCallback(() => dispatch(openDialog(ContextMenuMore)), [ dispatch ]);
32
     const openMoreMenu = useCallback(() => dispatch(openDialog(ContextMenuMore)), [ dispatch ]);
32
     const closePane = useCallback(() => dispatch(close()), [ dispatch ]);
33
     const closePane = useCallback(() => dispatch(close()), [ dispatch ]);
33
     const isLocalModerator = useSelector(isLocalParticipantModerator);
34
     const isLocalModerator = useSelector(isLocalParticipantModerator);
35
+    const participantsCount = useSelector(getParticipantCount);
36
+    const everyoneModerator = useSelector(isEveryoneModerator);
37
+    const showContextMenu = !everyoneModerator && participantsCount > 2;
34
     const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
38
     const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
35
         [ dispatch ]);
39
         [ dispatch ]);
36
     const { t } = useTranslation();
40
     const { t } = useTranslation();
65
                         labelStyle = { styles.muteAllLabel }
69
                         labelStyle = { styles.muteAllLabel }
66
                         mode = 'contained'
70
                         mode = 'contained'
67
                         onPress = { muteAll }
71
                         onPress = { muteAll }
68
-                        style = { styles.muteAllButton } />
69
-                    <Button
70
-                        contentStyle = { styles.moreIcon }
71
-                        /* eslint-disable-next-line react/jsx-no-bind */
72
-                        icon = { () =>
73
-                            (<Icon
74
-                                size = { 24 }
75
-                                src = { IconHorizontalPoints } />)
76
-                        }
77
-                        mode = 'contained'
78
-                        onPress = { openMoreMenu }
79
-                        style = { styles.moreButton } />
72
+                        style = { showContextMenu ? styles.muteAllButton : button } />
73
+                    {
74
+                        showContextMenu
75
+                        && <Button
76
+                            contentStyle = { styles.moreIcon }
77
+                            /* eslint-disable-next-line react/jsx-no-bind */
78
+                            icon = { () =>
79
+                                (<Icon
80
+                                    size = { 24 }
81
+                                    src = { IconHorizontalPoints } />)
82
+                            }
83
+                            mode = 'contained'
84
+                            onPress = { openMoreMenu }
85
+                            style = { styles.moreButton } />
86
+                    }
80
                 </View>
87
                 </View>
81
             }
88
             }
82
         </JitsiModal>
89
         </JitsiModal>

+ 1
- 1
react/features/participants-pane/components/native/styles.js 查看文件

25
 /**
25
 /**
26
  * The style of the participants pane buttons.
26
  * The style of the participants pane buttons.
27
  */
27
  */
28
-const button = {
28
+export const button = {
29
     alignItems: 'center',
29
     alignItems: 'center',
30
     backgroundColor: BaseTheme.palette.action02,
30
     backgroundColor: BaseTheme.palette.action02,
31
     borderRadius: BaseTheme.shape.borderRadius,
31
     borderRadius: BaseTheme.shape.borderRadius,

+ 54
- 0
react/features/participants-pane/constants.js 查看文件

1
 // @flow
1
 // @flow
2
 
2
 
3
+import React from 'react';
4
+
5
+import {
6
+    Icon, IconCameraEmpty, IconCameraEmptyDisabled,
7
+    IconMicrophoneEmpty,
8
+    IconMicrophoneEmptySlash
9
+} from '../base/icons';
10
+
3
 /**
11
 /**
4
  * Reducer key for the feature.
12
  * Reducer key for the feature.
5
  */
13
  */
46
     ASK_TO_UNMUTE: 'AskToUnmute',
54
     ASK_TO_UNMUTE: 'AskToUnmute',
47
     NONE: 'None'
55
     NONE: 'None'
48
 };
56
 };
57
+
58
+/**
59
+ * Icon mapping for possible participant audio states.
60
+ */
61
+export const AudioStateIcons: {[MediaState]: React$Element<any> | null} = {
62
+    [MEDIA_STATE.FORCE_MUTED]: (
63
+        <Icon
64
+            color = '#E04757'
65
+            size = { 16 }
66
+            src = { IconMicrophoneEmptySlash } />
67
+    ),
68
+    [MEDIA_STATE.MUTED]: (
69
+        <Icon
70
+            size = { 16 }
71
+            src = { IconMicrophoneEmptySlash } />
72
+    ),
73
+    [MEDIA_STATE.UNMUTED]: (
74
+        <Icon
75
+            color = '#1EC26A'
76
+            size = { 16 }
77
+            src = { IconMicrophoneEmpty } />
78
+    ),
79
+    [MEDIA_STATE.NONE]: null
80
+};
81
+
82
+/**
83
+ * Icon mapping for possible participant video states.
84
+ */
85
+export const VideoStateIcons = {
86
+    [MEDIA_STATE.FORCE_MUTED]: (
87
+        <Icon
88
+            size = { 16 }
89
+            src = { IconCameraEmptyDisabled } />
90
+    ),
91
+    [MEDIA_STATE.MUTED]: (
92
+        <Icon
93
+            size = { 16 }
94
+            src = { IconCameraEmptyDisabled } />
95
+    ),
96
+    [MEDIA_STATE.UNMUTED]: (
97
+        <Icon
98
+            size = { 16 }
99
+            src = { IconCameraEmpty } />
100
+    ),
101
+    [MEDIA_STATE.NONE]: null
102
+};

+ 0
- 19
react/features/video-menu/actions.any.js 查看文件

24
     muteRemoteParticipant
24
     muteRemoteParticipant
25
 } from '../base/participants';
25
 } from '../base/participants';
26
 import { getIsParticipantAudioMuted } from '../base/tracks';
26
 import { getIsParticipantAudioMuted } from '../base/tracks';
27
-import { setKnockingParticipantApproval } from '../lobby/actions';
28
 
27
 
29
 declare var APP: Object;
28
 declare var APP: Object;
30
 
29
 
109
     };
108
     };
110
 }
109
 }
111
 
110
 
112
-/**
113
- * Admit all knocking participants.
114
- *
115
- * @param {Array<Object>} knockingParticipants - Array of participants waiting in lobby.
116
- * @param {boolean} lobbyEnabled - Is lobby mode enabled.
117
- *
118
- * @returns {Function}
119
- */
120
-export function admitAllKnockingParticipants(knockingParticipants: Array<Object>, lobbyEnabled: boolean) {
121
-    return (dispatch: Dispatch<any>) => {
122
-        const knockingParticipantsIds = knockingParticipants.map(participant => participant.id);
123
-
124
-        knockingParticipantsIds
125
-            .map(id => lobbyEnabled && setKnockingParticipantApproval(id, true))
126
-            .map(dispatch);
127
-    };
128
-}
129
-
130
 
111
 
131
 /**
112
 /**
132
  * Don't allow participants to unmute video/audio.
113
  * Don't allow participants to unmute video/audio.

正在加载...
取消
保存