We started on the way to responsive UI and its design with aspect ratio and keeping the filmstrip on the short side of the app's visible rectangle. Shortly, we're going to introduce reduced UI for Picture-in-Picture. And that's where we'll need another dimensions-based detector akin to the aspect ratio detector. While the AspectRatioDetector, the up-and-coming ReducedUIDetector, and their base DimensionsDetector are definitely separate abstractions and implementations not mixed for the purposes of easy extensibility and maintenance, the three of them are our building blocks on top of which we'll build our responsive UI.
78 lines
2.2 KiB
JavaScript
78 lines
2.2 KiB
JavaScript
// @flow
|
|
|
|
import PropTypes from 'prop-types';
|
|
import React, { Component } from 'react';
|
|
import { connect } from 'react-redux';
|
|
|
|
import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from '../constants';
|
|
|
|
/**
|
|
* Determines whether a specific React {@code Component} decorated into an
|
|
* {@link AspectRatioAware} has {@link ASPECT_RATIO_NARROW} as the value of its
|
|
* {@code aspectRatio} React prop.
|
|
*
|
|
* @param {AspectRatioAware} component - An {@link AspectRatioAware} which may
|
|
* have an {@code aspectRatio} React prop.
|
|
* @returns {boolean}
|
|
*/
|
|
export function isNarrowAspectRatio(component: React$Component<*>) {
|
|
return component.props.aspectRatio === ASPECT_RATIO_NARROW;
|
|
}
|
|
|
|
/**
|
|
* Decorates a specific React {@code Component} class into an
|
|
* {@link AspectRatioAware} which provides the React prop {@code aspectRatio}
|
|
* updated on each redux state change.
|
|
*
|
|
* @param {Class<React$Component>} WrappedComponent - A React {@code Component}
|
|
* class to be wrapped.
|
|
* @returns {AspectRatioAwareWrapper}
|
|
*/
|
|
export function makeAspectRatioAware(
|
|
WrappedComponent: Class<React$Component<*>>
|
|
): Class<React$Component<*>> {
|
|
/**
|
|
* Renders {@code WrappedComponent} with the React prop {@code aspectRatio}.
|
|
*/
|
|
class AspectRatioAware extends Component<*> {
|
|
/**
|
|
* Properties of the aspect ratio aware wrapper.
|
|
*/
|
|
static propTypes = {
|
|
/**
|
|
* Either {@link ASPECT_RATIO_NARROW} or {@link ASPECT_RATIO_WIDE}.
|
|
*/
|
|
aspectRatio: PropTypes.oneOf([
|
|
ASPECT_RATIO_NARROW,
|
|
ASPECT_RATIO_WIDE
|
|
])
|
|
}
|
|
|
|
/**
|
|
* Implement's React render method to wrap the nested component.
|
|
*
|
|
* @returns {React$Element}
|
|
*/
|
|
render(): React$Element<*> {
|
|
return <WrappedComponent { ...this.props } />;
|
|
}
|
|
}
|
|
|
|
return connect(_mapStateToProps)(AspectRatioAware);
|
|
}
|
|
|
|
/**
|
|
* Maps (parts of) the redux state to {@link AspectRatioAware} props.
|
|
*
|
|
* @param {Object} state - The whole redux state.
|
|
* @private
|
|
* @returns {{
|
|
* aspectRatio: Symbol
|
|
* }}
|
|
*/
|
|
function _mapStateToProps(state) {
|
|
return {
|
|
aspectRatio: state['features/base/responsive-ui'].aspectRatio
|
|
};
|
|
}
|