Quellcode durchsuchen

fix(DesktopPicker): Issues with selection (#2113)

j8
hristoterezov vor 7 Jahren
Ursprung
Commit
178235513b
1 geänderte Dateien mit 110 neuen und 50 gelöschten Zeilen
  1. 110
    50
      react/features/desktop-picker/components/DesktopPicker.js

+ 110
- 50
react/features/desktop-picker/components/DesktopPicker.js Datei anzeigen

@@ -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
         }

Laden…
Abbrechen
Speichern