From fb7a49ea333f60c91e88d9ec939ce0b8050adb93 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Mon, 25 Jan 2021 16:03:05 -0500 Subject: [PATCH 01/34] ZulipStatusBar [nfc]: Un-nest `StatusBar` from `View`. React Native's `StatusBar` component is unusual in that its `render` method always returns null [1]. The component isn't meant to participate in the spatial layout of the UI elements. Instead, the API works more like this: Mount a `StatusBar` component in order to tell something new to the native status bar API; e.g., what colors and animation you want to use. This commit is therefore NFC: the `StatusBar` still gets mounted in all cases where it was getting mounted before, and nothing changes in the spatial layout of the UI elements. The `` is doing an important job: it covers the "safe area" at the top of the screen (which includes the status bar), so that our content doesn't accidentally overlap with it. But `ZulipStatusBar` already has a very different job, which is to configure the status bar in kind of subtle ways, and depending on the platform. I'd like to pull the safe-area handling out of `ZulipStatusBar` to give it one less thing to worry about; that will happen in the rest of this series of commits. [1] https://github.com/facebook/react-native/blob/v0.63.4/Libraries/Components/StatusBar/StatusBar.js#L497 --- src/common/ZulipStatusBar.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/ZulipStatusBar.js b/src/common/ZulipStatusBar.js index 5aa495b6b80..cb79a301a8f 100644 --- a/src/common/ZulipStatusBar.js +++ b/src/common/ZulipStatusBar.js @@ -58,7 +58,8 @@ class ZulipStatusBar extends PureComponent { const statusBarColor = getStatusBarColor(backgroundColor, theme); return ( orientation === 'PORTRAIT' && ( - + <> + { backgroundColor={Color(statusBarColor).darken(0.1)} barStyle={getStatusBarStyle(statusBarColor)} /> - + ) ); } From fc08d86ce471fb223c3a18282b7ecb5afbc2d580 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Mon, 25 Jan 2021 17:01:15 -0500 Subject: [PATCH 02/34] Screen [nfc]: Grab `orientation` from Redux. We'll use this soon. --- src/common/Screen.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/common/Screen.js b/src/common/Screen.js index 078983ca982..87614dead27 100644 --- a/src/common/Screen.js +++ b/src/common/Screen.js @@ -5,17 +5,20 @@ import type { Node as React$Node } from 'react'; import { View, ScrollView } from 'react-native'; import type { ViewStyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet'; import { type EdgeInsets } from 'react-native-safe-area-context'; +import { compose } from 'redux'; import { withSafeAreaInsets } from '../react-native-safe-area-context'; +import { connect } from '../react-redux'; import type { ThemeData } from '../styles'; import styles, { createStyleSheet, ThemeContext } from '../styles'; -import type { LocalizableText } from '../types'; +import type { Dispatch, LocalizableText, Orientation } from '../types'; import KeyboardAvoider from './KeyboardAvoider'; import OfflineNotice from './OfflineNotice'; import LoadingBanner from './LoadingBanner'; import ZulipStatusBar from './ZulipStatusBar'; import ModalNavBar from '../nav/ModalNavBar'; import ModalSearchNavBar from '../nav/ModalSearchNavBar'; +import { getSession } from '../directSelectors'; const componentStyles = createStyleSheet({ screen: { @@ -36,6 +39,10 @@ const componentStyles = createStyleSheet({ }, }); +type SelectorProps = $ReadOnly<{| + orientation: Orientation, +|}>; + type Props = $ReadOnly<{| centerContent: boolean, +children: React$Node, @@ -52,6 +59,9 @@ type Props = $ReadOnly<{| canGoBack: boolean, +title: LocalizableText, + + dispatch: Dispatch, + ...SelectorProps, |}>; /** @@ -150,4 +160,9 @@ class Screen extends PureComponent { } } -export default withSafeAreaInsets(Screen); +export default compose( + connect((state, props) => ({ + orientation: getSession(state).orientation, + })), + withSafeAreaInsets, +)(Screen); From 6956fc08dbd8613c62c2db090812af1cb56556ed Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Mon, 25 Jan 2021 18:21:06 -0500 Subject: [PATCH 03/34] ZulipStatusBar [nfc]: Move sized `View` out to callers. Now, `ZulipStatusBar` doesn't have to worry about handling safe area views, and we can tailor that logic more specifically to each of the callers. --- src/chat/ChatScreen.js | 13 +++++++++++++ src/common/Screen.js | 13 +++++++++++++ src/common/ZulipStatusBar.js | 24 +++++++++++++----------- src/lightbox/LightboxScreen.js | 19 ++++++++++++++++++- src/main/MainTabsScreen.js | 18 ++++++++++++++++-- src/start/LoadingScreen.js | 16 ++++++++++++++++ 6 files changed, 89 insertions(+), 14 deletions(-) diff --git a/src/chat/ChatScreen.js b/src/chat/ChatScreen.js index b128d4e4116..0cff30ba56e 100644 --- a/src/chat/ChatScreen.js +++ b/src/chat/ChatScreen.js @@ -3,6 +3,7 @@ import React from 'react'; import { View } from 'react-native'; import { useIsFocused } from '@react-navigation/native'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useSelector, useDispatch } from '../react-redux'; import type { RouteProp } from '../react-navigation'; @@ -115,11 +116,23 @@ export default function ChatScreen(props: Props) { const showComposeBox = canSendToNarrow(narrow) && !showMessagePlaceholders; const titleBackgroundColor = useSelector(state => getTitleBackgroundColor(state, narrow)); + const orientation = useSelector(state => getSession(state).orientation); + const insets = useSafeAreaInsets(); + // This'll go away very soon, of course. + const statusBarHidden = false; return ( + {orientation === 'PORTRAIT' && ( + + )} diff --git a/src/common/Screen.js b/src/common/Screen.js index 87614dead27..34587dca535 100644 --- a/src/common/Screen.js +++ b/src/common/Screen.js @@ -19,6 +19,7 @@ import ZulipStatusBar from './ZulipStatusBar'; import ModalNavBar from '../nav/ModalNavBar'; import ModalSearchNavBar from '../nav/ModalSearchNavBar'; import { getSession } from '../directSelectors'; +import { DEFAULT_TITLE_BACKGROUND_COLOR } from '../title/titleSelectors'; const componentStyles = createStyleSheet({ screen: { @@ -119,8 +120,12 @@ class Screen extends PureComponent { style, title, shouldShowLoadingBanner, + orientation, } = this.props; + // This'll go away very soon, of course. + const statusBarHidden = false; + return ( { { paddingBottom: insets.bottom }, ]} > + {orientation === 'PORTRAIT' && ( + + )} {search ? ( { static defaultProps = { @@ -54,20 +57,19 @@ class ZulipStatusBar extends PureComponent { render() { const { theme, hidden, insets, orientation } = this.props; const backgroundColor = this.props.backgroundColor; + // We'll remove this soon. + // eslint-disable-next-line no-unused-vars const style = { height: hidden ? 0 : insets.top, backgroundColor }; const statusBarColor = getStatusBarColor(backgroundColor, theme); return ( orientation === 'PORTRAIT' && ( - <> - -