ref(Conference.native): move notifications container
Moves NotificationContainer to the toolbox and filmstrip container, so that there's no need to manually calculate the positions.
This commit is contained in:
parent
5119f41af6
commit
eac069c930
|
@ -11,10 +11,14 @@ import { connect, disconnect } from '../../base/connection';
|
||||||
import { DialogContainer } from '../../base/dialog';
|
import { DialogContainer } from '../../base/dialog';
|
||||||
import { getParticipantCount } from '../../base/participants';
|
import { getParticipantCount } from '../../base/participants';
|
||||||
import { Container, LoadingIndicator, TintedView } from '../../base/react';
|
import { Container, LoadingIndicator, TintedView } from '../../base/react';
|
||||||
|
import {
|
||||||
|
isNarrowAspectRatio,
|
||||||
|
makeAspectRatioAware
|
||||||
|
} from '../../base/responsive-ui';
|
||||||
import { TestConnectionInfo } from '../../base/testing';
|
import { TestConnectionInfo } from '../../base/testing';
|
||||||
import { createDesiredLocalTracks } from '../../base/tracks';
|
import { createDesiredLocalTracks } from '../../base/tracks';
|
||||||
import { ConferenceNotification } from '../../calendar-sync';
|
import { ConferenceNotification } from '../../calendar-sync';
|
||||||
import { Filmstrip } from '../../filmstrip';
|
import { FILMSTRIP_SIZE, Filmstrip, isFilmstripVisible } from '../../filmstrip';
|
||||||
import { LargeVideo } from '../../large-video';
|
import { LargeVideo } from '../../large-video';
|
||||||
import { CalleeInfoContainer } from '../../invite';
|
import { CalleeInfoContainer } from '../../invite';
|
||||||
import { NotificationsContainer } from '../../notifications';
|
import { NotificationsContainer } from '../../notifications';
|
||||||
|
@ -37,6 +41,13 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_connecting: boolean,
|
_connecting: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to {@code true} when the filmstrip is currently visible.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_filmstripVisible: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current conference's full URL.
|
* Current conference's full URL.
|
||||||
*
|
*
|
||||||
|
@ -272,6 +283,14 @@ class Conference extends Component<Props> {
|
||||||
<View
|
<View
|
||||||
pointerEvents = 'box-none'
|
pointerEvents = 'box-none'
|
||||||
style = { styles.toolboxAndFilmstripContainer }>
|
style = { styles.toolboxAndFilmstripContainer }>
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifications are rendered on the very top of other
|
||||||
|
* components like subtitles, toolbox and filmstrip.
|
||||||
|
*/
|
||||||
|
this._renderNotificationsContainer()
|
||||||
|
}
|
||||||
{/*
|
{/*
|
||||||
* The Toolbox is in a stacking layer bellow the Filmstrip.
|
* The Toolbox is in a stacking layer bellow the Filmstrip.
|
||||||
*/}
|
*/}
|
||||||
|
@ -293,8 +312,6 @@ class Conference extends Component<Props> {
|
||||||
this._renderConferenceNotification()
|
this._renderConferenceNotification()
|
||||||
}
|
}
|
||||||
|
|
||||||
<NotificationsContainer />
|
|
||||||
|
|
||||||
{/*
|
{/*
|
||||||
* The dialogs are in the topmost stacking layers.
|
* The dialogs are in the topmost stacking layers.
|
||||||
*/
|
*/
|
||||||
|
@ -350,6 +367,35 @@ class Conference extends Component<Props> {
|
||||||
? <ConferenceNotification />
|
? <ConferenceNotification />
|
||||||
: undefined);
|
: undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a container for notifications to be displayed by
|
||||||
|
* the base/notifications feature.
|
||||||
|
*
|
||||||
|
* @returns {React$Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_renderNotificationsContainer() {
|
||||||
|
const notificationsStyle = { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In the landscape mode (wide) there's problem with notifications being
|
||||||
|
* shadowed by the filmstrip rendered on the right. This makes the "x"
|
||||||
|
* button not clickable. In order to avoid that a margin of
|
||||||
|
* the filmstrip's size is added to the right.
|
||||||
|
*
|
||||||
|
* Pawel: after many attempts I failed to make notifications adjust to
|
||||||
|
* their contents width because of column and rows being used in
|
||||||
|
* the flex layout. The only option that seemed to limit
|
||||||
|
* the notification's size was explicit 'width' value which is not
|
||||||
|
* better than the margin added here.
|
||||||
|
*/
|
||||||
|
if (!isNarrowAspectRatio(this) && this.props._filmstripVisible) {
|
||||||
|
notificationsStyle.marginRight = FILMSTRIP_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <NotificationsContainer style = { notificationsStyle } />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,6 +469,7 @@ function _mapDispatchToProps(dispatch) {
|
||||||
* @private
|
* @private
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* _connecting: boolean,
|
* _connecting: boolean,
|
||||||
|
* _filmstripVisible: boolean,
|
||||||
* _locationURL: URL,
|
* _locationURL: URL,
|
||||||
* _participantCount: number,
|
* _participantCount: number,
|
||||||
* _reducedUI: boolean,
|
* _reducedUI: boolean,
|
||||||
|
@ -467,6 +514,11 @@ function _mapStateToProps(state) {
|
||||||
*/
|
*/
|
||||||
_connecting: Boolean(connecting_),
|
_connecting: Boolean(connecting_),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is {@code true} when the filmstrip is currently visible.
|
||||||
|
*/
|
||||||
|
_filmstripVisible: isFilmstripVisible(state),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current conference's full URL.
|
* Current conference's full URL.
|
||||||
*
|
*
|
||||||
|
@ -520,4 +572,4 @@ function _mapStateToProps(state) {
|
||||||
|
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
export default reactReduxConnect(_mapStateToProps, _mapDispatchToProps)(
|
export default reactReduxConnect(_mapStateToProps, _mapDispatchToProps)(
|
||||||
Conference);
|
makeAspectRatioAware(Conference));
|
||||||
|
|
|
@ -4,14 +4,6 @@ import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import {
|
|
||||||
isNarrowAspectRatio,
|
|
||||||
makeAspectRatioAware
|
|
||||||
} from '../../base/responsive-ui';
|
|
||||||
import { BoxModel } from '../../base/styles';
|
|
||||||
import { FILMSTRIP_SIZE, isFilmstripVisible } from '../../filmstrip';
|
|
||||||
import { HANGUP_BUTTON_SIZE } from '../../toolbox';
|
|
||||||
|
|
||||||
import AbstractNotificationsContainer, {
|
import AbstractNotificationsContainer, {
|
||||||
_abstractMapStateToProps,
|
_abstractMapStateToProps,
|
||||||
type Props as AbstractProps
|
type Props as AbstractProps
|
||||||
|
@ -22,21 +14,11 @@ import styles from './styles';
|
||||||
type Props = AbstractProps & {
|
type Props = AbstractProps & {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the {@code Filmstrip} is visible, false otherwise.
|
* Any custom styling applied to the notifications container.
|
||||||
*/
|
*/
|
||||||
_filmstripVisible: boolean,
|
style: Object
|
||||||
|
|
||||||
/**
|
|
||||||
* True if the {@ćode Toolbox} is visible, false otherwise.
|
|
||||||
*/
|
|
||||||
_toolboxVisible: boolean
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The margin of the container to be kept from other components.
|
|
||||||
*/
|
|
||||||
const CONTAINER_MARGIN = BoxModel.margin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a React {@link Component} which displays notifications and handles
|
* Implements a React {@link Component} which displays notifications and handles
|
||||||
* automatic dismissmal after a notification is shown for a defined timeout
|
* automatic dismissmal after a notification is shown for a defined timeout
|
||||||
|
@ -44,7 +26,8 @@ const CONTAINER_MARGIN = BoxModel.margin;
|
||||||
*
|
*
|
||||||
* @extends {Component}
|
* @extends {Component}
|
||||||
*/
|
*/
|
||||||
class NotificationsContainer extends AbstractNotificationsContainer<Props> {
|
class NotificationsContainer
|
||||||
|
extends AbstractNotificationsContainer<Props> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements React's {@link Component#render()}.
|
* Implements React's {@link Component#render()}.
|
||||||
|
@ -64,79 +47,22 @@ class NotificationsContainer extends AbstractNotificationsContainer<Props> {
|
||||||
pointerEvents = 'box-none'
|
pointerEvents = 'box-none'
|
||||||
style = { [
|
style = { [
|
||||||
styles.notificationContainer,
|
styles.notificationContainer,
|
||||||
this._getContainerStyle()
|
this.props.style
|
||||||
] }>
|
] } >
|
||||||
{
|
{
|
||||||
_notifications.map(notification => {
|
_notifications.map(
|
||||||
const { props, uid } = notification;
|
({ props, uid }) => (
|
||||||
|
|
||||||
return (
|
|
||||||
<Notification
|
<Notification
|
||||||
{ ...props }
|
{ ...props }
|
||||||
key = { uid }
|
key = { uid }
|
||||||
onDismissed = { this._onDismissed }
|
onDismissed = { this._onDismissed }
|
||||||
uid = { uid } />
|
uid = { uid } />))
|
||||||
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a style object that is to be used for the notification
|
|
||||||
* container.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @returns {?Object}
|
|
||||||
*/
|
|
||||||
_getContainerStyle() {
|
|
||||||
const { _filmstripVisible, _toolboxVisible } = this.props;
|
|
||||||
|
|
||||||
// The filmstrip only affects the position if we're on a narrow view.
|
|
||||||
const _narrow = isNarrowAspectRatio(this);
|
|
||||||
|
|
||||||
let bottom = 0;
|
|
||||||
let right = 0;
|
|
||||||
|
|
||||||
// The container needs additional distance from bottom when the
|
|
||||||
// filmstrip or the toolbox is visible.
|
|
||||||
_filmstripVisible && !_narrow && (right += FILMSTRIP_SIZE);
|
|
||||||
_filmstripVisible && _narrow && (bottom += FILMSTRIP_SIZE);
|
|
||||||
_toolboxVisible && (bottom += HANGUP_BUTTON_SIZE);
|
|
||||||
|
|
||||||
bottom += CONTAINER_MARGIN;
|
|
||||||
|
|
||||||
return {
|
|
||||||
bottom,
|
|
||||||
right
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDismissed: number => void;
|
_onDismissed: number => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export default connect(_abstractMapStateToProps)(NotificationsContainer);
|
||||||
* Maps (parts of) the Redux state to the associated NotificationsContainer's
|
|
||||||
* props.
|
|
||||||
*
|
|
||||||
* @param {Object} state - The Redux state.
|
|
||||||
* @private
|
|
||||||
* @returns {{
|
|
||||||
* _filmstripVisible: boolean,
|
|
||||||
* _notifications: Array,
|
|
||||||
* _showNotifications: boolean,
|
|
||||||
* _toolboxVisible: boolean
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
export function _mapStateToProps(state: Object) {
|
|
||||||
return {
|
|
||||||
..._abstractMapStateToProps(state),
|
|
||||||
_filmstripVisible: isFilmstripVisible(state),
|
|
||||||
_toolboxVisible: state['features/toolbox'].visible
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(_mapStateToProps)(
|
|
||||||
makeAspectRatioAware(NotificationsContainer));
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import { BoxModel, createStyleSheet, ColorPalette } from '../../base/styles';
|
import { BoxModel, createStyleSheet, ColorPalette } from '../../base/styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,9 +46,10 @@ export default createStyleSheet({
|
||||||
* Outermost container of a list of notifications.
|
* Outermost container of a list of notifications.
|
||||||
*/
|
*/
|
||||||
notificationContainer: {
|
notificationContainer: {
|
||||||
...StyleSheet.absoluteFillObject,
|
flexGrow: 0,
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
padding: 2 * BoxModel.padding
|
padding: 2 * BoxModel.padding,
|
||||||
|
paddingBottom: BoxModel.padding
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,10 +5,6 @@ import { View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { Container } from '../../../base/react';
|
import { Container } from '../../../base/react';
|
||||||
import {
|
|
||||||
isNarrowAspectRatio,
|
|
||||||
makeAspectRatioAware
|
|
||||||
} from '../../../base/responsive-ui';
|
|
||||||
import { InviteButton } from '../../../invite';
|
import { InviteButton } from '../../../invite';
|
||||||
|
|
||||||
import AudioMuteButton from '../AudioMuteButton';
|
import AudioMuteButton from '../AudioMuteButton';
|
||||||
|
@ -92,15 +88,10 @@ class Toolbox extends Component<Props, State> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const toolboxStyle
|
|
||||||
= isNarrowAspectRatio(this)
|
|
||||||
? styles.toolboxNarrow
|
|
||||||
: styles.toolboxWide;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
onLayout = { this._onLayout }
|
onLayout = { this._onLayout }
|
||||||
style = { toolboxStyle }
|
style = { styles.toolbox }
|
||||||
visible = { this.props._visible }>
|
visible = { this.props._visible }>
|
||||||
{ this._renderToolbar() }
|
{ this._renderToolbar() }
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -244,4 +235,4 @@ function _mapStateToProps(state: Object): Object {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(_mapStateToProps)(makeAspectRatioAware(Toolbox));
|
export default connect(_mapStateToProps)(Toolbox);
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import { BoxModel, ColorPalette, createStyleSheet } from '../../../base/styles';
|
import { BoxModel, ColorPalette, createStyleSheet } from '../../../base/styles';
|
||||||
|
|
||||||
import { HANGUP_BUTTON_SIZE } from '../../constants';
|
import { HANGUP_BUTTON_SIZE } from '../../constants';
|
||||||
|
@ -64,15 +62,11 @@ const styles = createStyleSheet({
|
||||||
*/
|
*/
|
||||||
toolbar: {
|
toolbar: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
bottom: 0,
|
|
||||||
flex: 0,
|
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
flexGrow: 0,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
left: 0,
|
|
||||||
marginBottom: BoxModel.margin / 2,
|
marginBottom: BoxModel.margin / 2,
|
||||||
paddingHorizontal: BoxModel.margin,
|
paddingHorizontal: BoxModel.margin
|
||||||
position: 'absolute',
|
|
||||||
right: 0
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,21 +81,10 @@ const styles = createStyleSheet({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The style of the root/top-level {@link Container} of {@link Toolbox}.
|
* The style of the root/top-level {@link Container} of {@link Toolbox}.
|
||||||
* This is the narrow layout version which locates the toolbar on top of
|
|
||||||
* the filmstrip, at the bottom of the screen.
|
|
||||||
*/
|
*/
|
||||||
toolboxNarrow: {
|
toolbox: {
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
flexGrow: 1
|
flexGrow: 0
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The style of the root/top-level {@link Container} of {@link Toolbox}.
|
|
||||||
* This is the wide layout version which locates the toolbar at the bottom
|
|
||||||
* of the screen.
|
|
||||||
*/
|
|
||||||
toolboxWide: {
|
|
||||||
...StyleSheet.absoluteFillObject
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue