mirror of https://github.com/jitsi/jitsi-meet
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.pull/2066/head
parent
2b46c37077
commit
c0a7d6144a
@ -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; |
||||
}); |
Loading…
Reference in new issue