|
@@ -7,16 +7,16 @@ import { connect } from 'react-redux';
|
7
|
7
|
|
8
|
8
|
import { createToolbarEvent, sendAnalytics } from '../../analytics';
|
9
|
9
|
import { translate } from '../../base/i18n';
|
|
10
|
+import { getParticipantCount } from '../../base/participants';
|
10
|
11
|
import {
|
11
|
12
|
ToolbarButton,
|
12
|
13
|
ToolbarButtonV2,
|
13
|
14
|
TOOLTIP_TO_POPUP_POSITION
|
14
|
15
|
} from '../../toolbox';
|
15
|
16
|
|
16
|
|
-import { setInfoDialogVisibility, updateDialInNumbers } from '../actions';
|
17
|
|
-import { InfoDialog } from './info-dialog';
|
|
17
|
+import { updateDialInNumbers } from '../actions';
|
18
|
18
|
|
19
|
|
-const { INITIAL_TOOLBAR_TIMEOUT } = interfaceConfig;
|
|
19
|
+import { InfoDialog } from './info-dialog';
|
20
|
20
|
|
21
|
21
|
/**
|
22
|
22
|
* A configuration object to describe how {@code ToolbarButton} should render
|
|
@@ -32,6 +32,14 @@ const DEFAULT_BUTTON_CONFIGURATION = {
|
32
|
32
|
tooltipKey: 'info.tooltip'
|
33
|
33
|
};
|
34
|
34
|
|
|
35
|
+/**
|
|
36
|
+ * The amount of time, in milliseconds, to wait until automatically showing
|
|
37
|
+ * the {@code InfoDialog}. This is essentially a hack as automatic showing
|
|
38
|
+ * should happen in a lonely call and some time is needed to populate
|
|
39
|
+ * participants already in the call.
|
|
40
|
+ */
|
|
41
|
+const INFO_DIALOG_AUTO_SHOW_TIMEOUT = 1500;
|
|
42
|
+
|
35
|
43
|
/**
|
36
|
44
|
* A React Component for displaying a button which opens a dialog with
|
37
|
45
|
* information about the conference and with ways to invite people.
|
|
@@ -55,15 +63,16 @@ class InfoDialogButton extends Component {
|
55
|
63
|
]),
|
56
|
64
|
|
57
|
65
|
/**
|
58
|
|
- * Whether or not the {@code InfoDialog} should close by itself after a
|
59
|
|
- * a timeout.
|
|
66
|
+ * Whether or not the {@code InfoDialog} should display automatically
|
|
67
|
+ * after {@link INFO_DIALOG_AUTO_SHOW_TIMEOUT}.
|
60
|
68
|
*/
|
61
|
|
- _shouldAutoClose: PropTypes.bool,
|
|
69
|
+ _disableAutoShow: PropTypes.bool,
|
62
|
70
|
|
63
|
71
|
/**
|
64
|
|
- * Whether or not {@code InfoDialog} should be displayed.
|
|
72
|
+ * The number of real participants in the call. If in a lonely call,
|
|
73
|
+ * the {@code InfoDialog} will be automatically shown.
|
65
|
74
|
*/
|
66
|
|
- _showDialog: PropTypes.bool,
|
|
75
|
+ _participantCount: PropTypes.number,
|
67
|
76
|
|
68
|
77
|
/**
|
69
|
78
|
* Whether or not the toolbox, in which this component exists, are
|
|
@@ -98,16 +107,23 @@ class InfoDialogButton extends Component {
|
98
|
107
|
super(props);
|
99
|
108
|
|
100
|
109
|
/**
|
101
|
|
- * The timeout to automatically hide the {@code InfoDialog} if it has
|
102
|
|
- * not been interacted with.
|
|
110
|
+ * The timeout to automatically show the {@code InfoDialog} if it has
|
|
111
|
+ * not been shown yet in a lonely call.
|
103
|
112
|
*
|
104
|
113
|
* @type {timeoutID}
|
105
|
114
|
*/
|
106
|
|
- this._autoHideDialogTimeout = null;
|
|
115
|
+ this._autoShowTimeout = null;
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+ this.state = {
|
|
119
|
+ /**
|
|
120
|
+ * Whether or not {@code InfoDialog} should be visible.
|
|
121
|
+ */
|
|
122
|
+ showDialog: false
|
|
123
|
+ };
|
107
|
124
|
|
108
|
125
|
// Bind event handlers so they are only bound once for every instance.
|
109
|
126
|
this._onDialogClose = this._onDialogClose.bind(this);
|
110
|
|
- this._onDialogMouseOver = this._onDialogMouseOver.bind(this);
|
111
|
127
|
this._onDialogToggle = this._onDialogToggle.bind(this);
|
112
|
128
|
}
|
113
|
129
|
|
|
@@ -117,30 +133,15 @@ class InfoDialogButton extends Component {
|
117
|
133
|
* @inheritdoc
|
118
|
134
|
*/
|
119
|
135
|
componentDidMount() {
|
120
|
|
- if (this.props._shouldAutoClose) {
|
121
|
|
- this._setAutoCloseTimeout();
|
122
|
|
- }
|
|
136
|
+ this._autoShowTimeout = setTimeout(() => {
|
|
137
|
+ this._maybeAutoShowDialog();
|
|
138
|
+ }, INFO_DIALOG_AUTO_SHOW_TIMEOUT);
|
123
|
139
|
|
124
|
140
|
if (!this.props._dialInNumbers) {
|
125
|
141
|
this.props.dispatch(updateDialInNumbers());
|
126
|
142
|
}
|
127
|
143
|
}
|
128
|
144
|
|
129
|
|
- /**
|
130
|
|
- * Set or clear the timeout to automatically hide the {@code InfoDialog}.
|
131
|
|
- *
|
132
|
|
- * @inheritdoc
|
133
|
|
- */
|
134
|
|
- componentDidUpdate(prevProps) {
|
135
|
|
- // If the _shouldAutoClose flag has been updated to be true then make
|
136
|
|
- // sure to set _autoHideDialogTimeout.
|
137
|
|
- if (this.props._shouldAutoClose && !prevProps._shouldAutoClose) {
|
138
|
|
- this._setAutoCloseTimeout();
|
139
|
|
- } else {
|
140
|
|
- this._clearAutoCloseTimeout();
|
141
|
|
- }
|
142
|
|
- }
|
143
|
|
-
|
144
|
145
|
/**
|
145
|
146
|
* Update the visibility of the {@code InfoDialog}.
|
146
|
147
|
*
|
|
@@ -148,7 +149,7 @@ class InfoDialogButton extends Component {
|
148
|
149
|
*/
|
149
|
150
|
componentWillReceiveProps(nextProps) {
|
150
|
151
|
// Ensure the dialog is closed when the toolbox becomes hidden.
|
151
|
|
- if (nextProps._showDialog && !nextProps._toolboxVisible) {
|
|
152
|
+ if (this.state.showDialog && !nextProps._toolboxVisible) {
|
152
|
153
|
this._onDialogClose();
|
153
|
154
|
}
|
154
|
155
|
}
|
|
@@ -159,7 +160,7 @@ class InfoDialogButton extends Component {
|
159
|
160
|
* @inheritdoc
|
160
|
161
|
*/
|
161
|
162
|
componentWillUnmount() {
|
162
|
|
- this._clearAutoCloseTimeout();
|
|
163
|
+ clearTimeout(this._autoShowTimeout);
|
163
|
164
|
}
|
164
|
165
|
|
165
|
166
|
/**
|
|
@@ -175,14 +176,16 @@ class InfoDialogButton extends Component {
|
175
|
176
|
}
|
176
|
177
|
|
177
|
178
|
/**
|
178
|
|
- * Cancels the timeout to automatically hide the {@code InfoDialog}.
|
|
179
|
+ * Callback invoked after a timeout to trigger display of the
|
|
180
|
+ * {@code InfoDialog} if certain conditions are met.
|
179
|
181
|
*
|
180
|
182
|
* @private
|
181
|
183
|
* @returns {void}
|
182
|
184
|
*/
|
183
|
|
- _clearAutoCloseTimeout() {
|
184
|
|
- clearTimeout(this._autoHideDialogTimeout);
|
185
|
|
- this._autoHideDialogTimeout = null;
|
|
185
|
+ _maybeAutoShowDialog() {
|
|
186
|
+ if (this.props._participantCount < 2 && !this.props._disableAutoShow) {
|
|
187
|
+ this.setState({ showDialog: true });
|
|
188
|
+ }
|
186
|
189
|
}
|
187
|
190
|
|
188
|
191
|
/**
|
|
@@ -192,17 +195,7 @@ class InfoDialogButton extends Component {
|
192
|
195
|
* @returns {void}
|
193
|
196
|
*/
|
194
|
197
|
_onDialogClose() {
|
195
|
|
- this.props.dispatch(setInfoDialogVisibility(false));
|
196
|
|
- }
|
197
|
|
-
|
198
|
|
- /**
|
199
|
|
- * Cancels the timeout to automatically hide the {@code InfoDialog}.
|
200
|
|
- *
|
201
|
|
- * @private
|
202
|
|
- * @returns {void}
|
203
|
|
- */
|
204
|
|
- _onDialogMouseOver() {
|
205
|
|
- this._clearAutoCloseTimeout();
|
|
198
|
+ this.setState({ showDialog: false });
|
206
|
199
|
}
|
207
|
200
|
|
208
|
201
|
/**
|
|
@@ -214,7 +207,7 @@ class InfoDialogButton extends Component {
|
214
|
207
|
_onDialogToggle() {
|
215
|
208
|
sendAnalytics(createToolbarEvent('info'));
|
216
|
209
|
|
217
|
|
- this.props.dispatch(setInfoDialogVisibility(!this.props._showDialog));
|
|
210
|
+ this.setState({ showDialog: !this.state.showDialog });
|
218
|
211
|
}
|
219
|
212
|
|
220
|
213
|
/**
|
|
@@ -225,22 +218,21 @@ class InfoDialogButton extends Component {
|
225
|
218
|
* @returns {ReactElement}
|
226
|
219
|
*/
|
227
|
220
|
_renderOldToolbarButton() {
|
228
|
|
- const { _showDialog, _toolboxVisible, tooltipPosition } = this.props;
|
|
221
|
+ const { tooltipPosition } = this.props;
|
|
222
|
+ const { showDialog } = this.state;
|
|
223
|
+
|
229
|
224
|
const buttonConfiguration = {
|
230
|
225
|
...DEFAULT_BUTTON_CONFIGURATION,
|
231
|
226
|
classNames: [
|
232
|
227
|
...DEFAULT_BUTTON_CONFIGURATION.classNames,
|
233
|
|
- _showDialog ? 'toggled button-active' : ''
|
|
228
|
+ showDialog ? 'toggled button-active' : ''
|
234
|
229
|
]
|
235
|
230
|
};
|
236
|
231
|
|
237
|
232
|
return (
|
238
|
233
|
<InlineDialog
|
239
|
|
- content = { <InfoDialog
|
240
|
|
- autoUpdateNumbers = { false }
|
241
|
|
- onClose = { this._onDialogClose }
|
242
|
|
- onMouseOver = { this._onDialogMouseOver } /> }
|
243
|
|
- isOpen = { _toolboxVisible && _showDialog }
|
|
234
|
+ content = { <InfoDialog onClose = { this._onDialogClose } /> }
|
|
235
|
+ isOpen = { showDialog }
|
244
|
236
|
onClose = { this._onDialogClose }
|
245
|
237
|
position = { TOOLTIP_TO_POPUP_POSITION[tooltipPosition] }>
|
246
|
238
|
<ToolbarButton
|
|
@@ -259,17 +251,16 @@ class InfoDialogButton extends Component {
|
259
|
251
|
* @returns {ReactElement}
|
260
|
252
|
*/
|
261
|
253
|
_renderNewToolbarButton() {
|
262
|
|
- const { _showDialog, _toolboxVisible, t } = this.props;
|
263
|
|
- const iconClass = `icon-info ${_showDialog ? 'toggled' : ''}`;
|
|
254
|
+ const { t } = this.props;
|
|
255
|
+ const { showDialog } = this.state;
|
|
256
|
+ const iconClass = `icon-info ${showDialog ? 'toggled' : ''}`;
|
264
|
257
|
|
265
|
258
|
return (
|
266
|
259
|
<div className = 'toolbox-button-wth-dialog'>
|
267
|
260
|
<InlineDialog
|
268
|
|
- content = { <InfoDialog
|
269
|
|
- autoUpdateNumbers = { false }
|
270
|
|
- onClose = { this._onDialogClose }
|
271
|
|
- onMouseOver = { this._onDialogMouseOver } /> }
|
272
|
|
- isOpen = { _toolboxVisible && _showDialog }
|
|
261
|
+ content = {
|
|
262
|
+ <InfoDialog onClose = { this._onDialogClose } /> }
|
|
263
|
+ isOpen = { showDialog }
|
273
|
264
|
onClose = { this._onDialogClose }
|
274
|
265
|
position = { 'top right' }>
|
275
|
266
|
<ToolbarButtonV2
|
|
@@ -281,22 +272,6 @@ class InfoDialogButton extends Component {
|
281
|
272
|
</div>
|
282
|
273
|
);
|
283
|
274
|
}
|
284
|
|
-
|
285
|
|
- /**
|
286
|
|
- * Set a timeout to automatically hide the {@code InfoDialog}.
|
287
|
|
- *
|
288
|
|
- * @private
|
289
|
|
- * @returns {void}
|
290
|
|
- */
|
291
|
|
- _setAutoCloseTimeout() {
|
292
|
|
- this._clearAutoCloseTimeout();
|
293
|
|
-
|
294
|
|
- this._autoHideDialogTimeout = setTimeout(() => {
|
295
|
|
- if (this.props._showDialog) {
|
296
|
|
- this._onDialogClose();
|
297
|
|
- }
|
298
|
|
- }, INITIAL_TOOLBAR_TIMEOUT);
|
299
|
|
- }
|
300
|
275
|
}
|
301
|
276
|
|
302
|
277
|
/**
|
|
@@ -307,22 +282,17 @@ class InfoDialogButton extends Component {
|
307
|
282
|
* @private
|
308
|
283
|
* @returns {{
|
309
|
284
|
* _dialInNumbers: Array,
|
310
|
|
- * _shouldAutoClose: boolean,
|
311
|
|
- * _showDialog: boolean,
|
|
285
|
+ * _disableAutoShow: bolean,
|
|
286
|
+ * _participantCount: number,
|
312
|
287
|
* _toolboxVisible: boolean
|
313
|
288
|
* }}
|
314
|
289
|
*/
|
315
|
290
|
function _mapStateToProps(state) {
|
316
|
|
- const {
|
317
|
|
- infoDialogVisible,
|
318
|
|
- infoDialogWillAutoClose,
|
319
|
|
- numbers
|
320
|
|
- } = state['features/invite'];
|
321
|
|
-
|
322
|
291
|
return {
|
323
|
|
- _dialInNumbers: numbers,
|
324
|
|
- _shouldAutoClose: infoDialogWillAutoClose,
|
325
|
|
- _showDialog: infoDialogVisible,
|
|
292
|
+ _dialInNumbers: state['features/invite'].numbers,
|
|
293
|
+ _disableAutoShow: state['features/base/config'].iAmRecorder,
|
|
294
|
+ _participantCount:
|
|
295
|
+ getParticipantCount(state['features/base/participants']),
|
326
|
296
|
_toolboxVisible: state['features/toolbox'].visible
|
327
|
297
|
};
|
328
|
298
|
}
|