feat: display filmstrip on the short side
Adds the ability to detect app area's aspect ratio on react-native through the features/base/aspect-ratio. Makes conference, filmstrip and toolbox react to the aspect ratio changes and display filmstrip on the shorter side of the screen.
This commit is contained in:
parent
2b46c37077
commit
c0a7d6144a
|
@ -1,10 +1,12 @@
|
||||||
/* global __DEV__ */
|
/* global __DEV__ */
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
import { Linking } from 'react-native';
|
import { Linking } from 'react-native';
|
||||||
|
|
||||||
import '../../analytics';
|
import '../../analytics';
|
||||||
import '../../authentication';
|
import '../../authentication';
|
||||||
|
import { AspectRatioDetector } from '../../base/aspect-ratio';
|
||||||
import { Platform } from '../../base/react';
|
import { Platform } from '../../base/react';
|
||||||
import '../../mobile/audio-mode';
|
import '../../mobile/audio-mode';
|
||||||
import '../../mobile/background';
|
import '../../mobile/background';
|
||||||
|
@ -86,6 +88,19 @@ export class App extends AbstractApp {
|
||||||
super.componentWillUnmount();
|
super.componentWillUnmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the super method to inject {@link AspectRatioDetector} as
|
||||||
|
* the top most component.
|
||||||
|
*
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
_createElement(component, props) {
|
||||||
|
return (
|
||||||
|
<AspectRatioDetector>
|
||||||
|
{super._createElement(component, props)}
|
||||||
|
</AspectRatioDetector>);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to disable the use of React Native
|
* Attempts to disable the use of React Native
|
||||||
* {@link ExceptionsManager#handleException} on platforms and in
|
* {@link ExceptionsManager#handleException} on platforms and in
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* The type of (redux) action which signals that a new aspect ratio has been
|
||||||
|
* detected by the app.
|
||||||
|
* {
|
||||||
|
* type: SET_ASPECT_RATIO,
|
||||||
|
* aspectRatio: Symbol
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
export const SET_ASPECT_RATIO = Symbol('SET_ASPECT_RATIO');
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* @flow */
|
||||||
|
|
||||||
|
import { SET_ASPECT_RATIO } from './actionTypes';
|
||||||
|
import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from './constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates new aspect ratio for the app based on provided width and height
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @param {number} width - The width of the app's area used on the screen.
|
||||||
|
* @param {number} height - The height of the app's area used on the screen.
|
||||||
|
* @returns {{
|
||||||
|
* type: SET_ASPECT_RATIO,
|
||||||
|
* aspectRatio: Symbol
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
export function calculateNewAspectRatio(width: number, height: number): Object {
|
||||||
|
return {
|
||||||
|
type: SET_ASPECT_RATIO,
|
||||||
|
aspectRatio: width > height ? ASPECT_RATIO_WIDE : ASPECT_RATIO_NARROW
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
// @flow
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { ASPECT_RATIO_NARROW } from '../constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorates given React component class into {@link AspectRatioAwareWrapper}
|
||||||
|
* which provides the <tt>aspectRatio</tt> property updated on each Redux state
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param {ReactClass} WrapperComponent - A React component class to be wrapped.
|
||||||
|
* @returns {AspectRatioAwareWrapper}
|
||||||
|
*/
|
||||||
|
export function AspectRatioAware(
|
||||||
|
WrapperComponent: ReactClass<*>): ReactClass<*> {
|
||||||
|
return connect(_mapStateToProps)(
|
||||||
|
class AspectRatioAwareWrapper extends Component {
|
||||||
|
/**
|
||||||
|
* Properties of the aspect ratio aware wrapper.
|
||||||
|
*/
|
||||||
|
static propTypes = {
|
||||||
|
/**
|
||||||
|
* Either {@link ASPECT_RATIO_NARROW} or
|
||||||
|
* {@link ASPECT_RATIO_WIDE}.
|
||||||
|
*/
|
||||||
|
aspectRatio: PropTypes.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement's React render method to wrap the nested component.
|
||||||
|
*
|
||||||
|
* @returns {XML}
|
||||||
|
*/
|
||||||
|
render(): React$Element<*> {
|
||||||
|
return <WrapperComponent { ...this.props } />;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps Redux state to {@link AspectRatioAwareWrapper} properties.
|
||||||
|
*
|
||||||
|
* @param {Object} state - The Redux whole state.
|
||||||
|
* @returns {{
|
||||||
|
* aspectRatio: Symbol
|
||||||
|
* }}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function _mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
aspectRatio: state['features/base/aspect-ratio'].aspectRatio
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if given React component decorated in {@link AspectRatioAwareWrapper}
|
||||||
|
* has currently the {@link ASPECT_RATIO_NARROW} set in the aspect ratio
|
||||||
|
* property.
|
||||||
|
*
|
||||||
|
* @param {AspectRatioAwareWrapper} component - A
|
||||||
|
* {@link AspectRatioAwareWrapper} which has <tt>aspectRation</tt> property.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export function isNarrowAspectRatio(component: ReactClass<*>) {
|
||||||
|
return component.props.aspectRatio === ASPECT_RATIO_NARROW;
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { calculateNewAspectRatio } from '../actions';
|
||||||
|
import styles from './styles';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A root {@link View} which captures the 'onLayout' event and figures out
|
||||||
|
* the aspect ratio of the app.
|
||||||
|
*/
|
||||||
|
class AspectRatioDetector extends Component {
|
||||||
|
/**
|
||||||
|
* AspectRatioDetector component's property types.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
static propTypes = {
|
||||||
|
/**
|
||||||
|
* The "onLayout" handler.
|
||||||
|
*/
|
||||||
|
_onLayout: PropTypes.func,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any nested components.
|
||||||
|
*/
|
||||||
|
children: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the root view and it's children.
|
||||||
|
*
|
||||||
|
* @returns {Component}
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
onLayout = { this.props._onLayout }
|
||||||
|
style = { styles.aspectRatioDetectorStyle } >
|
||||||
|
{this.props.children}
|
||||||
|
</View>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps dispatching of the aspect ratio actions to React component props.
|
||||||
|
*
|
||||||
|
* @param {Function} dispatch - Redux action dispatcher.
|
||||||
|
* @private
|
||||||
|
* @returns {{
|
||||||
|
* _onLayout: Function
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
function _mapDispatchToProps(dispatch) {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Handles the "on layout" View's event and dispatches aspect ratio
|
||||||
|
* changed action.
|
||||||
|
*
|
||||||
|
* @param {{ width: number, height: number }} event - The "on layout"
|
||||||
|
* event structure passed by react-native.
|
||||||
|
* @returns {void}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_onLayout(event) {
|
||||||
|
const { width, height } = event.nativeEvent.layout;
|
||||||
|
|
||||||
|
dispatch(calculateNewAspectRatio(width, height));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(undefined, _mapDispatchToProps)(AspectRatioDetector);
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './AspectRatioAware';
|
||||||
|
export { default as AspectRatioDetector } from './AspectRatioDetector';
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { createStyleSheet, fixAndroidViewClipping } from '../../styles/index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The styles of the feature app.
|
||||||
|
*/
|
||||||
|
export default createStyleSheet({
|
||||||
|
/**
|
||||||
|
* The style for {@link AspectRatioDetector} root view used on react-native.
|
||||||
|
*/
|
||||||
|
aspectRatioDetectorStyle: fixAndroidViewClipping({
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
flex: 1
|
||||||
|
})
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
/**
|
||||||
|
* The aspect ratio constant indicates that the app area's width is smaller than
|
||||||
|
* the height.
|
||||||
|
*
|
||||||
|
* @type {Symbol}
|
||||||
|
*/
|
||||||
|
export const ASPECT_RATIO_NARROW = Symbol('ASPECT_RATIO_NARROW');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aspect ratio constant indicates that the app area's width is larger than
|
||||||
|
* the height.
|
||||||
|
*
|
||||||
|
* @type {Symbol}
|
||||||
|
*/
|
||||||
|
export const ASPECT_RATIO_WIDE = Symbol('ASPECT_RATIO_WIDE');
|
|
@ -0,0 +1,6 @@
|
||||||
|
export * from './actions';
|
||||||
|
export * from './actionTypes';
|
||||||
|
export * from './components';
|
||||||
|
export * from './constants';
|
||||||
|
|
||||||
|
import './reducer';
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { ReducerRegistry, set } from '../redux';
|
||||||
|
|
||||||
|
import { SET_ASPECT_RATIO } from './actionTypes';
|
||||||
|
import { ASPECT_RATIO_NARROW } from './constants';
|
||||||
|
|
||||||
|
const INITIAL_STATE = {
|
||||||
|
aspectRatio: ASPECT_RATIO_NARROW
|
||||||
|
};
|
||||||
|
|
||||||
|
ReducerRegistry.register(
|
||||||
|
'features/base/aspect-ratio',
|
||||||
|
(state = INITIAL_STATE, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case SET_ASPECT_RATIO:
|
||||||
|
return set(state, 'aspectRatio', action.aspectRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
});
|
|
@ -184,15 +184,6 @@ class Conference extends Component {
|
||||||
*/}
|
*/}
|
||||||
<LargeVideo />
|
<LargeVideo />
|
||||||
|
|
||||||
{/*
|
|
||||||
* The Filmstrip is in a stacking layer above the LargeVideo.
|
|
||||||
* The LargeVideo and the Filmstrip form what the Web/React app
|
|
||||||
* calls "videospace". Presumably, the name and grouping stem
|
|
||||||
* from the fact that these two React Components depict the
|
|
||||||
* videos of the conference's participants.
|
|
||||||
*/}
|
|
||||||
<Filmstrip />
|
|
||||||
|
|
||||||
{/*
|
{/*
|
||||||
* The overlays need to be bellow the Toolbox so that the user
|
* The overlays need to be bellow the Toolbox so that the user
|
||||||
* may tap the ToolbarButtons.
|
* may tap the ToolbarButtons.
|
||||||
|
@ -209,10 +200,22 @@ class Conference extends Component {
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
|
|
||||||
{/*
|
<View style = { styles.toolboxAndFilmstripContainer } >
|
||||||
* The Toolbox is in a stacking layer above the Filmstrip.
|
{/*
|
||||||
*/}
|
* The Toolbox is in a stacking layer above the Filmstrip.
|
||||||
<Toolbox />
|
*/}
|
||||||
|
<Toolbox />
|
||||||
|
{/*
|
||||||
|
* The Filmstrip is in a stacking layer above
|
||||||
|
* the LargeVideo.
|
||||||
|
* The LargeVideo and the Filmstrip form what the Web/React
|
||||||
|
* app calls "videospace". Presumably, the name and
|
||||||
|
* grouping stem from the fact that these two React
|
||||||
|
* Components depict the videos of the conference's
|
||||||
|
* participants.
|
||||||
|
*/}
|
||||||
|
<Filmstrip />
|
||||||
|
</View>
|
||||||
|
|
||||||
{/*
|
{/*
|
||||||
* The dialogs are in the topmost stacking layers.
|
* The dialogs are in the topmost stacking layers.
|
||||||
|
|
|
@ -38,5 +38,19 @@ export default createStyleSheet({
|
||||||
// contrast and translucency.
|
// contrast and translucency.
|
||||||
backgroundColor: ColorPalette.appBackground,
|
backgroundColor: ColorPalette.appBackground,
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The style of the view which expands over the whole conference area and
|
||||||
|
* splits it between both the filmstrip and the toolbox.
|
||||||
|
*/
|
||||||
|
toolboxAndFilmstripContainer: {
|
||||||
|
bottom: 0,
|
||||||
|
flexDirection: 'column',
|
||||||
|
left: 0,
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
position: 'absolute',
|
||||||
|
right: 0,
|
||||||
|
top: 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@ import React, { Component } from 'react';
|
||||||
import { ScrollView } from 'react-native';
|
import { ScrollView } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { AspectRatioAware, isNarrowAspectRatio } from '../../base/aspect-ratio';
|
||||||
import { Container } from '../../base/react';
|
import { Container } from '../../base/react';
|
||||||
|
|
||||||
import Thumbnail from './Thumbnail';
|
import Thumbnail from './Thumbnail';
|
||||||
|
@ -47,15 +48,16 @@ class Filmstrip extends Component<*> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
|
const filmstripStyle
|
||||||
|
= isNarrowAspectRatio(this)
|
||||||
|
? styles.filmstripNarrow : styles.filmstripWide;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
style = { styles.filmstrip }
|
style = { filmstripStyle }
|
||||||
visible = { this.props._visible }>
|
visible = { this.props._visible } >
|
||||||
<ScrollView
|
<ScrollView
|
||||||
|
horizontal = { isNarrowAspectRatio(this) }
|
||||||
contentContainerStyle
|
|
||||||
= { styles.filmstripScrollViewContentContainer }
|
|
||||||
horizontal = { true }
|
|
||||||
showsHorizontalScrollIndicator = { false }
|
showsHorizontalScrollIndicator = { false }
|
||||||
showsVerticalScrollIndicator = { false }>
|
showsVerticalScrollIndicator = { false }>
|
||||||
{
|
{
|
||||||
|
@ -121,6 +123,8 @@ class Filmstrip extends Component<*> {
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state) {
|
function _mapStateToProps(state) {
|
||||||
|
const participants = state['features/base/participants'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* The participants in the conference.
|
* The participants in the conference.
|
||||||
|
@ -128,20 +132,20 @@ function _mapStateToProps(state) {
|
||||||
* @private
|
* @private
|
||||||
* @type {Participant[]}
|
* @type {Participant[]}
|
||||||
*/
|
*/
|
||||||
_participants: state['features/base/participants'],
|
_participants: participants,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the filmstrip is visible.
|
* The indicator which determines whether the filmstrip is visible.
|
||||||
*
|
*
|
||||||
* XXX The React Component Filmstrip is used on mobile only at the time
|
* XXX The React Component Filmstrip is used on mobile only at the time
|
||||||
* of this writing and on mobile the filmstrip is visible when the
|
* of this writing and on mobile the filmstrip is when there are at
|
||||||
* toolbar is not.
|
* least 2 participants in the conference (including the local one).
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
_visible: !state['features/toolbox'].visible
|
_visible: participants.length > 1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(_mapStateToProps)(Filmstrip);
|
export default connect(_mapStateToProps)(AspectRatioAware(Filmstrip));
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
import { Platform } from '../../base/react';
|
import { Platform } from '../../base/react';
|
||||||
import { BoxModel, ColorPalette } from '../../base/styles';
|
import { BoxModel, ColorPalette } from '../../base/styles';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base filmstrip style shared between narrow and wide versions.
|
||||||
|
*/
|
||||||
|
const filmstripBaseStyle = {
|
||||||
|
flexGrow: 0,
|
||||||
|
flexDirection: 'column'
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The styles of the feature filmstrip common to both Web and native.
|
* The styles of the feature filmstrip common to both Web and native.
|
||||||
*/
|
*/
|
||||||
|
@ -40,26 +48,28 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The style of the Container which represents the very filmstrip.
|
* The style of the narrow filmstrip version which displays thumbnails
|
||||||
|
* in a row at the bottom of the screen.
|
||||||
*/
|
*/
|
||||||
filmstrip: {
|
filmstripNarrow: {
|
||||||
|
...filmstripBaseStyle,
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
alignSelf: 'stretch',
|
height: 90,
|
||||||
bottom: BoxModel.margin,
|
marginBottom: BoxModel.margin,
|
||||||
flex: 1,
|
marginLeft: BoxModel.margin,
|
||||||
flexDirection: 'column',
|
marginRight: BoxModel.margin
|
||||||
left: 0,
|
|
||||||
position: 'absolute',
|
|
||||||
right: 0
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The style of the content container of the ScrollView which is placed
|
* The style of the wide version of the filmstrip which appears as a column
|
||||||
* inside filmstrip and which contains the participants' thumbnails in order
|
* on the short side of the screen.
|
||||||
* to allow scrolling through them if they do not fit within the display.
|
|
||||||
*/
|
*/
|
||||||
filmstripScrollViewContentContainer: {
|
filmstripWide: {
|
||||||
paddingHorizontal: BoxModel.padding
|
...filmstripBaseStyle,
|
||||||
|
bottom: BoxModel.margin,
|
||||||
|
left: BoxModel.margin,
|
||||||
|
position: 'absolute',
|
||||||
|
top: BoxModel.margin
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,8 +96,7 @@ export default {
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
marginLeft: 2,
|
margin: 2,
|
||||||
marginRight: 2,
|
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
position: 'relative'
|
position: 'relative'
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { sendAnalyticsEvent } from '../../analytics';
|
import { sendAnalyticsEvent } from '../../analytics';
|
||||||
|
import { AspectRatioAware, isNarrowAspectRatio } from '../../base/aspect-ratio';
|
||||||
import { toggleAudioOnly } from '../../base/conference';
|
import { toggleAudioOnly } from '../../base/conference';
|
||||||
import {
|
import {
|
||||||
MEDIA_TYPE,
|
MEDIA_TYPE,
|
||||||
|
@ -119,15 +120,25 @@ class Toolbox extends Component {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
|
if (!this.props._visible) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
style = { styles.toolbarContainer }
|
style = {
|
||||||
visible = { this.props._visible }>
|
isNarrowAspectRatio(this)
|
||||||
|
? styles.toolbarContainerNarrow
|
||||||
|
: styles.toolbarContainerWide } >
|
||||||
{
|
{
|
||||||
this._renderPrimaryToolbar()
|
isNarrowAspectRatio(this)
|
||||||
|
? this._renderSecondaryToolbar()
|
||||||
|
: this._renderPrimaryToolbar()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this._renderSecondaryToolbar()
|
isNarrowAspectRatio(this)
|
||||||
|
? this._renderPrimaryToolbar()
|
||||||
|
: this._renderSecondaryToolbar()
|
||||||
}
|
}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
@ -420,4 +431,5 @@ function _mapStateToProps(state) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(_mapStateToProps, _mapDispatchToProps)(Toolbox);
|
export default connect(_mapStateToProps, _mapDispatchToProps)(
|
||||||
|
AspectRatioAware(Toolbox));
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { BoxModel, ColorPalette, createStyleSheet } from '../../base/styles';
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
const _toolbar = {
|
const _toolbar = {
|
||||||
flex: 1,
|
flex: 0,
|
||||||
position: 'absolute'
|
position: 'absolute'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ export default createStyleSheet({
|
||||||
*/
|
*/
|
||||||
primaryToolbar: {
|
primaryToolbar: {
|
||||||
..._toolbar,
|
..._toolbar,
|
||||||
bottom: 3 * BoxModel.margin,
|
bottom: 0,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
left: 0,
|
left: 0,
|
||||||
|
@ -135,9 +135,23 @@ export default 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}
|
||||||
* which contains {@link Toolbar}s.
|
* which contains {@link Toolbar}s. This is narrow layout version which
|
||||||
|
* spans from the top of the screen to the top of the filmstrip located at
|
||||||
|
* the bottom of the screen.
|
||||||
*/
|
*/
|
||||||
toolbarContainer: {
|
toolbarContainerNarrow: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
flexGrow: 1
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The style of the root/top-level {@link Container} of {@link Toolbox}
|
||||||
|
* which contains {@link Toolbar}s. This is wide layout version which
|
||||||
|
* spans from the top to the bottom of the screen and is located to
|
||||||
|
* the right of the filmstrip which is displayed as a column on the left
|
||||||
|
* side of the screen.
|
||||||
|
*/
|
||||||
|
toolbarContainerWide: {
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
Loading…
Reference in New Issue