Просмотр исходного кода

android: enter PiP mode when pressing back button

When in a conference, try to enter PiP when pressing the back button. If this is
not possible (because it's unsupported, not enabled, etc.) fall back to the
previous behavior of simply hanging up.
master
Saúl Ibarra Corretgé 6 лет назад
Родитель
Сommit
cb3419ba2a
1 измененных файлов: 67 добавлений и 66 удалений
  1. 67
    66
      react/features/conference/components/native/Conference.js

+ 67
- 66
react/features/conference/components/native/Conference.js Просмотреть файл

1
 // @flow
1
 // @flow
2
 
2
 
3
 import React from 'react';
3
 import React from 'react';
4
-
5
-import { BackHandler, SafeAreaView, StatusBar, View } from 'react-native';
4
+import { BackHandler, NativeModules, SafeAreaView, StatusBar, View } from 'react-native';
6
 
5
 
7
 import { appNavigate } from '../../../app';
6
 import { appNavigate } from '../../../app';
7
+import { getAppProp } from '../../../base/app';
8
 import { getParticipantCount } from '../../../base/participants';
8
 import { getParticipantCount } from '../../../base/participants';
9
 import { Container, LoadingIndicator, TintedView } from '../../../base/react';
9
 import { Container, LoadingIndicator, TintedView } from '../../../base/react';
10
-import { connect as reactReduxConnect } from '../../../base/redux';
10
+import { connect } from '../../../base/redux';
11
 import {
11
 import {
12
     isNarrowAspectRatio,
12
     isNarrowAspectRatio,
13
     makeAspectRatioAware
13
     makeAspectRatioAware
65
     _largeVideoParticipantId: string,
65
     _largeVideoParticipantId: string,
66
 
66
 
67
     /**
67
     /**
68
-     * Handles a hardware button press for back navigation. Leaves the
69
-     * associated {@code Conference}.
68
+     * The number of participants in the conference.
70
      *
69
      *
71
      * @private
70
      * @private
72
-     * @returns {boolean} As the associated conference is unconditionally left
73
-     * and exiting the app while it renders a {@code Conference} is undesired,
74
-     * {@code true} is always returned.
75
      */
71
      */
76
-    _onHardwareBackPress: Function,
72
+    _participantCount: number,
77
 
73
 
78
     /**
74
     /**
79
-     * The number of participants in the conference.
75
+     * Whether Picture-in-Picture is enabled.
80
      *
76
      *
81
      * @private
77
      * @private
82
      */
78
      */
83
-    _participantCount: number,
79
+    _pictureInPictureEnabled: boolean,
84
 
80
 
85
     /**
81
     /**
86
      * The indicator which determines whether the UI is reduced (to accommodate
82
      * The indicator which determines whether the UI is reduced (to accommodate
113
      *
109
      *
114
      * @private
110
      * @private
115
      */
111
      */
116
-    _toolboxAlwaysVisible: boolean
112
+    _toolboxAlwaysVisible: boolean,
113
+
114
+    /**
115
+     * The redux {@code dispatch} function.
116
+     */
117
+    dispatch: Function
117
 };
118
 };
118
 
119
 
119
 /**
120
 /**
131
 
132
 
132
         // Bind event handlers so they are only bound once per instance.
133
         // Bind event handlers so they are only bound once per instance.
133
         this._onClick = this._onClick.bind(this);
134
         this._onClick = this._onClick.bind(this);
135
+        this._onHardwareBackPress = this._onHardwareBackPress.bind(this);
136
+        this._setToolboxVisible = this._setToolboxVisible.bind(this);
134
     }
137
     }
135
 
138
 
136
     /**
139
     /**
141
      * @returns {void}
144
      * @returns {void}
142
      */
145
      */
143
     componentDidMount() {
146
     componentDidMount() {
144
-        BackHandler.addEventListener(
145
-            'hardwareBackPress',
146
-            this.props._onHardwareBackPress);
147
+        BackHandler.addEventListener('hardwareBackPress', this._onHardwareBackPress);
147
 
148
 
148
         // Show the toolbox if we are the only participant; otherwise, the whole
149
         // Show the toolbox if we are the only participant; otherwise, the whole
149
         // UI looks too unpopulated the LargeVideo visible.
150
         // UI looks too unpopulated the LargeVideo visible.
150
-        const { _participantCount, _setToolboxVisible } = this.props;
151
-
152
-        _participantCount === 1 && _setToolboxVisible(true);
151
+        this.props._participantCount === 1 && this._setToolboxVisible(true);
153
     }
152
     }
154
 
153
 
155
     /**
154
     /**
163
         } = prevProps;
162
         } = prevProps;
164
         const {
163
         const {
165
             _participantCount: newParticipantCount,
164
             _participantCount: newParticipantCount,
166
-            _setToolboxVisible,
167
             _toolboxVisible
165
             _toolboxVisible
168
         } = this.props;
166
         } = this.props;
169
 
167
 
170
         if (oldParticipantCount === 1
168
         if (oldParticipantCount === 1
171
                 && newParticipantCount > 1
169
                 && newParticipantCount > 1
172
                 && _toolboxVisible) {
170
                 && _toolboxVisible) {
173
-            _setToolboxVisible(false);
171
+            this._setToolboxVisible(false);
174
         } else if (oldParticipantCount > 1
172
         } else if (oldParticipantCount > 1
175
                 && newParticipantCount === 1
173
                 && newParticipantCount === 1
176
                 && !_toolboxVisible) {
174
                 && !_toolboxVisible) {
177
-            _setToolboxVisible(true);
175
+            this._setToolboxVisible(true);
178
         }
176
         }
179
     }
177
     }
180
 
178
 
188
      */
186
      */
189
     componentWillUnmount() {
187
     componentWillUnmount() {
190
         // Tear handling any hardware button presses for back navigation down.
188
         // Tear handling any hardware button presses for back navigation down.
191
-        BackHandler.removeEventListener(
192
-            'hardwareBackPress',
193
-            this.props._onHardwareBackPress);
189
+        BackHandler.removeEventListener('hardwareBackPress', this._onHardwareBackPress);
194
     }
190
     }
195
 
191
 
196
     /**
192
     /**
299
             return;
295
             return;
300
         }
296
         }
301
 
297
 
302
-        const toolboxVisible = !this.props._toolboxVisible;
298
+        this._setToolboxVisible(!this.props._toolboxVisible);
299
+    }
300
+
301
+    _onHardwareBackPress: () => boolean;
302
+
303
+    /**
304
+     * Handles a hardware button press for back navigation. Enters Picture-in-Picture mode
305
+     * (if supported) or leaves the associated {@code Conference} otherwise.
306
+     *
307
+     * @returns {boolean} Exiting the app is undesired, so {@code true} is always returned.
308
+     */
309
+    _onHardwareBackPress() {
310
+        let p;
311
+
312
+        if (this.props._pictureInPictureEnabled) {
313
+            const { PictureInPicture } = NativeModules;
314
+
315
+            p = PictureInPicture.enterPictureInPicture();
316
+        } else {
317
+            p = Promise.reject(new Error('PiP not enabled'));
318
+        }
319
+
320
+        p.catch(() => {
321
+            this.props.dispatch(appNavigate(undefined));
322
+        });
303
 
323
 
304
-        this.props._setToolboxVisible(toolboxVisible);
324
+        return true;
305
     }
325
     }
