浏览代码

feat(toolbox): Adaptive toolbar on mobile

j8
Vlad Piersec 4 年前
父节点
当前提交
e7297714c6

+ 1
- 0
react/features/base/styles/components/styles/ColorPalette.js 查看文件

@@ -29,6 +29,7 @@ export const ColorPalette = {
29 29
     overflowMenuItemUnderlay: '#EEEEEE',
30 30
     red: '#D00000',
31 31
     transparent: 'rgba(0, 0, 0, 0)',
32
+    toggled: 'rgba(255,255,255,.15)',
32 33
     warning: 'rgb(215, 121, 118)',
33 34
     white: '#FFFFFF',
34 35
 

+ 14
- 6
react/features/toolbox/components/native/OverflowMenu.js 查看文件

@@ -18,6 +18,7 @@ import { RoomLockButton } from '../../../room-lock';
18 18
 import { SharedVideoButton } from '../../../shared-video/components';
19 19
 import { ClosedCaptionButton } from '../../../subtitles';
20 20
 import { TileViewButton } from '../../../video-layout';
21
+import { getMovableButtons } from '../../functions.native';
21 22
 import HelpButton from '../HelpButton';
22 23
 import MuteEveryoneButton from '../MuteEveryoneButton';
23 24
 
@@ -48,6 +49,11 @@ type Props = {
48 49
      */
49 50
     _recordingEnabled: boolean,
50 51
 
52
+    /**
53
+     * The width of the screen.
54
+     */
55
+    _width: number,
56
+
51 57
     /**
52 58
      * Used for hiding the dialog when the selection was completed.
53 59
      */
@@ -108,8 +114,9 @@ class OverflowMenu extends PureComponent<Props, State> {
108 114
      * @returns {ReactElement}
109 115
      */
110 116
     render() {
111
-        const { _bottomSheetStyles } = this.props;
117
+        const { _bottomSheetStyles, _width } = this.props;
112 118
         const { showMore } = this.state;
119
+        const toolbarButtons = getMovableButtons(_width);
113 120
 
114 121
         const buttonProps = {
115 122
             afterClick: this._onCancel,
@@ -129,15 +136,15 @@ class OverflowMenu extends PureComponent<Props, State> {
129 136
                 onSwipe = { this._onSwipe }
130 137
                 renderHeader = { this._renderMenuExpandToggle }>
131 138
                 <AudioRouteButton { ...buttonProps } />
132
-                <InviteButton { ...buttonProps } />
139
+                {!toolbarButtons.has('invite') && <InviteButton { ...buttonProps } />}
133 140
                 <AudioOnlyButton { ...buttonProps } />
134
-                <RaiseHandButton { ...buttonProps } />
141
+                {!toolbarButtons.has('raisehand') && <RaiseHandButton { ...buttonProps } />}
135 142
                 <LobbyModeButton { ...buttonProps } />
136 143
                 <ScreenSharingButton { ...buttonProps } />
137 144
                 <MoreOptionsButton { ...moreOptionsButtonProps } />
138 145
                 <Collapsible collapsed = { !showMore }>
139
-                    <ToggleCameraButton { ...buttonProps } />
140
-                    <TileViewButton { ...buttonProps } />
146
+                    {!toolbarButtons.has('togglecamera') && <ToggleCameraButton { ...buttonProps } />}
147
+                    {!toolbarButtons.has('tileview') && <TileViewButton { ...buttonProps } />}
141 148
                     <RecordButton { ...buttonProps } />
142 149
                     <LiveStreamButton { ...buttonProps } />
143 150
                     <SharedVideoButton { ...buttonProps } />
@@ -244,7 +251,8 @@ class OverflowMenu extends PureComponent<Props, State> {
244 251
 function _mapStateToProps(state) {
245 252
     return {
246 253
         _bottomSheetStyles: ColorSchemeRegistry.get(state, 'BottomSheet'),
247
-        _isOpen: isDialogOpen(state, OverflowMenu_)
254
+        _isOpen: isDialogOpen(state, OverflowMenu_),
255
+        _width: state['features/base/responsive-ui'].clientWidth
248 256
     };
249 257
 }
250 258
 

+ 66
- 72
react/features/toolbox/components/native/Toolbox.js 查看文件

@@ -1,18 +1,22 @@
1 1
 // @flow
2 2
 
3
-import React, { PureComponent } from 'react';
3
+import React from 'react';
4 4
 import { SafeAreaView, View } from 'react-native';
5 5
 
6 6
 import { ColorSchemeRegistry } from '../../../base/color-scheme';
7 7
 import { connect } from '../../../base/redux';
8 8
 import { StyleType } from '../../../base/styles';
9 9
 import { ChatButton } from '../../../chat';
10
-import { isToolboxVisible } from '../../functions';
10
+import { InviteButton } from '../../../invite';
11
+import { TileViewButton } from '../../../video-layout';
12
+import { isToolboxVisible, getMovableButtons } from '../../functions.native';
11 13
 import AudioMuteButton from '../AudioMuteButton';
12 14
 import HangupButton from '../HangupButton';
13 15
 import VideoMuteButton from '../VideoMuteButton';
14 16
 
15 17
 import OverflowMenuButton from './OverflowMenuButton';
18
+import RaiseHandButton from './RaiseHandButton';
19
+import ToggleCameraButton from './ToggleCameraButton';
16 20
 import styles from './styles';
17 21
 
18 22
 /**
@@ -30,6 +34,11 @@ type Props = {
30 34
      */
31 35
     _visible: boolean,
32 36
 
37
+    /**
38
+     * The width of the screen.
39
+     */
40
+    _width: number,
41
+
33 42
     /**
34 43
      * The redux {@code dispatch} function.
35 44
      */
@@ -37,80 +46,64 @@ type Props = {
37 46
 };
38 47
 
39 48
 /**
40
- * Implements the conference toolbox on React Native.
49
+ * Implements the conference Toolbox on React Native.
50
+ *
51
+ * @param {Object} props - The props of the component.
52
+ * @returns {React$Element}.
41 53
  */
42
-class Toolbox extends PureComponent<Props> {
43
-    /**
44
-     * Implements React's {@link Component#render()}.
45
-     *
46
-     * @inheritdoc
47
-     * @returns {ReactElement}
48
-     */
49
-    render() {
50
-        if (!this.props._visible) {
51
-            return null;
52
-        }
53
-
54
-        const { _styles } = this.props;
55
-        const { buttonStylesBorderless, hangupButtonStyles, toggledButtonStyles } = _styles;
56
-
57
-        return (
58
-            <View
59
-                pointerEvents = 'box-none'
60
-                style = { styles.toolboxContainer }>
61
-                <SafeAreaView
62
-                    accessibilityRole = 'toolbar'
63
-                    pointerEvents = 'box-none'
64
-                    style = { styles.toolbox }>
65
-                    <AudioMuteButton
66
-                        styles = { buttonStylesBorderless }
67
-                        toggledStyles = { toggledButtonStyles } />
68
-                    <VideoMuteButton
69
-                        styles = { buttonStylesBorderless }
70
-                        toggledStyles = { toggledButtonStyles } />
71
-                    <ChatButton
72
-                        styles = { buttonStylesBorderless }
73
-                        toggledStyles = { this._getChatButtonToggledStyle(toggledButtonStyles) } />
74
-                    <OverflowMenuButton
75
-                        styles = { buttonStylesBorderless }
76
-                        toggledStyles = { toggledButtonStyles } />
77
-                    <HangupButton
78
-                        styles = { hangupButtonStyles } />
79
-                </SafeAreaView>
80
-            </View>
81
-        );
54
+function Toolbox(props: Props) {
55
+    if (!props._visible) {
56
+        return null;
82 57
     }
83 58
 
84
-    /**
85
-     * Constructs the toggled style of the chat button. This cannot be done by
86
-     * simple style inheritance due to the size calculation done in this
87
-     * component.
88
-     *
89
-     * @param {Object} baseStyle - The base style that was originally
90
-     * calculated.
91
-     * @returns {Object | Array}
92
-     */
93
-    _getChatButtonToggledStyle(baseStyle) {
94
-        const { _styles } = this.props;
59
+    const { _styles, _width } = props;
60
+    const { buttonStylesBorderless, hangupButtonStyles, toggledButtonStyles } = _styles;
61
+    const additionalButtons = getMovableButtons(_width);
62
+    const backgroundToggledStyle = {
63
+        ...toggledButtonStyles,
64
+        style: [
65
+            toggledButtonStyles.style,
66
+            _styles.backgroundToggle
67
+        ]
68
+    };
95 69
 
96
-        if (Array.isArray(baseStyle.style)) {
97
-            return {
98
-                ...baseStyle,
99
-                style: [
100
-                    ...baseStyle.style,
101
-                    _styles.chatButtonOverride.toggled
102
-                ]
103
-            };
104
-        }
70
+    return (
71
+        <View
72
+            pointerEvents = 'box-none'
73
+            style = { styles.toolboxContainer }>
74
+            <SafeAreaView
75
+                accessibilityRole = 'toolbar'
76
+                pointerEvents = 'box-none'
77
+                style = { styles.toolbox }>
78
+                <AudioMuteButton
79
+                    styles = { buttonStylesBorderless }
80
+                    toggledStyles = { toggledButtonStyles } />
81
+                <VideoMuteButton
82
+                    styles = { buttonStylesBorderless }
83
+                    toggledStyles = { toggledButtonStyles } />
84
+                { additionalButtons.has('chat')
85
+                      && <ChatButton
86
+                          styles = { buttonStylesBorderless }
87
+                          toggledStyles = { backgroundToggledStyle } />}
105 88
 
106
-        return {
107
-            ...baseStyle,
108
-            style: [
109
-                baseStyle.style,
110
-                _styles.chatButtonOverride.toggled
111
-            ]
112
-        };
113
-    }
89
+                { additionalButtons.has('raisehand')
90
+                      && <RaiseHandButton
91
+                          styles = { buttonStylesBorderless }
92
+                          toggledStyles = { backgroundToggledStyle } />}
93
+                {additionalButtons.has('tileview') && <TileViewButton styles = { buttonStylesBorderless } />}
94
+                {additionalButtons.has('invite') && <InviteButton styles = { buttonStylesBorderless } />}
95
+                {additionalButtons.has('togglecamera')
96
+                      && <ToggleCameraButton
97
+                          styles = { buttonStylesBorderless }
98
+                          toggledStyles = { backgroundToggledStyle } />}
99
+                <OverflowMenuButton
100
+                    styles = { buttonStylesBorderless }
101
+                    toggledStyles = { toggledButtonStyles } />
102
+                <HangupButton
103
+                    styles = { hangupButtonStyles } />
104
+            </SafeAreaView>
105
+        </View>
106
+    );
114 107
 }
115 108
 
116 109
 /**
@@ -125,7 +118,8 @@ class Toolbox extends PureComponent<Props> {
125 118
 function _mapStateToProps(state: Object): Object {
126 119
     return {
127 120
         _styles: ColorSchemeRegistry.get(state, 'Toolbox'),
128
-        _visible: isToolboxVisible(state)
121
+        _visible: isToolboxVisible(state),
122
+        _width: state['features/base/responsive-ui'].clientWidth
129 123
     };
130 124
 }
131 125
 

+ 6
- 13
react/features/toolbox/components/native/styles.js 查看文件

@@ -17,10 +17,8 @@ const toolbarButton = {
17 17
     flexDirection: 'row',
18 18
     height: BUTTON_SIZE,
19 19
     justifyContent: 'center',
20
-
21
-    // XXX We probably tested BoxModel.margin and discovered it to be too small
22
-    // for our taste.
23
-    marginHorizontal: 7,
20
+    marginHorizontal: 6,
21
+    marginTop: 6,
24 22
     width: BUTTON_SIZE
25 23
 };
26 24
 
@@ -65,7 +63,8 @@ const styles = {
65 63
     toolbox: {
66 64
         alignItems: 'center',
67 65
         backgroundColor: ColorPalette.darkBackground,
68
-        borderRadius: 3,
66
+        borderTopLeftRadius: 3,
67
+        borderTopRightRadius: 3,
69 68
         flexDirection: 'row',
70 69
         flexGrow: 0,
71 70
         justifyContent: 'space-between',
@@ -108,14 +107,8 @@ ColorSchemeRegistry.register('Toolbox', {
108 107
         }
109 108
     },
110 109
 
111
-    /**
112
-     * Overrides to the standard styles that we apply to the chat button, as
113
-     * that behaves slightly differently to other buttons.
114
-     */
115
-    chatButtonOverride: {
116
-        toggled: {
117
-            backgroundColor: ColorPalette.blue
118
-        }
110
+    backgroundToggle: {
111
+        backgroundColor: ColorPalette.toggled
119 112
     },
120 113
 
121 114
     hangupButtonStyles: {

+ 45
- 0
react/features/toolbox/functions.native.js 查看文件

@@ -5,6 +5,51 @@ import { TOOLBOX_ALWAYS_VISIBLE, getFeatureFlag, TOOLBOX_ENABLED } from '../base
5 5
 import { toState } from '../base/redux';
6 6
 import { isLocalVideoTrackDesktop } from '../base/tracks';
7 7
 
8
+const WIDTH = {
9
+    FIT_9_ICONS: 560,
10
+    FIT_8_ICONS: 500,
11
+    FIT_7_ICONS: 440,
12
+    FIT_6_ICONS: 380
13
+};
14
+
15
+/**
16
+ * Returns a set of the buttons that are shown in the toolbar
17
+ * but removed from the overflow menu, based on the width of the screen.
18
+ *
19
+ * @param {number} width - The width of the screen.
20
+ * @returns {Set}
21
+ */
22
+export function getMovableButtons(width: number): Set<string> {
23
+    let buttons = [];
24
+
25
+    switch (true) {
26
+    case width >= WIDTH.FIT_9_ICONS: {
27
+        buttons = [ 'togglecamera', 'chat', 'invite', 'raisehand', 'tileview' ];
28
+        break;
29
+    }
30
+    case width >= WIDTH.FIT_8_ICONS: {
31
+        buttons = [ 'chat', 'invite', 'raisehand', 'tileview' ];
32
+        break;
33
+    }
34
+
35
+    case width >= WIDTH.FIT_7_ICONS: {
36
+        buttons = [ 'chat', 'raisehand', 'invite' ];
37
+        break;
38
+    }
39
+
40
+    case width >= WIDTH.FIT_6_ICONS: {
41
+        buttons = [ 'chat', 'raisehand' ];
42
+        break;
43
+    }
44
+
45
+    default: {
46
+        buttons = [ 'chat' ];
47
+    }
48
+    }
49
+
50
+    return new Set(buttons);
51
+}
52
+
8 53
 /**
9 54
  * Returns true if the toolbox is visible.
10 55
  *

正在加载...
取消
保存