From c6d553738fbd6cbab0ecd39f5dea8e87aa0a5902 Mon Sep 17 00:00:00 2001 From: Lyubo Marinov Date: Fri, 1 Jun 2018 14:53:46 -0500 Subject: [PATCH] [RN] Refactor SideBar layout and animation (coding style) --- .../base/react/components/native/SideBar.js | 68 +++++++++---------- .../base/react/components/native/styles.js | 20 +++--- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/react/features/base/react/components/native/SideBar.js b/react/features/base/react/components/native/SideBar.js index 9c082af9c..7999fb625 100644 --- a/react/features/base/react/components/native/SideBar.js +++ b/react/features/base/react/components/native/SideBar.js @@ -1,11 +1,7 @@ // @flow import React, { Component, type Node } from 'react'; -import { - Animated, - TouchableWithoutFeedback, - View -} from 'react-native'; +import { Animated, TouchableWithoutFeedback, View } from 'react-native'; import styles, { SIDEBAR_WIDTH } from './styles'; @@ -15,21 +11,21 @@ import styles, { SIDEBAR_WIDTH } from './styles'; type Props = { /** - * The children of the Component + * The children of {@code SideBar}. */ children: Node, /** - * Callback to notify the containing Component that the sidebar is + * Callback to notify the containing {@code Component} that the sidebar is * closing. */ onHide: Function, /** - * Sets the menu displayed or hidden. + * Whether the menu (of the {@code SideBar}?) is displayed/rendered/shown. */ show: boolean -} +}; /** * The type of the React {@code Component} state of {@link SideBar}. @@ -37,18 +33,18 @@ type Props = { type State = { /** - * Indicates whether the side overlay should be rendered or not. + * Whether the side overlay should be displayed/rendered/shown. */ showOverlay: boolean, /** * The native animation object. */ - sliderAnimation: Object -} + sliderAnimation: Animated.Value +}; /** - * A generic animated side bar to be used for left side menus + * A generic animated side bar to be used for left-side, hamburger-style menus. */ export default class SideBar extends Component { /** @@ -64,11 +60,12 @@ export default class SideBar extends Component { sliderAnimation: new Animated.Value(0) }; + // Bind event handlers so they are only bound once per instance. this._onHideMenu = this._onHideMenu.bind(this); } /** - * Implements the Component's componentDidMount method. + * Implements React's {@link Component#componentDidMount()}. * * @inheritdoc */ @@ -77,14 +74,12 @@ export default class SideBar extends Component { } /** - * Implements the Component's componentWillReceiveProps method. + * Implements React's {@link Component#componentWillReceiveProps()}. * * @inheritdoc */ - componentWillReceiveProps(newProps: Props) { - if (newProps.show !== this.props.show) { - this._setShow(newProps.show); - } + componentWillReceiveProps({ show }: Props) { + (show === this.props.show) || this._setShow(show); } /** @@ -120,17 +115,16 @@ export default class SideBar extends Component { * @returns {Array} */ _getContentStyle() { - const { sliderAnimation } = this.state; - const transformStyle - = { transform: [ { translateX: sliderAnimation } ] }; - - return [ styles.sideMenuContent, transformStyle ]; + return [ + styles.sideMenuContent, + { transform: [ { translateX: this.state.sliderAnimation } ] } + ]; } _onHideMenu: () => void; /** - * Hides the menu. + * Hides the side menu. * * @private * @returns {void} @@ -146,28 +140,30 @@ export default class SideBar extends Component { _setShow: (boolean) => void; /** - * Sets the side menu visible or hidden. + * Shows/hides the side menu. * - * @param {boolean} show - The new expected visibility value. + * @param {boolean} show - If the side menu is to be made visible, + * {@code true}; otherwise, {@code false}. * @private * @returns {void} */ _setShow(show) { - if (show) { - this.setState({ showOverlay: true }); - } + show && this.setState({ showOverlay: true }); Animated .timing( - this.state.sliderAnimation, - { + /* value */ this.state.sliderAnimation, + /* config */ { toValue: show ? SIDEBAR_WIDTH : 0, useNativeDriver: true }) - .start(animationState => { - if (animationState.finished && !show) { - this.setState({ showOverlay: false }); - } + .start(({ finished }) => { + finished && !show && this.setState({ showOverlay: false }); + + // XXX Technically, the arrow function can further be simplified + // by removing the {} and returning the boolean expression + // above. Practically and unfortunately though, Flow freaks out + // and states that Animated.timing doesn't exist!? }); } } diff --git a/react/features/base/react/components/native/styles.js b/react/features/base/react/components/native/styles.js index 33510f6c9..d422dfb13 100644 --- a/react/features/base/react/components/native/styles.js +++ b/react/features/base/react/components/native/styles.js @@ -1,10 +1,8 @@ +// @flow + import { StyleSheet } from 'react-native'; -import { - BoxModel, - ColorPalette, - createStyleSheet -} from '../../../styles'; +import { BoxModel, ColorPalette, createStyleSheet } from '../../../styles'; const AVATAR_OPACITY = 0.4; const AVATAR_SIZE = 65; @@ -21,7 +19,7 @@ export const UNDERLAY_COLOR = 'rgba(255, 255, 255, 0.2)'; const HEADER_STYLES = { /** - * Platform specific header button (e.g. back, menu...etc). + * Platform specific header button (e.g. back, menu, etc). */ headerButton: { alignSelf: 'center', @@ -57,7 +55,7 @@ const HEADER_STYLES = { }, /** - * Base style of Header + * Base style of Header. */ screenHeader: { alignItems: 'center', @@ -293,8 +291,8 @@ const SIDEBAR_STYLES = { }, /** - * The opaque area that covers the rest of the screen, when - * the side bar is open. + * The opaque area that covers the rest of the screen, when the side bar is + * open. */ sideMenuShadow: { ...StyleSheet.absoluteFillObject, @@ -303,8 +301,8 @@ const SIDEBAR_STYLES = { }; /** - * The styles of the React {@code Components} of the generic components - * in the app. + * The styles of the generic React {@code Component}s implemented by the feature + * base/react. */ export default createStyleSheet({ ...HEADER_STYLES,