306
 
326
 
307
     /**
327
     /**
349
             }
369
             }
350
         );
370
         );
351
     }
371
     }
352
-}
353
 
372
 
354
-/**
355
- * Maps dispatching of some action to React component props.
356
- *
357
- * @param {Function} dispatch - Redux action dispatcher.
358
- * @private
359
- * @returns {{
360
- *     _onHardwareBackPress: Function,
361
- *     _setToolboxVisible: Function
362
- * }}
363
- */
364
-function _mapDispatchToProps(dispatch) {
365
-    return {
366
-        /**
367
-         * Handles a hardware button press for back navigation. Leaves the
368
-         * associated {@code Conference}.
369
-         *
370
-         * @returns {boolean} As the associated conference is unconditionally
371
-         * left and exiting the app while it renders a {@code Conference} is
372
-         * undesired, {@code true} is always returned.
373
-         */
374
-        _onHardwareBackPress() {
375
-            dispatch(appNavigate(undefined));
376
-
377
-            return true;
378
-        },
373
+    _setToolboxVisible: (boolean) => void;
379
 
374
 
380
-        /**
381
-         * Dispatches an action changing the visibility of the {@link Toolbox}.
382
-         *
383
-         * @private
384
-         * @param {boolean} visible - Pass {@code true} to show the
385
-         * {@code Toolbox} or {@code false} to hide it.
386
-         * @returns {void}
387
-         */
388
-        _setToolboxVisible(visible) {
389
-            dispatch(setToolboxVisible(visible));
390
-        }
391
-    };
375
+    /**
376
+     * Dispatches an action changing the visibility of the {@link Toolbox}.
377
+     *
378
+     * @private
379
+     * @param {boolean} visible - Pass {@code true} to show the
380
+     * {@code Toolbox} or {@code false} to hide it.
381
+     * @returns {void}
382
+     */
383
+    _setToolboxVisible(visible) {
384
+        this.props.dispatch(setToolboxVisible(visible));
385
+    }
392
 }
386
 }
393
 
387
 
394
 /**
388
 /**
452
          */
446
          */
453
         _participantCount: getParticipantCount(state),
447
         _participantCount: getParticipantCount(state),
454
 
448
 
449
+        /**
450
+         * Whether Picture-in-Picture is enabled.
451
+         *
452
+         * @private
453
+         * @type {boolean}
454
+         */
455
+        _pictureInPictureEnabled: getAppProp(state, 'pictureInPictureEnabled'),
456
+
455
         /**
457
         /**
456
          * The indicator which determines whether the UI is reduced (to
458
          * The indicator which determines whether the UI is reduced (to
457
          * accommodate smaller display areas).
459
          * accommodate smaller display areas).
479
     };
481
     };
480
 }
482
 }
481
 
483
 
482
-export default reactReduxConnect(_mapStateToProps, _mapDispatchToProps)(
483
-    makeAspectRatioAware(Conference));
484
+export default connect(_mapStateToProps)(makeAspectRatioAware(Conference));

Загрузка…
Отмена
Сохранить