浏览代码

ref(info): be explicit when opening the dialog with a timeout

Instead of assuming the initial info dialog open should auto
close, explicitly call opening of the dialog with a flag for
auto closing. This better facilitates the auto close timeout
being set at any time.

The changes led to refactoring out state in the InfoDialogButton
in preference for always clearing the timeout instead of
first checking for interaction before clearing.
j8
Leonard Kim 8 年前
父节点
当前提交
887e1b6828

+ 7
- 1
react/features/invite/actions.js 查看文件

@@ -24,14 +24,20 @@ export function openInviteDialog() {
24 24
  * Opens the inline conference info dialog.
25 25
  *
26 26
  * @param {boolean} visible - Whether or not the dialog should be displayed.
27
+ * @param {boolean} autoClose - Whether or not the dialog should automatically
28
+ * close after a set period of time.
27 29
  * @returns {{
28 30
  *     type: SET_INFO_DIALOG_VISIBILITY,
31
+ *     autoClose: boolean,
29 32
  *     visible: boolean
30 33
  * }}
31 34
  */
32
-export function setInfoDialogVisibility(visible: boolean) {
35
+export function setInfoDialogVisibility(
36
+        visible: boolean,
37
+        autoClose: boolean = false) {
33 38
     return {
34 39
         type: SET_INFO_DIALOG_VISIBILITY,
40
+        autoClose,
35 41
         visible
36 42
     };
37 43
 }

+ 57
- 33
react/features/invite/components/InfoDialogButton.web.js 查看文件

@@ -40,6 +40,12 @@ class InfoDialogButton extends Component {
40 40
      * @static
41 41
      */
42 42
     static propTypes = {
43
+        /**
44
+         * Whether or not the {@code InfoDialog} should close by itself after a
45
+         * a timeout.
46
+         */
47
+        _shouldAutoClose: PropTypes.bool,
48
+
43 49
         /**
44 50
          * Whether or not {@code InfoDialog} should be displayed.
45 51
          */
@@ -80,15 +86,6 @@ class InfoDialogButton extends Component {
80 86
          */
81 87
         this._autoHideDialogTimeout = null;
82 88
 
83
-        this.state = {
84
-            /**
85
-             * Whether or not the dialog has been interacted with somehow, such
86
-             * as clicking or toggle display. A value of true will prevent the
87
-             * dialog from being automatically hidden.
88
-             */
89
-            hasInteractedWithDialog: false
90
-        };
91
-
92 89
         // Bind event handlers so they are only bound once for every instance.
93 90
         this._onDialogClose = this._onDialogClose.bind(this);
94 91
         this._onDialogMouseOver = this._onDialogMouseOver.bind(this);
@@ -101,23 +98,34 @@ class InfoDialogButton extends Component {
101 98
      * @inheritdoc
102 99
      */
103 100
     componentDidMount() {
104
-        this._autoHideDialogTimeout = setTimeout(() => {
105
-            this._maybeHideDialog();
106
-        }, INITIAL_TOOLBAR_TIMEOUT);
101
+        if (this.props._shouldAutoClose) {
102
+            this._setAutoCloseTimeout();
103
+        }
107 104
     }
108 105
 
109 106
     /**
110
-     * Update the state when the {@code InfoDialog} visibility has been updated.
107
+     * Set or clear the timeout to automatically hide the {@code InfoDialog}.
111 108
      *
112 109
      * @inheritdoc
113 110
      */
114
-    componentWillReceiveProps(nextProps) {
115
-        if (!this.state.hasInteractedWithDialog
116
-            && (nextProps._showDialog !== this.props._showDialog)) {
117
-            this.setState({ hasInteractedWithDialog: true });
111
+    componentDidUpdate(prevProps) {
112
+        // If the _shouldAutoClose flag has been updated to be true then make
113
+        // sure to set _autoHideDialogTimeout.
114
+        if (this.props._shouldAutoClose && !prevProps._shouldAutoClose) {
115
+            this._setAutoCloseTimeout();
116
+        } else {
117
+            this._clearAutoCloseTimeout();
118 118
         }
119
+    }
119 120
 
120
-        if (!nextProps._toolboxVisible && this.props._toolboxVisible) {
121
+    /**
122
+     * Update the visibility of the {@code InfoDialog}.
123
+     *
124
+     * @inheritdoc
125
+     */
126
+    componentWillReceiveProps(nextProps) {
127
+        // Ensure the dialog is closed when the toolbox becomes hidden.
128
+        if (nextProps._showDialog && !nextProps._toolboxVisible) {
121 129
             this._onDialogClose();
122 130
         }
123 131
     }
@@ -128,7 +136,7 @@ class InfoDialogButton extends Component {
128 136
      * @inheritdoc
129 137
      */
130 138
     componentWillUnmount() {
131
-        clearTimeout(this._autoHideDialogTimeout);
139
+        this._clearAutoCloseTimeout();
132 140
     }
133 141
 
134 142
     /**
@@ -154,7 +162,6 @@ class InfoDialogButton extends Component {
154 162
                     onMouseOver = { this._onDialogMouseOver } /> }
155 163
                 isOpen = { _toolboxVisible && _showDialog }
156 164
                 onClose = { this._onDialogClose }
157
-                onContentClick = { this._onDialogInteract }
158 165
                 position = { TOOLTIP_TO_POPUP_POSITION[tooltipPosition] }>
159 166
                 <ToolbarButton
160 167
                     button = { buttonConfiguration }
@@ -165,17 +172,14 @@ class InfoDialogButton extends Component {
165 172
     }
166 173
 
167 174
     /**
168
-     * Callback invoked after a timeout to trigger hiding of the
169
-     * {@code InfoDialog} if there has been no interaction with the dialog
170
-     * and the dialog is currently showing.
175
+     * Cancels the timeout to automatically hide the {@code InfoDialog}.
171 176
      *
172 177
      * @private
173 178
      * @returns {void}
174 179
      */
175
-    _maybeHideDialog() {
176
-        if (!this.state.hasInteractedWithDialog && this.props._showDialog) {
177
-            this._onDialogToggle();
178
-        }
180
+    _clearAutoCloseTimeout() {
181
+        clearTimeout(this._autoHideDialogTimeout);
182
+        this._autoHideDialogTimeout = null;
179 183
     }
180 184
 
181 185
     /**
@@ -189,16 +193,13 @@ class InfoDialogButton extends Component {
189 193
     }
190 194
 
191 195
     /**
192
-     * Updates the internal state to mark the {@code InfoDialog} as having been
193
-     * interacted with.
196
+     * Cancels the timeout to automatically hide the {@code InfoDialog}.
194 197
      *
195 198
      * @private
196 199
      * @returns {void}
197 200
      */
198 201
     _onDialogMouseOver() {
199
-        if (!this.state.hasInteractedWithDialog) {
200
-            this.setState({ hasInteractedWithDialog: true });
201
-        }
202
+        this._clearAutoCloseTimeout();
202 203
     }
203 204
 
204 205
     /**
@@ -210,6 +211,22 @@ class InfoDialogButton extends Component {
210 211
     _onDialogToggle() {
211 212
         this.props.dispatch(setInfoDialogVisibility(!this.props._showDialog));
212 213
     }
214
+
215
+    /**
216
+     * Set a timeout to automatically hide the {@code InfoDialog}.
217
+     *
218
+     * @private
219
+     * @returns {void}
220
+     */
221
+    _setAutoCloseTimeout() {
222
+        this._clearAutoCloseTimeout();
223
+
224
+        this._autoHideDialogTimeout = setTimeout(() => {
225
+            if (this.props._showDialog) {
226
+                this._onDialogClose();
227
+            }
228
+        }, INITIAL_TOOLBAR_TIMEOUT);
229
+    }
213 230
 }
214 231
 
215 232
 /**
@@ -219,13 +236,20 @@ class InfoDialogButton extends Component {
219 236
  * @param {Object} state - The Redux state.
220 237
  * @private
221 238
  * @returns {{
239
+ *     _shouldAutoClose: boolean,
222 240
  *     _showDialog: boolean,
223 241
  *     _toolboxVisible: boolean
224 242
  * }}
225 243
  */
226 244
 function _mapStateToProps(state) {
245
+    const {
246
+        infoDialogVisible,
247
+        infoDialogWillAutoClose
248
+    } = state['features/invite'];
249
+
227 250
     return {
228
-        _showDialog: state['features/invite'].infoDialogVisible,
251
+        _shouldAutoClose: infoDialogWillAutoClose,
252
+        _showDialog: infoDialogVisible,
229 253
         _toolboxVisible: state['features/toolbox'].visible
230 254
     };
231 255
 }

+ 1
- 1
react/features/invite/middleware.js 查看文件

@@ -18,7 +18,7 @@ MiddlewareRegistry.register(store => next => action => {
18 18
 
19 19
     switch (action.type) {
20 20
     case CONFERENCE_JOINED:
21
-        store.dispatch(setInfoDialogVisibility(true));
21
+        store.dispatch(setInfoDialogVisibility(true, true));
22 22
         break;
23 23
 
24 24
     case UPDATE_DIAL_IN_NUMBERS_FAILED:

+ 2
- 1
react/features/invite/reducer.js 查看文件

@@ -15,7 +15,8 @@ ReducerRegistry.register('features/invite', (state = DEFAULT_STATE, action) => {
15 15
     case SET_INFO_DIALOG_VISIBILITY:
16 16
         return {
17 17
             ...state,
18
-            infoDialogVisible: action.visible
18
+            infoDialogVisible: action.visible,
19
+            infoDialogWillAutoClose: action.autoClose
19 20
         };
20 21
 
21 22
     case UPDATE_DIAL_IN_NUMBERS_FAILED:

正在加载...
取消
保存