feat(RN-filmtrip) stop reordering small meetings

This commit is contained in:
Hristo Terezov 2022-05-06 05:18:57 -05:00 committed by GitHub
parent 61abf0d882
commit adef5095da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 345 additions and 154 deletions

View File

@ -1,6 +1,7 @@
// @flow
import React from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import SplashScreen from 'react-native-splash-screen';
import { DialogContainer } from '../../base/dialog';
@ -8,7 +9,7 @@ import { updateFlags } from '../../base/flags/actions';
import { CALL_INTEGRATION_ENABLED, SERVER_URL_CHANGE_ENABLED } from '../../base/flags/constants';
import { getFeatureFlag } from '../../base/flags/functions';
import { Platform } from '../../base/react';
import { DimensionsDetector, clientResized } from '../../base/responsive-ui';
import { DimensionsDetector, clientResized, setSafeAreaInsets } from '../../base/responsive-ui';
import { updateSettings } from '../../base/settings';
import { _getRouteToRender } from '../getRouteToRender.native';
import logger from '../logger';
@ -76,6 +77,7 @@ export class App extends AbstractApp {
// Bind event handler so it is only bound once per instance.
this._onDimensionsChanged = this._onDimensionsChanged.bind(this);
this._onSafeAreaInsetsChanged = this._onSafeAreaInsetsChanged.bind(this);
}
/**
@ -138,10 +140,13 @@ export class App extends AbstractApp {
*/
_createMainElement(component, props) {
return (
<DimensionsDetector
onDimensionsChanged = { this._onDimensionsChanged }>
{ super._createMainElement(component, props) }
</DimensionsDetector>
<SafeAreaProvider>
<DimensionsDetector
onDimensionsChanged = { this._onDimensionsChanged }
onSafeAreaInsetsChanged = { this._onSafeAreaInsetsChanged }>
{ super._createMainElement(component, props) }
</DimensionsDetector>
</SafeAreaProvider>
);
}
@ -198,6 +203,23 @@ export class App extends AbstractApp {
dispatch(clientResized(width, height));
}
/**
* Updates the safe are insets values.
*
* @param {Object} insets - The insets.
* @param {number} insets.top - The top inset.
* @param {number} insets.right - The right inset.
* @param {number} insets.bottom - The bottom inset.
* @param {number} insets.left - The left inset.
* @private
* @returns {void}
*/
_onSafeAreaInsetsChanged(insets) {
const { dispatch } = this.state.store;
dispatch(setSafeAreaInsets(insets));
}
/**
* Renders the platform specific dialog container.
*

View File

@ -7,6 +7,16 @@
*/
export const CLIENT_RESIZED = 'CLIENT_RESIZED';
/**
* The type of (redux) action which indicates that the insets from the SafeAreaProvider have changed.
*
* {
* type: SAFE_AREA_INSETS_CHANGED,
* insets: Object
* }
*/
export const SAFE_AREA_INSETS_CHANGED = 'SAFE_AREA_INSETS_CHANGED';
/**
* The type of (redux) action which sets the aspect ratio of the app's user
* interface.

View File

@ -7,7 +7,13 @@ import { CHAT_SIZE } from '../../chat/constants';
import { getParticipantsPaneOpen } from '../../participants-pane/functions';
import theme from '../components/themes/participantsPaneTheme.json';
import { CLIENT_RESIZED, SET_ASPECT_RATIO, SET_CONTEXT_MENU_OPEN, SET_REDUCED_UI } from './actionTypes';
import {
CLIENT_RESIZED,
SAFE_AREA_INSETS_CHANGED,
SET_ASPECT_RATIO,
SET_CONTEXT_MENU_OPEN,
SET_REDUCED_UI
} from './actionTypes';
import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from './constants';
/**
@ -123,3 +129,19 @@ export function setParticipantContextMenuOpen(isOpen: boolean) {
isOpen
};
}
/**
* Sets the insets from the SafeAreaProvider.
*
* @param {Object} insets - The new insets to be set.
* @returns {{
* type: SAFE_AREA_INSETS_CHANGED,
* insets: Object
* }}
*/
export function setSafeAreaInsets(insets) {
return {
type: SAFE_AREA_INSETS_CHANGED,
insets
};
}

