From 136b796ac32f1b08a6b6256bcb3259b51eead4d6 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Thu, 30 Jun 2022 11:14:07 -0400 Subject: [PATCH] Fix theming and navigation stack tracking (#6443) --- .../channel_actions/info_box/index.tsx | 1 - app/components/markdown/hashtag/index.tsx | 4 +- .../post/body/reactions/reactions.tsx | 2 +- app/constants/screens.ts | 14 +++++- app/context/theme/index.tsx | 50 +++++++++++-------- app/screens/channel/header/header.tsx | 1 - app/screens/custom_status/index.tsx | 2 +- .../quick_options/quick_options.tsx | 6 +-- .../header/plus_menu/index.tsx | 6 +-- app/screens/navigation.ts | 26 +--------- .../post_options/options/edit_option.tsx | 1 - .../reaction_bar/reaction_bar.tsx | 2 +- app/utils/server/index.ts | 1 - app/utils/theme/index.ts | 13 +++-- test/setup.ts | 1 - 15 files changed, 62 insertions(+), 68 deletions(-) diff --git a/app/components/channel_actions/info_box/index.tsx b/app/components/channel_actions/info_box/index.tsx index ec3cad4aba..6d236197fb 100644 --- a/app/components/channel_actions/info_box/index.tsx +++ b/app/components/channel_actions/info_box/index.tsx @@ -37,7 +37,6 @@ const InfoBox = ({channelId, containerStyle, showAsLabel = false, testID}: Props testID: 'close.channel_info.button', }], }, - modal: {swipeToDismiss: false}, }; showModal(Screens.CHANNEL_INFO, title, {channelId, closeButtonId}, options); }, [intl, channelId, theme]); diff --git a/app/components/markdown/hashtag/index.tsx b/app/components/markdown/hashtag/index.tsx index e7327fd4f3..5d40580ebe 100644 --- a/app/components/markdown/hashtag/index.tsx +++ b/app/components/markdown/hashtag/index.tsx @@ -4,7 +4,7 @@ import React from 'react'; import {Text, TextStyle} from 'react-native'; -import {popToRoot, showSearchModal, dismissAllModals} from '@screens/navigation'; +import {popToRoot, dismissAllModals} from '@screens/navigation'; type HashtagProps = { hashtag: string; @@ -17,7 +17,7 @@ const Hashtag = ({hashtag, linkStyle}: HashtagProps) => { await dismissAllModals(); await popToRoot(); - showSearchModal('#' + hashtag); + // showSearchModal('#' + hashtag); }; return ( diff --git a/app/components/post_list/post/body/reactions/reactions.tsx b/app/components/post_list/post/body/reactions/reactions.tsx index e875b2e99e..420bafe013 100644 --- a/app/components/post_list/post/body/reactions/reactions.tsx +++ b/app/components/post_list/post/body/reactions/reactions.tsx @@ -120,7 +120,7 @@ const Reactions = ({currentUserId, canAddReaction, canRemoveReaction, disabled, onEmojiPress: handleAddReactionToPost, }; - showModal(Screens.EMOJI_PICKER, title, passProps, {modal: {swipeToDismiss: false}}); + showModal(Screens.EMOJI_PICKER, title, passProps); }), [intl, theme]); const handleReactionPress = useCallback(async (emoji: string, remove: boolean) => { diff --git a/app/constants/screens.ts b/app/constants/screens.ts index 84f655f120..dba5ad7293 100644 --- a/app/constants/screens.ts +++ b/app/constants/screens.ts @@ -117,7 +117,7 @@ export default { USER_PROFILE, }; -export const MODAL_SCREENS_WITHOUT_BACK = [ +export const MODAL_SCREENS_WITHOUT_BACK = new Set([ BROWSE_CHANNELS, CHANNEL_INFO, CREATE_DIRECT_MESSAGE, @@ -131,7 +131,17 @@ export const MODAL_SCREENS_WITHOUT_BACK = [ GALLERY, PERMALINK, REACTIONS, -]; +]); + +export const SCREENS_WITH_TRANSPARENT_BACKGROUND = new Set([ + BOTTOM_SHEET, + POST_OPTIONS, + THREAD_OPTIONS, + PERMALINK, + REACTIONS, + SNACK_BAR, + USER_PROFILE, +]); export const NOT_READY = [ CHANNEL_ADD_PEOPLE, diff --git a/app/context/theme/index.tsx b/app/context/theme/index.tsx index 4b5ab6c4c7..68e0730b78 100644 --- a/app/context/theme/index.tsx +++ b/app/context/theme/index.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import withObservables from '@nozbe/with-observables'; -import React, {ComponentType, createContext, useEffect} from 'react'; +import React, {ComponentType, createContext, useEffect, useState} from 'react'; import {Appearance} from 'react-native'; import {Preferences} from '@constants'; @@ -33,35 +33,43 @@ export function getDefaultThemeByAppearance(): Theme { export const ThemeContext = createContext(getDefaultThemeByAppearance()); const {Consumer, Provider} = ThemeContext; -const ThemeProvider = ({currentTeamId, children, themes}: Props) => { - const getTheme = (): Theme => { - if (currentTeamId) { - const teamTheme = themes.find((t) => t.name === currentTeamId) || themes[0]; - if (teamTheme?.value) { - try { - const theme = setThemeDefaults(JSON.parse(teamTheme.value)); - updateThemeIfNeeded(theme); - - return theme; - } catch { - // no theme change - } +const getTheme = (teamId: string | undefined, themes: PreferenceModel[]): Theme => { + if (teamId) { + const teamTheme = themes.find((t) => t.name === teamId) || themes[0]; + if (teamTheme?.value) { + try { + const theme = setThemeDefaults(JSON.parse(teamTheme.value)); + return theme; + } catch { + // no theme change } } + } - const defaultTheme = getDefaultThemeByAppearance(); - updateThemeIfNeeded(defaultTheme); + const defaultTheme = getDefaultThemeByAppearance(); - return defaultTheme; - }; + return defaultTheme; +}; + +const ThemeProvider = ({currentTeamId, children, themes}: Props) => { + const [theme, setTheme] = useState(() => getTheme(currentTeamId, themes)); useEffect(() => { - const listener = Appearance.addChangeListener(getTheme); + const listener = Appearance.addChangeListener(() => { + const newTheme = getTheme(currentTeamId, themes); + if (theme !== newTheme) { + setTheme(newTheme); + } + }); return () => listener.remove(); - }, []); + }, [currentTeamId, themes, theme]); - return ({children}); + useEffect(() => { + updateThemeIfNeeded(theme); + }, [theme]); + + return ({children}); }; export function withTheme(Component: ComponentType): ComponentType { diff --git a/app/screens/channel/header/header.tsx b/app/screens/channel/header/header.tsx index 6c6fedb8e4..8ccdbbec72 100644 --- a/app/screens/channel/header/header.tsx +++ b/app/screens/channel/header/header.tsx @@ -114,7 +114,6 @@ const ChannelHeader = ({ testID: 'close.channel_info.button', }], }, - modal: {swipeToDismiss: false}, }; showModal(Screens.CHANNEL_INFO, title, {channelId, closeButtonId}, options); }), [channelId, channelType, intl, theme]); diff --git a/app/screens/custom_status/index.tsx b/app/screens/custom_status/index.tsx index 2d34c6d038..0fae454b18 100644 --- a/app/screens/custom_status/index.tsx +++ b/app/screens/custom_status/index.tsx @@ -284,7 +284,7 @@ class CustomStatusModal extends NavigationComponent { const title = intl.formatMessage({id: 'mobile.custom_status.choose_emoji', defaultMessage: 'Choose an emoji'}); const passProps = {closeButton: source, onEmojiPress: this.handleEmojiClick}; - showModal(screen, title, passProps, {modal: {swipeToDismiss: false}}); + showModal(screen, title, passProps); }); }); diff --git a/app/screens/find_channels/quick_options/quick_options.tsx b/app/screens/find_channels/quick_options/quick_options.tsx index 1811939b2a..db817db0ea 100644 --- a/app/screens/find_channels/quick_options/quick_options.tsx +++ b/app/screens/find_channels/quick_options/quick_options.tsx @@ -43,14 +43,14 @@ const QuickOptions = ({canCreateChannels, canJoinChannels, close}: Props) => { await close(); showModal(Screens.BROWSE_CHANNELS, title, { closeButton, - }, {modal: {swipeToDismiss: false}}); + }); }, [intl, theme]); const createNewChannel = useCallback(async () => { const title = intl.formatMessage({id: 'mobile.create_channel.title', defaultMessage: 'New channel'}); await close(); - showModal(Screens.CREATE_OR_EDIT_CHANNEL, title, undefined, {modal: {swipeToDismiss: false}}); + showModal(Screens.CREATE_OR_EDIT_CHANNEL, title); }, [intl]); const openDirectMessage = useCallback(async () => { @@ -60,7 +60,7 @@ const QuickOptions = ({canCreateChannels, canJoinChannels, close}: Props) => { await close(); showModal(Screens.CREATE_DIRECT_MESSAGE, title, { closeButton, - }, {modal: {swipeToDismiss: false}}); + }); }, [intl, theme]); return ( diff --git a/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx b/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx index cfed362825..40b854e747 100644 --- a/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx +++ b/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx @@ -28,14 +28,14 @@ const PlusMenuList = ({canCreateChannels, canJoinChannels}: Props) => { showModal(Screens.BROWSE_CHANNELS, title, { closeButton, - }, {modal: {swipeToDismiss: false}}); + }); }, [intl, theme]); const createNewChannel = useCallback(async () => { await dismissBottomSheet(); const title = intl.formatMessage({id: 'mobile.create_channel.title', defaultMessage: 'New channel'}); - showModal(Screens.CREATE_OR_EDIT_CHANNEL, title, undefined, {modal: {swipeToDismiss: false}}); + showModal(Screens.CREATE_OR_EDIT_CHANNEL, title); }, [intl]); const openDirectMessage = useCallback(async () => { @@ -45,7 +45,7 @@ const PlusMenuList = ({canCreateChannels, canJoinChannels}: Props) => { const closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor); showModal(Screens.CREATE_DIRECT_MESSAGE, title, { closeButton, - }, {modal: {swipeToDismiss: false}}); + }); }, [intl, theme]); return ( diff --git a/app/screens/navigation.ts b/app/screens/navigation.ts index 8747e4e8e2..047272dc7c 100644 --- a/app/screens/navigation.ts +++ b/app/screens/navigation.ts @@ -84,9 +84,6 @@ export const bottomSheetModalOptions = (theme: Theme, closeButtonId?: string) => const closeButtonTestId = `${closeButtonId.replace('close-', 'close.').replace(/-/g, '_')}.button`; return { modalPresentationStyle: OptionsModalPresentationStyle.formSheet, - modal: { - swipeToDismiss: true, - }, topBar: { leftButtons: [{ id: closeButtonId, @@ -117,7 +114,6 @@ export const bottomSheetModalOptions = (theme: Theme, closeButtonId?: string) => ios: OptionsModalPresentationStyle.overFullScreen, default: OptionsModalPresentationStyle.overCurrentContext, }), - modal: {swipeToDismiss: true}, statusBar: { backgroundColor: null, drawBehind: true, @@ -465,6 +461,7 @@ export function showModal(name: string, title: string, passProps = {}, options = leftButtonColor: theme.sidebarHeaderTextColor, rightButtonColor: theme.sidebarHeaderTextColor, }, + modal: {swipeToDismiss: false}, }; NavigationStore.addNavigationModal(name); @@ -544,25 +541,6 @@ export function showModalOverCurrentContext(name: string, passProps = {}, option showModal(name, title, passProps, mergeOptions); } -export function showSearchModal(initialValue = '') { - const name = 'Search'; - const title = ''; - const passProps = {initialValue}; - const options = { - topBar: { - visible: false, - height: 0, - }, - ...Platform.select({ - ios: { - modalPresentationStyle: 'pageSheet', - }, - }), - }; - - showModal(name, title, passProps, options); -} - export async function dismissModal(options?: Options & { componentId: string}) { if (!NavigationStore.hasModalsOpened()) { return; @@ -717,7 +695,7 @@ export const showAppForm = async (form: AppForm, call: AppCallRequest) => { }; export async function findChannels(title: string, theme: Theme) { - const options: Options = {modal: {swipeToDismiss: false}}; + const options: Options = {}; const closeButtonId = 'close-find-channels'; const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor); options.topBar = { diff --git a/app/screens/post_options/options/edit_option.tsx b/app/screens/post_options/options/edit_option.tsx index 1bbcea719f..a5f8d47dcf 100644 --- a/app/screens/post_options/options/edit_option.tsx +++ b/app/screens/post_options/options/edit_option.tsx @@ -29,7 +29,6 @@ const EditOption = ({post, canDelete}: Props) => { const closeButtonId = 'close-edit-post'; const passProps = {post, closeButtonId, canDelete}; const options = { - modal: {swipeToDismiss: false}, topBar: { leftButtons: [{ id: closeButtonId, diff --git a/app/screens/post_options/reaction_bar/reaction_bar.tsx b/app/screens/post_options/reaction_bar/reaction_bar.tsx index 116ed85e62..24690b4a67 100644 --- a/app/screens/post_options/reaction_bar/reaction_bar.tsx +++ b/app/screens/post_options/reaction_bar/reaction_bar.tsx @@ -62,7 +62,7 @@ const ReactionBar = ({recentEmojis = [], postId}: QuickReactionProps) => { const title = intl.formatMessage({id: 'mobile.post_info.add_reaction', defaultMessage: 'Add Reaction'}); const passProps = {closeButton, onEmojiPress: handleEmojiPress}; - showModal(screen, title, passProps, {modal: {swipeToDismiss: false}}); + showModal(screen, title, passProps); }, [intl, theme]); let containerSize = LARGE_CONTAINER_SIZE; diff --git a/app/utils/server/index.ts b/app/utils/server/index.ts index bf9687bf85..022552d9f5 100644 --- a/app/utils/server/index.ts +++ b/app/utils/server/index.ts @@ -241,7 +241,6 @@ function buildServerModalOptions(theme: Theme, closeButtonId: string) { backgroundColor: theme.centerChannelBg, componentBackgroundColor: theme.centerChannelBg, }, - modal: {swipeToDismiss: false}, topBar: { visible: true, drawBehind: true, diff --git a/app/utils/theme/index.ts b/app/utils/theme/index.ts index 9719fcda15..3f5217e538 100644 --- a/app/utils/theme/index.ts +++ b/app/utils/theme/index.ts @@ -6,7 +6,7 @@ import {StatusBar, StyleSheet} from 'react-native'; import tinyColor from 'tinycolor2'; import {Preferences} from '@constants'; -import {MODAL_SCREENS_WITHOUT_BACK} from '@constants/screens'; +import {MODAL_SCREENS_WITHOUT_BACK, SCREENS_WITH_TRANSPARENT_BACKGROUND} from '@constants/screens'; import EphemeralStore from '@store/ephemeral_store'; import NavigationStore from '@store/navigation_store'; import {appearanceControlledScreens, mergeNavigationOptions} from '@utils/navigation'; @@ -96,12 +96,15 @@ export function setNavigatorStyles(componentId: string, theme: Theme, additional backgroundColor: theme.sidebarBg, style: isDark ? 'light' : 'dark', }, - layout: { - componentBackgroundColor: theme.centerChannelBg, - }, }; - if (!MODAL_SCREENS_WITHOUT_BACK.includes(componentId) && options.topBar) { + if (!SCREENS_WITH_TRANSPARENT_BACKGROUND.has(componentId)) { + options.layout = { + componentBackgroundColor: theme.centerChannelBg, + }; + } + + if (!MODAL_SCREENS_WITHOUT_BACK.has(componentId) && options.topBar) { options.topBar.backButton = { color: theme.sidebarHeaderTextColor, }; diff --git a/test/setup.ts b/test/setup.ts index d0e714b728..6e4eed3afb 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -332,7 +332,6 @@ jest.mock('@screens/navigation', () => ({ popTopScreen: jest.fn(), showModal: jest.fn(), showModalOverCurrentContext: jest.fn(), - showSearchModal: jest.fn(), setButtons: jest.fn(), showOverlay: jest.fn(), mergeNavigationOptions: jest.fn(),