|
@@ -11,35 +11,36 @@ import { translate } from '../../base/i18n';
|
11
|
11
|
import DesktopPickerPane from './DesktopPickerPane';
|
12
|
12
|
import { obtainDesktopSources } from '../functions';
|
13
|
13
|
|
|
14
|
+/**
|
|
15
|
+ * The size of the requested thumbnails.
|
|
16
|
+ *
|
|
17
|
+ * @type {Object}
|
|
18
|
+ */
|
14
|
19
|
const THUMBNAIL_SIZE = {
|
15
|
20
|
height: 300,
|
16
|
21
|
width: 300
|
17
|
22
|
};
|
18
|
23
|
|
|
24
|
+/**
|
|
25
|
+ * The sources polling interval in ms.
|
|
26
|
+ *
|
|
27
|
+ * @type {int}
|
|
28
|
+ */
|
19
|
29
|
const UPDATE_INTERVAL = 2000;
|
20
|
30
|
|
21
|
|
-type TabConfiguration = {
|
22
|
|
- defaultSelected?: boolean,
|
23
|
|
- label: string
|
24
|
|
-};
|
|
31
|
+/**
|
|
32
|
+ * The default selected tab.
|
|
33
|
+ *
|
|
34
|
+ * @type {string}
|
|
35
|
+ */
|
|
36
|
+const DEFAULT_TAB_TYPE = 'screen';
|
25
|
37
|
|
26
|
|
-const TAB_CONFIGURATIONS: { [type: string]: TabConfiguration} = {
|
27
|
|
- screen: {
|
28
|
|
- /**
|
29
|
|
- * The indicator which determines whether this tab configuration is
|
30
|
|
- * selected by default.
|
31
|
|
- *
|
32
|
|
- * @type {boolean}
|
33
|
|
- */
|
34
|
|
- defaultSelected: true,
|
35
|
|
- label: 'dialog.yourEntireScreen'
|
36
|
|
- },
|
37
|
|
- window: {
|
38
|
|
- label: 'dialog.applicationWindow'
|
39
|
|
- }
|
|
38
|
+const TAB_LABELS = {
|
|
39
|
+ screen: 'dialog.yourEntireScreen',
|
|
40
|
+ window: 'dialog.applicationWindow'
|
40
|
41
|
};
|
41
|
42
|
|
42
|
|
-const VALID_TYPES = Object.keys(TAB_CONFIGURATIONS);
|
|
43
|
+const VALID_TYPES = Object.keys(TAB_LABELS);
|
43
|
44
|
|
44
|
45
|
/**
|
45
|
46
|
* React component for DesktopPicker.
|
|
@@ -84,6 +85,13 @@ class DesktopPicker extends Component {
|
84
|
85
|
types: []
|
85
|
86
|
};
|
86
|
87
|
|
|
88
|
+ /**
|
|
89
|
+ * Stores the type of the selected tab.
|
|
90
|
+ *
|
|
91
|
+ * @type {string}
|
|
92
|
+ */
|
|
93
|
+ _selectedTabType = DEFAULT_TAB_TYPE;
|
|
94
|
+
|
87
|
95
|
/**
|
88
|
96
|
* Initializes a new DesktopPicker instance.
|
89
|
97
|
*
|
|
@@ -97,6 +105,7 @@ class DesktopPicker extends Component {
|
97
|
105
|
this._onCloseModal = this._onCloseModal.bind(this);
|
98
|
106
|
this._onPreviewClick = this._onPreviewClick.bind(this);
|
99
|
107
|
this._onSubmit = this._onSubmit.bind(this);
|
|
108
|
+ this._onTabSelected = this._onTabSelected.bind(this);
|
100
|
109
|
this._updateSources = this._updateSources.bind(this);
|
101
|
110
|
|
102
|
111
|
this.state.types
|
|
@@ -167,6 +176,58 @@ class DesktopPicker extends Component {
|
167
|
176
|
);
|
168
|
177
|
}
|
169
|
178
|
|
|
179
|
+ /**
|
|
180
|
+ * Computates the selected source.
|
|
181
|
+ *
|
|
182
|
+ * @param {Object} sources - The available sources.
|
|
183
|
+ * @returns {Object} The selectedSource value.
|
|
184
|
+ */
|
|
185
|
+ _getSelectedSource(sources = {}) {
|
|
186
|
+ const { selectedSource } = this.state;
|
|
187
|
+
|
|
188
|
+ /**
|
|
189
|
+ * If there are no sources for this type (or no sources for any type)
|
|
190
|
+ * we can't select anything.
|
|
191
|
+ */
|
|
192
|
+ if (!Array.isArray(sources[this._selectedTabType])
|
|
193
|
+ || sources[this._selectedTabType].length <= 0) {
|
|
194
|
+ return {};
|
|
195
|
+ }
|
|
196
|
+
|
|
197
|
+ /**
|
|
198
|
+ * Select the first available source for this type in the following
|
|
199
|
+ * scenarios:
|
|
200
|
+ * 1) Nothing is yet selected.
|
|
201
|
+ * 2) Tab change.
|
|
202
|
+ * 3) The selected source is no longer available.
|
|
203
|
+ */
|
|
204
|
+ if (!selectedSource // scenario 1)
|
|
205
|
+ || selectedSource.type !== this._selectedTabType // scenario 2)
|
|
206
|
+ || !sources[this._selectedTabType].some( // scenario 3)
|
|
207
|
+ source => source.id === selectedSource.id)) {
|
|
208
|
+ return {
|
|
209
|
+ id: sources[this._selectedTabType][0].id,
|
|
210
|
+ type: this._selectedTabType
|
|
211
|
+ };
|
|
212
|
+ }
|
|
213
|
+
|
|
214
|
+ /**
|
|
215
|
+ * For all other scenarios don't change the selection.
|
|
216
|
+ */
|
|
217
|
+ return selectedSource;
|
|
218
|
+ }
|
|
219
|
+
|
|
220
|
+ /**
|
|
221
|
+ * Extracts only the valid types from the passed {@code types}.
|
|
222
|
+ *
|
|
223
|
+ * @param {Array<string>} types - The types to filter.
|
|
224
|
+ * @returns {Array<string>} The filtered types.
|
|
225
|
+ */
|
|
226
|
+ _getValidTypes(types = []) {
|
|
227
|
+ return types.filter(
|
|
228
|
+ type => VALID_TYPES.includes(type));
|
|
229
|
+ }
|
|
230
|
+
|
170
|
231
|
_onCloseModal: (?string, string) => void;
|
171
|
232
|
|
172
|
233
|
/**
|
|
@@ -202,17 +263,6 @@ class DesktopPicker extends Component {
|
202
|
263
|
});
|
203
|
264
|
}
|
204
|
265
|
|
205
|
|
- /**
|
206
|
|
- * Extracts only the valid types from the passed {@code types}.
|
207
|
|
- *
|
208
|
|
- * @param {Array<string>} types - The types to filter.
|
209
|
|
- * @returns {Array<string>} The filtered types.
|
210
|
|
- */
|
211
|
|
- _getValidTypes(types = []) {
|
212
|
|
- return types.filter(
|
213
|
|
- type => VALID_TYPES.includes(type));
|
214
|
|
- }
|
215
|
|
-
|
216
|
266
|
_onSubmit: () => void;
|
217
|
267
|
|
218
|
268
|
/**
|
|
@@ -227,6 +277,24 @@ class DesktopPicker extends Component {
|
227
|
277
|
this._onCloseModal(id, type);
|
228
|
278
|
}
|
229
|
279
|
|
|
280
|
+ _onTabSelected: () => void;
|
|
281
|
+
|
|
282
|
+ /**
|
|
283
|
+ * Stores the selected tab and updates the selected source via
|
|
284
|
+ * {@code _getSelectedSource}.
|
|
285
|
+ *
|
|
286
|
+ * @param {int} idx - The index of the selected tab.
|
|
287
|
+ * @returns {void}
|
|
288
|
+ */
|
|
289
|
+ _onTabSelected(idx) {
|
|
290
|
+ const { types, sources } = this.state;
|
|
291
|
+
|
|
292
|
+ this._selectedTabType = types[idx];
|
|
293
|
+ this.setState({
|
|
294
|
+ selectedSource: this._getSelectedSource(sources)
|
|
295
|
+ });
|
|
296
|
+ }
|
|
297
|
+
|
230
|
298
|
/**
|
231
|
299
|
* Configures and renders the tabs for display.
|
232
|
300
|
*
|
|
@@ -239,8 +307,6 @@ class DesktopPicker extends Component {
|
239
|
307
|
const tabs
|
240
|
308
|
= types.map(
|
241
|
309
|
type => {
|
242
|
|
- const { defaultSelected, label } = TAB_CONFIGURATIONS[type];
|
243
|
|
-
|
244
|
310
|
return {
|
245
|
311
|
content: <DesktopPickerPane
|
246
|
312
|
key = { type }
|
|
@@ -249,12 +315,15 @@ class DesktopPicker extends Component {
|
249
|
315
|
selectedSourceId = { selectedSource.id }
|
250
|
316
|
sources = { sources[type] }
|
251
|
317
|
type = { type } />,
|
252
|
|
- defaultSelected,
|
253
|
|
- label: t(label)
|
|
318
|
+ defaultSelected: type === DEFAULT_TAB_TYPE,
|
|
319
|
+ label: t(TAB_LABELS[type])
|
254
|
320
|
};
|
255
|
321
|
});
|
256
|
322
|
|
257
|
|
- return <Tabs tabs = { tabs } />;
|
|
323
|
+ return (
|
|
324
|
+ <Tabs
|
|
325
|
+ onSelect = { this._onTabSelected }
|
|
326
|
+ tabs = { tabs } />);
|
258
|
327
|
}
|
259
|
328
|
|
260
|
329
|
/**
|
|
@@ -283,7 +352,7 @@ class DesktopPicker extends Component {
|
283
|
352
|
_updateSources: () => void;
|
284
|
353
|
|
285
|
354
|
/**
|
286
|
|
- * Dispatches an action to get currently available DesktopCapturerSources.
|
|
355
|
+ * Obtains the desktop sources and updates state with them.
|
287
|
356
|
*
|
288
|
357
|
* @private
|
289
|
358
|
* @returns {void}
|
|
@@ -297,23 +366,14 @@ class DesktopPicker extends Component {
|
297
|
366
|
{ thumbnailSize: THUMBNAIL_SIZE }
|
298
|
367
|
)
|
299
|
368
|
.then(sources => {
|
300
|
|
- const nextState: Object = {
|
301
|
|
- sources
|
302
|
|
- };
|
303
|
|
-
|
304
|
|
- // FIXME: selectedSource when screen is disabled, when the
|
305
|
|
- // source has been removed or when the selectedTab is changed!!!
|
306
|
|
- if (!this.state.selectedSource.id
|
307
|
|
- && sources.screen.length > 0) {
|
308
|
|
- nextState.selectedSource = {
|
309
|
|
- id: sources.screen[0].id,
|
310
|
|
- type: 'screen'
|
311
|
|
- };
|
312
|
|
- }
|
|
369
|
+ const selectedSource = this._getSelectedSource(sources);
|
313
|
370
|
|
314
|
371
|
// TODO: Maybe check if we have stopped the timer and unmounted
|
315
|
372
|
// the component.
|
316
|
|
- this.setState(nextState);
|
|
373
|
+ this.setState({
|
|
374
|
+ sources,
|
|
375
|
+ selectedSource
|
|
376
|
+ });
|
317
|
377
|
})
|
318
|
378
|
.catch(() => { /* ignore */ });
|
319
|
379
|
}
|