View File

@ -1,8 +1,8 @@
// @flow
import React, { PureComponent } from 'react';
import React, { useCallback, useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
type Props = {
@ -11,6 +11,11 @@ type Props = {
*/
onDimensionsChanged: Function,
/**
* The safe are insets handler.
*/
onSafeAreaInsetsChanged: Function,
/**
* Any nested components.
*/
@ -20,21 +25,23 @@ type Props = {
/**
* A {@link View} which captures the 'onLayout' event and calls a prop with the
* component size.
*
* @param {Props} props - The read-only properties with which the new
* instance is to be initialized.
* @returns {Component} - Renders the root view and it's children.
*/
export default class DimensionsDetector extends PureComponent<Props> {
/**
* Initializes a new DimensionsDetector instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Object) {
super(props);
export default function DimensionsDetector(props: Props) {
const { top = 0, right = 0, bottom = 0, left = 0 } = useSafeAreaInsets();
const { children, onDimensionsChanged, onSafeAreaInsetsChanged } = props;
this._onLayout = this._onLayout.bind(this);
}
_onLayout: (Object) => void;
useEffect(() => {
onSafeAreaInsetsChanged && onSafeAreaInsetsChanged({
top,
right,
bottom,
left
});
}, [ onSafeAreaInsetsChanged, top, right, bottom, left ]);
/**
* Handles the "on layout" View's event and calls the onDimensionsChanged
@ -45,24 +52,15 @@ export default class DimensionsDetector extends PureComponent<Props> {
* @private
* @returns {void}
*/
_onLayout({ nativeEvent: { layout: { height, width } } }) {
const { onDimensionsChanged } = this.props;
const onLayout = useCallback(({ nativeEvent: { layout: { height, width } } }) => {
onDimensionsChanged && onDimensionsChanged(width, height);
}
}, [ onDimensionsChanged ]);
/**
* Renders the root view and it's children.
*
* @returns {Component}
*/
render() {
return (
<View
onLayout = { this._onLayout }
style = { StyleSheet.absoluteFillObject } >
{ this.props.children }
</View>
);
}
return (
<View
onLayout = { onLayout }
style = { StyleSheet.absoluteFillObject } >
{ children }
</View>
);
}

View File

@ -2,7 +2,13 @@
import { ReducerRegistry, set } from '../redux';
import { CLIENT_RESIZED, SET_ASPECT_RATIO, SET_CONTEXT_MENU_OPEN, SET_REDUCED_UI } from './actionTypes';
import {
CLIENT_RESIZED,
SAFE_AREA_INSETS_CHANGED,
SET_ASPECT_RATIO,
SET_CONTEXT_MENU_OPEN,
SET_REDUCED_UI
} from './actionTypes';
import { ASPECT_RATIO_NARROW } from './constants';
const {
@ -30,6 +36,13 @@ ReducerRegistry.register('features/base/responsive-ui', (state = DEFAULT_STATE,
clientHeight: action.clientHeight
};
}
case SAFE_AREA_INSETS_CHANGED:
return {
...state,
safeAreaInsets: action.insets
};
case SET_ASPECT_RATIO:
return set(state, 'aspectRatio', action.aspectRatio);

View File

@ -1,10 +1,12 @@
// @flow
import { getParticipantCountWithFake } from '../base/participants';
import conferenceStyles from '../conference/components/native/styles';
import { SET_TILE_VIEW_DIMENSIONS } from './actionTypes';
import { styles } from './components';
import { SQUARE_TILE_ASPECT_RATIO, TILE_MARGIN } from './constants';
import { getColumnCount } from './functions.native';
import { getColumnCount } from './functions';
import { getTileViewParticipantCount } from './functions.native';
export * from './actions.any';
@ -18,16 +20,19 @@ export * from './actions.any';
export function setTileViewDimensions() {
return (dispatch: Function, getState: Function) => {
const state = getState();
const participantCount = getParticipantCountWithFake(state);
const { clientHeight: height, clientWidth: width } = state['features/base/responsive-ui'];
const participantCount = getTileViewParticipantCount(state);
const { clientHeight: height, clientWidth: width, safeAreaInsets = {} } = state['features/base/responsive-ui'];
const { left = 0, right = 0, top = 0, bottom = 0 } = safeAreaInsets;
const columns = getColumnCount(state);
const heightToUse = height - (TILE_MARGIN * 2);
const widthToUse = width - (TILE_MARGIN * 2);
const rows = Math.ceil(participantCount / columns);
const conferenceBorder = conferenceStyles.conference.borderWidth || 0;
const heightToUse = height - top - (2 * conferenceBorder);
const widthToUse = width - (TILE_MARGIN * 2) - left - right - (2 * conferenceBorder);
let tileWidth;
// If there is going to be at least two rows, ensure that at least two
// rows display fully on screen.
if (participantCount / columns > 1) {
if (rows / columns > 1) {
tileWidth = Math.min(widthToUse / columns, heightToUse / 2);
} else {
tileWidth = Math.min(widthToUse / columns, heightToUse);
@ -37,6 +42,9 @@ export function setTileViewDimensions() {
tileWidth = Math.floor(tileWidth);
// Adding safeAreaInsets.bottom to the total height of all thumbnails because we add it as a padding to the
// thumbnails container.
const hasScroll = heightToUse < ((tileHeight + (2 * styles.thumbnail.margin)) * rows) + bottom;
dispatch({
type: SET_TILE_VIEW_DIMENSIONS,
@ -45,7 +53,8 @@ export function setTileViewDimensions() {
thumbnailSize: {
height: tileHeight,
width: tileWidth
}
},
hasScroll
}
});
};

View File

@ -2,7 +2,7 @@
import React, { PureComponent } from 'react';
import { FlatList } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { SafeAreaView, withSafeAreaInsets } from 'react-native-safe-area-context';
import { getLocalParticipant } from '../../../base/participants';
import { Platform } from '../../../base/react';
@ -11,7 +11,12 @@ import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants';
import { shouldHideSelfView } from '../../../base/settings/functions.any';
import { isToolboxVisible } from '../../../toolbox/functions';
import { setVisibleRemoteParticipants } from '../../actions';
import { isFilmstripVisible, shouldRemoteVideosBeVisible } from '../../functions';
import {
getFilmstripDimensions,
isFilmstripVisible,
shouldDisplayLocalThumbnailSeparately,
shouldRemoteVideosBeVisible
} from '../../functions';
import LocalThumbnail from './LocalThumbnail';
import Thumbnail from './Thumbnail';
@ -60,6 +65,11 @@ type Props = {
* Invoked to trigger state changes in Redux.
*/
dispatch: Function,
/**
* Object containing the safe area insets.
*/
insets: Object,
};
/**
@ -105,7 +115,7 @@ class Filmstrip extends PureComponent<Props> {
// indicators such as moderator, audio and video muted, etc. For now we
// do not have much of a choice but to continue rendering LocalThumbnail
// as any other remote Thumbnail on Android.
this._separateLocalThumbnail = Platform.OS !== 'android';
this._separateLocalThumbnail = shouldDisplayLocalThumbnailSeparately();
this._viewabilityConfig = {
itemVisiblePercentThreshold: 30,
@ -136,20 +146,23 @@ class Filmstrip extends PureComponent<Props> {
* @returns {Object} - The width and the height.
*/
_getDimensions() {
const { _aspectRatio, _clientWidth, _clientHeight } = this.props;
const { height, width, margin } = styles.thumbnail;
const {
_aspectRatio,
_clientWidth,
_clientHeight,
_disableSelfView,
_localParticipantId,
insets
} = this.props;
const localParticipantVisible = Boolean(_localParticipantId) && !_disableSelfView;
if (_aspectRatio === ASPECT_RATIO_NARROW) {
return {
height,
width: this._separateLocalThumbnail ? _clientWidth - width - (margin * 2) : _clientWidth
};
}
return {
height: this._separateLocalThumbnail ? _clientHeight - height - (margin * 2) : _clientHeight,
width
};
return getFilmstripDimensions({
aspectRatio: _aspectRatio,
clientHeight: _clientHeight,
clientWidth: _clientWidth,
insets,
localParticipantVisible
});
}
_getItemLayout: (?Array<string>, number) => {length: number, offset: number, index: number};
@ -312,7 +325,7 @@ function _mapStateToProps(state) {
const responsiveUI = state['features/base/responsive-ui'];
return {
_aspectRatio: state['features/base/responsive-ui'].aspectRatio,
_aspectRatio: responsiveUI.aspectRatio,
_clientHeight: responsiveUI.clientHeight,
_clientWidth: responsiveUI.clientWidth,
_disableSelfView: disableSelfView,
@ -323,4 +336,4 @@ function _mapStateToProps(state) {
};
}
export default connect(_mapStateToProps)(Filmstrip);
export default withSafeAreaInsets(connect(_mapStateToProps)(Filmstrip));

View File

@ -218,7 +218,7 @@ export const SHOW_TOOLBAR_CONTEXT_MENU_AFTER = 600;
/**
* The margin for each side of the tile view. Taken away from the available
* height and width for the tile container to display in.
* width for the tile container to display in.
*
* NOTE: Mobile specific.
*

View File

@ -4,7 +4,7 @@ import { getSourceNameSignalingFeatureFlag } from '../base/config';
import { getVirtualScreenshareParticipantOwnerId } from '../base/participants';
import { setRemoteParticipants } from './actions';
import { isReorderingEnabled } from './functions';
import { isFilmstripScrollVisible } from './functions';
/**
* Computes the reorderd list of the remote participants.
@ -118,3 +118,17 @@ export function updateRemoteParticipantsOnLeave(store: Object, participantId: ?s
reorderedParticipants.delete(participantId)
&& store.dispatch(setRemoteParticipants(Array.from(reorderedParticipants)));
}
/**
* Returns true if thumbnail reordering is enabled and false otherwise.
* Note: The function will return false if all participants are displayed on the screen.
*
* @param {Object} state - The redux state.
* @returns {boolean} - True if thumbnail reordering is enabled and false otherwise.
*/
export function isReorderingEnabled(state) {
const { testing = {} } = state['features/base/config'];
const enableThumbnailReordering = testing.enableThumbnailReordering ?? true;
return enableThumbnailReordering && isFilmstripScrollVisible(state);
}

View File

@ -1,9 +1,19 @@
// @flow
import { getFeatureFlag, FILMSTRIP_ENABLED } from '../base/flags';
import { getParticipantCountWithFake, getPinnedParticipant } from '../base/participants';
import {
getLocalParticipant,
getParticipantCountWithFake,
getPinnedParticipant
} from '../base/participants';
import { Platform } from '../base/react';
import { toState } from '../base/redux';
import { ASPECT_RATIO_NARROW } from '../base/responsive-ui/constants';
import { shouldHideSelfView } from '../base/settings/functions.any';
import conferenceStyles from '../conference/components/native/styles';
import { shouldDisplayTileView } from '../video-layout';
import { styles } from './components';
export * from './functions.any';
@ -61,6 +71,22 @@ export function shouldRemoteVideosBeVisible(state: Object) {
|| disable1On1Mode);
}
/**
* Returns the number of participants displayed in tile view.
*
* @param {Object | Function} stateful - The Object or Function that can be
* resolved to a Redux state object with the toState function.
* @returns {number} - The number of participants displayed in tile view.
*/
export function getTileViewParticipantCount(stateful: Object | Function) {
const state = toState(stateful);
const disableSelfView = shouldHideSelfView(state);
const localParticipant = getLocalParticipant(state);
const participantCount = getParticipantCountWithFake(state) - (disableSelfView && localParticipant ? 1 : 0);
return participantCount;
}
/**
* Returns how many columns should be displayed for tile view.
*
@ -71,7 +97,7 @@ export function shouldRemoteVideosBeVisible(state: Object) {
*/
export function getColumnCount(stateful: Object | Function) {
const state = toState(stateful);
const participantCount = getParticipantCountWithFake(state);
const participantCount = getTileViewParticipantCount(state);
const { aspectRatio } = state['features/base/responsive-ui'];
// For narrow view, tiles should stack on top of each other for a lonely
@ -90,16 +116,38 @@ export function getColumnCount(stateful: Object | Function) {
}
/**
* Returns true if thumbnail reordering is enabled and false otherwise.
* Returns true if the filmstrip has a scroll and false otherwise.
*
* @param {Object} state - The redux state.
* @returns {boolean} - True if thumbnail reordering is enabled and false otherwise.
* @returns {boolean} - True if the scroll is displayed and false otherwise.
*/
export function isReorderingEnabled(state) {
const { testing = {} } = state['features/base/config'];
const enableThumbnailReordering = testing.enableThumbnailReordering ?? true;
export function isFilmstripScrollVisible(state) {
if (shouldDisplayTileView(state)) {
return state['features/filmstrip']?.tileViewDimensions?.hasScroll;
}
return enableThumbnailReordering;
const { aspectRatio, clientWidth, clientHeight, safeAreaInsets = {} } = state['features/base/responsive-ui'];
const isNarrowAspectRatio = aspectRatio === ASPECT_RATIO_NARROW;
const disableSelfView = shouldHideSelfView(state);
const localParticipant = Boolean(getLocalParticipant(state));
const localParticipantVisible = localParticipant && !disableSelfView;
const participantCount
= getParticipantCountWithFake(state)
- (localParticipant && (shouldDisplayLocalThumbnailSeparately() || disableSelfView) ? 1 : 0);
const { height: thumbnailHeight, width: thumbnailWidth, margin } = styles.thumbnail;
const { height, width } = getFilmstripDimensions({
aspectRatio,
clientWidth,
clientHeight,
insets: safeAreaInsets,
localParticipantVisible
});
if (isNarrowAspectRatio) {
return width < (thumbnailWidth + (2 * margin)) * participantCount;
}
return height < (thumbnailHeight + (2 * margin)) * participantCount;
}
/**
@ -120,3 +168,68 @@ export function isStageFilmstripAvailable() {
export function isStageFilmstripEnabled() {
return false;
}
/**
* Calculates the width and height of the filmstrip based on the screen size and aspect ratio.
*
* @param {Object} options - The screen aspect ratio, width, height and safe are insets.
* @returns {Object} - The width and the height.
*/
export function getFilmstripDimensions({
aspectRatio,
clientWidth,
clientHeight,
insets = {},
localParticipantVisible = true
}) {
const { height, width, margin } = styles.thumbnail;
const conferenceBorder = conferenceStyles.conference.borderWidth || 0;
const { left = 0, right = 0, top = 0, bottom = 0 } = insets;
if (aspectRatio === ASPECT_RATIO_NARROW) {
return {
height,
width:
(shouldDisplayLocalThumbnailSeparately() && localParticipantVisible
? clientWidth - width - (margin * 2) : clientWidth)
- left - right - (styles.filmstripNarrow.margin * 2) - (conferenceBorder * 2)
};
}
return {
height:
(shouldDisplayLocalThumbnailSeparately() && localParticipantVisible
? clientHeight - height - (margin * 2) : clientHeight)
- top - bottom - (conferenceBorder * 2),
width
};
}
/**
* Returns true if the local thumbnail should be displayed separately and false otherwise.
*
* @returns {boolean} - True if the local thumbnail should be displayed separately and flase otherwise.
*/
export function shouldDisplayLocalThumbnailSeparately() {
// XXX Our current design is to have the local participant separate from
// the remote participants. Unfortunately, Android's Video
// implementation cannot accommodate that because remote participants'
// videos appear on top of the local participant's video at times.
// That's because Android's Video utilizes EGL and EGL gives us only two
// practical layers in which we can place our participants' videos:
// layer #0 sits behind the window, creates a hole in the window, and
// there we render the LargeVideo; layer #1 is known as media overlay in
// EGL terms, renders on top of layer #0, and, consequently, is for the
// Filmstrip. With the separate LocalThumbnail, we should have left the
// remote participants' Thumbnails in layer #1 and utilized layer #2 for
// LocalThumbnail. Unfortunately, layer #2 is not practical (that's why
// I said we had two practical layers only) because it renders on top of
// everything which in our case means on top of participant-related
// indicators such as moderator, audio and video muted, etc. For now we
// do not have much of a choice but to continue rendering LocalThumbnail
// as any other remote Thumbnail on Android.
return Platform.OS !== 'android';
}

View File

@ -652,20 +652,6 @@ export function getVerticalViewMaxWidth(state) {
return maxWidth;
}
/**
* Returns true if thumbnail reordering is enabled and false otherwise.
* Note: The function will return false if all participants are displayed on the screen.
*
* @param {Object} state - The redux state.
* @returns {boolean} - True if thumbnail reordering is enabled and false otherwise.
*/
export function isReorderingEnabled(state) {
const { testing = {} } = state['features/base/config'];
const enableThumbnailReordering = testing.enableThumbnailReordering ?? true;
return enableThumbnailReordering && isFilmstripScrollVisible(state);
}
/**
* Returns true if the scroll is displayed and false otherwise.
*

View File

@ -2,7 +2,7 @@
import { PARTICIPANT_JOINED, PARTICIPANT_LEFT } from '../base/participants';
import { MiddlewareRegistry } from '../base/redux';
import { CLIENT_RESIZED, SET_ASPECT_RATIO } from '../base/responsive-ui';
import { CLIENT_RESIZED, SAFE_AREA_INSETS_CHANGED, SET_ASPECT_RATIO } from '../base/responsive-ui';
import { setTileViewDimensions } from './actions';
import { updateRemoteParticipants, updateRemoteParticipantsOnLeave } from './functions';
@ -25,6 +25,7 @@ MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case CLIENT_RESIZED:
case SAFE_AREA_INSETS_CHANGED:
case SET_ASPECT_RATIO:
store.dispatch(setTileViewDimensions());
break;

View File

@ -204,12 +204,15 @@ ReducerRegistry.register(
}
};
case SET_VISIBLE_REMOTE_PARTICIPANTS: {
const { endIndex, startIndex } = action;
const { remoteParticipants } = state;
const visibleRemoteParticipants = new Set(remoteParticipants.slice(startIndex, endIndex + 1));
return {
...state,
visibleParticipantsStartIndex: action.startIndex,
visibleParticipantsEndIndex: action.endIndex,
visibleRemoteParticipants:
new Set(state.remoteParticipants.slice(action.startIndex, action.endIndex + 1))
visibleParticipantsStartIndex: startIndex,
visibleParticipantsEndIndex: endIndex,
visibleRemoteParticipants
};
}
case PARTICIPANT_LEFT: {

View File

@ -2,7 +2,7 @@
import { StateListenerRegistry } from '../base/redux';
import { updateRemoteParticipants } from './functions';
import { isFilmstripScrollVisible, updateRemoteParticipants } from './functions';
/**
* Listens for changes to the screensharing status of the remote participants to recompute the reordered list of the
@ -25,3 +25,10 @@ StateListenerRegistry.register(
StateListenerRegistry.register(
/* selector */ state => state['features/base/participants'].dominantSpeaker,
/* listener */ (dominantSpeaker, store) => updateRemoteParticipants(store));
/**
* Listens for changes in the filmstrip scroll visibility.
*/
StateListenerRegistry.register(
/* selector */ state => isFilmstripScrollVisible(state),
/* listener */ (_, store) => updateRemoteParticipants(store));

View File

@ -1,25 +1,17 @@
// @flow
import { getParticipantCountWithFake } from '../base/participants';
import { StateListenerRegistry } from '../base/redux';
import { shouldDisplayTileView } from '../video-layout';
import { setTileViewDimensions } from './actions';
import { getTileViewParticipantCount } from './functions.native';
import './subscriber.any';
/**
* Listens for changes in the number of participants to calculate the dimensions of the tile view grid and the tiles.
*/
StateListenerRegistry.register(
/* selector */ state => {
const participantCount = getParticipantCountWithFake(state);
if (participantCount < 6) { // the dimensions are updated only when the participant count is lower than 6.
return participantCount;
}
return 5; // make sure we don't update the dimensions.
},
/* selector */ state => getTileViewParticipantCount(state),
/* listener */ (_, store) => {
const state = store.getState();

View File

@ -23,9 +23,7 @@ import {
DISPLAY_DRAWER_THRESHOLD
} from './constants';
import {
isFilmstripResizable,
isFilmstripScrollVisible,
updateRemoteParticipants
isFilmstripResizable
} from './functions';
import './subscriber.any';
@ -166,13 +164,6 @@ StateListenerRegistry.register(
store.dispatch(setVerticalViewDimensions());
});
/**
* Listens for changes in the filmstrip scroll visibility.
*/
StateListenerRegistry.register(
/* selector */ state => isFilmstripScrollVisible(state),
/* listener */ (_, store) => updateRemoteParticipants(store));
/**
* Listens for changes to determine the size of the stage filmstrip tiles.
*/

View File

@ -1,7 +1,6 @@
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import React from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { connect } from '../../../base/redux';
import { DialInSummary } from '../../../invite';
@ -36,43 +35,41 @@ const RootNavigationContainer = ({ isWelcomePageAvailable }: Props) => {
? screen.root : screen.connecting;
return (
<SafeAreaProvider>
<NavigationContainer
independent = { true }
ref = { rootNavigationRef }
theme = { navigationContainerTheme }>
<RootStack.Navigator
initialRouteName = { initialRouteName }>
{
isWelcomePageAvailable
&& <>
<RootStack.Screen
component = { WelcomePageNavigationContainer }
name = { screen.root }
options = { drawerNavigatorScreenOptions } />
<RootStack.Screen
component = { DialInSummary }
name = { screen.dialInSummary }
options = { dialInSummaryScreenOptions } />
</>
}
<RootStack.Screen
component = { ConnectingPage }
name = { screen.connecting }
options = {{
gestureEnabled: false,
headerShown: false
}} />
<RootStack.Screen
component = { ConferenceNavigationContainer }
name = { screen.conference.root }
options = {{
gestureEnabled: false,
headerShown: false
}} />
</RootStack.Navigator>
</NavigationContainer>
</SafeAreaProvider>
<NavigationContainer
independent = { true }
ref = { rootNavigationRef }
theme = { navigationContainerTheme }>
<RootStack.Navigator
initialRouteName = { initialRouteName }>
{
isWelcomePageAvailable
&& <>
<RootStack.Screen
component = { WelcomePageNavigationContainer }
name = { screen.root }
options = { drawerNavigatorScreenOptions } />
<RootStack.Screen
component = { DialInSummary }
name = { screen.dialInSummary }
options = { dialInSummaryScreenOptions } />
</>
}
<RootStack.Screen
component = { ConnectingPage }
name = { screen.connecting }
options = {{
gestureEnabled: false,
headerShown: false
}} />
<RootStack.Screen
component = { ConferenceNavigationContainer }
name = { screen.conference.root }
options = {{
gestureEnabled: false,
headerShown: false
}} />
</RootStack.Navigator>
</NavigationContainer>
);
};