瀏覽代碼

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

master
Calin Chitu 4 年之前
父節點
當前提交
b7389e1c31

+ 13
- 0
react/features/lobby/functions.js 查看文件

@@ -9,3 +9,16 @@
9 9
 export function getLobbyState(state: any) {
10 10
     return state['features/lobby'];
11 11
 }
12
+
13
+
14
+/**
15
+ * Selector to return lobby state.
16
+ *
17
+ * @param {any} state - State object.
18
+ * @returns {Array}
19
+ */
20
+export function getKnockingParticipantsById(state: any) {
21
+    const { knockingParticipants } = state['features/lobby'];
22
+
23
+    return knockingParticipants.map(participant => participant.id);
24
+}

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

@@ -4,7 +4,7 @@ import React, { useCallback } from 'react';
4 4
 import { useTranslation } from 'react-i18next';
5 5
 import { TouchableOpacity, View } from 'react-native';
6 6
 import { Divider, Text } from 'react-native-paper';
7
-import { useDispatch } from 'react-redux';
7
+import { useDispatch, useSelector } from 'react-redux';
8 8
 
9 9
 import { Avatar } from '../../../base/avatar';
10 10
 import { hideDialog } from '../../../base/dialog';
@@ -13,6 +13,7 @@ import {
13 13
     Icon, IconClose
14 14
 } from '../../../base/icons';
15 15
 import { setKnockingParticipantApproval } from '../../../lobby/actions.native';
16
+import { getKnockingParticipantsById } from '../../../lobby/functions';
16 17
 
17 18
 import styles from './styles';
