mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 03:12:29 +00:00
RN refactor immersive mode (#13583)
* fix(android): refactor immersive mode
This commit is contained in:
committed by
GitHub
parent
d335438f12
commit
ec9fcdf1cb
@@ -82,7 +82,7 @@ dependencies {
|
||||
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
// Sync with react-native-google-signin
|
||||
implementation 'com.google.android.gms:play-services-auth:19.0.2'
|
||||
implementation 'com.google.android.gms:play-services-auth:19.2.0'
|
||||
|
||||
// Firebase
|
||||
// - Crashlytics
|
||||
|
||||
@@ -74,7 +74,7 @@ dependencies {
|
||||
}
|
||||
implementation project(':react-native-gesture-handler')
|
||||
implementation project(':react-native-get-random-values')
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-immersive-mode')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-orientation-locker')
|
||||
implementation project(':react-native-pager-view')
|
||||
|
||||
@@ -26,7 +26,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.rnimmersive.RNImmersiveModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
@@ -229,22 +228,4 @@ public class JitsiMeetView extends FrameLayout {
|
||||
dispose();
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the window containing this view gains or loses focus.
|
||||
*
|
||||
* @param hasFocus If the window of this view now has focus, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
|
||||
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
|
||||
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
|
||||
|
||||
if (hasFocus && immersive != null) {
|
||||
immersive.emitImmersiveStateChangeEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class ReactInstanceManagerHolder {
|
||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||
new com.swmansion.gesturehandler.RNGestureHandlerPackage(),
|
||||
new org.linusu.RNGetRandomValuesPackage(),
|
||||
new com.rnimmersive.RNImmersivePackage(),
|
||||
new com.rnimmersivemode.RNImmersiveModePackage(),
|
||||
new com.swmansion.rnscreens.RNScreensPackage(),
|
||||
new com.zmxv.RNSound.RNSoundPackage(),
|
||||
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),
|
||||
|
||||
@@ -27,8 +27,8 @@ include ':react-native-giphy'
|
||||
project(':react-native-giphy').projectDir = new File(rootProject.projectDir, '../node_modules/@giphy/react-native-sdk/android')
|
||||
include ':react-native-google-signin'
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-google-signin/google-signin/android')
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-immersive-mode'
|
||||
project(':react-native-immersive-mode').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive-mode/android')
|
||||
include ':react-native-keep-awake'
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
|
||||
include ':react-native-orientation-locker'
|
||||
|
||||
20
package-lock.json
generated
20
package-lock.json
generated
@@ -83,7 +83,7 @@
|
||||
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
|
||||
"react-native-gesture-handler": "2.9.0",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-immersive-mode": "2.0.1",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "1.5.0",
|
||||
"react-native-pager-view": "5.4.9",
|
||||
@@ -15812,12 +15812,12 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.7.tgz",
|
||||
"integrity": "sha512-+4JpbIx42zGTONhBTIXSyfyHICHC29VTvhkkoUOJAh/XHPEixpuBduYgf6Y4y9wsN1ARlQhBBoptTvXvAFQf5g=="
|
||||
},
|
||||
"node_modules/react-native-immersive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive/-/react-native-immersive-2.0.0.tgz",
|
||||
"integrity": "sha512-9TL05nTHN/x9sN1wbUlBoGyzH4NCuZ/7WEEUp5CvOoKuUABvdYosov0O0SAMbm/5J913RRoy98VB6tGNi9lRSw==",
|
||||
"node_modules/react-native-immersive-mode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive-mode/-/react-native-immersive-mode-2.0.1.tgz",
|
||||
"integrity": "sha512-2wlL7VIHl4rr4gwgnUp9K1UvsN7J5VCGqoAvBWQXvB4xn7XaoDEl6z9vqaqOiEdC6aAh2d/7zqcJz+dfcR2ELw==",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.47.0"
|
||||
"react-native": ">=0.60.5"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-keep-awake": {
|
||||
@@ -31587,10 +31587,10 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.7.tgz",
|
||||
"integrity": "sha512-+4JpbIx42zGTONhBTIXSyfyHICHC29VTvhkkoUOJAh/XHPEixpuBduYgf6Y4y9wsN1ARlQhBBoptTvXvAFQf5g=="
|
||||
},
|
||||
"react-native-immersive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive/-/react-native-immersive-2.0.0.tgz",
|
||||
"integrity": "sha512-9TL05nTHN/x9sN1wbUlBoGyzH4NCuZ/7WEEUp5CvOoKuUABvdYosov0O0SAMbm/5J913RRoy98VB6tGNi9lRSw=="
|
||||
"react-native-immersive-mode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive-mode/-/react-native-immersive-mode-2.0.1.tgz",
|
||||
"integrity": "sha512-2wlL7VIHl4rr4gwgnUp9K1UvsN7J5VCGqoAvBWQXvB4xn7XaoDEl6z9vqaqOiEdC6aAh2d/7zqcJz+dfcR2ELw=="
|
||||
},
|
||||
"react-native-keep-awake": {
|
||||
"version": "4.0.0",
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
|
||||
"react-native-gesture-handler": "2.9.0",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-immersive-mode": "2.0.1",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "1.5.0",
|
||||
"react-native-pager-view": "5.4.9",
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
diff --git a/node_modules/react-native-immersive/index.js b/node_modules/react-native-immersive/index.js
|
||||
index 55dab57..110260b 100644
|
||||
--- a/node_modules/react-native-immersive/index.js
|
||||
+++ b/node_modules/react-native-immersive/index.js
|
||||
@@ -18,7 +18,13 @@ const Immersive = Platform.OS === 'android' ? {
|
||||
isListenerEnabled = true
|
||||
RNImmersive.addImmersiveListener()
|
||||
},
|
||||
- removeImmersiveListener: (listener) => DeviceEventEmitter.removeListener('@@IMMERSIVE_STATE_CHANGED', listener)
|
||||
+ removeImmersiveListener: (listener) => {
|
||||
+ const immersiveListener = DeviceEventEmitter.addListener('@@IMMERSIVE_STATE_CHANGED', listener);
|
||||
+
|
||||
+ return () => {
|
||||
+ immersiveListener.remove();
|
||||
+ }
|
||||
+ }
|
||||
} : {
|
||||
on: unSupportedError,
|
||||
off: unSupportedError,
|
||||
@@ -1,5 +1,4 @@
|
||||
import { AppState } from 'react-native';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../../base/app/actionTypes';
|
||||
@@ -23,12 +22,12 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
case APP_WILL_MOUNT: {
|
||||
const { dispatch } = store;
|
||||
|
||||
_setAppStateListener(store, next, action, _onAppStateChange.bind(undefined, dispatch));
|
||||
_setAppStateListener(store, _onAppStateChange.bind(undefined, dispatch));
|
||||
break;
|
||||
}
|
||||
|
||||
case APP_WILL_UNMOUNT:
|
||||
_setAppStateListener(store, next, action, undefined);
|
||||
_setAppStateListener(store, undefined);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -55,20 +54,14 @@ function _onAppStateChange(dispatch: IStore['dispatch'], appState: string) {
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified action is being
|
||||
* dispatched.
|
||||
* @param {Dispatch} next - The redux dispatch function to dispatch the
|
||||
* specified action to the specified store.
|
||||
* @param {Action} action - The redux action {@code _SET_IMMERSIVE_LISTENER}
|
||||
* which is being dispatched in the specified store.
|
||||
* @param {any} listener - Listener for app state status.
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _setAppStateListener({ dispatch, getState }: IStore, next: Function, action: AnyAction, listener: any) {
|
||||
function _setAppStateListener({ dispatch, getState }: IStore, listener: any) {
|
||||
const { subscription } = getState()['features/background'];
|
||||
const result = next(action);
|
||||
|
||||
subscription?.remove();
|
||||
listener && dispatch(_setAppStateSubscription(AppState.addEventListener('change', listener)));
|
||||
|
||||
return result;
|
||||
dispatch(_setAppStateSubscription(listener ? AppState.addEventListener('change', listener) : undefined));
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* The type of (redux) action to set the react-native-immersive's change event
|
||||
* listener.
|
||||
* subscription.
|
||||
*
|
||||
* {
|
||||
* type: _SET_IMMERSIVE_LISTENER,
|
||||
* listener: Function
|
||||
* type: _SET_IMMERSIVE_SUBSCRIPTION,
|
||||
* subscription: Function
|
||||
* }
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
export const _SET_IMMERSIVE_LISTENER = '_SET_IMMERSIVE_LISTENER';
|
||||
export const _SET_IMMERSIVE_SUBSCRIPTION = '_SET_IMMERSIVE_SUBSCRIPTION';
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { _SET_IMMERSIVE_LISTENER } from './actionTypes';
|
||||
import { NativeEventSubscription } from 'react-native';
|
||||
|
||||
import { _SET_IMMERSIVE_SUBSCRIPTION } from './actionTypes';
|
||||
|
||||
/**
|
||||
* Sets the change event listener to be used with react-native-immersive's API.
|
||||
*
|
||||
* @param {Function} [listener] - The function to be used with
|
||||
* @param {Function} subscription - The function to be used with
|
||||
* react-native-immersive's API as the change event listener.
|
||||
* @protected
|
||||
* @returns {{
|
||||
* type: _SET_IMMERSIVE_LISTENER,
|
||||
* listener: ?Function
|
||||
* type: _SET_IMMERSIVE_SUBSCRIPTION,
|
||||
* subscription: ?NativeEventSubscription
|
||||
* }}
|
||||
*/
|
||||
export function _setImmersiveListener(listener?: Function) {
|
||||
export function _setImmersiveSubscription(subscription?: NativeEventSubscription) {
|
||||
return {
|
||||
type: _SET_IMMERSIVE_LISTENER,
|
||||
listener
|
||||
type: _SET_IMMERSIVE_SUBSCRIPTION,
|
||||
subscription
|
||||
};
|
||||
}
|
||||
|
||||
3
react/features/mobile/full-screen/logger.ts
Normal file
3
react/features/mobile/full-screen/logger.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { getLogger } from '../../base/logging/functions';
|
||||
|
||||
export default getLogger('features/full-screen');
|
||||
@@ -1,6 +1,4 @@
|
||||
// @ts-expect-error
|
||||
import { Immersive } from 'react-native-immersive';
|
||||
import { AnyAction } from 'redux';
|
||||
import ImmersiveMode from 'react-native-immersive-mode';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../../base/app/actionTypes';
|
||||
@@ -8,12 +6,18 @@ import { getCurrentConference } from '../../base/conference/functions';
|
||||
import { isAnyDialogOpen } from '../../base/dialog/functions';
|
||||
import { FULLSCREEN_ENABLED } from '../../base/flags/constants';
|
||||
import { getFeatureFlag } from '../../base/flags/functions';
|
||||
import Platform from '../../base/react/Platform.native';
|
||||
import MiddlewareRegistry from '../../base/redux/MiddlewareRegistry';
|
||||
import StateListenerRegistry from '../../base/redux/StateListenerRegistry';
|
||||
|
||||
import { _SET_IMMERSIVE_LISTENER } from './actionTypes';
|
||||
import { _setImmersiveListener as _setImmersiveListenerA } from './actions';
|
||||
import { _setImmersiveSubscription } from './actions';
|
||||
import logger from './logger';
|
||||
|
||||
type BarVisibilityType = {
|
||||
navigationBottomBar: boolean;
|
||||
statusBar: boolean;
|
||||
};
|
||||
|
||||
type ImmersiveListener = (visibility: BarVisibilityType) => void;
|
||||
|
||||
/**
|
||||
* Middleware that captures conference actions and activates or deactivates the
|
||||
@@ -28,20 +32,14 @@ import { _setImmersiveListener as _setImmersiveListenerA } from './actions';
|
||||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case _SET_IMMERSIVE_LISTENER:
|
||||
return _setImmersiveListenerF(store, next, action);
|
||||
|
||||
case APP_WILL_MOUNT: {
|
||||
const result = next(action);
|
||||
_setImmersiveListener(store, _onImmersiveChange.bind(undefined, store));
|
||||
|
||||
store.dispatch(
|
||||
_setImmersiveListenerA(_onImmersiveChange.bind(undefined, store)));
|
||||
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
|
||||
case APP_WILL_UNMOUNT:
|
||||
store.dispatch(_setImmersiveListenerA(undefined));
|
||||
_setImmersiveListener(store, undefined);
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -95,11 +93,9 @@ function _onImmersiveChange({ getState }: IStore) {
|
||||
* @returns {void}
|
||||
*/
|
||||
function _setFullScreen(fullScreen: boolean) {
|
||||
// XXX The React Native module Immersive is only implemented on Android and
|
||||
// throws on other platforms.
|
||||
if (Platform.OS === 'android') {
|
||||
fullScreen ? Immersive.on() : Immersive.off();
|
||||
}
|
||||
logger.info(`Setting full-screen mode: ${fullScreen}`);
|
||||
ImmersiveMode.fullLayout(fullScreen);
|
||||
ImmersiveMode.setBarMode(fullScreen ? 'Full' : 'Normal');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,29 +105,14 @@ function _setFullScreen(fullScreen: boolean) {
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified action is being
|
||||
* dispatched.
|
||||
* @param {Dispatch} next - The redux dispatch function to dispatch the
|
||||
* specified action to the specified store.
|
||||
* @param {Action} action - The redux action {@code _SET_IMMERSIVE_LISTENER}
|
||||
* which is being dispatched in the specified store.
|
||||
* @param {Function} listener - Listener for immersive state.
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _setImmersiveListenerF({ getState }: IStore, next: Function, action: AnyAction) {
|
||||
// XXX The React Native module Immersive is only implemented on Android and
|
||||
// throws on other platforms.
|
||||
if (Platform.OS === 'android') {
|
||||
// Remove the old Immersive listener and add the new one.
|
||||
const { listener: oldListener } = getState()['features/full-screen'];
|
||||
const result = next(action);
|
||||
const { listener: newListener } = getState()['features/full-screen'];
|
||||
function _setImmersiveListener({ dispatch, getState }: IStore, listener?: ImmersiveListener) {
|
||||
const { subscription } = getState()['features/full-screen'];
|
||||
|
||||
if (oldListener !== newListener) {
|
||||
oldListener && Immersive.removeImmersiveListener(oldListener);
|
||||
newListener && Immersive.addImmersiveListener(newListener);
|
||||
}
|
||||
subscription?.remove();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return next(action);
|
||||
dispatch(_setImmersiveSubscription(listener ? ImmersiveMode.addEventListener(listener) : undefined));
|
||||
}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { NativeEventSubscription } from 'react-native';
|
||||
|
||||
import ReducerRegistry from '../../base/redux/ReducerRegistry';
|
||||
|
||||
import { _SET_IMMERSIVE_LISTENER } from './actionTypes';
|
||||
import { _SET_IMMERSIVE_SUBSCRIPTION } from './actionTypes';
|
||||
|
||||
export interface IFullScreenState {
|
||||
listener?: Function;
|
||||
subscription?: NativeEventSubscription;
|
||||
}
|
||||
|
||||
ReducerRegistry.register<IFullScreenState>('features/full-screen', (state = {}, action): IFullScreenState => {
|
||||
switch (action.type) {
|
||||
case _SET_IMMERSIVE_LISTENER:
|
||||
case _SET_IMMERSIVE_SUBSCRIPTION:
|
||||
return {
|
||||
...state,
|
||||
listener: action.listener
|
||||
subscription: action.subscription
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user