18 19
 type Props = {
@@ -25,6 +26,8 @@ type Props = {
25 26
 
26 27
 export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) => {
27 28
     const dispatch = useDispatch();
29
+    const knockParticipantsIDArr = useSelector(getKnockingParticipantsById);
30
+    const knockParticipantIsAvailable = knockParticipantsIDArr.find(knockPartId => knockPartId === p.id);
28 31
     const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
29 32
     const displayName = p.name;
30 33
     const reject = useCallback(() => dispatch(setKnockingParticipantApproval(p.id, false), [ dispatch ]));
@@ -32,14 +35,16 @@ export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) =>
32 35
 
33 36
     return (
34 37
         <BottomSheet
38
+            addScrollViewPadding = { false }
35 39
             onCancel = { cancel }
40
+            showSlidingView = { Boolean(knockParticipantIsAvailable) }
36 41
             style = { styles.contextMenuMore }>
37 42
             <View
38 43
                 style = { styles.contextMenuItemSectionAvatar }>
39 44
                 <Avatar
40 45
                     className = 'participant-avatar'
41 46
                     participantId = { p.id }
42
-                    size = { 30 } />
47
+                    size = { 20 } />
43 48
                 <View style = { styles.contextMenuItemAvatarText }>
44 49
                     <Text style = { styles.contextMenuItemName }>
45 50
                         { displayName }
@@ -51,9 +56,8 @@ export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) =>
51 56
                 onPress = { reject }
52 57
                 style = { styles.contextMenuItem }>
53 58
                 <Icon
54
-                    size = { 24 }
55
-                    src = { IconClose }
56
-                    style = { styles.contextMenuItemIcon } />
59
+                    size = { 20 }
60
+                    src = { IconClose } />
57 61
                 <Text style = { styles.contextMenuItemText }>{ t('lobby.reject') }</Text>
58 62
             </TouchableOpacity>
59 63
         </BottomSheet>

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

@@ -15,6 +15,7 @@ import {
15 15
     IconMuteEveryoneElse, IconVideoOff
16 16
 } from '../../../base/icons';
17 17
 import {
18
+    getParticipantsById,
18 19
     isLocalParticipantModerator
19 20
 } from '../../../base/participants';
20 21
 import { getIsParticipantVideoMuted } from '../../../base/tracks';
@@ -39,11 +40,12 @@ type Props = {
39 40
 
40 41
 export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props) => {
41 42
     const dispatch = useDispatch();
43
+    const participantsIDArr = useSelector(getParticipantsById);
44
+    const participantIsAvailable = participantsIDArr.find(partId => partId === p.id);
42 45
     const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
43 46
     const displayName = p.name;
44 47
     const isLocalModerator = useSelector(isLocalParticipantModerator);
45 48
     const isParticipantVideoMuted = useSelector(getIsParticipantVideoMuted(p));
46
-
47 49
     const kickRemoteParticipant = useCallback(() => {
48 50
         dispatch(openDialog(KickRemoteParticipantDialog, {
49 51
             participantID: p.id
@@ -73,14 +75,16 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
73 75
 
74 76
     return (
75 77
         <BottomSheet
78
+            addScrollViewPadding = { false }
76 79
             onCancel = { cancel }
80
+            showSlidingView = { Boolean(participantIsAvailable) }
77 81
             style = { styles.contextMenuMeetingParticipantDetails }>
78 82
             <View
79 83
                 style = { styles.contextMenuItemSectionAvatar }>
80 84
                 <Avatar
81 85
                     className = 'participant-avatar'
82 86
                     participantId = { p.id }
83
-                    size = { 30 } />
87
+                    size = { 20 } />
84 88
                 <View style = { styles.contextMenuItemAvatarText }>
85 89
                     <Text style = { styles.contextMenuItemName }>
86 90
                         { displayName }
@@ -94,9 +98,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
94 98
                     onPress = { muteAudio }
95 99
                     style = { styles.contextMenuItem }>
96 100
                     <Icon
97
-                        size = { 24 }
98
-                        src = { IconMicrophoneEmptySlash }
99
-                        style = { styles.contextMenuItemIcon } />
101
+                        size = { 20 }
102
+                        src = { IconMicrophoneEmptySlash } />
100 103
                     <Text style = { styles.contextMenuItemText }>
101 104
                         { t('participantsPane.actions.mute') }
102 105
                     </Text>
@@ -108,9 +111,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
108 111
                     onPress = { muteEveryoneElse }
109 112
                     style = { styles.contextMenuItem }>
110 113
                     <Icon
111
-                        size = { 24 }
112
-                        src = { IconMuteEveryoneElse }
113
-                        style = { styles.contextMenuItemIcon } />
114
+                        size = { 20 }
115
+                        src = { IconMuteEveryoneElse } />
114 116
                     <Text style = { styles.contextMenuItemText }>
115 117
                         { t('participantsPane.actions.muteEveryoneElse') }
116 118
                     </Text>
@@ -124,9 +126,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
124 126
                         onPress = { muteVideo }
125 127
                         style = { styles.contextMenuItemSection }>
126 128
                         <Icon
127
-                            size = { 24 }
128
-                            src = { IconVideoOff }
129
-                            style = { styles.contextMenuItemIcon } />
129
+                            size = { 20 }
130
+                            src = { IconVideoOff } />
130 131
                         <Text style = { styles.contextMenuItemText }>
131 132
                             { t('participantsPane.actions.stopVideo') }
132 133
                         </Text>
@@ -139,9 +140,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
139 140
                     onPress = { kickRemoteParticipant }
140 141
                     style = { styles.contextMenuItem }>
141 142
                     <Icon
142
-                        size = { 24 }
143
-                        src = { IconCloseCircle }
144
-                        style = { styles.contextMenuItemIcon } />
143
+                        size = { 20 }
144
+                        src = { IconCloseCircle } />
145 145
                     <Text style = { styles.contextMenuItemText }>
146 146
                         { t('videothumbnail.kick') }
147 147
                     </Text>
@@ -151,9 +151,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
151 151
                 onPress = { sendPrivateMessage }
152 152
                 style = { styles.contextMenuItem }>
153 153
                 <Icon
154
-                    size = { 24 }
155
-                    src = { IconMessage }
156
-                    style = { styles.contextMenuItemIcon } />
154
+                    size = { 20 }
155
+                    src = { IconMessage } />
157 156
                 <Text style = { styles.contextMenuItemText }>
158 157
                     { t('toolbar.accessibilityLabel.privateMessage') }
159 158
                 </Text>

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

@@ -12,7 +12,10 @@ import {
12 12
     Icon, IconMicDisabledHollow,
13 13
     IconVideoOff
14 14
 } from '../../../base/icons';
15
-import { getLocalParticipant } from '../../../base/participants';
15
+import {
16
+    getLocalParticipant,
17
+    getParticipantCount, isEveryoneModerator
18
+} from '../../../base/participants';
16 19
 import { BlockAudioVideoDialog } from '../../../video-menu';
17 20
 import MuteEveryonesVideoDialog
18 21
     from '../../../video-menu/components/native/MuteEveryonesVideoDialog';
@@ -24,6 +27,9 @@ export const ContextMenuMore = () => {
24 27
     const blockAudioVideo = useCallback(() => dispatch(openDialog(BlockAudioVideoDialog)), [ dispatch ]);
25 28
     const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
26 29
     const { id } = useSelector(getLocalParticipant);
30
+    const everyoneModerator = useSelector(isEveryoneModerator);
31
+    const participantsCount = useSelector(getParticipantCount);
32
+    const showSlidingView = !everyoneModerator && participantsCount > 2;
27 33
     const muteAllVideo = useCallback(() =>
28 34
         dispatch(openDialog(MuteEveryonesVideoDialog,
29 35
             { exclude: [ id ] })),
@@ -32,13 +38,15 @@ export const ContextMenuMore = () => {
32 38
 
33 39
     return (
34 40
         <BottomSheet
41
+            addScrollViewPadding = { false }
35 42
             onCancel = { cancel }
43
+            showSlidingView = { showSlidingView }
36 44
             style = { styles.contextMenuMore }>
37 45
             <TouchableOpacity
38 46
                 onPress = { muteAllVideo }
39 47
                 style = { styles.contextMenuItem }>
40 48
                 <Icon
41
-                    size = { 24 }
49
+                    size = { 20 }
42 50
                     src = { IconVideoOff } />
43 51
                 <Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.stopEveryonesVideo')}</Text>
44 52
             </TouchableOpacity>
@@ -46,7 +54,7 @@ export const ContextMenuMore = () => {
46 54
                 onPress = { blockAudioVideo }
47 55
                 style = { styles.contextMenuItem }>
48 56
                 <Icon
49
-                    size = { 24 }
57
+                    size = { 20 }
50 58
                     src = { IconMicDisabledHollow }
51 59
                     style = { styles.contextMenuIcon } />
52 60
                 <Text style = { styles.contextMenuItemText }>

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

@@ -34,7 +34,7 @@ export const MeetingParticipantList = () => {
34 34
                     /* eslint-disable-next-line react/jsx-no-bind */
35 35
                     icon = { () =>
36 36
                         (<Icon
37
-                            size = { 24 }
37
+                            size = { 20 }
38 38
                             src = { IconInviteMore } />)
39 39
                     }
40 40
                     labelStyle = { styles.inviteLabel }

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

@@ -49,7 +49,7 @@ const ParticipantsPane = () => {
49 49
                     /* eslint-disable-next-line react/jsx-no-bind */
50 50
                     icon = { () =>
51 51
                         (<Icon
52
-                            size = { 24 }
52
+                            size = { 20 }
53 53
                             src = { IconClose } />)
54 54
                     }
55 55
                     labelStyle = { styles.closeIcon }
@@ -76,7 +76,7 @@ const ParticipantsPane = () => {
76 76
                             /* eslint-disable-next-line react/jsx-no-bind */
77 77
                             icon = { () =>
78 78
                                 (<Icon
79
-                                    size = { 24 }
79
+                                    size = { 20 }
80 80
                                     src = { IconHorizontalPoints } />)
81 81
                             }
82 82
                             labelStyle = { styles.moreIcon }

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

@@ -37,6 +37,8 @@ export const button = {
37 37
     backgroundColor: BaseTheme.palette.action02,
38 38
     borderRadius: BaseTheme.shape.borderRadius,
39 39
     display: 'flex',
40
+    flexDirection: 'row',
41
+    justifyContent: 'center',
40 42
     minWidth: 0
41 43
 };
42 44
 
@@ -62,8 +64,9 @@ const muteAllButton = {
62 64
  */
63 65
 const buttonContent = {
64 66
     ...BaseTheme.typography.labelButton,
65
-    alignSelf: 'center',
67
+    alignContent: 'center',
66 68
     color: BaseTheme.palette.text01,
69
+    display: 'flex',
67 70
     justifyContent: 'center'
68 71
 };
69 72
 
@@ -71,9 +74,12 @@ const buttonContent = {
71 74
  * The style of the context menu pane items.
72 75
  */
73 76
 const contextMenuItem = {
77
+    alignItems: 'center',
78
+    display: 'flex',
74 79
     flexDirection: 'row',
75
-    paddingBottom: 16,
76
-    paddingTop: 16
80
+    height: BaseTheme.spacing[7],
81
+    marginLeft: BaseTheme.spacing[3],
82
+    marginTop: BaseTheme.spacing[2]
77 83
 };
78 84
 
79 85
 /**
@@ -173,7 +179,7 @@ export default {
173 179
         backgroundColor: BaseTheme.palette.warning02,
174 180
         borderRadius: BaseTheme.shape.borderRadius / 2,
175 181
         height: BaseTheme.spacing[4],
176
-        marginLeft: BaseTheme.spacing[1],
182
+        marginLeft: BaseTheme.spacing[2],
177 183
         width: BaseTheme.spacing[4]
178 184
     },
179 185
 
@@ -245,11 +251,7 @@ export default {
245 251
     closeIcon: {
246 252
         ...buttonContent,
247 253
         height: BaseTheme.spacing[5],
248
-        marginLeft: 'auto',
249
-        paddingTop: 12,
250
-        paddingBottom: 12,
251
-        paddingRight: BaseTheme.spacing[3],
252
-        paddingLeft: BaseTheme.spacing[3]
254
+        marginLeft: 'auto'
253 255
     },
254 256
 
255 257
     inviteButton: {
@@ -271,11 +273,7 @@ export default {
271 273
     moreIcon: {
272 274
         ...buttonContent,
273 275
         height: BaseTheme.spacing[5],
274
-        marginLeft: 'auto',
275
-        paddingTop: 12,
276
-        paddingBottom: 12,
277
-        paddingRight: BaseTheme.spacing[3],
278
-        paddingLeft: BaseTheme.spacing[3]
276
+        marginLeft: 'auto'
279 277
     },
280 278
 
281 279
     contextMenuMore: {
@@ -300,7 +298,6 @@ export default {
300 298
     muteAllLabel: {
301 299
         ...BaseTheme.typography.labelButtonLarge,
302 300
         color: BaseTheme.palette.text01,
303
-        flexDirection: 'column',
304 301
         height: BaseTheme.spacing[7],
305 302
         marginVertical: BaseTheme.spacing[0],
306 303
         marginHorizontal: BaseTheme.spacing[0],
@@ -322,12 +319,12 @@ export default {
322 319
 
323 320
     contextMenuItemSectionAvatar: {
324 321
         ...contextMenuItem,
325
-        marginLeft: BaseTheme.spacing[1]
322
+        marginLeft: BaseTheme.spacing[3]
326 323
     },
327 324
 
328 325
     contextMenuItemAvatarText: {
329 326
         ...contextMenuItemText,
330
-        marginLeft: BaseTheme.spacing[2]
327
+        marginLeft: BaseTheme.spacing[3]
331 328
     },
332 329
 
333 330
     contextMenuItemText: {
@@ -335,10 +332,6 @@ export default {
335 332
         marginLeft: BaseTheme.spacing[3]
336 333
     },
337 334
 
338
-    contextMenuItemIcon: {
339
-        marginLeft: BaseTheme.spacing[1]
340
-    },
341
-
342 335
     contextMenuItemName: {
343 336
         ...BaseTheme.typography.bodyShortRegularLarge,
344 337
         color: BaseTheme.palette.text01

+ 2
- 3
react/features/video-menu/components/native/VolumeSlider.js 查看文件

@@ -101,9 +101,8 @@ class VolumeSlider extends PureComponent<Props, State> {
101 101
         return (
102 102
             <View style = { styles.volumeSliderContainer } >
103 103
                 <Icon
104
-                    size = { 24 }
105
-                    src = { IconVolumeEmpty }
106
-                    style = { styles.volumeIcon } />
104
+                    size = { 20 }
105
+                    src = { IconVolumeEmpty } />
107 106
                 <Slider
108 107
                     maximumTrackTintColor = { palette.field02 }
109 108
                     maximumValue = { VOLUME_SLIDER_SCALE }

+ 2
- 7
react/features/video-menu/components/native/styles.js 查看文件

@@ -54,17 +54,12 @@ export default createStyleSheet({
54 54
     volumeSliderContainer: {
55 55
         alignItems: 'center',
56 56
         flexDirection: 'row',
57
-        marginBottom: BaseTheme.spacing[3],
57
+        marginLeft: BaseTheme.spacing[3],
58 58
         marginTop: BaseTheme.spacing[3]
59 59
     },
60 60
 
61
-    volumeIcon: {
62
-        marginLeft: BaseTheme.spacing[1],
63
-        minWidth: '5%'
64
-    },
65
-
66 61
     sliderContainer: {
67 62
         marginLeft: BaseTheme.spacing[3],
68
-        minWidth: '90%'
63
+        minWidth: '84%'
69 64
     }
70 65
 });

Loading…
取消
儲存