From 8899c586ab85f2fc3de3f768ae46d86accfce710 Mon Sep 17 00:00:00 2001 From: Mattermost Build Date: Tue, 24 Nov 2020 01:24:06 +0100 Subject: [PATCH] MM-30164 fix safe area insets (#4979) (#4984) * MM-30164 fix safe area insets * Fix unit test setup mock for react-native-device-info * Add insets for edit profile screen * Fix about screen * Fix theme screen * Lock phone screen to portrait * fix unit tests * Fix autocomplete layout (cherry picked from commit dcaaaee44c6c0a613c463dc22f9290f521ec09b4) Co-authored-by: Elias Nahum --- app/actions/navigation/index.js | 8 +- .../announcement_banner.test.js.snap | 232 +++++---- .../announcement_banner.js | 183 +++---- .../announcement_banner.test.js | 5 +- app/components/announcement_banner/index.js | 2 - .../autocomplete/at_mention/at_mention.js | 2 - .../autocomplete/at_mention/index.js | 2 - .../at_mention_group/at_mention_group.js | 79 ++- .../at_mention_item/at_mention_item.js | 241 +++++---- .../autocomplete/at_mention_item/index.js | 10 +- app/components/autocomplete/autocomplete.js | 12 +- .../autocomplete_section_header.js | 91 ++-- .../channel_mention/channel_mention.js | 2 - .../autocomplete/channel_mention/index.js | 7 +- .../channel_mention_item.js | 191 ++++--- .../channel_mention_item/index.js | 7 +- .../autocomplete/slash_suggestion/index.js | 2 - .../slash_suggestion/slash_suggestion.js | 10 +- .../slash_suggestion/slash_suggestion_item.js | 135 +++-- .../autocomplete_selector.js | 17 +- app/components/autocomplete_selector/index.js | 2 - app/components/channel_intro/channel_intro.js | 10 +- app/components/channel_intro/index.js | 2 - .../__snapshots__/channel_loader.test.js.snap | 1 - .../channel_loader/channel_loader.js | 9 +- .../channel_loader/channel_loader.test.js | 1 - app/components/channel_loader/index.js | 3 - .../__snapshots__/index.test.js.snap | 11 +- .../channel_list_row/channel_list_row.js | 2 - .../custom_list/channel_list_row/index.js | 2 - app/components/custom_list/custom_list_row.js | 6 +- app/components/custom_list/index.js | 7 +- .../custom_list/option_list_row/index.js | 2 - .../option_list_row/option_list_row.js | 7 - .../__snapshots__/user_list_test.test.js.snap | 4 - .../custom_list/user_list_row/index.js | 2 - .../user_list_row/user_list_row.js | 2 - .../user_list_row/user_list_test.test.js | 1 - .../edit_channel_info.test.js.snap | 146 ++---- .../edit_channel_info/edit_channel_info.js | 453 ---------------- .../edit_channel_info.test.js | 3 +- app/components/edit_channel_info/index.js | 451 +++++++++++++++- .../__snapshots__/emoji_picker.test.js.snap | 93 ++-- .../emoji_picker/emoji_picker.ios.js | 51 +- .../emoji_picker/emoji_picker.test.js | 12 - .../emoji_picker/emoji_picker_base.js | 6 +- app/components/emoji_picker/index.js | 4 +- .../network_indicator.test.js.snap | 6 + .../network_indicator/network_indicator.js | 60 +-- app/components/post/index.js | 2 - app/components/post/post.js | 5 +- .../__snapshots__/post_draft.test.js.snap | 92 ++-- .../post_draft/draft_input/draft_input.js | 13 +- .../post_draft/post_input/post_input.test.js | 1 - .../__snapshots__/read_only.test.js.snap | 9 +- app/components/post_draft/read_only/index.tsx | 10 +- app/components/post_draft/typing/typing.js | 19 +- .../more_messages_button.test.js.snap | 2 +- .../more_messages_button.js | 2 +- .../reaction_picker.test.js.snap | 42 +- app/components/reaction_picker/index.js | 4 - .../reaction_picker/reaction_picker.js | 150 +++--- .../reaction_picker/reaction_picker.test.js | 2 - .../safe_area_view.ios.test.js.snap | 32 -- app/components/safe_area_view/index.js | 2 +- .../safe_area_view/iphone_x_spacing/index.js | 20 - app/components/safe_area_view/safe_area.tsx | 84 +++ .../safe_area_view/safe_area_view.android.js | 8 - .../safe_area_view/safe_area_view.ios.js | 243 --------- .../safe_area_view/safe_area_view.ios.test.js | 305 ----------- .../{ => drawer_layout}/drawer_layout.js | 4 - .../sidebars/drawer_layout/index.tsx | 57 ++ .../__snapshots__/main_sidebar.test.js.snap | 8 +- .../__snapshots__/channel_item.test.js.snap | 9 - .../channel_item/channel_item.js | 5 +- .../channel_item/channel_item.test.js | 1 - .../main/channels_list/channel_item/index.js | 6 +- .../main/channels_list/channels_list.js | 16 +- .../filtered_list/filtered_list.js | 26 +- .../main/channels_list/filtered_list/index.js | 2 - .../sidebars/main/channels_list/index.js | 2 - .../sidebars/main/channels_list/list/index.js | 5 +- .../sidebars/main/channels_list/list/list.js | 22 +- .../sidebars/main/main_sidebar.ios.js | 9 +- .../sidebars/main/main_sidebar.test.js | 34 +- .../sidebars/main/main_sidebar_base.js | 14 +- .../sidebars/main/teams_list/teams_list.js | 13 +- .../main/teams_list/teams_list_item/index.js | 3 - .../teams_list_item/teams_list_item.js | 5 +- .../settings_sidebar.test.js.snap | 8 +- .../settings/settings_sidebar.android.js | 4 +- .../sidebars/settings/settings_sidebar.ios.js | 36 +- .../settings/settings_sidebar_base.js | 6 +- .../slide_up_panel/slide_up_panel.js | 58 ++- .../__snapshots__/radio_setting.test.js.snap | 60 +-- .../widgets/settings/bool_setting.js | 23 +- .../widgets/settings/bool_setting.test.js | 1 - .../widgets/settings/radio_setting.js | 13 +- .../widgets/settings/text_setting.js | 14 +- app/constants/device.js | 5 +- app/constants/view.js | 2 + app/screens/about/about.js | 16 +- app/screens/about/index.js | 2 - app/screens/add_reaction/index.js | 121 +++-- app/screens/channel/channel.android.js | 2 + app/screens/channel/channel.ios.js | 37 +- .../channel_nav_bar.test.js.snap | 109 ++-- .../channel_nav_bar/channel_nav_bar.js | 225 ++++---- .../channel_nav_bar/channel_nav_bar.test.js | 113 +--- .../channel_post_list.test.js.snap | 1 - .../channel_post_list/channel_post_list.js | 20 +- .../channel_add_members.js | 77 ++- .../channel_add_members.test.js | 1 - app/screens/channel_add_members/index.js | 2 - .../__snapshots__/channel_info.test.js.snap | 40 +- .../channel_info_header.test.js.snap | 148 ++---- .../channel_info_row.test.js.snap | 15 +- .../__snapshots__/add_members.test.js.snap | 1 - .../add_members/add_members.test.js | 1 - .../channel_info/add_members/add_members.tsx | 4 +- .../__snapshots__/archive.test.js.snap | 2 - .../channel_info/archive/archive.test.js | 1 - app/screens/channel_info/archive/archive.tsx | 5 +- app/screens/channel_info/channel_info.js | 22 +- app/screens/channel_info/channel_info.test.js | 1 - .../channel_info/channel_info_header.js | 17 +- .../channel_info/channel_info_header.test.js | 1 - app/screens/channel_info/channel_info_row.js | 5 +- .../channel_info/channel_info_row.test.js | 1 - .../convert_private.test.js.snap | 1 - .../convert_private/convert_private.test.js | 1 - .../convert_private/convert_private.tsx | 4 +- .../__snapshots__/edit_channel.test.js.snap | 1 - .../edit_channel/edit_channel.test.js | 1 - .../edit_channel/edit_channel.tsx | 4 +- .../__snapshots__/favorite.test.js.snap | 2 - .../channel_info/favorite/favorite.test.js | 1 - .../channel_info/favorite/favorite.tsx | 4 +- .../ignore_mentions.test.js.snap | 2 - .../ignore_mentions/ignore_mentions.test.js | 1 - .../ignore_mentions/ignore_mentions.tsx | 4 +- .../leave/__snapshots__/leave.test.js.snap | 4 - app/screens/channel_info/leave/leave.test.js | 1 - app/screens/channel_info/leave/leave.tsx | 5 +- .../__snapshots__/manage_members.test.js.snap | 3 - .../manage_members/manage_members.test.js | 1 - .../manage_members/manage_members.tsx | 4 +- .../mute/__snapshots__/mute.test.js.snap | 2 - app/screens/channel_info/mute/mute.test.js | 1 - app/screens/channel_info/mute/mute.tsx | 4 +- .../notification_preference.test.js.snap | 1 - .../notification_preference.test.js | 1 - .../notification_preference.tsx | 4 +- .../pinned/__snapshots__/pinned.test.js.snap | 1 - .../channel_info/pinned/pinned.test.js | 1 - app/screens/channel_info/pinned/pinned.tsx | 4 +- .../channel_members.test.js.snap | 109 ++-- .../channel_members/channel_members.js | 96 ++-- .../channel_members/channel_members.test.js | 1 - app/screens/channel_members/index.js | 2 - ...annel_notification_preference.test.js.snap | 102 ++-- .../channel_notification_preference.ios.js | 44 +- .../channel_notification_preference.test.js | 1 - .../channel_notification_preference_base.js | 1 - app/screens/client_upgrade/client_upgrade.js | 5 +- app/screens/code/code.js | 35 +- app/screens/code/index.js | 2 - app/screens/create_channel/create_channel.js | 10 +- app/screens/create_channel/index.js | 4 - app/screens/edit_channel/edit_channel.js | 56 +- app/screens/edit_channel/index.js | 4 - .../__snapshots__/edit_post.test.js.snap | 5 +- app/screens/edit_post/edit_post.js | 11 +- app/screens/edit_post/edit_post.test.js | 1 - app/screens/edit_post/index.js | 3 +- app/screens/edit_profile/edit_profile.js | 9 +- app/screens/edit_profile/edit_profile.test.js | 1 - .../error_teams_list.test.js.snap | 4 +- .../error_teams_list/error_teams_list.js | 11 +- .../expanded_announcement_banner.js | 8 +- .../forgot_password.test.js.snap | 12 +- .../forgot_password/forgot_password.js | 5 +- .../footer/prepare_file/prepare_file.tsx | 5 +- .../gallery/footer/summary/summary.tsx | 10 +- app/screens/gallery/video_controls.tsx | 45 +- app/screens/index.js | 14 +- .../dialog_introduction_text.test.js.snap | 9 +- .../interactive_dialog.test.js.snap | 5 +- .../interactive_dialog/dialog_element.js | 6 - .../interactive_dialog/dialog_element.test.js | 1 - .../dialog_introduction_text.js | 5 +- .../dialog_introduction_text.test.js | 1 - .../interactive_dialog/interactive_dialog.js | 26 +- app/screens/login/index.js | 2 - app/screens/login/login.js | 9 +- app/screens/login/login.test.js | 1 - app/screens/login_options/index.js | 2 - app/screens/login_options/login_options.js | 65 +-- .../__snapshots__/long_post.test.js.snap | 17 +- app/screens/long_post/index.js | 2 - app/screens/long_post/long_post.js | 5 +- app/screens/long_post/long_post.test.js | 1 - app/screens/mfa/mfa.js | 79 +-- .../__snapshots__/more_channels.test.js.snap | 209 ++++---- app/screens/more_channels/index.js | 9 +- app/screens/more_channels/more_channels.js | 76 ++- .../more_channels/more_channels.test.js | 1 - app/screens/more_dms/index.js | 7 +- app/screens/more_dms/more_dms.js | 92 ++-- .../options_modal_list.test.js.snap | 288 ++++++----- app/screens/options_modal/index.js | 3 +- app/screens/options_modal/options_modal.js | 3 - .../options_modal/options_modal_list.ios.js | 41 +- .../options_modal/options_modal_list.test.js | 1 - .../__snapshots__/permalink.test.js.snap | 15 +- app/screens/permalink/index.js | 2 - app/screens/permalink/permalink.js | 6 +- app/screens/permalink/permalink.test.js | 1 - .../__snapshots__/pinned_posts.test.js.snap | 33 +- app/screens/pinned_posts/pinned_posts.js | 9 +- .../__snapshots__/post_options.test.js.snap | 14 - app/screens/post_options/index.js | 3 +- app/screens/post_options/index.test.js | 1 - app/screens/post_options/post_option.js | 6 +- app/screens/post_options/post_options.js | 7 +- app/screens/post_options/post_options.test.js | 1 - .../reaction_header.test.js.snap | 3 +- .../__snapshots__/reaction_list.test.js.snap | 8 +- app/screens/reaction_list/reaction_header.js | 5 +- .../reaction_list/reaction_header.test.js | 1 - app/screens/reaction_list/reaction_list.js | 8 +- .../__snapshots__/reaction_row.test.js.snap | 11 +- .../reaction_list/reaction_row/index.js | 160 +++++- .../reaction_row/reaction_row.js | 164 ------ .../reaction_row/reaction_row.test.js | 3 +- .../recent_mentions.test.js.snap | 12 +- .../recent_mentions/recent_mentions.js | 7 +- .../__snapshots__/saved_posts.test.js.snap} | 18 +- .../{flagged_posts => saved_posts}/index.js | 4 +- .../saved_posts.js} | 7 +- .../saved_posts.test.js} | 12 +- .../__snapshots__/modifier.test.js.snap | 13 +- .../__snapshots__/recent_item.test.js.snap | 15 +- .../channel_display_name.js | 6 +- .../search/channel_display_name/index.js | 2 - app/screens/search/index.js | 2 - app/screens/search/modifier.js | 10 +- app/screens/search/recent_item.js | 10 +- app/screens/search/search.js | 73 ++- .../search/search_result_post/index.js | 2 +- .../search_result_post/search_result_post.js | 2 +- app/screens/select_server/select_server.js | 2 +- .../__snapshots__/select_team.test.js.snap | 16 +- app/screens/select_team/index.js | 2 - app/screens/select_team/select_team.js | 17 +- app/screens/select_team/select_team.test.js | 1 - .../selector_screen.test.js.snap | 486 ++++++++---------- app/screens/selector_screen/index.js | 2 - .../selector_screen/selector_screen.js | 74 ++- .../selector_screen/selector_screen.test.js | 1 - .../advanced_settings/advanced_settings.js | 16 +- .../settings/advanced_settings/index.js | 2 - .../clock_display/clock_display.ios.js | 13 +- app/screens/settings/clock_display/index.js | 2 - .../display_settings.test.js.snap | 23 +- .../display_settings/display_settings.js | 29 +- .../display_settings/display_settings.test.js | 1 - .../settings/display_settings/index.js | 7 +- app/screens/settings/general/index.js | 2 - app/screens/settings/general/settings.js | 23 +- .../notification_settings.test.js.snap | 15 +- .../notification_settings.js | 13 +- .../notification_settings.test.js | 1 - .../index.js | 2 - .../notification_settings_auto_responder.js | 19 +- ...tification_settings_email.ios.test.js.snap | 3 - .../notification_settings_email/index.js | 2 - .../notification_settings_email.ios.js | 31 +- .../notification_settings_email.ios.test.js | 1 - .../notification_settings_mentions/index.js | 2 - .../notification_settings_mentions.ios.js | 35 +- ...on_settings_mentions_keywords.test.js.snap | 40 +- .../index.js | 2 - ...notification_settings_mentions_keywords.js | 26 +- ...ication_settings_mentions_keywords.test.js | 1 - .../notification_settings_mobile/index.js | 2 - .../notification_settings_mobile.ios.js | 30 +- app/screens/settings/section.js | 7 +- app/screens/settings/section_item.js | 4 +- app/screens/settings/settings_item/index.js | 8 +- .../__snapshots__/sidebar.test.js.snap | 12 +- app/screens/settings/sidebar/index.js | 16 +- app/screens/settings/sidebar/sidebar.test.js | 1 - .../theme/__snapshots__/theme.test.js.snap | 4 - app/screens/settings/theme/theme.js | 17 +- app/screens/settings/theme/theme.test.js | 1 - app/screens/settings/timezone/index.js | 2 - .../timezone/select_timezone/index.js | 2 - .../select_timezone/select_timezone.js | 66 ++- .../select_timezone/select_timezone_row.js | 6 +- app/screens/settings/timezone/timezone.js | 13 +- app/screens/sso/index.js | 2 - app/screens/sso/sso.js | 9 +- app/screens/table/index.js | 68 ++- app/screens/table/table.js | 69 --- .../terms_of_service.test.js.snap | 30 +- .../terms_of_service/terms_of_service.js | 5 +- .../__snapshots__/thread.ios.test.js.snap | 12 +- .../__snapshots__/user_profile.test.js.snap | 119 +---- app/screens/user_profile/index.js | 6 +- app/screens/user_profile/user_profile.js | 37 +- app/screens/user_profile/user_profile.test.js | 1 - app/screens/user_profile/user_profile_row.js | 7 +- app/utils/images.js | 1 + package-lock.json | 14 +- test/setup.js | 2 + 316 files changed, 3800 insertions(+), 5091 deletions(-) delete mode 100644 app/components/edit_channel_info/edit_channel_info.js delete mode 100644 app/components/safe_area_view/__snapshots__/safe_area_view.ios.test.js.snap delete mode 100644 app/components/safe_area_view/iphone_x_spacing/index.js create mode 100644 app/components/safe_area_view/safe_area.tsx delete mode 100644 app/components/safe_area_view/safe_area_view.android.js delete mode 100644 app/components/safe_area_view/safe_area_view.ios.js delete mode 100644 app/components/safe_area_view/safe_area_view.ios.test.js rename app/components/sidebars/{ => drawer_layout}/drawer_layout.js (99%) create mode 100644 app/components/sidebars/drawer_layout/index.tsx delete mode 100644 app/screens/reaction_list/reaction_row/reaction_row.js rename app/screens/{flagged_posts/__snapshots__/flagged_posts.test.js.snap => saved_posts/__snapshots__/saved_posts.test.js.snap} (81%) rename app/screens/{flagged_posts => saved_posts}/index.js (95%) rename app/screens/{flagged_posts/flagged_posts.js => saved_posts/saved_posts.js} (97%) rename app/screens/{flagged_posts/flagged_posts.test.js => saved_posts/saved_posts.test.js} (92%) delete mode 100644 app/screens/table/table.js diff --git a/app/actions/navigation/index.js b/app/actions/navigation/index.js index 6d4ea2636..ec96ca1ea 100644 --- a/app/actions/navigation/index.js +++ b/app/actions/navigation/index.js @@ -9,9 +9,15 @@ import {Preferences} from '@mm-redux/constants'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import EventEmmiter from '@mm-redux/utils/event_emitter'; +import {DeviceTypes, NavigationTypes} from '@constants'; import EphemeralStore from '@store/ephemeral_store'; import Store from '@store/store'; -import {NavigationTypes} from '@constants'; + +Navigation.setDefaultOptions({ + layout: { + orientation: [DeviceTypes.IS_TABLET ? undefined : 'portrait'], + }, +}); function getThemeFromState() { const state = Store.redux?.getState() || {}; diff --git a/app/components/announcement_banner/__snapshots__/announcement_banner.test.js.snap b/app/components/announcement_banner/__snapshots__/announcement_banner.test.js.snap index ec043ae11..e62ee7b9f 100644 --- a/app/components/announcement_banner/__snapshots__/announcement_banner.test.js.snap +++ b/app/components/announcement_banner/__snapshots__/announcement_banner.test.js.snap @@ -1,121 +1,133 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`AnnouncementBanner should match snapshot 1`] = ` - - - - - - - - + } + theme={ + Object { + "awayIndicator": "#ffbc42", + "buttonBg": "#166de0", + "buttonColor": "#ffffff", + "centerChannelBg": "#ffffff", + "centerChannelColor": "#3d3c40", + "codeTheme": "github", + "dndIndicator": "#f74343", + "errorTextColor": "#fd5960", + "linkColor": "#2389d7", + "mentionBg": "#ffffff", + "mentionBj": "#ffffff", + "mentionColor": "#145dbf", + "mentionHighlightBg": "#ffe577", + "mentionHighlightLink": "#166de0", + "newMessageSeparator": "#ff8800", + "onlineIndicator": "#06d6a0", + "sidebarBg": "#145dbf", + "sidebarHeaderBg": "#1153ab", + "sidebarHeaderTextColor": "#ffffff", + "sidebarText": "#ffffff", + "sidebarTextActiveBorder": "#579eff", + "sidebarTextActiveColor": "#ffffff", + "sidebarTextHoverBg": "#4578bf", + "sidebarUnreadText": "#ffffff", + "type": "Mattermost", + } + } +/> `; exports[`AnnouncementBanner should match snapshot 2`] = ` - - - - - - - - + } + theme={ + Object { + "awayIndicator": "#ffbc42", + "buttonBg": "#166de0", + "buttonColor": "#ffffff", + "centerChannelBg": "#ffffff", + "centerChannelColor": "#3d3c40", + "codeTheme": "github", + "dndIndicator": "#f74343", + "errorTextColor": "#fd5960", + "linkColor": "#2389d7", + "mentionBg": "#ffffff", + "mentionBj": "#ffffff", + "mentionColor": "#145dbf", + "mentionHighlightBg": "#ffe577", + "mentionHighlightLink": "#166de0", + "newMessageSeparator": "#ff8800", + "onlineIndicator": "#06d6a0", + "sidebarBg": "#145dbf", + "sidebarHeaderBg": "#1153ab", + "sidebarHeaderTextColor": "#ffffff", + "sidebarText": "#ffffff", + "sidebarTextActiveBorder": "#579eff", + "sidebarTextActiveColor": "#ffffff", + "sidebarTextHoverBg": "#4578bf", + "sidebarUnreadText": "#ffffff", + "type": "Mattermost", + } + } +/> `; diff --git a/app/components/announcement_banner/announcement_banner.js b/app/components/announcement_banner/announcement_banner.js index 218a067e0..932876626 100644 --- a/app/components/announcement_banner/announcement_banner.js +++ b/app/components/announcement_banner/announcement_banner.js @@ -1,62 +1,33 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import PropTypes from 'prop-types'; import { Animated, - InteractionManager, StyleSheet, Text, TouchableOpacity, } from 'react-native'; -import {intlShape} from 'react-intl'; +import {injectIntl} from 'react-intl'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; +import {goToScreen} from '@actions/navigation'; import CompassIcon from '@components/compass_icon'; import RemoveMarkdown from '@components/remove_markdown'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; -import {goToScreen} from '@actions/navigation'; +import {ViewTypes} from '@constants'; +import EventEmitter from '@mm-redux/utils/event_emitter'; const {View: AnimatedView} = Animated; -export default class AnnouncementBanner extends PureComponent { - static propTypes = { - bannerColor: PropTypes.string, - bannerDismissed: PropTypes.bool, - bannerEnabled: PropTypes.bool, - bannerText: PropTypes.string, - bannerTextColor: PropTypes.string, - theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, - }; - - static contextTypes = { - intl: intlShape, - }; - - state = { - bannerHeight: new Animated.Value(0), - }; - - componentDidMount() { - const {bannerDismissed, bannerEnabled, bannerText} = this.props; - const showBanner = bannerEnabled && !bannerDismissed && Boolean(bannerText); - this.toggleBanner(showBanner); - } - - componentDidUpdate(prevProps) { - if (this.props.bannerText !== prevProps.bannerText || - this.props.bannerEnabled !== prevProps.bannerEnabled || - this.props.bannerDismissed !== prevProps.bannerDismissed - ) { - const showBanner = this.props.bannerEnabled && !this.props.bannerDismissed && Boolean(this.props.bannerText); - this.toggleBanner(showBanner); - } - } - - handlePress = () => { - const {intl} = this.context; +const AnnouncementBanner = injectIntl((props) => { + const {bannerColor, bannerDismissed, bannerEnabled, bannerText, bannerTextColor, intl} = props; + const insets = useSafeAreaInsets(); + const translateY = useRef(new Animated.Value(0)).current; + const [visible, setVisible] = useState(false); + const [navHeight, setNavHeight] = useState(0); + const handlePress = () => { const screen = 'ExpandedAnnouncementBanner'; const title = intl.formatMessage({ id: 'mobile.announcement_banner.title', @@ -66,80 +37,88 @@ export default class AnnouncementBanner extends PureComponent { goToScreen(screen, title); }; - toggleBanner = (show = true) => { - const value = show ? 38 : 0; - if (show && !this.state.visible) { - this.setState({visible: show}); - } + useEffect(() => { + const handleNavbarHeight = (height) => { + setNavHeight(height); + }; - InteractionManager.runAfterInteractions(() => { - Animated.timing(this.state.bannerHeight, { - toValue: value, - duration: 350, - useNativeDriver: false, - }).start(() => { - if (this.state.visible !== show) { - this.setState({visible: show}); - } - }); - }); + EventEmitter.on(ViewTypes.CHANNEL_NAV_BAR_CHANGED, handleNavbarHeight); + + return () => EventEmitter.off(ViewTypes.CHANNEL_NAV_BAR_CHANGED, handleNavbarHeight); + }, [insets]); + + useEffect(() => { + const showBanner = bannerEnabled && !bannerDismissed && Boolean(bannerText); + setVisible(showBanner); + EventEmitter.emit(ViewTypes.INDICATOR_BAR_VISIBLE, showBanner); + }, [bannerDismissed, bannerEnabled, bannerText]); + + useEffect(() => { + Animated.timing(translateY, { + toValue: visible ? navHeight : insets.top, + duration: 50, + useNativeDriver: true, + }).start(); + }, [visible, navHeight]); + + if (!visible) { + return null; + } + + const bannerStyle = { + backgroundColor: bannerColor, + height: ViewTypes.INDICATOR_BAR_HEIGHT, + transform: [{translateY}], }; - render() { - if (!this.state.visible) { - return null; - } + const bannerTextStyle = { + color: bannerTextColor, + }; - const {bannerHeight} = this.state; - const { - bannerColor, - bannerText, - bannerTextColor, - isLandscape, - } = this.props; - - const bannerStyle = { - backgroundColor: bannerColor, - height: bannerHeight, - }; - - const bannerTextStyle = { - color: bannerTextColor, - }; - - return ( - + - - - - - - - - ); - } -} + + + + + + ); +}); + +AnnouncementBanner.propTypes = { + bannerColor: PropTypes.string, + bannerDismissed: PropTypes.bool, + bannerEnabled: PropTypes.bool, + bannerText: PropTypes.string, + bannerTextColor: PropTypes.string, +}; + +export default AnnouncementBanner; const style = StyleSheet.create({ bannerContainer: { + elevation: 2, paddingHorizontal: 10, position: 'absolute', top: 0, overflow: 'hidden', width: '100%', + zIndex: 2, }, wrapper: { alignItems: 'center', diff --git a/app/components/announcement_banner/announcement_banner.test.js b/app/components/announcement_banner/announcement_banner.test.js index d12d1a0c7..cd9c529bf 100644 --- a/app/components/announcement_banner/announcement_banner.test.js +++ b/app/components/announcement_banner/announcement_banner.test.js @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import React from 'react'; -import {shallow} from 'enzyme'; +import {shallowWithIntl} from 'test/intl-test-helper'; import Preferences from '@mm-redux/constants/preferences'; @@ -18,11 +18,10 @@ describe('AnnouncementBanner', () => { bannerText: 'Banner Text', bannerTextColor: '#fff', theme: Preferences.THEMES.default, - isLandscape: false, }; test('should match snapshot', () => { - const wrapper = shallow( + const wrapper = shallowWithIntl( , ); diff --git a/app/components/announcement_banner/index.js b/app/components/announcement_banner/index.js index 64d45b7a4..245628431 100644 --- a/app/components/announcement_banner/index.js +++ b/app/components/announcement_banner/index.js @@ -4,7 +4,6 @@ import {connect} from 'react-redux'; import {getConfig, getLicense} from '@mm-redux/selectors/entities/general'; -import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {isLandscape} from 'app/selectors/device'; @@ -21,7 +20,6 @@ function mapStateToProps(state) { bannerEnabled: config.EnableBanner === 'true' && license.IsLicensed === 'true', bannerText: config.BannerText, bannerTextColor: config.BannerTextColor || '#000', - theme: getTheme(state), isLandscape: isLandscape(state), }; } diff --git a/app/components/autocomplete/at_mention/at_mention.js b/app/components/autocomplete/at_mention/at_mention.js index ce65b34f2..18c1ff19e 100644 --- a/app/components/autocomplete/at_mention/at_mention.js +++ b/app/components/autocomplete/at_mention/at_mention.js @@ -35,7 +35,6 @@ export default class AtMention extends PureComponent { teamMembers: PropTypes.array, theme: PropTypes.object.isRequired, value: PropTypes.string, - isLandscape: PropTypes.bool.isRequired, nestedScrollEnabled: PropTypes.bool, useChannelMentions: PropTypes.bool.isRequired, groups: PropTypes.array, @@ -213,7 +212,6 @@ export default class AtMention extends PureComponent { id={section.id} defaultMessage={section.defaultMessage} theme={this.props.theme} - isLandscape={this.props.isLandscape} isFirstSection={isFirstSection} /> ); diff --git a/app/components/autocomplete/at_mention/index.js b/app/components/autocomplete/at_mention/index.js index 1bfc69d08..e83f35572 100644 --- a/app/components/autocomplete/at_mention/index.js +++ b/app/components/autocomplete/at_mention/index.js @@ -10,7 +10,6 @@ import {getLicense} from '@mm-redux/selectors/entities/general'; import {getCurrentChannelId, getDefaultChannel} from '@mm-redux/selectors/entities/channels'; import {getAssociatedGroupsForReference, searchAssociatedGroupsForReferenceLocal} from '@mm-redux/selectors/entities/groups'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; -import {isLandscape} from 'app/selectors/device'; import { filterMembersInChannel, @@ -76,7 +75,6 @@ function mapStateToProps(state, ownProps) { outChannel, requestStatus: state.requests.users.autocompleteUsers.status, theme: getTheme(state), - isLandscape: isLandscape(state), useChannelMentions, groups, }; diff --git a/app/components/autocomplete/at_mention_group/at_mention_group.js b/app/components/autocomplete/at_mention_group/at_mention_group.js index 01d925367..b26200606 100644 --- a/app/components/autocomplete/at_mention_group/at_mention_group.js +++ b/app/components/autocomplete/at_mention_group/at_mention_group.js @@ -1,56 +1,18 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { Text, View, } from 'react-native'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; import CompassIcon from '@components/compass_icon'; import TouchableWithFeedback from '@components/touchable_with_feedback'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; -export default class GroupMentionItem extends PureComponent { - static propTypes = { - completeHandle: PropTypes.string.isRequired, - onPress: PropTypes.func.isRequired, - theme: PropTypes.object.isRequired, - }; - - completeMention = () => { - const {onPress, completeHandle} = this.props; - onPress(completeHandle); - }; - - render() { - const { - completeHandle, - theme, - } = this.props; - - const style = getStyleFromTheme(theme); - - return ( - - - - - {`@${completeHandle}`} - {' - '} - {`${completeHandle}`} - - ); - } -} const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { row: { @@ -85,3 +47,40 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, }; }); + +const GroupMentionItem = (props) => { + const insets = useSafeAreaInsets(); + const {onPress, completeHandle, theme} = props; + + const completeMention = () => { + onPress(completeHandle); + }; + + const style = getStyleFromTheme(theme); + + return ( + + + + + {`@${completeHandle}`} + {' - '} + {`${completeHandle}`} + + ); +}; + +GroupMentionItem.propTypes = { + completeHandle: PropTypes.string.isRequired, + onPress: PropTypes.func.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default GroupMentionItem; diff --git a/app/components/autocomplete/at_mention_item/at_mention_item.js b/app/components/autocomplete/at_mention_item/at_mention_item.js index dfe3099b2..2f8cc7728 100644 --- a/app/components/autocomplete/at_mention_item/at_mention_item.js +++ b/app/components/autocomplete/at_mention_item/at_mention_item.js @@ -1,129 +1,16 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import { - Text, - View, -} from 'react-native'; +import {Text, View} from 'react-native'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import ProfilePicture from 'app/components/profile_picture'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; -import {BotTag, GuestTag} from 'app/components/tag'; -import TouchableWithFeedback from 'app/components/touchable_with_feedback'; -import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme'; -import FormattedText from 'app/components/formatted_text'; - -export default class AtMentionItem extends PureComponent { - static propTypes = { - firstName: PropTypes.string, - lastName: PropTypes.string, - nickname: PropTypes.string, - onPress: PropTypes.func.isRequired, - userId: PropTypes.string.isRequired, - username: PropTypes.string, - isGuest: PropTypes.bool, - isBot: PropTypes.bool, - theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, - isCurrentUser: PropTypes.bool.isRequired, - showFullName: PropTypes.string, - testID: PropTypes.string, - }; - - static defaultProps = { - firstName: '', - lastName: '', - }; - - completeMention = () => { - const {onPress, username} = this.props; - onPress(username); - }; - - renderNameBlock = () => { - let name = ''; - const {showFullName, firstName, lastName, nickname} = this.props; - const hasNickname = nickname.length > 0; - - if (showFullName === 'true') { - name += `${firstName} ${lastName} `; - } - - if (hasNickname) { - name += `(${nickname})`; - } - - return name.trim(); - } - - render() { - const { - userId, - username, - theme, - isBot, - isLandscape, - isGuest, - isCurrentUser, - testID, - } = this.props; - - const style = getStyleFromTheme(theme); - const name = this.renderNameBlock(); - - return ( - - - - - - - - {Boolean(name.length) && - - {name} - {isCurrentUser && - } - - } - - {` @${username}`} - - - - ); - } -} +import FormattedText from '@components/formatted_text'; +import ProfilePicture from '@components/profile_picture'; +import {BotTag, GuestTag} from '@components/tag'; +import TouchableWithFeedback from '@components/touchable_with_feedback'; +import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { @@ -155,3 +42,115 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, }; }); + +const AtMentionItem = (props) => { + const insets = useSafeAreaInsets(); + const { + firstName, + isBot, + isCurrentUser, + isGuest, + lastName, + nickname, + onPress, + showFullName, + testID, + theme, + userId, + username, + } = props; + + const completeMention = () => { + onPress(username); + }; + + const renderNameBlock = () => { + let name = ''; + const hasNickname = nickname.length > 0; + + if (showFullName === 'true') { + name += `${firstName} ${lastName} `; + } + + if (hasNickname) { + name += `(${nickname})`; + } + + return name.trim(); + }; + + const style = getStyleFromTheme(theme); + const name = renderNameBlock(); + + return ( + + + + + + + + {Boolean(name.length) && + + {name} + {isCurrentUser && + } + + } + + {` @${username}`} + + + + ); +}; + +AtMentionItem.propTypes = { + firstName: PropTypes.string, + lastName: PropTypes.string, + nickname: PropTypes.string, + onPress: PropTypes.func.isRequired, + userId: PropTypes.string.isRequired, + username: PropTypes.string, + isGuest: PropTypes.bool, + isBot: PropTypes.bool, + theme: PropTypes.object.isRequired, + isCurrentUser: PropTypes.bool.isRequired, + showFullName: PropTypes.string, + testID: PropTypes.string, +}; + +AtMentionItem.defaultProps = { + firstName: '', + lastName: '', +}; + +export default AtMentionItem; diff --git a/app/components/autocomplete/at_mention_item/index.js b/app/components/autocomplete/at_mention_item/index.js index 6fe8e84cc..2c995cc86 100644 --- a/app/components/autocomplete/at_mention_item/index.js +++ b/app/components/autocomplete/at_mention_item/index.js @@ -3,16 +3,13 @@ import {connect} from 'react-redux'; -import {getCurrentUserId, getUser} from '@mm-redux/selectors/entities/users'; - -import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getConfig} from '@mm-redux/selectors/entities/general'; +import {getTheme} from '@mm-redux/selectors/entities/preferences'; +import {getCurrentUserId, getUser} from '@mm-redux/selectors/entities/users'; +import {isGuest} from '@utils/users'; import AtMentionItem from './at_mention_item'; -import {isLandscape} from 'app/selectors/device'; -import {isGuest} from 'app/utils/users'; - function mapStateToProps(state, ownProps) { const user = getUser(state, ownProps.userId); const config = getConfig(state); @@ -25,7 +22,6 @@ function mapStateToProps(state, ownProps) { isBot: Boolean(user.is_bot), isGuest: isGuest(user), theme: getTheme(state), - isLandscape: isLandscape(state), isCurrentUser: getCurrentUserId(state) === user.id, }; } diff --git a/app/components/autocomplete/autocomplete.js b/app/components/autocomplete/autocomplete.js index e4641c206..8afeeeabd 100644 --- a/app/components/autocomplete/autocomplete.js +++ b/app/components/autocomplete/autocomplete.js @@ -10,12 +10,11 @@ import { ViewPropTypes, } from 'react-native'; +import {DeviceTypes} from '@constants'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {emptyFunction} from '@utils/general'; import EventEmitter from '@mm-redux/utils/event_emitter'; -import {DeviceTypes} from 'app/constants'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import {emptyFunction} from 'app/utils/general'; - import AtMention from './at_mention'; import ChannelMention from './channel_mention'; import EmojiSuggestion from './emoji_suggestion'; @@ -203,7 +202,10 @@ export default class Autocomplete extends PureComponent { } return ( - + - - - {loading && - - } - - - ); - } -} +import FormattedText from '@components/formatted_text'; +import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { @@ -79,3 +36,43 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, }; }); + +const AutocompleteSectionHeader = (props) => { + const insets = useSafeAreaInsets(); + const {defaultMessage, id, loading, theme, isFirstSection} = props; + + const style = getStyleFromTheme(theme); + const sectionStyles = [style.section, {marginLeft: insets.left, marginRight: insets.right}]; + + if (!isFirstSection) { + sectionStyles.push(style.borderTop); + } + + return ( + + + + {loading && + + } + + + ); +}; + +AutocompleteSectionHeader.propTypes = { + defaultMessage: PropTypes.string.isRequired, + id: PropTypes.string.isRequired, + loading: PropTypes.bool, + theme: PropTypes.object.isRequired, + isFirstSection: PropTypes.bool, +}; + +export default AutocompleteSectionHeader; \ No newline at end of file diff --git a/app/components/autocomplete/channel_mention/channel_mention.js b/app/components/autocomplete/channel_mention/channel_mention.js index 3a6610d96..9feba18bc 100644 --- a/app/components/autocomplete/channel_mention/channel_mention.js +++ b/app/components/autocomplete/channel_mention/channel_mention.js @@ -36,7 +36,6 @@ export default class ChannelMention extends PureComponent { requestStatus: PropTypes.string.isRequired, theme: PropTypes.object.isRequired, value: PropTypes.string, - isLandscape: PropTypes.bool.isRequired, nestedScrollEnabled: PropTypes.bool, }; @@ -191,7 +190,6 @@ export default class ChannelMention extends PureComponent { defaultMessage={section.defaultMessage} loading={!section.hideLoadingIndicator && this.props.requestStatus === RequestStatus.STARTED} theme={this.props.theme} - isLandscape={this.props.isLandscape} isFirstSection={isFirstSection} /> ); diff --git a/app/components/autocomplete/channel_mention/index.js b/app/components/autocomplete/channel_mention/index.js index 614a84935..d792bb494 100644 --- a/app/components/autocomplete/channel_mention/index.js +++ b/app/components/autocomplete/channel_mention/index.js @@ -6,9 +6,8 @@ import {connect} from 'react-redux'; import {searchChannels, autocompleteChannelsForSearch} from '@mm-redux/actions/channels'; import {getMyChannelMemberships} from '@mm-redux/selectors/entities/channels'; +import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; -import {isLandscape} from 'app/selectors/device'; - import { filterMyChannels, filterOtherChannels, @@ -16,8 +15,7 @@ import { filterPrivateChannels, filterDirectAndGroupMessages, getMatchTermForChannelMention, -} from 'app/selectors/autocomplete'; -import {getTheme} from '@mm-redux/selectors/entities/preferences'; +} from '@selectors/autocomplete'; import ChannelMention from './channel_mention'; @@ -52,7 +50,6 @@ function mapStateToProps(state, ownProps) { matchTerm, requestStatus: state.requests.channels.getChannels.status, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/components/autocomplete/channel_mention_item/channel_mention_item.js b/app/components/autocomplete/channel_mention_item/channel_mention_item.js index 5b7bde4d3..d62ae7fa7 100644 --- a/app/components/autocomplete/channel_mention_item/channel_mention_item.js +++ b/app/components/autocomplete/channel_mention_item/channel_mention_item.js @@ -1,113 +1,17 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import { - Text, - View, -} from 'react-native'; +import {Text, View} from 'react-native'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; import {General} from '@mm-redux/constants'; import CompassIcon from '@components/compass_icon'; import {BotTag, GuestTag} from '@components/tag'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import TouchableWithFeedback from '@components/touchable_with_feedback'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; -export default class ChannelMentionItem extends PureComponent { - static propTypes = { - channelId: PropTypes.string.isRequired, - displayName: PropTypes.string, - name: PropTypes.string, - type: PropTypes.string, - isBot: PropTypes.bool.isRequired, - isGuest: PropTypes.bool.isRequired, - onPress: PropTypes.func.isRequired, - theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, - }; - - completeMention = () => { - const {onPress, displayName, name, type} = this.props; - if (type === General.DM_CHANNEL || type === General.GM_CHANNEL) { - onPress('@' + displayName.replace(/ /g, '')); - } else { - onPress(name); - } - }; - - render() { - const { - channelId, - displayName, - name, - theme, - type, - isBot, - isLandscape, - isGuest, - } = this.props; - - const style = getStyleFromTheme(theme); - let iconName = 'globe'; - let component; - if (type === General.PRIVATE_CHANNEL) { - iconName = 'lock'; - } - - if (type === General.DM_CHANNEL || type === General.GM_CHANNEL) { - if (!displayName) { - return null; - } - - component = ( - - {'@' + displayName} - - - - ); - } else { - component = ( - - - - {displayName} - {` ~${name}`} - - - ); - } - - return ( - - {component} - - ); - } -} - const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { icon: { @@ -133,3 +37,92 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, }; }); + +const ChannelMentionItem = (props) => { + const insets = useSafeAreaInsets(); + const { + channelId, + displayName, + isBot, + isGuest, + name, + onPress, + theme, + type, + } = props; + + const completeMention = () => { + if (type === General.DM_CHANNEL || type === General.GM_CHANNEL) { + onPress('@' + displayName.replace(/ /g, '')); + } else { + onPress(name); + } + }; + + const style = getStyleFromTheme(theme); + const margins = {marginLeft: insets.left, marginRight: insets.right}; + let iconName = 'globe'; + let component; + if (type === General.PRIVATE_CHANNEL) { + iconName = 'lock'; + } + + if (type === General.DM_CHANNEL || type === General.GM_CHANNEL) { + if (!displayName) { + return null; + } + + component = ( + + {'@' + displayName} + + + + ); + } else { + component = ( + + + + {displayName} + {` ~${name}`} + + + ); + } + + return component; +}; + +ChannelMentionItem.propTypes = { + channelId: PropTypes.string.isRequired, + displayName: PropTypes.string, + name: PropTypes.string, + type: PropTypes.string, + isBot: PropTypes.bool.isRequired, + isGuest: PropTypes.bool.isRequired, + onPress: PropTypes.func.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default ChannelMentionItem; diff --git a/app/components/autocomplete/channel_mention_item/index.js b/app/components/autocomplete/channel_mention_item/index.js index 0a97e4398..7b8b7cc34 100644 --- a/app/components/autocomplete/channel_mention_item/index.js +++ b/app/components/autocomplete/channel_mention_item/index.js @@ -7,10 +7,8 @@ import {General} from '@mm-redux/constants'; import {getChannel} from '@mm-redux/selectors/entities/channels'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getUser} from '@mm-redux/selectors/entities/users'; - -import {getChannelNameForSearchAutocomplete} from 'app/selectors/channel'; -import {isLandscape} from 'app/selectors/device'; -import {isGuest as isGuestUser} from 'app/utils/users'; +import {getChannelNameForSearchAutocomplete} from '@selectors/channel'; +import {isGuest as isGuestUser} from '@utils/users'; import ChannelMentionItem from './channel_mention_item'; @@ -36,7 +34,6 @@ function mapStateToProps(state, ownProps) { isBot, isGuest, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/components/autocomplete/slash_suggestion/index.js b/app/components/autocomplete/slash_suggestion/index.js index 958c4b89e..c7677b597 100644 --- a/app/components/autocomplete/slash_suggestion/index.js +++ b/app/components/autocomplete/slash_suggestion/index.js @@ -9,7 +9,6 @@ import {getAutocompleteCommands, getCommandAutocompleteSuggestions} from '@mm-re import {getAutocompleteCommandsList, getCommandAutocompleteSuggestionsList} from '@mm-redux/selectors/entities/integrations'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; -import {isLandscape} from 'app/selectors/device'; import SlashSuggestion from './slash_suggestion'; @@ -31,7 +30,6 @@ function mapStateToProps(state) { commands: mobileCommandsSelector(state), currentTeamId: getCurrentTeamId(state), theme: getTheme(state), - isLandscape: isLandscape(state), suggestions: getCommandAutocompleteSuggestionsList(state), }; } diff --git a/app/components/autocomplete/slash_suggestion/slash_suggestion.js b/app/components/autocomplete/slash_suggestion/slash_suggestion.js index a88aed272..2089d8f40 100644 --- a/app/components/autocomplete/slash_suggestion/slash_suggestion.js +++ b/app/components/autocomplete/slash_suggestion/slash_suggestion.js @@ -8,12 +8,12 @@ import { Platform, } from 'react-native'; -import {makeStyleSheetFromTheme} from 'app/utils/theme'; - -import SlashSuggestionItem from './slash_suggestion_item'; +import {analytics} from '@init/analytics.ts'; import {Client4} from '@mm-redux/client'; import {isMinimumServerVersion} from '@mm-redux/utils/helpers'; -import {analytics} from '@init/analytics.ts'; +import {makeStyleSheetFromTheme} from '@utils/theme'; + +import SlashSuggestionItem from './slash_suggestion_item'; const TIME_BEFORE_NEXT_COMMAND_REQUEST = 1000 * 60 * 5; @@ -31,7 +31,6 @@ export default class SlashSuggestion extends PureComponent { onChangeText: PropTypes.func.isRequired, onResultCountChange: PropTypes.func.isRequired, value: PropTypes.string, - isLandscape: PropTypes.bool.isRequired, nestedScrollEnabled: PropTypes.bool, suggestions: PropTypes.array, rootId: PropTypes.string, @@ -187,7 +186,6 @@ export default class SlashSuggestion extends PureComponent { theme={this.props.theme} suggestion={item.Suggestion} complete={item.Complete} - isLandscape={this.props.isLandscape} /> ) diff --git a/app/components/autocomplete/slash_suggestion/slash_suggestion_item.js b/app/components/autocomplete/slash_suggestion/slash_suggestion_item.js index d75f0c4b9..cd6e8bceb 100644 --- a/app/components/autocomplete/slash_suggestion/slash_suggestion_item.js +++ b/app/components/autocomplete/slash_suggestion/slash_suggestion_item.js @@ -1,79 +1,14 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import {Image, Text, View} from 'react-native'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; +import slashIcon from '@assets/images/autocomplete/slash_command.png'; import TouchableWithFeedback from '@components/touchable_with_feedback'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; -import slashIcon from '@assets/images/autocomplete/slash_command.png'; - -export default class SlashSuggestionItem extends PureComponent { - static propTypes = { - description: PropTypes.string, - hint: PropTypes.string, - onPress: PropTypes.func.isRequired, - theme: PropTypes.object.isRequired, - suggestion: PropTypes.string, - complete: PropTypes.string, - isLandscape: PropTypes.bool.isRequired, - }; - - completeSuggestion = () => { - const {onPress, complete} = this.props; - onPress(complete); - }; - - render() { - const { - description, - hint, - theme, - suggestion, - complete, - isLandscape, - } = this.props; - - const style = getStyleFromTheme(theme); - - let suggestionText = suggestion; - if (suggestionText[0] === '/' && complete.split(' ').length === 1) { - suggestionText = suggestionText.substring(1); - } - - return ( - - - - - - - {`${suggestionText} ${hint}`} - - {description} - - - - - ); - } -} const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { @@ -112,3 +47,67 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, }; }); + +const SlashSuggestionItem = (props) => { + const insets = useSafeAreaInsets(); + const { + complete, + description, + hint, + onPress, + suggestion, + theme, + } = props; + + const completeSuggestion = () => { + onPress(complete); + }; + + const style = getStyleFromTheme(theme); + + let suggestionText = suggestion; + if (suggestionText[0] === '/' && complete.split(' ').length === 1) { + suggestionText = suggestionText.substring(1); + } + + return ( + + + + + + + {`${suggestionText} ${hint}`} + + {description} + + + + + ); +}; + +SlashSuggestionItem.propTypes = { + description: PropTypes.string, + hint: PropTypes.string, + onPress: PropTypes.func.isRequired, + theme: PropTypes.object.isRequired, + suggestion: PropTypes.string, + complete: PropTypes.string, +}; + +export default SlashSuggestionItem; diff --git a/app/components/autocomplete_selector/autocomplete_selector.js b/app/components/autocomplete_selector/autocomplete_selector.js index 0833e9aca..bc378c5ed 100644 --- a/app/components/autocomplete_selector/autocomplete_selector.js +++ b/app/components/autocomplete_selector/autocomplete_selector.js @@ -10,7 +10,6 @@ import {displayUsername} from '@mm-redux/utils/user_utils'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import TouchableWithFeedback from '@components/touchable_with_feedback'; import {preventDoubleTap} from '@utils/tap'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; @@ -35,7 +34,6 @@ export default class AutocompleteSelector extends PureComponent { helpText: PropTypes.node, errorText: PropTypes.node, roundedBorders: PropTypes.bool, - isLandscape: PropTypes.bool.isRequired, disabled: PropTypes.bool, }; @@ -119,7 +117,6 @@ export default class AutocompleteSelector extends PureComponent { optional, showRequiredAsterisk, roundedBorders, - isLandscape, disabled, } = this.props; const {selectedText} = this.state; @@ -186,9 +183,7 @@ export default class AutocompleteSelector extends PureComponent { return ( - - {labelContent} - + {labelContent} {text} @@ -205,14 +200,12 @@ export default class AutocompleteSelector extends PureComponent { - - {helpTextContent} - {errorTextContent} - + {helpTextContent} + {errorTextContent} ); } diff --git a/app/components/autocomplete_selector/index.js b/app/components/autocomplete_selector/index.js index 67a148292..dc3f4fe16 100644 --- a/app/components/autocomplete_selector/index.js +++ b/app/components/autocomplete_selector/index.js @@ -9,13 +9,11 @@ import {getTeammateNameDisplaySetting, getTheme} from '@mm-redux/selectors/entit import {setAutocompleteSelector} from 'app/actions/views/post'; import AutocompleteSelector from './autocomplete_selector'; -import {isLandscape} from 'app/selectors/device'; function mapStateToProps(state) { return { teammateNameDisplay: getTeammateNameDisplaySetting(state), theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/components/channel_intro/channel_intro.js b/app/components/channel_intro/channel_intro.js index f0cee2e1a..62e23333d 100644 --- a/app/components/channel_intro/channel_intro.js +++ b/app/components/channel_intro/channel_intro.js @@ -15,7 +15,6 @@ import {General} from '@mm-redux/constants'; import {showModal} from '@actions/navigation'; import CompassIcon from '@components/compass_icon'; import ProfilePicture from '@components/profile_picture'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {BotTag, GuestTag} from '@components/tag'; import TouchableWithFeedback from '@components/touchable_with_feedback'; import {preventDoubleTap} from '@utils/tap'; @@ -30,7 +29,6 @@ class ChannelIntro extends PureComponent { currentChannelMembers: PropTypes.array.isRequired, intl: intlShape.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, teammateNameDisplay: PropTypes.string.isRequired, }; @@ -329,7 +327,7 @@ class ChannelIntro extends PureComponent { }; render() { - const {currentChannel, theme, isLandscape} = this.props; + const {currentChannel, theme} = this.props; const style = getStyleSheet(theme); const channelType = currentChannel.type; @@ -337,10 +335,10 @@ class ChannelIntro extends PureComponent { if (channelType === General.DM_CHANNEL || channelType === General.GM_CHANNEL) { profiles = ( - + {this.buildProfiles()} - + {this.buildNames()} @@ -350,7 +348,7 @@ class ChannelIntro extends PureComponent { return ( {profiles} - + {this.buildContent()} diff --git a/app/components/channel_intro/index.js b/app/components/channel_intro/index.js index b46acabb8..c05b85dff 100644 --- a/app/components/channel_intro/index.js +++ b/app/components/channel_intro/index.js @@ -9,7 +9,6 @@ import {makeGetChannel} from '@mm-redux/selectors/entities/channels'; import {getCurrentUserId, getUser, makeGetProfilesInChannel} from '@mm-redux/selectors/entities/users'; import {getTeammateNameDisplaySetting, getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import {getChannelMembersForDm} from 'app/selectors/channel'; import ChannelIntro from './channel_intro'; @@ -48,7 +47,6 @@ function makeMapStateToProps() { currentChannel, currentChannelMembers, theme: getTheme(state), - isLandscape: isLandscape(state), teammateNameDisplay: getTeammateNameDisplaySetting(state), }; }; diff --git a/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap b/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap index 8f1d0b9f8..dc01e0f27 100644 --- a/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap +++ b/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap @@ -10,7 +10,6 @@ exports[`ChannelLoader should match snapshot 1`] = ` "overflow": "hidden", }, undefined, - null, Object { "backgroundColor": "#ffffff", }, diff --git a/app/components/channel_loader/channel_loader.js b/app/components/channel_loader/channel_loader.js index 6d016e83f..a52e322f9 100644 --- a/app/components/channel_loader/channel_loader.js +++ b/app/components/channel_loader/channel_loader.js @@ -10,9 +10,8 @@ import { } from 'react-native'; import * as RNPlaceholder from 'rn-placeholder'; -import CustomPropTypes from 'app/constants/custom_prop_types'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; +import CustomPropTypes from '@constants/custom_prop_types'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; function calculateMaxRows(height) { return Math.round(height / 100); @@ -36,7 +35,6 @@ export default class ChannelLoader extends PureComponent { style: CustomPropTypes.Style, theme: PropTypes.object.isRequired, height: PropTypes.number, - isLandscape: PropTypes.bool.isRequired, }; constructor(props) { @@ -107,7 +105,6 @@ export default class ChannelLoader extends PureComponent { channelIsLoading, style: styleProp, theme, - isLandscape, } = this.props; if (!channelIsLoading) { @@ -119,7 +116,7 @@ export default class ChannelLoader extends PureComponent { return ( {Array(this.state.maxRows).fill().map((item, index) => this.buildSections({ diff --git a/app/components/channel_loader/channel_loader.test.js b/app/components/channel_loader/channel_loader.test.js index f8cc5af17..cdd42f267 100644 --- a/app/components/channel_loader/channel_loader.test.js +++ b/app/components/channel_loader/channel_loader.test.js @@ -12,7 +12,6 @@ describe('ChannelLoader', () => { const baseProps = { channelIsLoading: true, theme: Preferences.THEMES.default, - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/components/channel_loader/index.js b/app/components/channel_loader/index.js index b86ce03ec..14543f740 100644 --- a/app/components/channel_loader/index.js +++ b/app/components/channel_loader/index.js @@ -5,8 +5,6 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; - import ChannelLoader from './channel_loader'; function mapStateToProps(state, ownProps) { @@ -15,7 +13,6 @@ function mapStateToProps(state, ownProps) { return { channelIsLoading, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/components/custom_list/__snapshots__/index.test.js.snap b/app/components/custom_list/__snapshots__/index.test.js.snap index 38087a1d3..79bcda2bf 100644 --- a/app/components/custom_list/__snapshots__/index.test.js.snap +++ b/app/components/custom_list/__snapshots__/index.test.js.snap @@ -117,13 +117,10 @@ exports[`CustomList should match snapshot, renderSectionHeader 1`] = ` > section_id diff --git a/app/components/custom_list/channel_list_row/channel_list_row.js b/app/components/custom_list/channel_list_row/channel_list_row.js index f98cf9b63..b2086d387 100644 --- a/app/components/custom_list/channel_list_row/channel_list_row.js +++ b/app/components/custom_list/channel_list_row/channel_list_row.js @@ -19,7 +19,6 @@ export default class ChannelListRow extends React.PureComponent { theme: PropTypes.object.isRequired, channel: PropTypes.object.isRequired, ...CustomListRow.propTypes, - isLandscape: PropTypes.bool.isRequired, }; onPress = () => { @@ -49,7 +48,6 @@ export default class ChannelListRow extends React.PureComponent { enabled={this.props.enabled} selectable={this.props.selectable} selected={this.props.selected} - isLandscape={this.props.isLandscape} > diff --git a/app/components/custom_list/channel_list_row/index.js b/app/components/custom_list/channel_list_row/index.js index 948a182f3..a4054a965 100644 --- a/app/components/custom_list/channel_list_row/index.js +++ b/app/components/custom_list/channel_list_row/index.js @@ -6,7 +6,6 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {makeGetChannel} from '@mm-redux/selectors/entities/channels'; -import {isLandscape} from 'app/selectors/device'; import ChannelListRow from './channel_list_row'; function makeMapStateToProps() { @@ -16,7 +15,6 @@ function makeMapStateToProps() { return { theme: getTheme(state), channel: getChannel(state, ownProps), - isLandscape: isLandscape(state), }; }; } diff --git a/app/components/custom_list/custom_list_row.js b/app/components/custom_list/custom_list_row.js index 4e02cac7a..505cfaa7f 100644 --- a/app/components/custom_list/custom_list_row.js +++ b/app/components/custom_list/custom_list_row.js @@ -9,7 +9,6 @@ import { } from 'react-native'; import CompassIcon from '@components/compass_icon'; -import {paddingLeft as padding} from '@components/safe_area_view/iphone_x_spacing'; import ConditionalTouchable from '@components/conditional_touchable'; import CustomPropTypes from '@constants/custom_prop_types'; @@ -20,14 +19,11 @@ export default class CustomListRow extends React.PureComponent { selectable: PropTypes.bool, selected: PropTypes.bool, children: CustomPropTypes.Children, - item: PropTypes.object, - isLandscape: PropTypes.bool.isRequired, testID: PropTypes.string, }; static defaultProps = { enabled: true, - isLandscape: false, }; render() { @@ -38,7 +34,7 @@ export default class CustomListRow extends React.PureComponent { style={style.touchable} testID={this.props.testID} > - + {this.props.selectable && diff --git a/app/components/custom_list/index.js b/app/components/custom_list/index.js index 5a2b1a371..b178da73a 100644 --- a/app/components/custom_list/index.js +++ b/app/components/custom_list/index.js @@ -7,7 +7,6 @@ import {FlatList, Keyboard, Platform, RefreshControl, SectionList, Text, View} f import {ListTypes} from 'app/constants'; import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme'; -import {paddingLeft as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export const FLATLIST = 'flat'; export const SECTIONLIST = 'section'; @@ -32,13 +31,11 @@ export default class CustomList extends PureComponent { selectable: PropTypes.bool, theme: PropTypes.object.isRequired, shouldRenderSeparator: PropTypes.bool, - isLandscape: PropTypes.bool.isRequired, testID: PropTypes.string, }; static defaultProps = { canRefresh: true, - isLandscape: false, listType: FLATLIST, showNoResults: true, shouldRenderSeparator: true, @@ -165,13 +162,13 @@ export default class CustomList extends PureComponent { }; renderSectionHeader = ({section}) => { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const style = getStyleFromTheme(theme); return ( - {section.id} + {section.id} ); diff --git a/app/components/custom_list/option_list_row/index.js b/app/components/custom_list/option_list_row/index.js index 8b3d5af46..184006f8e 100644 --- a/app/components/custom_list/option_list_row/index.js +++ b/app/components/custom_list/option_list_row/index.js @@ -4,13 +4,11 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import OptionListRow from './option_list_row'; function mapStateToProps(state) { return { theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/components/custom_list/option_list_row/option_list_row.js b/app/components/custom_list/option_list_row/option_list_row.js index 64ba5d4a2..680b7424b 100644 --- a/app/components/custom_list/option_list_row/option_list_row.js +++ b/app/components/custom_list/option_list_row/option_list_row.js @@ -17,17 +17,12 @@ export default class OptionListRow extends React.PureComponent { id: PropTypes.string, theme: PropTypes.object.isRequired, ...CustomListRow.propTypes, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { intl: intlShape, }; - static defaultProps = { - isLandscape: false, - }; - onPress = () => { if (this.props.onPress) { this.props.onPress(this.props.id, this.props.item); @@ -41,7 +36,6 @@ export default class OptionListRow extends React.PureComponent { selected, theme, item, - isLandscape, } = this.props; const {text, value} = item; @@ -54,7 +48,6 @@ export default class OptionListRow extends React.PureComponent { enabled={enabled} selectable={selectable} selected={selected} - isLandscape={isLandscape} > diff --git a/app/components/custom_list/user_list_row/__snapshots__/user_list_test.test.js.snap b/app/components/custom_list/user_list_row/__snapshots__/user_list_test.test.js.snap index 76238c0d1..d190621d7 100644 --- a/app/components/custom_list/user_list_row/__snapshots__/user_list_test.test.js.snap +++ b/app/components/custom_list/user_list_row/__snapshots__/user_list_test.test.js.snap @@ -14,7 +14,6 @@ exports[`UserListRow should match snapshot 1`] = ` diff --git a/app/components/custom_list/user_list_row/user_list_test.test.js b/app/components/custom_list/user_list_row/user_list_test.test.js index cfd458240..927a7eabf 100644 --- a/app/components/custom_list/user_list_row/user_list_test.test.js +++ b/app/components/custom_list/user_list_row/user_list_test.test.js @@ -29,7 +29,6 @@ describe('UserListRow', () => { }, theme: Preferences.THEMES.default, teammateNameDisplay: 'test', - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/components/edit_channel_info/__snapshots__/edit_channel_info.test.js.snap b/app/components/edit_channel_info/__snapshots__/edit_channel_info.test.js.snap index 3ddd12ba1..0f00e9804 100644 --- a/app/components/edit_channel_info/__snapshots__/edit_channel_info.test.js.snap +++ b/app/components/edit_channel_info/__snapshots__/edit_channel_info.test.js.snap @@ -1,7 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`EditChannelInfo should match snapshot 1`] = ` - + @@ -41,30 +49,20 @@ exports[`EditChannelInfo should match snapshot 1`] = ` defaultMessage="Name" id="channel_modal.name" style={ - Array [ - Object { - "color": "#3d3c40", - "fontSize": 14, - "marginLeft": 15, - }, - Object { - "paddingHorizontal": 44, - }, - ] + Object { + "color": "#3d3c40", + "fontSize": 14, + "marginLeft": 15, + } } /> @@ -202,15 +185,10 @@ exports[`EditChannelInfo should match snapshot 1`] = ` @@ -342,5 +310,5 @@ exports[`EditChannelInfo should match snapshot 1`] = ` value="header" /> - + `; diff --git a/app/components/edit_channel_info/edit_channel_info.js b/app/components/edit_channel_info/edit_channel_info.js deleted file mode 100644 index c2f04545f..000000000 --- a/app/components/edit_channel_info/edit_channel_info.js +++ /dev/null @@ -1,453 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React, {PureComponent} from 'react'; -import PropTypes from 'prop-types'; -import { - Platform, - TouchableWithoutFeedback, - View, -} from 'react-native'; -import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scrollview'; - -import {General} from '@mm-redux/constants'; - -import Autocomplete, {AUTOCOMPLETE_MAX_HEIGHT} from 'app/components/autocomplete'; -import ErrorText from 'app/components/error_text'; -import FormattedText from 'app/components/formatted_text'; -import Loading from 'app/components/loading'; -import StatusBar from 'app/components/status_bar'; -import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_localized_placeholder'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; - -import { - changeOpacity, - makeStyleSheetFromTheme, - getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; - -import {t} from 'app/utils/i18n'; -import {popTopScreen, dismissModal} from 'app/actions/navigation'; - -export default class EditChannelInfo extends PureComponent { - static propTypes = { - theme: PropTypes.object.isRequired, - deviceWidth: PropTypes.number.isRequired, - deviceHeight: PropTypes.number.isRequired, - channelType: PropTypes.string, - enableRightButton: PropTypes.func, - saving: PropTypes.bool.isRequired, - editing: PropTypes.bool, - error: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), - displayName: PropTypes.string, - currentTeamUrl: PropTypes.string, - channelURL: PropTypes.string, - purpose: PropTypes.string, - header: PropTypes.string, - onDisplayNameChange: PropTypes.func, - onChannelURLChange: PropTypes.func, - onPurposeChange: PropTypes.func, - onHeaderChange: PropTypes.func, - oldDisplayName: PropTypes.string, - oldChannelURL: PropTypes.string, - oldHeader: PropTypes.string, - oldPurpose: PropTypes.string, - isLandscape: PropTypes.bool.isRequired, - testID: PropTypes.string, - }; - - static defaultProps = { - editing: false, - }; - - constructor(props) { - super(props); - - this.nameInput = React.createRef(); - this.urlInput = React.createRef(); - this.purposeInput = React.createRef(); - this.headerInput = React.createRef(); - this.scroll = React.createRef(); - - this.state = { - keyboardVisible: false, - keyboardPosition: 0, - }; - } - - blur = () => { - if (this.nameInput?.current) { - this.nameInput.current.blur(); - } - - // TODO: uncomment below once the channel URL field is added - // if (this.urlInput?.current) { - // this.urlInput.current.blur(); - // } - - if (this.purposeInput?.current) { - this.purposeInput.current.blur(); - } - if (this.headerInput?.current) { - this.headerInput.current.blur(); - } - - if (this.scroll?.current) { - this.scroll.current.scrollTo({x: 0, y: 0, animated: true}); - } - }; - - close = (goBack = false) => { - if (goBack) { - popTopScreen(); - } else { - dismissModal(); - } - }; - - canUpdate = (displayName, channelURL, purpose, header) => { - const { - oldDisplayName, - oldChannelURL, - oldPurpose, - oldHeader, - } = this.props; - - return displayName !== oldDisplayName || channelURL !== oldChannelURL || - purpose !== oldPurpose || header !== oldHeader; - }; - - enableRightButton = (enable = false) => { - this.props.enableRightButton(enable); - }; - - onDisplayNameChangeText = (displayName) => { - const {editing, onDisplayNameChange} = this.props; - onDisplayNameChange(displayName); - - if (editing) { - const {channelURL, purpose, header} = this.props; - const canUpdate = this.canUpdate(displayName, channelURL, purpose, header); - this.enableRightButton(canUpdate); - return; - } - - const displayNameExists = displayName && displayName.length >= 2; - this.props.enableRightButton(displayNameExists); - }; - - onPurposeChangeText = (purpose) => { - const {editing, onPurposeChange} = this.props; - onPurposeChange(purpose); - - if (editing) { - const {displayName, channelURL, header} = this.props; - const canUpdate = this.canUpdate(displayName, channelURL, purpose, header); - this.enableRightButton(canUpdate); - } - }; - - onHeaderChangeText = (header) => { - const {editing, onHeaderChange} = this.props; - onHeaderChange(header); - - if (editing) { - const {displayName, channelURL, purpose} = this.props; - const canUpdate = this.canUpdate(displayName, channelURL, purpose, header); - this.enableRightButton(canUpdate); - } - }; - - onHeaderLayout = ({nativeEvent}) => { - this.setState({headerPosition: nativeEvent.layout.y}); - } - - onKeyboardDidShow = () => { - this.setState({keyboardVisible: true}); - - if (this.state.headerHasFocus) { - this.setState({headerHasFocus: false}); - this.scrollHeaderToTop(); - } - } - - onKeyboardDidHide = () => { - this.setState({keyboardVisible: false}); - } - - onKeyboardOffsetChanged = (keyboardPosition) => { - this.setState({keyboardPosition}); - } - - onHeaderFocus = () => { - if (this.state.keyboardVisible) { - this.scrollHeaderToTop(); - } else { - this.setState({headerHasFocus: true}); - } - }; - - scrollHeaderToTop = () => { - if (this.scroll.current) { - this.scroll.current.scrollTo({x: 0, y: this.state.headerPosition}); - } - } - - render() { - const { - theme, - channelType, - deviceWidth, - deviceHeight, - displayName, - header, - purpose, - isLandscape, - error, - saving, - testID, - } = this.props; - const {keyboardVisible, keyboardPosition} = this.state; - const bottomStyle = { - bottom: Platform.select({ - ios: keyboardPosition, - android: 0, - }), - }; - const style = getStyleSheet(theme); - - const displayHeaderOnly = channelType === General.DM_CHANNEL || - channelType === General.GM_CHANNEL; - - if (saving) { - return ( - - - - - ); - } - - let displayError; - if (error) { - displayError = ( - - - - - - ); - } - - return ( - - - - {displayError} - - - {!displayHeaderOnly && ( - - - - - - - - - )} - {!displayHeaderOnly && ( - - - - - - - - - - - - - )} - - - - - - - - - - - - - - - - - - ); - } -} - -const getStyleSheet = makeStyleSheetFromTheme((theme) => { - return { - autocomplete: { - position: undefined, - }, - autocompleteContainer: { - position: 'absolute', - width: '100%', - flex: 1, - justifyContent: 'flex-end', - }, - container: { - flex: 1, - }, - scrollView: { - flex: 1, - backgroundColor: changeOpacity(theme.centerChannelColor, 0.06), - paddingTop: 30, - }, - errorContainer: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0.06), - }, - errorWrapper: { - justifyContent: 'center', - alignItems: 'center', - }, - inputContainer: { - marginTop: 10, - backgroundColor: theme.centerChannelBg, - }, - input: { - color: theme.centerChannelColor, - fontSize: 14, - height: 40, - paddingHorizontal: 15, - }, - titleContainer30: { - flexDirection: 'row', - marginTop: 30, - }, - titleContainer15: { - flexDirection: 'row', - marginTop: 15, - }, - title: { - fontSize: 14, - color: theme.centerChannelColor, - marginLeft: 15, - }, - optional: { - color: changeOpacity(theme.centerChannelColor, 0.5), - fontSize: 14, - marginLeft: 5, - }, - helpText: { - fontSize: 14, - color: changeOpacity(theme.centerChannelColor, 0.5), - marginTop: 10, - marginHorizontal: 15, - }, - headerHelpText: { - zIndex: -1, - }, - }; -}); diff --git a/app/components/edit_channel_info/edit_channel_info.test.js b/app/components/edit_channel_info/edit_channel_info.test.js index 5e1f81b94..c20dd81af 100644 --- a/app/components/edit_channel_info/edit_channel_info.test.js +++ b/app/components/edit_channel_info/edit_channel_info.test.js @@ -7,7 +7,7 @@ import {shallow} from 'enzyme'; import Preferences from '@mm-redux/constants/preferences'; import Autocomplete from 'app/components/autocomplete'; -import EditChannelInfo from './edit_channel_info'; +import EditChannelInfo from './index'; describe('EditChannelInfo', () => { const baseProps = { @@ -32,7 +32,6 @@ describe('EditChannelInfo', () => { oldChannelURL: '/team_a/channels/channel_old', oldHeader: 'old_header', oldPurpose: 'old_purpose', - isLandscape: true, }; test('should match snapshot', () => { diff --git a/app/components/edit_channel_info/index.js b/app/components/edit_channel_info/index.js index 851b7a735..391be69dd 100644 --- a/app/components/edit_channel_info/index.js +++ b/app/components/edit_channel_info/index.js @@ -1,15 +1,452 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {connect} from 'react-redux'; +import React, {PureComponent} from 'react'; +import PropTypes from 'prop-types'; +import { + Platform, + TouchableWithoutFeedback, + View, +} from 'react-native'; +import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scrollview'; +import {SafeAreaView} from 'react-native-safe-area-context'; -import {isLandscape} from 'app/selectors/device'; -import EditChannelInfo from './edit_channel_info'; +import {General} from '@mm-redux/constants'; -function mapStateToProps(state) { - return { - isLandscape: isLandscape(state), +import Autocomplete, {AUTOCOMPLETE_MAX_HEIGHT} from 'app/components/autocomplete'; +import ErrorText from 'app/components/error_text'; +import FormattedText from 'app/components/formatted_text'; +import Loading from 'app/components/loading'; +import StatusBar from 'app/components/status_bar'; +import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_localized_placeholder'; + +import { + changeOpacity, + makeStyleSheetFromTheme, + getKeyboardAppearanceFromTheme, +} from 'app/utils/theme'; + +import {t} from 'app/utils/i18n'; +import {popTopScreen, dismissModal} from 'app/actions/navigation'; + +export default class EditChannelInfo extends PureComponent { + static propTypes = { + theme: PropTypes.object.isRequired, + channelType: PropTypes.string, + enableRightButton: PropTypes.func, + saving: PropTypes.bool.isRequired, + editing: PropTypes.bool, + error: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + displayName: PropTypes.string, + channelURL: PropTypes.string, + purpose: PropTypes.string, + header: PropTypes.string, + onDisplayNameChange: PropTypes.func, + onPurposeChange: PropTypes.func, + onHeaderChange: PropTypes.func, + oldDisplayName: PropTypes.string, + oldChannelURL: PropTypes.string, + oldHeader: PropTypes.string, + oldPurpose: PropTypes.string, + testID: PropTypes.string, }; + + static defaultProps = { + editing: false, + }; + + constructor(props) { + super(props); + + this.nameInput = React.createRef(); + this.urlInput = React.createRef(); + this.purposeInput = React.createRef(); + this.headerInput = React.createRef(); + this.scroll = React.createRef(); + + this.state = { + keyboardVisible: false, + keyboardPosition: 0, + }; + } + + blur = () => { + if (this.nameInput?.current) { + this.nameInput.current.blur(); + } + + // TODO: uncomment below once the channel URL field is added + // if (this.urlInput?.current) { + // this.urlInput.current.blur(); + // } + + if (this.purposeInput?.current) { + this.purposeInput.current.blur(); + } + if (this.headerInput?.current) { + this.headerInput.current.blur(); + } + + if (this.scroll?.current) { + this.scroll.current.scrollTo({x: 0, y: 0, animated: true}); + } + }; + + close = (goBack = false) => { + if (goBack) { + popTopScreen(); + } else { + dismissModal(); + } + }; + + canUpdate = (displayName, channelURL, purpose, header) => { + const { + oldDisplayName, + oldChannelURL, + oldPurpose, + oldHeader, + } = this.props; + + return displayName !== oldDisplayName || channelURL !== oldChannelURL || + purpose !== oldPurpose || header !== oldHeader; + }; + + enableRightButton = (enable = false) => { + this.props.enableRightButton(enable); + }; + + onDisplayNameChangeText = (displayName) => { + const {editing, onDisplayNameChange} = this.props; + onDisplayNameChange(displayName); + + if (editing) { + const {channelURL, purpose, header} = this.props; + const canUpdate = this.canUpdate(displayName, channelURL, purpose, header); + this.enableRightButton(canUpdate); + return; + } + + const displayNameExists = displayName && displayName.length >= 2; + this.props.enableRightButton(displayNameExists); + }; + + onPurposeChangeText = (purpose) => { + const {editing, onPurposeChange} = this.props; + onPurposeChange(purpose); + + if (editing) { + const {displayName, channelURL, header} = this.props; + const canUpdate = this.canUpdate(displayName, channelURL, purpose, header); + this.enableRightButton(canUpdate); + } + }; + + onHeaderChangeText = (header) => { + const {editing, onHeaderChange} = this.props; + onHeaderChange(header); + + if (editing) { + const {displayName, channelURL, purpose} = this.props; + const canUpdate = this.canUpdate(displayName, channelURL, purpose, header); + this.enableRightButton(canUpdate); + } + }; + + onHeaderLayout = ({nativeEvent}) => { + this.setState({headerPosition: nativeEvent.layout.y}); + } + + onKeyboardDidShow = () => { + this.setState({keyboardVisible: true}); + + if (this.state.headerHasFocus) { + this.setState({headerHasFocus: false}); + this.scrollHeaderToTop(); + } + } + + onKeyboardDidHide = () => { + this.setState({keyboardVisible: false}); + } + + onKeyboardOffsetChanged = (keyboardPosition) => { + this.setState({keyboardPosition}); + } + + onHeaderFocus = () => { + if (this.state.keyboardVisible) { + this.scrollHeaderToTop(); + } else { + this.setState({headerHasFocus: true}); + } + }; + + scrollHeaderToTop = () => { + if (this.scroll.current) { + this.scroll.current.scrollTo({x: 0, y: this.state.headerPosition}); + } + } + + render() { + const { + theme, + channelType, + displayName, + header, + purpose, + error, + saving, + testID, + } = this.props; + const {keyboardVisible, keyboardPosition} = this.state; + const bottomStyle = { + bottom: Platform.select({ + ios: keyboardPosition, + android: 0, + }), + }; + const style = getStyleSheet(theme); + + const displayHeaderOnly = channelType === General.DM_CHANNEL || + channelType === General.GM_CHANNEL; + + if (saving) { + return ( + + + + + ); + } + + let displayError; + if (error) { + displayError = ( + + + + + + ); + } + + return ( + + + + {displayError} + + + {!displayHeaderOnly && ( + + + + + + + + + )} + {!displayHeaderOnly && ( + + + + + + + + + + + + + )} + + + + + + + + + + + + + + + + + + ); + } } -export default connect(mapStateToProps)(EditChannelInfo); +const getStyleSheet = makeStyleSheetFromTheme((theme) => { + return { + autocomplete: { + position: undefined, + }, + autocompleteContainer: { + position: 'absolute', + width: '100%', + flex: 1, + justifyContent: 'flex-end', + }, + container: { + flex: 1, + }, + scrollView: { + flex: 1, + backgroundColor: changeOpacity(theme.centerChannelColor, 0.06), + paddingTop: 30, + }, + errorContainer: { + backgroundColor: changeOpacity(theme.centerChannelColor, 0.06), + width: '100%', + }, + errorWrapper: { + justifyContent: 'center', + alignItems: 'center', + }, + inputContainer: { + marginTop: 10, + backgroundColor: theme.centerChannelBg, + }, + input: { + color: theme.centerChannelColor, + fontSize: 14, + height: 40, + paddingHorizontal: 15, + }, + titleContainer30: { + flexDirection: 'row', + marginTop: 30, + }, + titleContainer15: { + flexDirection: 'row', + marginTop: 15, + }, + title: { + fontSize: 14, + color: theme.centerChannelColor, + marginLeft: 15, + }, + optional: { + color: changeOpacity(theme.centerChannelColor, 0.5), + fontSize: 14, + marginLeft: 5, + }, + helpText: { + fontSize: 14, + color: changeOpacity(theme.centerChannelColor, 0.5), + marginTop: 10, + marginHorizontal: 15, + }, + headerHelpText: { + zIndex: -1, + }, + }; +}); diff --git a/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap b/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap index 8ff29e3c8..7b5ca7aec 100644 --- a/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap +++ b/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap @@ -1,9 +1,18 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`components/emoji_picker/emoji_picker.ios should match snapshot 1`] = ` - - - - + } + keyboardAppearance="light" + keyboardShouldPersist={false} + keyboardType="default" + onAnimationComplete={[Function]} + onBlur={[Function]} + onCancelButtonPress={[Function]} + onChangeText={[Function]} + onSelectionChange={[Function]} + placeholder="Search" + placeholderTextColor="rgba(61,60,64,0.5)" + returnKeyType="search" + searchBarRightMargin={0} + searchIconSize={24} + showArrow={false} + showCancel={true} + tintColorDelete="rgba(61,60,64,0.5)" + tintColorSearch="rgba(61,60,64,0.8)" + titleCancelColor="#3d3c40" + value="" + /> - + `; diff --git a/app/components/emoji_picker/emoji_picker.ios.js b/app/components/emoji_picker/emoji_picker.ios.js index 64e9d2632..c76aa3d41 100644 --- a/app/components/emoji_picker/emoji_picker.ios.js +++ b/app/components/emoji_picker/emoji_picker.ios.js @@ -7,12 +7,11 @@ import { View, } from 'react-native'; import {KeyboardTrackingView} from 'react-native-keyboard-tracking-view'; +import {SafeAreaView} from 'react-native-safe-area-context'; -import SafeAreaView from 'app/components/safe_area_view'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; -import SearchBar from 'app/components/search_bar'; -import {DeviceTypes} from 'app/constants'; -import {changeOpacity, getKeyboardAppearanceFromTheme} from 'app/utils/theme'; +import SearchBar from '@components/search_bar'; +import {DeviceTypes} from '@constants'; +import {changeOpacity, getKeyboardAppearanceFromTheme} from '@utils/theme'; import EmojiPickerBase, {getStyleSheetFromTheme, SCROLLVIEW_NATIVE_ID} from './emoji_picker_base'; @@ -38,8 +37,8 @@ export default class EmojiPicker extends EmojiPickerBase { return ( - - - + {this.renderListComponent(shorten)} diff --git a/app/components/emoji_picker/emoji_picker.test.js b/app/components/emoji_picker/emoji_picker.test.js index 5b984da7f..0697e23f1 100644 --- a/app/components/emoji_picker/emoji_picker.test.js +++ b/app/components/emoji_picker/emoji_picker.test.js @@ -80,18 +80,6 @@ describe('components/emoji_picker/emoji_picker.ios', () => { expect(result).toEqual(output); }); - test('should set rebuildEmojis to true when deviceWidth changes', async () => { - const wrapper = shallowWithIntl(); - const instance = wrapper.instance(); - - expect(instance.rebuildEmojis).toBe(undefined); - - const newDeviceWidth = baseProps.deviceWidth * 2; - wrapper.setProps({deviceWidth: newDeviceWidth}); - - expect(instance.rebuildEmojis).toBe(true); - }); - test('should rebuild emojis emojis when emojis change', async () => { const wrapper = shallowWithIntl(); const instance = wrapper.instance(); diff --git a/app/components/emoji_picker/emoji_picker_base.js b/app/components/emoji_picker/emoji_picker_base.js index 29c4e8de3..c265ddbbe 100644 --- a/app/components/emoji_picker/emoji_picker_base.js +++ b/app/components/emoji_picker/emoji_picker_base.js @@ -19,7 +19,6 @@ import sectionListGetItemLayout from 'react-native-section-list-get-item-layout' import CompassIcon from '@components/compass_icon'; import Emoji from '@components/emoji'; import FormattedText from '@components/formatted_text'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {DeviceTypes} from '@constants'; import {emptyFunction} from '@utils/general'; import { @@ -101,8 +100,9 @@ export default class EmojiPicker extends PureComponent { if (this.props.emojis !== prevProps.emojis) { this.rebuildEmojis = true; - this.setRebuiltEmojis(); } + + this.setRebuiltEmojis(); } setSearchBarRef = (ref) => { @@ -305,7 +305,7 @@ export default class EmojiPicker extends PureComponent { onPress={() => this.props.onEmojiPress(item)} style={style.flatListRow} > - + { - if (Platform.OS === 'android') { - if (isLandscape) { - return ANDROID_TOP_LANDSCAPE; - } - - return ANDROID_TOP_PORTRAIT; - } - - const iPhoneWithInsets = DeviceTypes.IS_IPHONE_WITH_INSETS; - - if (iPhoneWithInsets && isLandscape) { - return IOS_TOP_LANDSCAPE; - } else if (iPhoneWithInsets) { - return IOS_INSETS_TOP_PORTRAIT; - } else if (isLandscape && !DeviceTypes.IS_TABLET) { - return IOS_TOP_LANDSCAPE; - } - - return IOS_TOP_PORTRAIT; + getNavBarHeight = (navBarHeight) => { + this.setState({navBarHeight}); }; handleWebSocket = (open) => { @@ -329,7 +318,7 @@ export default class NetworkIndicator extends PureComponent { Animated.timing( this.top, { - toValue: this.getNavBarHeight(), + toValue: this.state.navBarHeight, duration: 300, useNativeDriver: false, }, @@ -391,14 +380,17 @@ export default class NetworkIndicator extends PureComponent { pointerEvents='none' style={[styles.container, {top: this.top, backgroundColor: background, opacity: this.state.opacity}]} > - + {action} - + ); } diff --git a/app/components/post/index.js b/app/components/post/index.js index 29954cba7..6fdc9d4ac 100644 --- a/app/components/post/index.js +++ b/app/components/post/index.js @@ -14,7 +14,6 @@ import {isDateLine, isStartOfNewMessages} from '@mm-redux/utils/post_list'; import {isPostFlagged, isSystemMessage} from '@mm-redux/utils/post_utils'; import {insertToDraft, setPostTooltipVisible} from 'app/actions/views/channel'; -import {isLandscape} from 'app/selectors/device'; import Post from './post'; @@ -86,7 +85,6 @@ function makeMapStateToProps() { theme: getTheme(state), isFlagged: isPostFlagged(post.id, myPreferences), isCommentMention, - isLandscape: isLandscape(state), previousPostExists: Boolean(previousPost), beforePrevPostUserId: (beforePrevPost ? beforePrevPost.user_id : null), }; diff --git a/app/components/post/post.js b/app/components/post/post.js index a4feaf332..4c972814d 100644 --- a/app/components/post/post.js +++ b/app/components/post/post.js @@ -23,7 +23,6 @@ import PostHeader from '@components/post_header'; import PostProfilePicture from '@components/post_profile_picture'; import PostPreHeader from '@components/post_header/post_pre_header'; import TouchableWithFeedback from '@components/touchable_with_feedback'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {NavigationTypes} from '@constants'; @@ -70,7 +69,6 @@ export default class Post extends PureComponent { isCommentMention: PropTypes.bool, location: PropTypes.string, isBot: PropTypes.bool, - isLandscape: PropTypes.bool.isRequired, previousPostExists: PropTypes.bool, beforePrevPostUserId: PropTypes.string, }; @@ -266,7 +264,6 @@ export default class Post extends PureComponent { skipFlaggedHeader, skipPinnedHeader, location, - isLandscape, previousPostExists, beforePrevPostUserId, } = this.props; @@ -327,7 +324,7 @@ export default class Post extends PureComponent { return ( - - - - + /> - @@ -566,13 +550,17 @@ exports[`PostDraft Should render the DraftInput 1`] = ` - + `; exports[`PostDraft Should render the ReadOnly for canPost 1`] = ` - - + `; exports[`PostDraft Should render the ReadOnly for channelIsReadOnly 1`] = ` - - + `; diff --git a/app/components/post_draft/draft_input/draft_input.js b/app/components/post_draft/draft_input/draft_input.js index d317fcd0f..e7375aa24 100644 --- a/app/components/post_draft/draft_input/draft_input.js +++ b/app/components/post_draft/draft_input/draft_input.js @@ -6,6 +6,7 @@ import PropTypes from 'prop-types'; import {Platform, ScrollView, View} from 'react-native'; import {intlShape} from 'react-intl'; import HWKeyboardEvent from 'react-native-hw-keyboard-event'; +import {SafeAreaView} from 'react-native-safe-area-context'; import Autocomplete from '@components/autocomplete'; import PostInput from '@components/post_draft/post_input'; @@ -13,7 +14,6 @@ import QuickActions from '@components/post_draft/quick_actions'; import SendAction from '@components/post_draft/send_action'; import Typing from '@components/post_draft/typing'; import Uploads from '@components/post_draft/uploads'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {CHANNEL_POST_TEXTBOX_CURSOR_CHANGE, CHANNEL_POST_TEXTBOX_VALUE_CHANGE, IS_REACTION_REGEX} from '@constants/post_draft'; import {NOTIFY_ALL_MEMBERS} from '@constants/view'; import EventEmitter from '@mm-redux/utils/event_emitter'; @@ -400,8 +400,8 @@ export default class DraftInput extends PureComponent { channelDisplayName, channelId, cursorPositionEvent, - isLandscape, files, + isLandscape, maxMessageLength, screenId, valueEvent, @@ -417,10 +417,11 @@ export default class DraftInput extends PureComponent { theme={theme} registerTypingAnimation={registerTypingAnimation} /> - - + {Platform.OS === 'android' && { handleCommentDraftChanged: jest.fn(), handlePostDraftChanged: jest.fn(), inputEventType: '', - isLandscape: false, maxMessageLength: 4000, onPasteFiles: jest.fn(), onSend: jest.fn(), diff --git a/app/components/post_draft/read_only/__snapshots__/read_only.test.js.snap b/app/components/post_draft/read_only/__snapshots__/read_only.test.js.snap index 9402d1f6f..026c1fbe6 100644 --- a/app/components/post_draft/read_only/__snapshots__/read_only.test.js.snap +++ b/app/components/post_draft/read_only/__snapshots__/read_only.test.js.snap @@ -1,7 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`PostDraft ReadOnly Should match snapshot 1`] = ` - - + `; diff --git a/app/components/post_draft/read_only/index.tsx b/app/components/post_draft/read_only/index.tsx index 365c0c293..2ce8193e1 100644 --- a/app/components/post_draft/read_only/index.tsx +++ b/app/components/post_draft/read_only/index.tsx @@ -2,7 +2,8 @@ // See LICENSE.txt for license information. import React, {ReactNode} from 'react'; -import {SafeAreaView, View} from 'react-native'; +import {View} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; @@ -16,10 +17,13 @@ interface ReadOnlyProps { const ReadOnlyChannnel = ({theme}: ReadOnlyProps): ReactNode => { const style = getStyle(theme); return ( - + - - - {this.renderTyping()} - - + {this.renderTyping()} + ); } diff --git a/app/components/post_list/more_messages_button/__snapshots__/more_messages_button.test.js.snap b/app/components/post_list/more_messages_button/__snapshots__/more_messages_button.test.js.snap index 34fe62292..7cf44130f 100644 --- a/app/components/post_list/more_messages_button/__snapshots__/more_messages_button.test.js.snap +++ b/app/components/post_list/more_messages_button/__snapshots__/more_messages_button.test.js.snap @@ -18,7 +18,7 @@ exports[`MoreMessagesButton should match snapshot 1`] = ` Object { "transform": Array [ Object { - "translateY": -138, + "translateY": -438, }, ], }, diff --git a/app/components/post_list/more_messages_button/more_messages_button.js b/app/components/post_list/more_messages_button/more_messages_button.js index 7b30a50b9..cd33e3545 100644 --- a/app/components/post_list/more_messages_button/more_messages_button.js +++ b/app/components/post_list/more_messages_button/more_messages_button.js @@ -15,7 +15,7 @@ import ViewTypes, {INDICATOR_BAR_HEIGHT} from '@constants/view'; import {makeStyleSheetFromTheme, hexToHue} from '@utils/theme'; import {t} from '@utils/i18n'; -const HIDDEN_TOP = -100; +const HIDDEN_TOP = -400; const SHOWN_TOP = 0; export const INDICATOR_BAR_FACTOR = Math.abs(INDICATOR_BAR_HEIGHT / (HIDDEN_TOP - SHOWN_TOP)); export const MIN_INPUT = 0; diff --git a/app/components/reaction_picker/__snapshots__/reaction_picker.test.js.snap b/app/components/reaction_picker/__snapshots__/reaction_picker.test.js.snap index c6ebbcdf2..9cde6cacc 100644 --- a/app/components/reaction_picker/__snapshots__/reaction_picker.test.js.snap +++ b/app/components/reaction_picker/__snapshots__/reaction_picker.test.js.snap @@ -3,19 +3,14 @@ exports[`Reactions Should match snapshot with default emojis 1`] = ` { + const {theme} = props; + const style = getStyleSheet(theme); + const {width} = useWindowDimensions(); + const isSmallDevice = width < SMALL_ICON_BREAKPOINT; + + const handlePress = (emoji) => { + props.addReaction(emoji); + }; + + let containerSize = LARGE_CONTAINER_SIZE; + let iconSize = LARGE_ICON_SIZE; + + if (isSmallDevice) { + containerSize = SMALL_CONTAINER_SIZE; + iconSize = SMALL_ICON_SIZE; } - handlePress = (emoji) => { - this.props.addReaction(emoji); - } - - render() { - const { - theme, - deviceWidth, - isLandscape, - } = this.props; - const style = getStyleSheet(theme); - const isSmallDevice = deviceWidth < SMALL_ICON_BREAKPOINT; - - let containerSize = LARGE_CONTAINER_SIZE; - let iconSize = LARGE_ICON_SIZE; - - if (isSmallDevice) { - containerSize = SMALL_CONTAINER_SIZE; - iconSize = SMALL_ICON_SIZE; - } - - // Mixing recent emojis with default list and removing duplicates - const emojis = Array.from(new Set(this.props.recentEmojis.concat(DEFAULT_EMOJIS))).splice(0, 6); - - const list = emojis.map((emoji) => { - return ( - - ); - }); - - let paddingRes = padding(isLandscape, 12); - if (!paddingRes) { - paddingRes = { - paddingLeft: 12, - paddingRight: 12, - }; - } - + const emojis = Array.from(new Set(props.recentEmojis.concat(DEFAULT_EMOJIS))).splice(0, 6); + const list = emojis.map((emoji) => { return ( - - {list} - - - - - - + ); - } -} + }); + + return ( + + {list} + + + + + + + ); +}; + +ReactionPicker.propTypes = { + addReaction: PropTypes.func.isRequired, + openReactionScreen: PropTypes.func.isRequired, + theme: PropTypes.object.isRequired, + recentEmojis: PropTypes.array, +}; + +export default ReactionPicker; const getStyleSheet = makeStyleSheetFromTheme((theme) => { return { @@ -117,6 +98,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { alignItems: 'center', height: REACTION_PICKER_HEIGHT, justifyContent: 'space-between', + paddingHorizontal: 12, }, reactionContainer: { backgroundColor: changeOpacity(theme.centerChannelColor, 0.04), diff --git a/app/components/reaction_picker/reaction_picker.test.js b/app/components/reaction_picker/reaction_picker.test.js index 829a5da5a..edd61a682 100644 --- a/app/components/reaction_picker/reaction_picker.test.js +++ b/app/components/reaction_picker/reaction_picker.test.js @@ -11,8 +11,6 @@ import Preferences from '@mm-redux/constants/preferences'; describe('Reactions', () => { const baseProps = { addReaction: jest.fn(), - deviceWidth: undefined, - isLandscape: false, openReactionScreen: jest.fn(), recentEmojis: [], theme: Preferences.THEMES.default, diff --git a/app/components/safe_area_view/__snapshots__/safe_area_view.ios.test.js.snap b/app/components/safe_area_view/__snapshots__/safe_area_view.ios.test.js.snap deleted file mode 100644 index 4aef1154f..000000000 --- a/app/components/safe_area_view/__snapshots__/safe_area_view.ios.test.js.snap +++ /dev/null @@ -1,32 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`SafeAreaIos should match snapshot 1`] = ` - - - - -`; diff --git a/app/components/safe_area_view/index.js b/app/components/safe_area_view/index.js index 9ba90cb89..e41e9b2f2 100644 --- a/app/components/safe_area_view/index.js +++ b/app/components/safe_area_view/index.js @@ -5,7 +5,7 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import SafeAreaView from './safe_area_view'; +import SafeAreaView from './safe_area'; function mapStateToProps(state) { return { diff --git a/app/components/safe_area_view/iphone_x_spacing/index.js b/app/components/safe_area_view/iphone_x_spacing/index.js deleted file mode 100644 index 8d8bfa9c6..000000000 --- a/app/components/safe_area_view/iphone_x_spacing/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import {DeviceTypes, ViewTypes} from 'app/constants'; - -export const paddingHorizontal = (isLandscape, modifier = 0) => { - return DeviceTypes.IS_IPHONE_WITH_INSETS && isLandscape ? {paddingHorizontal: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; -}; - -export const paddingLeft = (isLandscape, modifier = 0) => { - return DeviceTypes.IS_IPHONE_WITH_INSETS && isLandscape ? {paddingLeft: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; -}; - -export const paddingRight = (isLandscape, modifier = 0) => { - return DeviceTypes.IS_IPHONE_WITH_INSETS && isLandscape ? {paddingRight: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; -}; - -export const marginHorizontal = (isLandscape, modifier = 0) => { - return DeviceTypes.IS_IPHONE_WITH_INSETS && isLandscape ? {marginHorizontal: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; -}; diff --git a/app/components/safe_area_view/safe_area.tsx b/app/components/safe_area_view/safe_area.tsx new file mode 100644 index 000000000..04f96d8e5 --- /dev/null +++ b/app/components/safe_area_view/safe_area.tsx @@ -0,0 +1,84 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useCallback} from 'react'; +import {View} from 'react-native'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; + +import type {Theme} from '@mm-redux/types/preferences'; + +type SafeAreaProps = { + backgroundColor?: string; + children: Array | React.ReactChild; + excludeHeader?: boolean; + excludeFooter?: boolean; + excludeLeft?: boolean; + excludeRight?: boolean; + headerComponent?: React.ReactElement; + footerColor?: string; + footerComponent?: React.ReactElement; + navBarBackgroundColor?: string; + theme: Theme; +} + +const SafeArea = (props: SafeAreaProps) => { + const { + backgroundColor, + excludeFooter, + excludeHeader, + excludeLeft, + excludeRight, + footerColor, + footerComponent, + headerComponent, + navBarBackgroundColor, + theme, + } = props; + const insets = useSafeAreaInsets(); + + const renderTop = useCallback(() => { + if (excludeHeader) { + return null; + } + + let topColor = theme.sidebarHeaderBg; + if (navBarBackgroundColor) { + topColor = navBarBackgroundColor; + } + + return ( + + {headerComponent} + + ); + }, [insets, props.theme]); + + let bgColor = theme.centerChannelBg; + if (backgroundColor) { + bgColor = backgroundColor; + } + + let bottomColor = theme.centerChannelBg; + if (footerColor) { + bottomColor = footerColor; + } + + let bottomInset = insets.bottom; + if (excludeFooter) { + bottomInset = 0; + } + + return ( + + {renderTop()} + + {props.children} + + + {footerComponent} + + + ); +}; + +export default SafeArea; diff --git a/app/components/safe_area_view/safe_area_view.android.js b/app/components/safe_area_view/safe_area_view.android.js deleted file mode 100644 index e348be099..000000000 --- a/app/components/safe_area_view/safe_area_view.android.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -const SafeAreaAndroid = (props) => { - return props.children; -}; - -export default SafeAreaAndroid; \ No newline at end of file diff --git a/app/components/safe_area_view/safe_area_view.ios.js b/app/components/safe_area_view/safe_area_view.ios.js deleted file mode 100644 index 973a1feb6..000000000 --- a/app/components/safe_area_view/safe_area_view.ios.js +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React, {PureComponent} from 'react'; -import PropTypes from 'prop-types'; -import {Animated, Dimensions, Keyboard, NativeModules, View} from 'react-native'; -import SafeArea from 'react-native-safe-area'; - -import EventEmitter from '@mm-redux/utils/event_emitter'; - -import {DeviceTypes, ViewTypes} from 'app/constants'; -import mattermostManaged from 'app/mattermost_managed'; -import EphemeralStore from 'app/store/ephemeral_store'; - -const {StatusBarManager} = NativeModules; -const {PORTRAIT, LANDSCAPE} = ViewTypes; - -export default class SafeAreaIos extends PureComponent { - static propTypes = { - backgroundColor: PropTypes.string, - children: PropTypes.node.isRequired, - excludeHeader: PropTypes.bool, - excludeFooter: PropTypes.bool, - footerColor: PropTypes.string, - footerComponent: PropTypes.node, - keyboardOffset: PropTypes.number.isRequired, - navBarBackgroundColor: PropTypes.string, - headerComponent: PropTypes.node, - theme: PropTypes.object.isRequired, - useLandscapeMargin: PropTypes.bool.isRequired, - }; - - static defaultProps = { - keyboardOffset: 0, - useLandscapeMargin: false, - }; - - constructor(props) { - super(props); - - const insetTop = DeviceTypes.IS_IPHONE_WITH_INSETS ? 44 : 20; - let insetBottom = 0; - if ((DeviceTypes.IS_IPHONE_WITH_INSETS || mattermostManaged.hasSafeAreaInsets) && props.excludeFooter) { - insetBottom = 20; - } - - this.state = { - keyboard: false, - safeAreaInsets: { - top: insetTop, - left: 0, - bottom: insetBottom, - right: 0, - }, - }; - - this.topBarHeight = new Animated.Value(insetTop); - } - - componentDidMount() { - this.mounted = true; - - Dimensions.addEventListener('change', this.getSafeAreaInsets); - EventEmitter.on('update_safe_area_view', this.getSafeAreaInsets); - if (EphemeralStore.safeAreaInsets[PORTRAIT] === null || EphemeralStore.safeAreaInsets[LANDSCAPE] === null) { - SafeArea.addEventListener('safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsForRootViewChange); - } - - this.keyboardDidShowListener = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); - this.keyboardDidHideListener = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide); - - this.getSafeAreaInsets(); - } - - componentWillUnmount() { - Dimensions.removeEventListener('change', this.getSafeAreaInsets); - EventEmitter.off('update_safe_area_view', this.getSafeAreaInsets); - SafeArea.removeEventListener('safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsForRootViewChange); - this.keyboardDidShowListener.remove(); - this.keyboardDidHideListener.remove(); - - this.mounted = false; - } - - getSafeAreaInsets = async (dimensions) => { - this.getStatusBarHeight(); - - if (DeviceTypes.IS_IPHONE_WITH_INSETS || mattermostManaged.hasSafeAreaInsets) { - const window = dimensions?.window || Dimensions.get('window'); - const orientation = window.width > window.height ? LANDSCAPE : PORTRAIT; - const {safeAreaInsets} = await SafeArea.getSafeAreaInsetsForRootView(); - this.setSafeAreaInsets(safeAreaInsets, orientation); - } - } - - setSafeAreaInsets = (safeAreaInsets, orientation) => { - if (EphemeralStore.safeAreaInsets[orientation] === null) { - EphemeralStore.safeAreaInsets[orientation] = safeAreaInsets; - } - - if (this.mounted) { - this.setState({ - safeAreaInsets: EphemeralStore.safeAreaInsets[orientation], - }); - } - } - - getStatusBarHeight = () => { - try { - StatusBarManager.getHeight( - (statusBarFrameData) => { - if (this.mounted) { - if (statusBarFrameData.height === 0) { - this.hideTopBar(); - } else { - this.showTopBar(); - } - } - }, - ); - } catch (e) { - // not needed - } - }; - - onSafeAreaInsetsForRootViewChange = ({safeAreaInsets}) => { - if (EphemeralStore.safeAreaInsets[PORTRAIT] !== null && EphemeralStore.safeAreaInsets[LANDSCAPE] !== null) { - SafeArea.removeEventListener('safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsForRootViewChange); - return; - } - - if (DeviceTypes.IS_IPHONE_WITH_INSETS || mattermostManaged.hasSafeAreaInsets) { - this.getStatusBarHeight(); - - const {width, height} = Dimensions.get('window'); - const orientation = width > height ? LANDSCAPE : PORTRAIT; - this.setSafeAreaInsets(safeAreaInsets, orientation); - } - } - - keyboardWillHide = () => { - this.setState({keyboard: false}); - }; - - keyboardWillShow = () => { - this.setState({keyboard: true}); - }; - - hideTopBar = () => { - Animated.timing(this.topBarHeight, { - toValue: 10, - duration: 350, - useNativeDriver: false, - }).start(); - } - - showTopBar = () => { - Animated.timing(this.topBarHeight, { - toValue: this.state.safeAreaInsets.top, - duration: 350, - useNativeDriver: false, - }).start(); - } - - renderTopBar = () => { - const {headerComponent, excludeHeader, navBarBackgroundColor, theme} = this.props; - - if (excludeHeader) { - return null; - } - - let topColor = theme.sidebarHeaderBg; - if (navBarBackgroundColor) { - topColor = navBarBackgroundColor; - } - - if (headerComponent) { - return ( - - {headerComponent} - - ); - } - - return ( - - ); - }; - - render() { - const {backgroundColor, children, excludeFooter, footerColor, footerComponent, keyboardOffset, theme, useLandscapeMargin} = this.props; - const {keyboard, safeAreaInsets} = this.state; - - let bgColor = theme.centerChannelBg; - if (backgroundColor) { - bgColor = backgroundColor; - } - - let bottomColor = theme.centerChannelBg; - if (footerColor) { - bottomColor = footerColor; - } - - let offset = 0; - if (keyboardOffset && mattermostManaged.hasSafeAreaInsets) { - offset = keyboardOffset; - } - - let bottomInset = safeAreaInsets.bottom; - if (excludeFooter) { - bottomInset = 0; - } - - return ( - - {this.renderTopBar()} - {children} - - {footerComponent} - - - ); - } -} diff --git a/app/components/safe_area_view/safe_area_view.ios.test.js b/app/components/safe_area_view/safe_area_view.ios.test.js deleted file mode 100644 index 5b3067afc..000000000 --- a/app/components/safe_area_view/safe_area_view.ios.test.js +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -import React from 'react'; -import SafeArea from 'react-native-safe-area'; -import {shallow} from 'enzyme'; - -import Preferences from '@mm-redux/constants/preferences'; - -import {DeviceTypes, ViewTypes} from 'app/constants'; -import mattermostManaged from 'app/mattermost_managed'; -import EphemeralStore from 'app/store/ephemeral_store'; - -import SafeAreaIos from './safe_area_view.ios'; - -const {PORTRAIT, LANDSCAPE} = ViewTypes; - -describe('SafeAreaIos', () => { - const baseProps = { - children: [], - keyboardOffset: 100, - useLandscapeMargin: false, - theme: Preferences.THEMES.default, - }; - - const TEST_INSETS_1 = { - safeAreaInsets: { - top: 123, - left: 123, - bottom: 123, - right: 123, - }, - }; - - const TEST_INSETS_2 = { - safeAreaInsets: { - top: 456, - left: 456, - bottom: 456, - right: 456, - }, - }; - - const PORTRAIT_INSETS = { - safeAreaInsets: { - top: 111, - left: 111, - bottom: 111, - right: 111, - }, - }; - - const LANDSCAPE_INSETS = { - safeAreaInsets: { - top: 222, - left: 222, - bottom: 222, - right: 222, - }, - }; - - const IGNORED_INSETS = { - safeAreaInsets: { - top: 333, - left: 333, - bottom: 333, - right: 333, - }, - }; - - SafeArea.getSafeAreaInsetsForRootView = jest.fn().mockImplementation(() => { - return Promise.resolve(TEST_INSETS_1); - }); - - beforeEach(() => { - EphemeralStore.safeAreaInsets = { - [PORTRAIT]: null, - [LANDSCAPE]: null, - }; - }); - - test('should match snapshot', () => { - const wrapper = shallow( - , - ); - - expect(wrapper.getElement()).toMatchSnapshot(); - }); - - test('should get safe area insets on mount if DeviceTypes.IS_IPHONE_WITH_INSETS is true', async () => { - DeviceTypes.IS_IPHONE_WITH_INSETS = true; - mattermostManaged.hasSafeAreaInsets = false; - - const wrapper = shallow( - , - ); - - expect(SafeArea.getSafeAreaInsetsForRootView).toHaveBeenCalled(); - await SafeArea.getSafeAreaInsetsForRootView(); - expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_1.safeAreaInsets); - }); - - test('should get safe area insets on mount if mattermostManaged.hasSafeAreaInsets is true', async () => { - DeviceTypes.IS_IPHONE_WITH_INSETS = false; - mattermostManaged.hasSafeAreaInsets = true; - - const wrapper = shallow( - , - ); - - expect(SafeArea.getSafeAreaInsetsForRootView).toHaveBeenCalled(); - await SafeArea.getSafeAreaInsetsForRootView(); - expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_1.safeAreaInsets); - }); - - test('should not get safe area insets on mount if neither DeviceTypes.IS_IPHONE_WITH_INSET nor mattermostManaged.hasSafeAreaInsets is true', async () => { - DeviceTypes.IS_IPHONE_WITH_INSETS = false; - mattermostManaged.hasSafeAreaInsets = false; - - const wrapper = shallow( - , - ); - - expect(SafeArea.getSafeAreaInsetsForRootView).not.toHaveBeenCalled(); - await SafeArea.getSafeAreaInsetsForRootView(); - expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_1.safeAreaInsets); - }); - - test('should set safe area insets on change if mounted and DeviceTypes.IS_IPHONE_WITH_INSETS is true', async () => { - DeviceTypes.IS_IPHONE_WITH_INSETS = true; - mattermostManaged.hasSafeAreaInsets = false; - - const wrapper = shallow( - , - ); - - expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); - - const instance = wrapper.instance(); - instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); - expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_2.safeAreaInsets); - }); - - test('should set safe area insets on change if mounted and mattermostManaged.hasSafeAreaInsets is true', async () => { - DeviceTypes.IS_IPHONE_WITH_INSETS = false; - mattermostManaged.hasSafeAreaInsets = true; - - const wrapper = shallow( - , - ); - - expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); - - const instance = wrapper.instance(); - instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); - expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_2.safeAreaInsets); - }); - - test('should not set safe area insets on change if mounted and neither DeviceTypes.IS_IPHONE_WITH_INSETS nor mattermostManaged.hasSafeAreaInsets is true', async () => { - DeviceTypes.IS_IPHONE_WITH_INSETS = false; - mattermostManaged.hasSafeAreaInsets = false; - - const wrapper = shallow( - , - ); - - expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); - - const instance = wrapper.instance(); - instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); - expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); - }); - - test('should set safe area insets on change not mounted', async () => { - DeviceTypes.IS_IPHONE_WITH_INSETS = true; - mattermostManaged.hasSafeAreaInsets = true; - - const wrapper = shallow( - , - ); - - expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); - - const instance = wrapper.instance(); - instance.mounted = false; - instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); - expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); - }); - - test('should set portrait safe area insets', async () => { - const wrapper = shallow( - , - ); - - expect(wrapper.state().safeAreaInsets).not.toEqual(PORTRAIT_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null); - - const orientation = PORTRAIT; - const instance = wrapper.instance(); - instance.setSafeAreaInsets(PORTRAIT_INSETS.safeAreaInsets, orientation); - expect(wrapper.state().safeAreaInsets).toEqual(PORTRAIT_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(PORTRAIT_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null); - }); - - test('should set portrait safe area insets from EphemeralStore', async () => { - const wrapper = shallow( - , - ); - - EphemeralStore.safeAreaInsets[PORTRAIT] = PORTRAIT_INSETS.safeAreaInsets; - expect(wrapper.state().safeAreaInsets).not.toEqual(PORTRAIT_INSETS.safeAreaInsets); - - const orientation = PORTRAIT; - const instance = wrapper.instance(); - instance.setSafeAreaInsets(IGNORED_INSETS.safeAreaInsets, orientation); - expect(wrapper.state().safeAreaInsets).toEqual(PORTRAIT_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(PORTRAIT_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null); - }); - - test('should set landscape safe area insets', () => { - const wrapper = shallow( - , - ); - - expect(wrapper.state().safeAreaInsets).not.toEqual(LANDSCAPE_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null); - - const orientation = LANDSCAPE; - const instance = wrapper.instance(); - instance.setSafeAreaInsets(LANDSCAPE_INSETS.safeAreaInsets, orientation); - expect(wrapper.state().safeAreaInsets).toEqual(LANDSCAPE_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(LANDSCAPE_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null); - }); - - test('should set landscape safe area insets from EphemeralStore', async () => { - const wrapper = shallow( - , - ); - - EphemeralStore.safeAreaInsets[LANDSCAPE] = LANDSCAPE_INSETS.safeAreaInsets; - expect(wrapper.state().safeAreaInsets).not.toEqual(LANDSCAPE_INSETS.safeAreaInsets); - - const orientation = LANDSCAPE; - const instance = wrapper.instance(); - instance.setSafeAreaInsets(IGNORED_INSETS.safeAreaInsets, orientation); - expect(wrapper.state().safeAreaInsets).toEqual(LANDSCAPE_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(LANDSCAPE_INSETS.safeAreaInsets); - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null); - }); - - test('should add safeAreaInsetsForRootViewDidChange listener when EphemeralStore values are not set', async () => { - const addEventListener = jest.spyOn(SafeArea, 'addEventListener'); - - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null); - let wrapper = shallow( - , - ); - let instance = wrapper.instance(); - expect(addEventListener).toHaveBeenCalledWith('safeAreaInsetsForRootViewDidChange', instance.onSafeAreaInsetsForRootViewChange); - addEventListener.mockClear(); - - EphemeralStore.safeAreaInsets[PORTRAIT] = TEST_INSETS_1.safeAreaInsets; - wrapper = shallow( - , - ); - instance = wrapper.instance(); - expect(addEventListener).toHaveBeenCalledWith('safeAreaInsetsForRootViewDidChange', instance.onSafeAreaInsetsForRootViewChange); - addEventListener.mockClear(); - - EphemeralStore.safeAreaInsets[PORTRAIT] = TEST_INSETS_1.safeAreaInsets; - EphemeralStore.safeAreaInsets[LANDSCAPE] = TEST_INSETS_1.safeAreaInsets; - wrapper = shallow( - , - ); - instance = wrapper.instance(); - expect(addEventListener).not.toHaveBeenCalled(); - }); - - test('should remove safeAreaInsetsForRootViewDidChange listener when EphemeralStore values are set', async () => { - const removeEventListener = jest.spyOn(SafeArea, 'removeEventListener'); - - const wrapper = shallow( - , - ); - const instance = wrapper.instance(); - expect(EphemeralStore.safeAreaInsets[PORTRAIT]).toEqual(null); - expect(EphemeralStore.safeAreaInsets[LANDSCAPE]).toEqual(null); - - instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_1); - expect(removeEventListener).not.toHaveBeenCalled(); - - EphemeralStore.safeAreaInsets[PORTRAIT] = TEST_INSETS_1.safeAreaInsets; - instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_1); - expect(removeEventListener).not.toHaveBeenCalled(); - - EphemeralStore.safeAreaInsets[LANDSCAPE] = TEST_INSETS_1.safeAreaInsets; - instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_1); - expect(removeEventListener).toHaveBeenCalledWith('safeAreaInsetsForRootViewDidChange', instance.onSafeAreaInsetsForRootViewChange); - }); -}); diff --git a/app/components/sidebars/drawer_layout.js b/app/components/sidebars/drawer_layout/drawer_layout.js similarity index 99% rename from app/components/sidebars/drawer_layout.js rename to app/components/sidebars/drawer_layout/drawer_layout.js index ca6f06101..a61572339 100644 --- a/app/components/sidebars/drawer_layout.js +++ b/app/components/sidebars/drawer_layout/drawer_layout.js @@ -28,10 +28,6 @@ const DRAGGING = 'Dragging'; const SETTLING = 'Settling'; const emptyObject = {}; -export const DRAWER_INITIAL_OFFSET = 40; -export const TABLET_WIDTH = 250; - - export default class DrawerLayout extends Component { static propTypes = { children: PropTypes.any, diff --git a/app/components/sidebars/drawer_layout/index.tsx b/app/components/sidebars/drawer_layout/index.tsx new file mode 100644 index 000000000..985f96db6 --- /dev/null +++ b/app/components/sidebars/drawer_layout/index.tsx @@ -0,0 +1,57 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; + +import DrawerLayout from './drawer_layout'; + +export const DRAWER_INITIAL_OFFSET = 40; +export const TABLET_WIDTH = 250; + +interface DrawerLayoutAdapterProps { + children: any; + drawerBackgroundColor?: string; + drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open'; + drawerPosition?: 'left' | 'right'; + drawerWidth: number; + keyboardDismissMode?: 'none' | 'on-drag'; + forwardRef: any; + isTablet: boolean; + onDrawerClose?: () => void; + onDrawerOpen?: () => void; + onDrawerSlide?: (event: {nativeEvent: {offset: number}}) => void; + onDrawerStateChanged?: () => 'Idle' | 'Dragging' | 'Settling'; + renderNavigationView: (drawerWidth: number) => any; + statusBarBackgroundColor?: string; + testID?: string; +} + +const DrawerLayoutAdapter = (props: DrawerLayoutAdapterProps) => { + const insets = useSafeAreaInsets(); + const horizontal = insets.left + insets.right; + + return ( + + {props.children} + + ); +}; + +export default DrawerLayoutAdapter; \ No newline at end of file diff --git a/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap b/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap index b055ce8d4..d955b64b8 100644 --- a/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap +++ b/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap @@ -1,9 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`MainSidebar should match, full snapshot 1`] = ` - @@ -117,7 +116,6 @@ exports[`ChannelItem should match snapshot for current user i.e currentUser (you "height": 44, }, undefined, - null, ] } > @@ -230,7 +228,6 @@ exports[`ChannelItem should match snapshot for current user i.e currentUser (you "height": 44, }, undefined, - null, ] } > @@ -343,7 +340,6 @@ exports[`ChannelItem should match snapshot for deactivated user and is currentCh "height": 44, }, undefined, - null, ] } > @@ -456,7 +452,6 @@ exports[`ChannelItem should match snapshot for deactivated user and is searchRes "height": 44, }, undefined, - null, ] } > @@ -559,7 +554,6 @@ exports[`ChannelItem should match snapshot for deactivated user and not searchRe "height": 44, }, undefined, - null, ] } > @@ -662,7 +656,6 @@ exports[`ChannelItem should match snapshot for isManualUnread 1`] = ` "height": 44, }, undefined, - null, ] } > @@ -769,7 +762,6 @@ exports[`ChannelItem should match snapshot with draft 1`] = ` "height": 44, }, undefined, - null, ] } > @@ -874,7 +866,6 @@ exports[`ChannelItem should match snapshot with mentions and muted 1`] = ` Object { "opacity": 0.5, }, - null, ] } > diff --git a/app/components/sidebars/main/channels_list/channel_item/channel_item.js b/app/components/sidebars/main/channels_list/channel_item/channel_item.js index 98e199af5..fd530390a 100644 --- a/app/components/sidebars/main/channels_list/channel_item/channel_item.js +++ b/app/components/sidebars/main/channels_list/channel_item/channel_item.js @@ -11,7 +11,6 @@ import { import {intlShape} from 'react-intl'; import {General} from '@mm-redux/constants'; -import {paddingLeft as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import Badge from 'app/components/badge'; import ChannelIcon from 'app/components/channel_icon'; import {preventDoubleTap} from 'app/utils/tap'; @@ -37,7 +36,6 @@ export default class ChannelItem extends PureComponent { unreadMsgs: PropTypes.number.isRequired, isSearchResult: PropTypes.bool, isBot: PropTypes.bool.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -78,7 +76,6 @@ export default class ChannelItem extends PureComponent { isSearchResult, channel, isBot, - isLandscape, } = this.props; // Only ever show an archived channel if it's the currently viewed channel. @@ -173,7 +170,7 @@ export default class ChannelItem extends PureComponent { underlayColor={changeOpacity(theme.sidebarTextHoverBg, 0.5)} onPress={this.onPress} > - + {extraBorder} {icon} diff --git a/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js b/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js index a317c1e5b..7a9ba72c3 100644 --- a/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js +++ b/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js @@ -39,7 +39,6 @@ describe('ChannelItem', () => { unreadMsgs: 1, isSearchResult: false, isBot: false, - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/components/sidebars/main/channels_list/channel_item/index.js b/app/components/sidebars/main/channels_list/channel_item/index.js index aa8801932..87230dbe0 100644 --- a/app/components/sidebars/main/channels_list/channel_item/index.js +++ b/app/components/sidebars/main/channels_list/channel_item/index.js @@ -15,9 +15,8 @@ import {getTheme, getTeammateNameDisplaySetting} from '@mm-redux/selectors/entit import {getCurrentUserId, getUser} from '@mm-redux/selectors/entities/users'; import {getUserIdFromChannelName, isChannelMuted} from '@mm-redux/utils/channel_utils'; import {displayUsername} from '@mm-redux/utils/user_utils'; -import {isLandscape} from 'app/selectors/device'; -import {getDraftForChannel} from 'app/selectors/views'; -import {isGuest as isGuestUser} from 'app/utils/users'; +import {getDraftForChannel} from '@selectors/views'; +import {isGuest as isGuestUser} from '@utils/users'; import ChannelItem from './channel_item'; @@ -82,7 +81,6 @@ function makeMapStateToProps() { isBot, isChannelMuted: isChannelMuted(member), isGuest, - isLandscape: isLandscape(state), isManualUnread: isManuallyUnread(state, ownProps.channelId), mentions: member ? member.mention_count : 0, shouldHideChannel, diff --git a/app/components/sidebars/main/channels_list/channels_list.js b/app/components/sidebars/main/channels_list/channels_list.js index f302c0776..e12bb70fb 100644 --- a/app/components/sidebars/main/channels_list/channels_list.js +++ b/app/components/sidebars/main/channels_list/channels_list.js @@ -8,10 +8,10 @@ import { View, } from 'react-native'; import {intlShape} from 'react-intl'; +import {SafeAreaView} from 'react-native-safe-area-context'; import CompassIcon from '@components/compass_icon'; import SearchBar from '@components/search_bar'; -import {paddingLeft as padding} from '@components/safe_area_view/iphone_x_spacing'; import {ViewTypes} from '@constants'; import { changeOpacity, @@ -32,7 +32,6 @@ export default class ChannelsList extends PureComponent { onSearchStart: PropTypes.func.isRequired, onSelectChannel: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, onShowTeams: PropTypes.func, }; @@ -93,11 +92,7 @@ export default class ChannelsList extends PureComponent { render() { const {intl} = this.context; - const { - onShowTeams, - theme, - isLandscape, - } = this.props; + const {onShowTeams, theme} = this.props; const {searching, term} = this.state; const styles = getStyleSheet(theme); @@ -130,7 +125,7 @@ export default class ChannelsList extends PureComponent { const title = ( @@ -166,7 +162,7 @@ export default class ChannelsList extends PureComponent { {title} {list} - + ); } } diff --git a/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js b/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js index b5f59321c..afcf9237f 100644 --- a/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js +++ b/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js @@ -13,13 +13,12 @@ import { } from 'react-native'; import {injectIntl, intlShape} from 'react-intl'; +import ChannelItem from '@components/sidebars/main/channels_list/channel_item'; +import {ListTypes} from '@constants'; import {General} from '@mm-redux/constants'; import {sortChannelsByDisplayName} from '@mm-redux/utils/channel_utils'; import {displayUsername} from '@mm-redux/utils/user_utils'; -import {t} from 'app/utils/i18n'; -import ChannelItem from 'app/components/sidebars/main/channels_list/channel_item'; -import {ListTypes} from 'app/constants'; -import {paddingLeft} from 'app/components/safe_area_view/iphone_x_spacing'; +import {t} from '@utils/i18n'; const VIEWABILITY_CONFIG = ListTypes.VISIBILITY_CONFIG_DEFAULTS; @@ -50,7 +49,6 @@ class FilteredList extends Component { styles: PropTypes.object.isRequired, term: PropTypes.string, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -354,23 +352,21 @@ class FilteredList extends Component { }; renderSectionHeader = ({section}) => { - const {intl, isLandscape, styles} = this.props; + const {intl, styles} = this.props; const { defaultMessage, id, } = section; return ( - - - - {intl.formatMessage({id, defaultMessage}).toUpperCase()} - - - - + + + {intl.formatMessage({id, defaultMessage}).toUpperCase()} + + + - + ); }; diff --git a/app/components/sidebars/main/channels_list/filtered_list/index.js b/app/components/sidebars/main/channels_list/filtered_list/index.js index 02a6811dd..1ab906731 100644 --- a/app/components/sidebars/main/channels_list/filtered_list/index.js +++ b/app/components/sidebars/main/channels_list/filtered_list/index.js @@ -21,7 +21,6 @@ import {getConfig} from '@mm-redux/selectors/entities/general'; import {getCurrentTeam} from '@mm-redux/selectors/entities/teams'; import {getCurrentUserId, getProfilesInCurrentTeam, getUsers, getUserIdsInChannels, getUserStatuses} from '@mm-redux/selectors/entities/users'; import {getDirectShowPreferences, getTeammateNameDisplaySetting, getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from '@selectors/device'; import FilteredList from './filtered_list'; @@ -127,7 +126,6 @@ function mapStateToProps(state) { pastDirectMessages: pastDirectMessages(state), restrictDms, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/components/sidebars/main/channels_list/index.js b/app/components/sidebars/main/channels_list/index.js index 0c1de974c..07dd98be7 100644 --- a/app/components/sidebars/main/channels_list/index.js +++ b/app/components/sidebars/main/channels_list/index.js @@ -4,13 +4,11 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import ChannelsList from './channels_list'; function mapStateToProps(state) { return { theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/components/sidebars/main/channels_list/list/index.js b/app/components/sidebars/main/channels_list/list/index.js index 97286566a..2e08d9409 100644 --- a/app/components/sidebars/main/channels_list/list/index.js +++ b/app/components/sidebars/main/channels_list/list/index.js @@ -3,6 +3,7 @@ import {connect} from 'react-redux'; +import {DeviceTypes, ViewTypes} from '@constants'; import {General} from '@mm-redux/constants'; import { getSortedFavoriteChannelIds, @@ -19,9 +20,6 @@ import {getConfig, getLicense, hasNewPermissions} from '@mm-redux/selectors/enti import {haveITeamPermission} from '@mm-redux/selectors/entities/roles'; import Permissions from '@mm-redux/constants/permissions'; -import {isLandscape} from 'app/selectors/device'; -import {DeviceTypes, ViewTypes} from 'app/constants'; - import List from './list'; const filterZeroUnreads = memoizeResult((sections) => { @@ -71,7 +69,6 @@ function mapStateToProps(state) { theme: getTheme(state), unreadChannelIds, orderedChannelIds, - isLandscape: isLandscape(state), }; } diff --git a/app/components/sidebars/main/channels_list/list/list.js b/app/components/sidebars/main/channels_list/list/list.js index 9b304ecee..a4cb9d478 100644 --- a/app/components/sidebars/main/channels_list/list/list.js +++ b/app/components/sidebars/main/channels_list/list/list.js @@ -21,7 +21,6 @@ import {debounce} from '@mm-redux/actions/helpers'; import CompassIcon from '@components/compass_icon'; import ChannelItem from '@components/sidebars/main/channels_list/channel_item'; -import {paddingLeft} from '@components/safe_area_view/iphone_x_spacing'; import {DeviceTypes, ListTypes, NavigationTypes} from '@constants'; import {SidebarSectionTypes} from '@constants/view'; @@ -48,7 +47,6 @@ export default class List extends PureComponent { styles: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, orderedChannelIds: PropTypes.array.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -326,24 +324,22 @@ export default class List extends PureComponent { }; renderSectionHeader = ({section}) => { - const {styles, isLandscape} = this.props; + const {styles} = this.props; const {intl} = this.context; const {action, defaultMessage, id} = section; const anchor = (id === 'sidebar.types.recent' || id === 'mobile.channel_list.channels'); return ( - - - - {intl.formatMessage({id, defaultMessage}).toUpperCase()} - - - - - {action && this.renderSectionAction(styles, action, anchor, id)} + + + {intl.formatMessage({id, defaultMessage}).toUpperCase()} + + + - + {action && this.renderSectionAction(styles, action, anchor, id)} + ); }; diff --git a/app/components/sidebars/main/main_sidebar.ios.js b/app/components/sidebars/main/main_sidebar.ios.js index 21bc1c02b..c995b755c 100644 --- a/app/components/sidebars/main/main_sidebar.ios.js +++ b/app/components/sidebars/main/main_sidebar.ios.js @@ -6,10 +6,9 @@ import {Dimensions, Keyboard} from 'react-native'; import {intlShape} from 'react-intl'; import AsyncStorage from '@react-native-community/async-storage'; +import DrawerLayout, {DRAWER_INITIAL_OFFSET, TABLET_WIDTH} from '@components/sidebars/drawer_layout/index.tsx'; +import {DeviceTypes, NavigationTypes} from '@constants'; import EventEmitter from '@mm-redux/utils/event_emitter'; - -import DrawerLayout, {DRAWER_INITIAL_OFFSET, TABLET_WIDTH} from 'app/components/sidebars/drawer_layout'; -import {DeviceTypes, NavigationTypes} from 'app/constants'; import mattermostManaged from 'app/mattermost_managed'; import MainSidebarBase from './main_sidebar_base'; @@ -125,7 +124,7 @@ export default class MainSidebarIOS extends MainSidebarBase { return ( ); } -} \ No newline at end of file +} diff --git a/app/components/sidebars/main/main_sidebar.test.js b/app/components/sidebars/main/main_sidebar.test.js index d8f892008..f0c3b94ee 100644 --- a/app/components/sidebars/main/main_sidebar.test.js +++ b/app/components/sidebars/main/main_sidebar.test.js @@ -4,10 +4,9 @@ import React from 'react'; import {shallow} from 'enzyme'; +import {DeviceTypes} from '@constants'; import Preferences from '@mm-redux/constants/preferences'; -import {DeviceTypes} from 'app/constants'; - import MainSidebar from './main_sidebar.ios'; jest.mock('react-intl'); @@ -31,27 +30,27 @@ describe('MainSidebar', () => { theme: Preferences.THEMES.default, }; - test('should match, full snapshot', () => { - const wrapper = shallow( - , + const loadShallow = (props) => { + return shallow( + , ); + }; + + test('should match, full snapshot', () => { + const wrapper = loadShallow(); expect(wrapper.getElement()).toMatchSnapshot(); }); test('should not set the permanentSidebar state if not Tablet', () => { - const wrapper = shallow( - , - ); + const wrapper = loadShallow(); wrapper.instance().handlePermanentSidebar(); expect(wrapper.state('permanentSidebar')).toBeUndefined(); }); test('should set the permanentSidebar state if Tablet', async () => { - const wrapper = shallow( - , - ); + const wrapper = loadShallow(); DeviceTypes.IS_TABLET = true; @@ -71,9 +70,7 @@ describe('MainSidebar', () => { theme, }; - const wrapper = shallow( - , - ); + const wrapper = loadShallow(props); const instance = wrapper.instance(); instance.render = jest.fn(); @@ -82,13 +79,4 @@ describe('MainSidebar', () => { wrapper.setProps({theme: newTheme}); expect(instance.render).toHaveBeenCalledTimes(1); }); - - test('should render main sidebar below PostList for iOS', () => { - const wrapper = shallow( - , - ); - const drawer = wrapper.dive().childAt(1); - const drawerStyle = drawer.props().style.reduce((acc, obj) => ({...acc, ...obj})); - expect(drawerStyle).toHaveProperty('zIndex', 0); - }); }); diff --git a/app/components/sidebars/main/main_sidebar_base.js b/app/components/sidebars/main/main_sidebar_base.js index dbc04078b..e2aeeb6c9 100644 --- a/app/components/sidebars/main/main_sidebar_base.js +++ b/app/components/sidebars/main/main_sidebar_base.js @@ -10,20 +10,18 @@ import { View, } from 'react-native'; +import SafeAreaView from '@components/safe_area_view'; +import {NavigationTypes, WebsocketEvents} from '@constants'; import {General} from '@mm-redux/constants'; import EventEmitter from '@mm-redux/utils/event_emitter'; - -import SafeAreaView from 'app/components/safe_area_view'; -import {NavigationTypes, WebsocketEvents} from 'app/constants'; -import tracker from 'app/utils/time_tracker'; -import {t} from 'app/utils/i18n'; +import {t} from '@utils/i18n'; +import tracker from '@utils/time_tracker'; +import telemetry from '@telemetry/'; import ChannelsList from './channels_list'; import DrawerSwiper from './drawer_swiper'; import TeamsList from './teams_list'; -import telemetry from 'app/telemetry'; - export default class MainSidebarBase extends Component { static propTypes = { actions: PropTypes.shape({ @@ -246,6 +244,8 @@ export default class MainSidebarBase extends Component { return ( + - + ); } } diff --git a/app/components/sidebars/main/teams_list/teams_list_item/index.js b/app/components/sidebars/main/teams_list/teams_list_item/index.js index 1dd38e98c..b0d1e178b 100644 --- a/app/components/sidebars/main/teams_list/teams_list_item/index.js +++ b/app/components/sidebars/main/teams_list/teams_list_item/index.js @@ -6,8 +6,6 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeamId, getTeam, makeGetBadgeCountForTeamId} from '@mm-redux/selectors/entities/teams'; -import {isLandscape} from 'app/selectors/device'; - import TeamsListItem from './teams_list_item.js'; function makeMapStateToProps() { @@ -22,7 +20,6 @@ function makeMapStateToProps() { mentionCount: getMentionCount(state, ownProps.teamId), name: team.name, theme: getTheme(state), - isLandscape: isLandscape(state), }; }; } diff --git a/app/components/sidebars/main/teams_list/teams_list_item/teams_list_item.js b/app/components/sidebars/main/teams_list/teams_list_item/teams_list_item.js index b43bd99db..b1856b7a9 100644 --- a/app/components/sidebars/main/teams_list/teams_list_item/teams_list_item.js +++ b/app/components/sidebars/main/teams_list/teams_list_item/teams_list_item.js @@ -12,7 +12,6 @@ import { import Badge from '@components/badge'; import CompassIcon from '@components/compass_icon'; import TeamIcon from '@components/team_icon'; -import {paddingLeft as padding} from '@components/safe_area_view/iphone_x_spacing'; import {preventDoubleTap} from '@utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; @@ -26,7 +25,6 @@ export default class TeamsListItem extends React.PureComponent { selectTeam: PropTypes.func.isRequired, teamId: PropTypes.string.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; selectTeam = preventDoubleTap(() => { @@ -42,7 +40,6 @@ export default class TeamsListItem extends React.PureComponent { name, teamId, theme, - isLandscape, } = this.props; const styles = getStyleSheet(theme); @@ -79,7 +76,7 @@ export default class TeamsListItem extends React.PureComponent { underlayColor={changeOpacity(theme.sidebarTextHoverBg, 0.5)} onPress={this.selectTeam} > - + { + goToSaved = preventDoubleTap(() => { const {intl} = this.providerRef.getChildContext(); - this.goToFlaggedScreen(intl); + this.goToSavedPostsScreen(intl); }); goToMentions = preventDoubleTap(() => { diff --git a/app/components/sidebars/settings/settings_sidebar.ios.js b/app/components/sidebars/settings/settings_sidebar.ios.js index 834ef132e..3571e1674 100644 --- a/app/components/sidebars/settings/settings_sidebar.ios.js +++ b/app/components/sidebars/settings/settings_sidebar.ios.js @@ -7,11 +7,11 @@ import {Dimensions, Keyboard, View} from 'react-native'; import EventEmitter from '@mm-redux/utils/event_emitter'; -import SafeAreaView from 'app/components/safe_area_view'; -import DrawerLayout, {DRAWER_INITIAL_OFFSET, TABLET_WIDTH} from 'app/components/sidebars/drawer_layout'; -import {DeviceTypes, NavigationTypes} from 'app/constants'; -import {preventDoubleTap} from 'app/utils/tap'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import SafeAreaView from '@components/safe_area_view'; +import DrawerLayout, {DRAWER_INITIAL_OFFSET, TABLET_WIDTH} from '@components/sidebars/drawer_layout/index.tsx'; +import {DeviceTypes, NavigationTypes} from '@constants'; +import {preventDoubleTap} from '@utils/tap'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import SettingsSidebarBase from './settings_sidebar_base'; @@ -23,6 +23,8 @@ export default class SettingsDrawer extends SettingsSidebarBase { constructor(props) { super(props); + this.drawerRef = React.createRef(); + this.state = { deviceWidth: Dimensions.get('window').width, openDrawerOffset: DRAWER_INITIAL_OFFSET, @@ -42,26 +44,22 @@ export default class SettingsDrawer extends SettingsSidebarBase { Dimensions.removeEventListener('change', this.handleDimensions); } - setDrawerRef = (ref) => { - this.drawerRef = ref; - } - confirmReset = (status) => { const {intl} = this.context; this.confirmResetBase(status, intl); }; closeSettingsSidebar = () => { - if (this.drawerRef && this.drawerOpened) { - this.drawerRef.closeDrawer(); + if (this.drawerRef.current && this.drawerOpened) { + this.drawerRef.current.closeDrawer(); } }; open = () => { EventEmitter.emit(NavigationTypes.BLUR_POST_DRAFT); - if (this.drawerRef && !this.drawerOpened) { - this.drawerRef.openDrawer(); + if (this.drawerRef.current && !this.drawerOpened) { + this.drawerRef.current.openDrawer(); } }; @@ -93,9 +91,9 @@ export default class SettingsDrawer extends SettingsSidebarBase { this.goToEditProfileScreen(intl); }); - goToFlagged = preventDoubleTap(() => { + goToSaved = preventDoubleTap(() => { const {intl} = this.context; - this.goToFlaggedScreen(intl); + this.goToSavedPostsScreen(intl); }); goToMentions = preventDoubleTap(() => { @@ -120,6 +118,8 @@ export default class SettingsDrawer extends SettingsSidebarBase { return ( } @@ -138,12 +138,12 @@ export default class SettingsDrawer extends SettingsSidebarBase { return ( {children} diff --git a/app/components/sidebars/settings/settings_sidebar_base.js b/app/components/sidebars/settings/settings_sidebar_base.js index 1ba2d73b9..8e1de4ce5 100644 --- a/app/components/sidebars/settings/settings_sidebar_base.js +++ b/app/components/sidebars/settings/settings_sidebar_base.js @@ -92,9 +92,9 @@ export default class SettingsSidebarBase extends PureComponent { ); }; - goToFlaggedScreen = (intl) => { + goToSavedPostsScreen = (intl) => { this.openModal( - 'FlaggedPosts', + 'SavedPosts', intl.formatMessage({id: 'search_header.title3', defaultMessage: 'Saved Messages'}), ); }; @@ -228,7 +228,7 @@ export default class SettingsSidebarBase extends PureComponent { defaultMessage='Saved Messages' i18nId='search_header.title3' iconName='bookmark-outline' - onPress={this.goToFlagged} + onPress={this.goToSaved} separator={false} theme={theme} /> diff --git a/app/components/slide_up_panel/slide_up_panel.js b/app/components/slide_up_panel/slide_up_panel.js index 1d52198f0..da935dbd2 100644 --- a/app/components/slide_up_panel/slide_up_panel.js +++ b/app/components/slide_up_panel/slide_up_panel.js @@ -236,6 +236,7 @@ export default class SlideUpPanel extends PureComponent { const styles = getStyleSheet(theme); const translateStyle = { + alignItems: 'center', transform: [{translateY: this.translateY}], }; const backdropStyle = { @@ -289,32 +290,34 @@ export default class SlideUpPanel extends PureComponent { {headerComponent} - - - - + + + - {children} - - - - + + {children} + + + + + @@ -331,6 +334,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { flex: 1, backgroundColor: theme.centerChannelBg, }, + wrapper: { + flex: 1, + maxWidth: 450, + width: '100%', + }, border: { ...Platform.select({ android: { diff --git a/app/components/widgets/settings/__snapshots__/radio_setting.test.js.snap b/app/components/widgets/settings/__snapshots__/radio_setting.test.js.snap index ca44b6575..40556fe61 100644 --- a/app/components/widgets/settings/__snapshots__/radio_setting.test.js.snap +++ b/app/components/widgets/settings/__snapshots__/radio_setting.test.js.snap @@ -35,16 +35,13 @@ exports[`components/widgets/settings/RadioSetting should match snapshot when err - + { @@ -53,7 +47,6 @@ export default class BoolSetting extends PureComponent { errorText, optional, theme, - isLandscape, } = this.props; const style = getStyleSheet(theme); @@ -104,27 +97,27 @@ export default class BoolSetting extends PureComponent { } return ( - - + <> + {labelContent} - + {placeholder} - + {helpTextContent} {errorTextContent} - + ); } } diff --git a/app/components/widgets/settings/bool_setting.test.js b/app/components/widgets/settings/bool_setting.test.js index 54827d1df..996c97b73 100644 --- a/app/components/widgets/settings/bool_setting.test.js +++ b/app/components/widgets/settings/bool_setting.test.js @@ -20,7 +20,6 @@ describe('components/widgets/settings/TextSetting', () => { optional={false} theme={theme} onChange={onChange} - isLandscape={false} />, ); diff --git a/app/components/widgets/settings/radio_setting.js b/app/components/widgets/settings/radio_setting.js index f08506a7d..0a04d5d29 100644 --- a/app/components/widgets/settings/radio_setting.js +++ b/app/components/widgets/settings/radio_setting.js @@ -6,7 +6,6 @@ import PropTypes from 'prop-types'; import {Text, TouchableOpacity, View} from 'react-native'; import CompassIcon from '@components/compass_icon'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme'; export default class RadioSetting extends PureComponent { @@ -17,15 +16,10 @@ export default class RadioSetting extends PureComponent { default: PropTypes.string, onChange: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, helpText: PropTypes.node, errorText: PropTypes.node, }; - static defaultProps = { - isLandscape: false, - }; - constructor(props) { super(props); @@ -66,7 +60,6 @@ export default class RadioSetting extends PureComponent { label, helpText, errorText, - isLandscape, } = this.props; const style = getStyleSheet(theme); @@ -90,7 +83,7 @@ export default class RadioSetting extends PureComponent { let additionalTextContent; if (errorText || helpText) { additionalTextContent = ( - + {helpTextContent} {errorTextContent} @@ -104,7 +97,7 @@ export default class RadioSetting extends PureComponent { onPress={() => this.handleChange(value)} key={value} > - + {text} @@ -121,7 +114,7 @@ export default class RadioSetting extends PureComponent { {' *'} - + {options} {additionalTextContent} diff --git a/app/components/widgets/settings/text_setting.js b/app/components/widgets/settings/text_setting.js index 1775e4ede..d1f1f7b47 100644 --- a/app/components/widgets/settings/text_setting.js +++ b/app/components/widgets/settings/text_setting.js @@ -10,13 +10,12 @@ import { Platform, } from 'react-native'; -import FormattedText from 'app/components/formatted_text'; +import FormattedText from '@components/formatted_text'; import { changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; +} from '@utils/theme'; export default class TextSetting extends PureComponent { static propTypes = { @@ -39,7 +38,6 @@ export default class TextSetting extends PureComponent { onChange: PropTypes.func.isRequired, value: PropTypes.string.isRequired, multiline: PropTypes.bool, - isLandscape: PropTypes.bool.isRequired, keyboardType: PropTypes.oneOf([ 'default', 'number-pad', @@ -57,7 +55,6 @@ export default class TextSetting extends PureComponent { disabled: false, multiline: false, keyboardType: 'default', - isLandscape: false, secureTextEntry: false, }; @@ -78,7 +75,6 @@ export default class TextSetting extends PureComponent { errorText, value, multiline, - isLandscape, secureTextEntry, } = this.props; const style = getStyleSheet(theme); @@ -151,12 +147,12 @@ export default class TextSetting extends PureComponent { return ( - + {labelContent} {asterisk} {optionalContent} - + - + {disabledTextContent} {helpTextContent} {errorTextContent} diff --git a/app/constants/device.js b/app/constants/device.js index 757304f71..c73e32cfc 100644 --- a/app/constants/device.js +++ b/app/constants/device.js @@ -1,12 +1,11 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import {Platform} from 'react-native'; import DeviceInfo from 'react-native-device-info'; import RNFetchBlobFS from 'rn-fetch-blob/fs'; import keyMirror from '@mm-redux/utils/key_mirror'; -const DeviceModel = DeviceInfo.getModel(); - const deviceTypes = keyMirror({ CONNECTION_CHANGED: null, DEVICE_DIMENSIONS_CHANGED: null, @@ -19,7 +18,7 @@ export default { ...deviceTypes, DOCUMENTS_PATH: `${RNFetchBlobFS.dirs.CacheDir}/Documents`, IMAGES_PATH: `${RNFetchBlobFS.dirs.CacheDir}/Images`, - IS_IPHONE_WITH_INSETS: DeviceModel.includes('iPhone X') || DeviceModel.includes('iPhone 11'), + IS_IPHONE_WITH_INSETS: Platform.OS === 'ios' && DeviceInfo.hasNotch(), IS_TABLET: DeviceInfo.isTablet(), VIDEOS_PATH: `${RNFetchBlobFS.dirs.CacheDir}/Videos`, PERMANENT_SIDEBAR_SETTINGS: '@PERMANENT_SIDEBAR_SETTINGS', diff --git a/app/constants/view.js b/app/constants/view.js index 07970082f..923021b4d 100644 --- a/app/constants/view.js +++ b/app/constants/view.js @@ -105,6 +105,7 @@ const ViewTypes = keyMirror({ LANDSCAPE: null, INDICATOR_BAR_VISIBLE: null, + CHANNEL_NAV_BAR_CHANGED: null, }); const RequiredServer = { @@ -136,4 +137,5 @@ export default { NotificationLevels, SidebarSectionTypes, IOS_HORIZONTAL_LANDSCAPE: 44, + INDICATOR_BAR_HEIGHT, }; diff --git a/app/screens/about/about.js b/app/screens/about/about.js index c2fa6879a..3c43a77dc 100644 --- a/app/screens/about/about.js +++ b/app/screens/about/about.js @@ -11,11 +11,11 @@ import { View, } from 'react-native'; import DeviceInfo from 'react-native-device-info'; +import {SafeAreaView} from 'react-native-safe-area-context'; import Config from '@assets/config'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import StatusBar from '@components/status_bar'; import AboutLinks from '@constants/about_links'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; @@ -27,7 +27,6 @@ export default class About extends PureComponent { config: PropTypes.object.isRequired, license: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; handleAboutTeam = () => { @@ -55,7 +54,7 @@ export default class About extends PureComponent { } render() { - const {theme, config, license, isLandscape} = this.props; + const {theme, config, license} = this.props; const style = getStyleSheet(theme); let title = ( @@ -210,10 +209,13 @@ export default class About extends PureComponent { } return ( - + @@ -335,14 +337,14 @@ export default class About extends PureComponent { - + ); } } const getStyleSheet = makeStyleSheetFromTheme((theme) => { return { - wrapper: { + container: { flex: 1, }, scrollView: { diff --git a/app/screens/about/index.js b/app/screens/about/index.js index 11e40ac97..3987e7877 100644 --- a/app/screens/about/index.js +++ b/app/screens/about/index.js @@ -5,7 +5,6 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getConfig, getLicense} from '@mm-redux/selectors/entities/general'; -import {isLandscape} from 'app/selectors/device'; import About from './about'; @@ -17,7 +16,6 @@ function mapStateToProps(state) { config, license, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/add_reaction/index.js b/app/screens/add_reaction/index.js index 1da5bd71e..7d05445d3 100644 --- a/app/screens/add_reaction/index.js +++ b/app/screens/add_reaction/index.js @@ -1,11 +1,12 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; +import React, {useEffect} from 'react'; import PropTypes from 'prop-types'; import { Keyboard, StyleSheet, + useWindowDimensions, View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; @@ -14,64 +15,72 @@ import EmojiPicker from 'app/components/emoji_picker'; import {emptyFunction} from 'app/utils/general'; import {dismissModal, setButtons} from 'app/actions/navigation'; -export default class AddReaction extends PureComponent { - static propTypes = { - componentId: PropTypes.string, - closeButton: PropTypes.object, - onEmojiPress: PropTypes.func, - }; - - static defaultProps = { - onEmojiPress: emptyFunction, - }; - - leftButton = { - id: 'close-add-reaction', - testID: 'close.add_reaction.button', - }; - - constructor(props) { - super(props); - - setButtons(props.componentId, { - leftButtons: [{...this.leftButton, icon: props.closeButton}], - }); - } - - componentDidMount() { - this.navigationEventListener = Navigation.events().bindComponent(this); - } - - navigationButtonPressed({buttonId}) { - if (buttonId === 'close-add-reaction') { - this.close(); - } - } - - close = () => { - Keyboard.dismiss(); - dismissModal(); - }; - - handleEmojiPress = (emoji) => { - this.props.onEmojiPress(emoji); - this.close(); - } - - render() { - return ( - - - - ); - } -} +const leftButton = { + id: 'close-add-reaction', + testID: 'close.add_reaction.button', +}; const styles = StyleSheet.create({ container: { flex: 1, }, }); + +const AddReaction = (props) => { + const {width} = useWindowDimensions(); + + const close = () => { + Keyboard.dismiss(); + dismissModal(); + }; + + const handleEmojiPress = (emoji) => { + props.onEmojiPress(emoji); + close(); + }; + + useEffect(() => { + setButtons(props.componentId, { + leftButtons: [{...leftButton, icon: props.closeButton}], + }); + + const listener = { + navigationButtonPressed: ({buttonId}) => { + if (buttonId === 'close-add-reaction') { + close(); + } + }, + }; + + const unsubscribe = Navigation.events().registerComponentListener(listener, props.componentId); + + return () => { + // Make sure to unregister the listener during cleanup + unsubscribe.remove(); + }; + }, []); + + return ( + + + + ); +}; + +AddReaction.propTypes = { + componentId: PropTypes.string, + closeButton: PropTypes.object, + onEmojiPress: PropTypes.func, +}; + +AddReaction.defaultProps = { + onEmojiPress: emptyFunction, +}; + +export default AddReaction; diff --git a/app/screens/channel/channel.android.js b/app/screens/channel/channel.android.js index a6e86243c..3ad15c658 100644 --- a/app/screens/channel/channel.android.js +++ b/app/screens/channel/channel.android.js @@ -6,6 +6,7 @@ import {StyleSheet, View, BackHandler, ToastAndroid} from 'react-native'; import {openMainSideMenu, openSettingsSideMenu} from '@actions/navigation'; import LocalConfig from '@assets/config'; +import AnnouncementBanner from 'app/components/announcement_banner'; import KeyboardLayout from '@components/layout/keyboard_layout'; import InteractiveDialogController from '@components/interactive_dialog_controller'; import NetworkIndicator from '@components/network_indicator'; @@ -90,6 +91,7 @@ export default class ChannelAndroid extends ChannelBase { /> {component} + {LocalConfig.EnableMobileClientUpgrade && } ); diff --git a/app/screens/channel/channel.ios.js b/app/screens/channel/channel.ios.js index 3e9a3a15f..688a7e85f 100644 --- a/app/screens/channel/channel.ios.js +++ b/app/screens/channel/channel.ios.js @@ -3,13 +3,14 @@ import React from 'react'; import {View} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import LocalConfig from '@assets/config'; +import AnnouncementBanner from 'app/components/announcement_banner'; import Autocomplete, {AUTOCOMPLETE_MAX_HEIGHT} from '@components/autocomplete'; import InteractiveDialogController from '@components/interactive_dialog_controller'; import NetworkIndicator from '@components/network_indicator'; import PostDraft from '@components/post_draft'; -import SafeAreaView from '@components/safe_area_view'; import MainSidebar from '@components/sidebars/main'; import SettingsSidebar from '@components/sidebars/settings'; import StatusBar from '@components/status_bar'; @@ -70,18 +71,33 @@ export default class ChannelIOS extends ChannelBase { } const style = getStyle(theme); + const indicators = ( + <> + + + + ); + const header = ( + <> + + + ); const drawerContent = ( <> - - - - + + {header} + {component} + {indicators} {renderDraftArea && ({ flex: 1, backgroundColor: theme.centerChannelBg, }, + flex: { + flex: 1, + }, })); \ No newline at end of file diff --git a/app/screens/channel/channel_nav_bar/__snapshots__/channel_nav_bar.test.js.snap b/app/screens/channel/channel_nav_bar/__snapshots__/channel_nav_bar.test.js.snap index 75d520ff2..8bed6cc5c 100644 --- a/app/screens/channel/channel_nav_bar/__snapshots__/channel_nav_bar.test.js.snap +++ b/app/screens/channel/channel_nav_bar/__snapshots__/channel_nav_bar.test.js.snap @@ -1,64 +1,73 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ChannelNavBar should match, full snapshot 1`] = ` - - - - - - + > + + + + + `; diff --git a/app/screens/channel/channel_nav_bar/channel_nav_bar.js b/app/screens/channel/channel_nav_bar/channel_nav_bar.js index 200a25d05..037a0574c 100644 --- a/app/screens/channel/channel_nav_bar/channel_nav_bar.js +++ b/app/screens/channel/channel_nav_bar/channel_nav_bar.js @@ -1,134 +1,31 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; +import React, {useEffect, useState} from 'react'; import PropTypes from 'prop-types'; import {Dimensions, Platform, View} from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; +import {DeviceTypes, ViewTypes} from '@constants'; import EventEmitter from '@mm-redux/utils/event_emitter'; - -import {DeviceTypes, ViewTypes} from 'app/constants'; +import {makeStyleSheetFromTheme} from '@utils/theme'; import mattermostManaged from 'app/mattermost_managed'; -import {makeStyleSheetFromTheme} from 'app/utils/theme'; import MainSidebarDrawerButton from './main_sidebar_drawer_button'; import ChannelSearchButton from './channel_search_button'; import ChannelTitle from './channel_title'; import SettingsSidebarDrawerButton from './settings_sidebar_drawer_button'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; const { ANDROID_TOP_LANDSCAPE, ANDROID_TOP_PORTRAIT, + CHANNEL_NAV_BAR_CHANGED, IOS_TOP_LANDSCAPE, IOS_TOP_PORTRAIT, STATUS_BAR_HEIGHT, } = ViewTypes; -export default class ChannelNavBar extends PureComponent { - static propTypes = { - isLandscape: PropTypes.bool.isRequired, - openMainSidebar: PropTypes.func.isRequired, - openSettingsSidebar: PropTypes.func.isRequired, - onPress: PropTypes.func.isRequired, - theme: PropTypes.object.isRequired, - }; - - state = { - isSplitView: false, - }; - - componentDidMount() { - this.mounted = true; - this.handleDimensions(); - this.handlePermanentSidebar(); - Dimensions.addEventListener('change', this.handleDimensions); - EventEmitter.on(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, this.handlePermanentSidebar); - } - - componentWillUnmount() { - this.mounted = false; - Dimensions.removeEventListener('change', this.handleDimensions); - EventEmitter.off(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, this.handlePermanentSidebar); - } - - handleDimensions = () => { - if (DeviceTypes.IS_TABLET && this.mounted) { - mattermostManaged.isRunningInSplitView().then((result) => { - const isSplitView = Boolean(result.isSplitView); - this.setState({isSplitView}); - }); - } - }; - - handlePermanentSidebar = async () => { - if (DeviceTypes.IS_TABLET && this.mounted) { - try { - const enabled = await AsyncStorage.getItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS); - this.setState({permanentSidebar: enabled === 'true'}); - } catch { - // do nothing - } - } - }; - - drawerButtonVisible = () => { - if (Platform.OS === 'android') { - return true; - } - - return (!DeviceTypes.IS_TABLET || this.state.isSplitView || !this.state.permanentSidebar); - }; - - render() { - const {isLandscape, onPress, theme} = this.props; - const {openMainSidebar, openSettingsSidebar} = this.props; - const style = getStyleFromTheme(theme); - - let height; - let canHaveSubtitle = true; - switch (Platform.OS) { - case 'android': - height = ANDROID_TOP_PORTRAIT; - if (DeviceTypes.IS_TABLET) { - height = ANDROID_TOP_LANDSCAPE; - } - break; - case 'ios': - height = IOS_TOP_PORTRAIT - STATUS_BAR_HEIGHT; - if (DeviceTypes.IS_TABLET && isLandscape) { - height -= 1; - } else if (isLandscape) { - height = IOS_TOP_LANDSCAPE; - canHaveSubtitle = false; - } - - if (DeviceTypes.IS_IPHONE_WITH_INSETS && isLandscape) { - canHaveSubtitle = false; - } - break; - } - - return ( - - - - - - - ); - } -} - const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { header: { @@ -147,3 +44,115 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, }; }); + +const ChannelNavBar = (props) => { + const {isLandscape, onPress, openMainSidebar, openSettingsSidebar, theme} = props; + const insets = useSafeAreaInsets(); + const style = getStyleFromTheme(theme); + const [splitView, setSplitView] = useState(false); + const [permanentSidebar, setPermanentSidebar] = useState(false); + let height = 0; + let canHaveSubtitle = true; + + const drawerButtonVisible = () => { + if (Platform.OS === 'android') { + return true; + } + + return (!DeviceTypes.IS_TABLET || splitView || !permanentSidebar); + }; + + const handleDimensions = () => { + if (DeviceTypes.IS_TABLET) { + mattermostManaged.isRunningInSplitView().then((result) => { + const isSplitView = Boolean(result.isSplitView); + setSplitView(isSplitView); + }); + } + }; + + const handlePermanentSidebar = async () => { + if (DeviceTypes.IS_TABLET) { + try { + const enabled = await AsyncStorage.getItem(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS); + setPermanentSidebar(enabled === 'true'); + } catch { + // do nothing + } + } + }; + + const onLayout = ({nativeEvent}) => { + const {height: layouHeight} = nativeEvent.layout; + if (height !== layouHeight && Platform.OS === 'ios') { + height = layouHeight; + EventEmitter.emit(CHANNEL_NAV_BAR_CHANGED, layouHeight); + } else { + EventEmitter.emit(CHANNEL_NAV_BAR_CHANGED, layouHeight); + } + }; + + useEffect(() => { + handleDimensions(); + handlePermanentSidebar(); + Dimensions.addEventListener('change', handleDimensions); + EventEmitter.on(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, handlePermanentSidebar); + + return () => { + Dimensions.removeEventListener('change', handleDimensions); + EventEmitter.off(DeviceTypes.PERMANENT_SIDEBAR_SETTINGS, handlePermanentSidebar); + }; + }, []); + + switch (Platform.OS) { + case 'android': + height = ANDROID_TOP_PORTRAIT; + if (DeviceTypes.IS_TABLET) { + height = ANDROID_TOP_LANDSCAPE; + } + break; + case 'ios': + height = IOS_TOP_PORTRAIT - STATUS_BAR_HEIGHT; + if (DeviceTypes.IS_TABLET && isLandscape) { + height -= 1; + } else if (isLandscape) { + height = IOS_TOP_LANDSCAPE; + canHaveSubtitle = false; + } + + if (DeviceTypes.IS_IPHONE_WITH_INSETS && isLandscape) { + canHaveSubtitle = false; + } + break; + } + + return ( + + + + + + + ); +}; + +ChannelNavBar.propTypes = { + isLandscape: PropTypes.bool.isRequired, + openMainSidebar: PropTypes.func.isRequired, + openSettingsSidebar: PropTypes.func.isRequired, + onPress: PropTypes.func.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default ChannelNavBar; \ No newline at end of file diff --git a/app/screens/channel/channel_nav_bar/channel_nav_bar.test.js b/app/screens/channel/channel_nav_bar/channel_nav_bar.test.js index 6b9cd4038..a8fa59e64 100644 --- a/app/screens/channel/channel_nav_bar/channel_nav_bar.test.js +++ b/app/screens/channel/channel_nav_bar/channel_nav_bar.test.js @@ -2,15 +2,26 @@ // See LICENSE.txt for license information. import React from 'react'; -import {Platform} from 'react-native'; import {shallow} from 'enzyme'; import Preferences from '@mm-redux/constants/preferences'; -import {DeviceTypes} from '@constants'; - import ChannelNavBar from './channel_nav_bar'; +import {SafeAreaProvider} from 'react-native-safe-area-context'; +export function testSafeAreaProvider(children) { + return ( + + {children} + + ); +} + jest.mock('react-intl'); jest.mock('app/mattermost_managed', () => ({ isRunningInSplitView: jest.fn().mockResolvedValue(false), @@ -26,102 +37,10 @@ describe('ChannelNavBar', () => { }; test('should match, full snapshot', () => { - const wrapper = shallow( + const wrapper = shallow(testSafeAreaProvider( , - ); + )); expect(wrapper.getElement()).toMatchSnapshot(); }); - - test('should not set the permanentSidebar state if not Tablet', async () => { - const wrapper = shallow( - , - ); - - await wrapper.instance().handlePermanentSidebar(); - expect(wrapper.state('permanentSidebar')).toBeUndefined(); - }); - - test('should set the permanentSidebar state if Tablet', async () => { - const wrapper = shallow( - , - ); - - DeviceTypes.IS_TABLET = true; - - await wrapper.instance().handlePermanentSidebar(); - expect(wrapper.state('permanentSidebar')).toBeDefined(); - }); - - test('drawerButtonVisible appears for android tablets', async () => { - const wrapper = shallow( - , - ); - - DeviceTypes.IS_TABLET = true; - Platform.OS = 'android'; - - expect(wrapper.instance().drawerButtonVisible()).toBe(true); - }); - - test('drawerButtonVisible appears for android phones', async () => { - const wrapper = shallow( - , - ); - - DeviceTypes.IS_TABLET = false; - Platform.OS = 'android'; - - expect(wrapper.instance().drawerButtonVisible()).toBe(true); - }); - - test('drawerButtonVisible appears for iOS phones', async () => { - const wrapper = shallow( - , - ); - - DeviceTypes.IS_TABLET = false; - Platform.OS = 'ios'; - - expect(wrapper.instance().drawerButtonVisible()).toBe(true); - }); - - test('drawerButtonVisible appears for iOS tablets with PermanentSidebar at default false, and not in splitview', async () => { - const wrapper = shallow( - , - ); - - wrapper.setState({permanentSidebar: false, isSplitView: false}); - - DeviceTypes.IS_TABLET = true; - Platform.OS = 'ios'; - - expect(wrapper.instance().drawerButtonVisible()).toBe(true); - }); - - test('drawerButtonVisible does not appear for iOS tablets with permanentSidebar enabled', async () => { - const wrapper = shallow( - , - ); - - wrapper.setState({permanentSidebar: true}); - - DeviceTypes.IS_TABLET = true; - Platform.OS = 'ios'; - - expect(wrapper.instance().drawerButtonVisible()).toBe(false); - }); - - test('drawerButtonVisible appears for iOS tablets with splitview enabled', async () => { - const wrapper = shallow( - , - ); - - wrapper.setState({isSplitView: true}); - - DeviceTypes.IS_TABLET = true; - Platform.OS = 'ios'; - - expect(wrapper.instance().drawerButtonVisible()).toBe(true); - }); }); diff --git a/app/screens/channel/channel_post_list/__snapshots__/channel_post_list.test.js.snap b/app/screens/channel/channel_post_list/__snapshots__/channel_post_list.test.js.snap index db33616c3..db735be80 100644 --- a/app/screens/channel/channel_post_list/__snapshots__/channel_post_list.test.js.snap +++ b/app/screens/channel/channel_post_list/__snapshots__/channel_post_list.test.js.snap @@ -36,7 +36,6 @@ exports[`ChannelPostList should match snapshot 1`] = ` scrollViewNativeID="channel-id" showMoreMessagesButton={true} /> - `; diff --git a/app/screens/channel/channel_post_list/channel_post_list.js b/app/screens/channel/channel_post_list/channel_post_list.js index 458d0a7cd..9c6c0abb8 100644 --- a/app/screens/channel/channel_post_list/channel_post_list.js +++ b/app/screens/channel/channel_post_list/channel_post_list.js @@ -10,18 +10,15 @@ import { Animated, } from 'react-native'; -import {getLastPostIndex} from '@mm-redux/utils/post_list'; -import EventEmitter from '@mm-redux/utils/event_emitter'; - -import AnnouncementBanner from 'app/components/announcement_banner'; -import PostList from 'app/components/post_list'; -import RetryBarIndicator from 'app/components/retry_bar_indicator'; -import tracker from 'app/utils/time_tracker'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import telemetry from 'app/telemetry'; -import {goToScreen} from 'app/actions/navigation'; - +import {goToScreen} from '@actions/navigation'; +import PostList from '@components/post_list'; +import RetryBarIndicator from '@components/retry_bar_indicator'; import {TYPING_HEIGHT} from '@constants/post_draft'; +import EventEmitter from '@mm-redux/utils/event_emitter'; +import {getLastPostIndex} from '@mm-redux/utils/post_list'; +import tracker from '@utils/time_tracker'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import telemetry from '@telemetry'; let ChannelIntro = null; let LoadMorePosts = null; @@ -221,7 +218,6 @@ export default class ChannelPostList extends PureComponent { {component} - ); diff --git a/app/screens/channel_add_members/channel_add_members.js b/app/screens/channel_add_members/channel_add_members.js index afa1110ba..609d34734 100644 --- a/app/screens/channel_add_members/channel_add_members.js +++ b/app/screens/channel_add_members/channel_add_members.js @@ -4,33 +4,28 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {intlShape} from 'react-intl'; -import { - Alert, - Platform, - View, -} from 'react-native'; +import {Alert, View} from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; +import {popTopScreen, setButtons} from '@actions/navigation'; +import Loading from '@components/loading'; +import CustomList, {FLATLIST, SECTIONLIST} from '@components/custom_list'; +import UserListRow from '@components/custom_list/user_list_row'; +import FormattedText from '@components/formatted_text'; +import KeyboardLayout from '@components/layout/keyboard_layout'; +import SearchBar from '@components/search_bar'; +import StatusBar from '@components/status_bar'; import {debounce} from '@mm-redux/actions/helpers'; import {General} from '@mm-redux/constants'; import {filterProfilesMatchingTerm} from '@mm-redux/utils/user_utils'; - -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; -import Loading from 'app/components/loading'; -import CustomList, {FLATLIST, SECTIONLIST} from 'app/components/custom_list'; -import UserListRow from 'app/components/custom_list/user_list_row'; -import FormattedText from 'app/components/formatted_text'; -import KeyboardLayout from 'app/components/layout/keyboard_layout'; -import SearchBar from 'app/components/search_bar'; -import StatusBar from 'app/components/status_bar'; -import {alertErrorIfInvalidPermissions} from 'app/utils/general'; -import {createProfilesSections, loadingText} from 'app/utils/member_list'; +import {alertErrorIfInvalidPermissions} from '@utils/general'; +import {createProfilesSections, loadingText} from '@utils/member_list'; import { changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; -import {popTopScreen, setButtons} from 'app/actions/navigation'; +} from '@utils/theme'; export default class ChannelAddMembers extends PureComponent { static propTypes = { @@ -47,7 +42,6 @@ export default class ChannelAddMembers extends PureComponent { currentUserId: PropTypes.string.isRequired, profilesNotInChannel: PropTypes.array.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -287,7 +281,7 @@ export default class ChannelAddMembers extends PureComponent { render() { const {formatMessage} = this.context.intl; - const {currentUserId, profilesNotInChannel, theme, isLandscape} = this.props; + const {currentUserId, profilesNotInChannel, theme} = this.props; const { adding, loading, @@ -337,9 +331,12 @@ export default class ChannelAddMembers extends PureComponent { return ( - - - + + + - - + + ); } @@ -387,11 +383,6 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { searchBar: { marginVertical: 5, height: 38, - ...Platform.select({ - ios: { - paddingLeft: 8, - }, - }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/channel_add_members/channel_add_members.test.js b/app/screens/channel_add_members/channel_add_members.test.js index e6e28100f..9133d8ebc 100644 --- a/app/screens/channel_add_members/channel_add_members.test.js +++ b/app/screens/channel_add_members/channel_add_members.test.js @@ -24,7 +24,6 @@ describe('ChannelAddMembers', () => { profilesNotInChannel: [], theme: Preferences.THEMES.default, componentId: 'component-id', - isLandscape: false, }; beforeEach(() => { diff --git a/app/screens/channel_add_members/index.js b/app/screens/channel_add_members/index.js index e8d2d47a3..742026a07 100644 --- a/app/screens/channel_add_members/index.js +++ b/app/screens/channel_add_members/index.js @@ -12,7 +12,6 @@ import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; import {getCurrentUserId, getProfilesNotInCurrentChannel} from '@mm-redux/selectors/entities/users'; import {handleAddChannelMembers} from 'app/actions/views/channel_add_members'; -import {isLandscape} from 'app/selectors/device'; import ChannelAddMembers from './channel_add_members'; function mapStateToProps(state) { @@ -25,7 +24,6 @@ function mapStateToProps(state) { currentUserId: getCurrentUserId(state), profilesNotInChannel: getProfilesNotInCurrentChannel(state), theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/channel_info/__snapshots__/channel_info.test.js.snap b/app/screens/channel_info/__snapshots__/channel_info.test.js.snap index 900561b49..4b5202209 100644 --- a/app/screens/channel_info/__snapshots__/channel_info.test.js.snap +++ b/app/screens/channel_info/__snapshots__/channel_info.test.js.snap @@ -1,7 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`channelInfo should match snapshot 1`] = ` - - + `; exports[`channelInfo should not include NotificationPreference for direct message 1`] = ` @@ -84,12 +83,9 @@ exports[`channel_info_header should match snapshot 1`] = ` @@ -334,7 +326,6 @@ exports[`channel_info_header should match snapshot when DM and hasGuests and is Object { "paddingHorizontal": 15, }, - null, ] } > @@ -395,12 +386,9 @@ exports[`channel_info_header should match snapshot when DM and hasGuests and is @@ -676,7 +657,6 @@ exports[`channel_info_header should match snapshot when DM and hasGuests but its Object { "paddingHorizontal": 15, }, - null, ] } > @@ -737,12 +717,9 @@ exports[`channel_info_header should match snapshot when DM and hasGuests but its @@ -987,7 +960,6 @@ exports[`channel_info_header should match snapshot when GM and hasGuests 1`] = ` Object { "paddingHorizontal": 15, }, - null, ] } > @@ -1048,12 +1020,9 @@ exports[`channel_info_header should match snapshot when GM and hasGuests 1`] = ` @@ -1329,7 +1291,6 @@ exports[`channel_info_header should match snapshot when is group constrained 1`] Object { "paddingHorizontal": 15, }, - null, ] } > @@ -1390,12 +1351,9 @@ exports[`channel_info_header should match snapshot when is group constrained 1`] @@ -1618,7 +1572,6 @@ exports[`channel_info_header should match snapshot when is group constrained 1`] Object { "paddingHorizontal": 15, }, - null, ] } > @@ -1662,7 +1615,6 @@ exports[`channel_info_header should match snapshot when public channel and hasGu Object { "paddingHorizontal": 15, }, - null, ] } > @@ -1723,12 +1675,9 @@ exports[`channel_info_header should match snapshot when public channel and hasGu diff --git a/app/screens/channel_info/__snapshots__/channel_info_row.test.js.snap b/app/screens/channel_info/__snapshots__/channel_info_row.test.js.snap index a2613f1e4..a6eb68cc9 100644 --- a/app/screens/channel_info/__snapshots__/channel_info_row.test.js.snap +++ b/app/screens/channel_info/__snapshots__/channel_info_row.test.js.snap @@ -6,15 +6,12 @@ exports[`ChannelInfoRow should match snapshot 1`] = ` > diff --git a/app/screens/channel_info/add_members/__snapshots__/add_members.test.js.snap b/app/screens/channel_info/add_members/__snapshots__/add_members.test.js.snap index 158f408fb..c45499d5c 100644 --- a/app/screens/channel_info/add_members/__snapshots__/add_members.test.js.snap +++ b/app/screens/channel_info/add_members/__snapshots__/add_members.test.js.snap @@ -37,7 +37,6 @@ exports[`ChannelInfo -> Add Members should match snapshot 1`] = ` action={[Function]} defaultMessage="Add Members" icon="account-plus-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_header.addMembers" diff --git a/app/screens/channel_info/add_members/add_members.test.js b/app/screens/channel_info/add_members/add_members.test.js index fd8ce4ef9..d26d14b2e 100644 --- a/app/screens/channel_info/add_members/add_members.test.js +++ b/app/screens/channel_info/add_members/add_members.test.js @@ -20,7 +20,6 @@ describe('ChannelInfo -> Add Members', () => { const baseProps = { canManageUsers: true, groupConstrained: false, - isLandscape: false, theme: Preferences.THEMES.default, }; diff --git a/app/screens/channel_info/add_members/add_members.tsx b/app/screens/channel_info/add_members/add_members.tsx index 089f802a5..15d153025 100644 --- a/app/screens/channel_info/add_members/add_members.tsx +++ b/app/screens/channel_info/add_members/add_members.tsx @@ -15,7 +15,6 @@ interface AddMembersProps { testID?: string; canManageUsers: boolean; groupConstrained: boolean; - isLandscape: boolean; theme: Theme; } @@ -33,7 +32,7 @@ export default class AddMembers extends PureComponent { }); render() { - const {testID, canManageUsers, groupConstrained, isLandscape, theme} = this.props; + const {canManageUsers, groupConstrained, testID, theme} = this.props; if (canManageUsers && !groupConstrained) { return ( @@ -46,7 +45,6 @@ export default class AddMembers extends PureComponent { icon='account-plus-outline' textId={t('channel_header.addMembers')} theme={theme} - isLandscape={isLandscape} /> ); diff --git a/app/screens/channel_info/archive/__snapshots__/archive.test.js.snap b/app/screens/channel_info/archive/__snapshots__/archive.test.js.snap index 1a661cace..82205648b 100644 --- a/app/screens/channel_info/archive/__snapshots__/archive.test.js.snap +++ b/app/screens/channel_info/archive/__snapshots__/archive.test.js.snap @@ -38,7 +38,6 @@ exports[`ChannelInfo -> Archive should match snapshot for Archive Channel 1`] = defaultMessage="Archive Channel" icon="archive-outline" iconColor="#CA3B27" - isLandscape={false} rightArrow={false} shouldRender={true} textColor="#CA3B27" @@ -114,7 +113,6 @@ exports[`ChannelInfo -> Archive should match snapshot for Unarchive Channel 1`] action={[Function]} defaultMessage="Unarchive Channel" icon="archive-arrow-up-outline" - isLandscape={false} rightArrow={false} shouldRender={true} textId="mobile.routes.channelInfo.unarchive_channel" diff --git a/app/screens/channel_info/archive/archive.test.js b/app/screens/channel_info/archive/archive.test.js index 43fd4b3df..9079bbe1c 100644 --- a/app/screens/channel_info/archive/archive.test.js +++ b/app/screens/channel_info/archive/archive.test.js @@ -26,7 +26,6 @@ describe('ChannelInfo -> Archive', () => { displayName: 'Test Channel', getChannel: jest.fn(), handleSelectChannel: jest.fn(), - isLandscape: false, isPublic: true, unarchiveChannel: jest.fn(), selectPenultimateChannel: jest.fn(), diff --git a/app/screens/channel_info/archive/archive.tsx b/app/screens/channel_info/archive/archive.tsx index 346d2d0ad..b0f0eeb3e 100644 --- a/app/screens/channel_info/archive/archive.tsx +++ b/app/screens/channel_info/archive/archive.tsx @@ -23,7 +23,6 @@ interface ArchiveProps { displayName: string; getChannel: (channelId: string) => Promise; handleSelectChannel: (channelId: string) => Promise; - isLandscape: boolean; isPublic: boolean; unarchiveChannel: (channelId: string) => Promise; selectPenultimateChannel: (channelId: string) => Promise; @@ -130,7 +129,7 @@ export default class Archive extends PureComponent { }); render() { - const {canArchive, canUnarchive, isLandscape, theme} = this.props; + const {canArchive, canUnarchive, theme} = this.props; if (!canArchive && !canUnarchive) { return null; @@ -145,7 +144,6 @@ export default class Archive extends PureComponent { icon='archive-arrow-up-outline' textId={t('mobile.routes.channelInfo.unarchive_channel')} theme={theme} - isLandscape={isLandscape} rightArrow={false} /> ); @@ -159,7 +157,6 @@ export default class Archive extends PureComponent { textId={t('mobile.routes.channelInfo.delete_channel')} textColor='#CA3B27' theme={theme} - isLandscape={isLandscape} rightArrow={false} /> ); diff --git a/app/screens/channel_info/channel_info.js b/app/screens/channel_info/channel_info.js index c9faa4cc2..d47d88ffc 100644 --- a/app/screens/channel_info/channel_info.js +++ b/app/screens/channel_info/channel_info.js @@ -9,6 +9,7 @@ import { View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {dismissModal} from '@actions/navigation'; import StatusBar from '@components/status_bar'; @@ -96,12 +97,11 @@ export default class ChannelInfo extends PureComponent { }; actionsRows = (channelIsArchived) => { - const {currentChannel, currentUserId, isLandscape, isDirectMessage, theme} = this.props; + const {currentChannel, currentUserId, isDirectMessage, theme} = this.props; if (channelIsArchived) { return ( ); @@ -112,14 +112,12 @@ export default class ChannelInfo extends PureComponent { @@ -127,7 +125,6 @@ export default class ChannelInfo extends PureComponent { @@ -135,7 +132,6 @@ export default class ChannelInfo extends PureComponent { <> @@ -144,27 +140,22 @@ export default class ChannelInfo extends PureComponent { @@ -181,16 +172,16 @@ export default class ChannelInfo extends PureComponent { theme, isBot, isTeammateGuest, - isLandscape, } = this.props; const style = getStyleSheet(theme); const channelIsArchived = currentChannel.delete_at !== 0; return ( - 0} isGroupConstrained={currentChannel.group_constrained} - isLandscape={isLandscape} /> } @@ -222,17 +212,15 @@ export default class ChannelInfo extends PureComponent { - + ); } } diff --git a/app/screens/channel_info/channel_info.test.js b/app/screens/channel_info/channel_info.test.js index 64ff9ec36..1be121f75 100644 --- a/app/screens/channel_info/channel_info.test.js +++ b/app/screens/channel_info/channel_info.test.js @@ -49,7 +49,6 @@ describe('channelInfo', () => { isBot: false, isTeammateGuest: false, isDirectMessage: false, - isLandscape: false, actions: { getChannelStats: jest.fn(), getCustomEmojisInText: jest.fn(), diff --git a/app/screens/channel_info/channel_info_header.js b/app/screens/channel_info/channel_info_header.js index e49854009..b6689c8e3 100644 --- a/app/screens/channel_info/channel_info_header.js +++ b/app/screens/channel_info/channel_info_header.js @@ -18,7 +18,6 @@ import ChannelIcon from 'app/components/channel_icon'; import FormattedDate from 'app/components/formatted_date'; import FormattedText from 'app/components/formatted_text'; import Markdown from 'app/components/markdown'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import mattermostManaged from 'app/mattermost_managed'; import BottomSheet from 'app/utils/bottom_sheet'; import {getMarkdownTextStyles, getMarkdownBlockStyles} from 'app/utils/markdown'; @@ -44,7 +43,6 @@ export default class ChannelInfoHeader extends React.PureComponent { hasGuests: PropTypes.bool.isRequired, isGroupConstrained: PropTypes.bool, timeZone: PropTypes.string, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -52,7 +50,7 @@ export default class ChannelInfoHeader extends React.PureComponent { }; renderHasGuestText = (style) => { - const {type, hasGuests, isLandscape, isTeammateGuest} = this.props; + const {type, hasGuests, isTeammateGuest} = this.props; if (!hasGuests) { return null; } @@ -74,7 +72,7 @@ export default class ChannelInfoHeader extends React.PureComponent { defaultMessage = 'This channel has guests'; } return ( - + - + {this.renderHasGuestText(style)} {purpose.length > 0 && - + } {header.length > 0 && - + } {isGroupConstrained && - + } {creator && - + { isTeammateGuest: false, hasGuests: false, isGroupConstrained: false, - isLandscape: false, }; test('should match snapshot', async () => { diff --git a/app/screens/channel_info/channel_info_row.js b/app/screens/channel_info/channel_info_row.js index 3a3d07d05..4bea8ad75 100644 --- a/app/screens/channel_info/channel_info_row.js +++ b/app/screens/channel_info/channel_info_row.js @@ -13,7 +13,6 @@ import { import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; function createTouchableComponent(children, action) { @@ -25,7 +24,7 @@ function createTouchableComponent(children, action) { } function channelInfoRow(props) { - const {testID, action, defaultMessage, detail, icon, iconColor, image, imageTintColor, rightArrow, textColor, textId, togglable, theme, shouldRender, isLandscape} = props; + const {testID, action, defaultMessage, detail, icon, iconColor, image, imageTintColor, rightArrow, textColor, textId, togglable, theme, shouldRender} = props; if (!shouldRender) { return null; @@ -72,7 +71,7 @@ function channelInfoRow(props) { const RowComponent = ( {iconElement} { iconColor: '#ababab', image: 1, imageTintColor: '#ffffff', - isLandscape: false, rightArrow: true, textId: 'text-id', togglable: false, diff --git a/app/screens/channel_info/convert_private/__snapshots__/convert_private.test.js.snap b/app/screens/channel_info/convert_private/__snapshots__/convert_private.test.js.snap index 2bdd94613..4d3de3cb3 100644 --- a/app/screens/channel_info/convert_private/__snapshots__/convert_private.test.js.snap +++ b/app/screens/channel_info/convert_private/__snapshots__/convert_private.test.js.snap @@ -37,7 +37,6 @@ exports[`ChannelInfo -> ConvertPrivate should match snapshot for Convert to Priv action={[Function]} defaultMessage="Convert to Private Channel" icon="lock" - isLandscape={false} rightArrow={false} shouldRender={true} textId="mobile.channel_info.convert" diff --git a/app/screens/channel_info/convert_private/convert_private.test.js b/app/screens/channel_info/convert_private/convert_private.test.js index 7576d5c0c..cf16883a4 100644 --- a/app/screens/channel_info/convert_private/convert_private.test.js +++ b/app/screens/channel_info/convert_private/convert_private.test.js @@ -22,7 +22,6 @@ describe('ChannelInfo -> ConvertPrivate', () => { channelId: '123', convertChannelToPrivate: jest.fn(), displayName: 'Test Channel', - isLandscape: false, theme: Preferences.THEMES.default, }; diff --git a/app/screens/channel_info/convert_private/convert_private.tsx b/app/screens/channel_info/convert_private/convert_private.tsx index 32d0fe1b2..d652f15b0 100644 --- a/app/screens/channel_info/convert_private/convert_private.tsx +++ b/app/screens/channel_info/convert_private/convert_private.tsx @@ -19,7 +19,6 @@ interface ConvertPrivateProps { channelId: string; convertChannelToPrivate: (channelId: string) => Promise; displayName: string; - isLandscape: boolean; theme: Theme; } @@ -80,7 +79,7 @@ export default class ConvertPrivate extends PureComponent { }); render() { - const {testID, canConvert, isLandscape, theme} = this.props; + const {canConvert, testID, theme} = this.props; if (!canConvert) { return null; @@ -94,7 +93,6 @@ export default class ConvertPrivate extends PureComponent { action={this.handleConvertToPrivate} defaultMessage='Convert to Private Channel' icon='lock' - isLandscape={isLandscape} rightArrow={false} theme={theme} textId={t('mobile.channel_info.convert')} diff --git a/app/screens/channel_info/edit_channel/__snapshots__/edit_channel.test.js.snap b/app/screens/channel_info/edit_channel/__snapshots__/edit_channel.test.js.snap index 87473a7c2..8ec42abc2 100644 --- a/app/screens/channel_info/edit_channel/__snapshots__/edit_channel.test.js.snap +++ b/app/screens/channel_info/edit_channel/__snapshots__/edit_channel.test.js.snap @@ -37,7 +37,6 @@ exports[`ChannelInfo -> EditChannel should match snapshot for Edit Channel 1`] = action={[Function]} defaultMessage="Edit Channel" icon="pencil-outline" - isLandscape={false} rightArrow={true} shouldRender={true} testID="test-id" diff --git a/app/screens/channel_info/edit_channel/edit_channel.test.js b/app/screens/channel_info/edit_channel/edit_channel.test.js index f97e48bd2..7f93ee55a 100644 --- a/app/screens/channel_info/edit_channel/edit_channel.test.js +++ b/app/screens/channel_info/edit_channel/edit_channel.test.js @@ -20,7 +20,6 @@ describe('ChannelInfo -> EditChannel', () => { const baseProps = { testID: 'test-id', canEdit: true, - isLandscape: false, theme: Preferences.THEMES.default, }; diff --git a/app/screens/channel_info/edit_channel/edit_channel.tsx b/app/screens/channel_info/edit_channel/edit_channel.tsx index 109385976..a04f13dd2 100644 --- a/app/screens/channel_info/edit_channel/edit_channel.tsx +++ b/app/screens/channel_info/edit_channel/edit_channel.tsx @@ -14,7 +14,6 @@ import {preventDoubleTap} from '@utils/tap'; interface EditChannelProps { testID?: string; canEdit: boolean; - isLandscape: boolean; theme: Theme; } @@ -34,7 +33,7 @@ export default class EditChannel extends PureComponent { }); render() { - const {testID, canEdit, isLandscape, theme} = this.props; + const {testID, canEdit, theme} = this.props; if (!canEdit) { return null; @@ -50,7 +49,6 @@ export default class EditChannel extends PureComponent { icon='pencil-outline' textId={t('mobile.channel_info.edit')} theme={theme} - isLandscape={isLandscape} /> ); diff --git a/app/screens/channel_info/favorite/__snapshots__/favorite.test.js.snap b/app/screens/channel_info/favorite/__snapshots__/favorite.test.js.snap index 8d5703253..bf4d08634 100644 --- a/app/screens/channel_info/favorite/__snapshots__/favorite.test.js.snap +++ b/app/screens/channel_info/favorite/__snapshots__/favorite.test.js.snap @@ -6,7 +6,6 @@ exports[`ChannelInfo -> Favorite should match snapshot for Favorite Channel 1`] defaultMessage="Favorite" detail={true} icon="star-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="mobile.routes.channelInfo.favorite" @@ -49,7 +48,6 @@ exports[`ChannelInfo -> Favorite should match snapshot for Unfavorite Channel 1` defaultMessage="Favorite" detail={false} icon="star-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="mobile.routes.channelInfo.favorite" diff --git a/app/screens/channel_info/favorite/favorite.test.js b/app/screens/channel_info/favorite/favorite.test.js index 973f3d56f..e8149efb8 100644 --- a/app/screens/channel_info/favorite/favorite.test.js +++ b/app/screens/channel_info/favorite/favorite.test.js @@ -21,7 +21,6 @@ describe('ChannelInfo -> Favorite', () => { channelId: '123', favoriteChannel: jest.fn(), isFavorite: false, - isLandscape: false, unfavoriteChannel: jest.fn(), theme: Preferences.THEMES.default, }; diff --git a/app/screens/channel_info/favorite/favorite.tsx b/app/screens/channel_info/favorite/favorite.tsx index 5bcd1c477..4566495f5 100644 --- a/app/screens/channel_info/favorite/favorite.tsx +++ b/app/screens/channel_info/favorite/favorite.tsx @@ -13,12 +13,11 @@ interface FavoriteProps { channelId: string; favoriteChannel: (channelId: string) => void; isFavorite: boolean; - isLandscape: boolean; unfavoriteChannel: (channelId: string) => void; theme: Theme; } -const Favorite = ({testID, channelId, favoriteChannel, isLandscape, isFavorite, unfavoriteChannel, theme}: FavoriteProps) => { +const Favorite = ({channelId, favoriteChannel, isFavorite, unfavoriteChannel, testID, theme}: FavoriteProps) => { const [favorite, setFavorite] = useState(isFavorite); const handleFavorite = preventDoubleTap(() => { @@ -37,7 +36,6 @@ const Favorite = ({testID, channelId, favoriteChannel, isLandscape, isFavorite, textId={t('mobile.routes.channelInfo.favorite')} togglable={true} theme={theme} - isLandscape={isLandscape} /> ); }; diff --git a/app/screens/channel_info/ignore_mentions/__snapshots__/ignore_mentions.test.js.snap b/app/screens/channel_info/ignore_mentions/__snapshots__/ignore_mentions.test.js.snap index 4387aa1b3..8afc036c6 100644 --- a/app/screens/channel_info/ignore_mentions/__snapshots__/ignore_mentions.test.js.snap +++ b/app/screens/channel_info/ignore_mentions/__snapshots__/ignore_mentions.test.js.snap @@ -6,7 +6,6 @@ exports[`ChannelInfo -> IgnoreMentions should match snapshot for Ignore Mentions defaultMessage="Ignore @channel, @here, @all" detail={true} icon="at" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_notifications.ignoreChannelMentions.settings" @@ -49,7 +48,6 @@ exports[`ChannelInfo -> IgnoreMentions should match snapshot for Not Ignore Ment defaultMessage="Ignore @channel, @here, @all" detail={false} icon="at" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_notifications.ignoreChannelMentions.settings" diff --git a/app/screens/channel_info/ignore_mentions/ignore_mentions.test.js b/app/screens/channel_info/ignore_mentions/ignore_mentions.test.js index 85dcf6d1f..9e65a578a 100644 --- a/app/screens/channel_info/ignore_mentions/ignore_mentions.test.js +++ b/app/screens/channel_info/ignore_mentions/ignore_mentions.test.js @@ -20,7 +20,6 @@ describe('ChannelInfo -> IgnoreMentions', () => { const baseProps = { channelId: '123', ignore: false, - isLandscape: false, theme: Preferences.THEMES.default, updateChannelNotifyProps: jest.fn(), userId: 'user-123', diff --git a/app/screens/channel_info/ignore_mentions/ignore_mentions.tsx b/app/screens/channel_info/ignore_mentions/ignore_mentions.tsx index a592c4736..19be086eb 100644 --- a/app/screens/channel_info/ignore_mentions/ignore_mentions.tsx +++ b/app/screens/channel_info/ignore_mentions/ignore_mentions.tsx @@ -13,13 +13,12 @@ interface IgnoreMentionsProps { testID?: string; channelId: string; ignore: boolean; - isLandscape: boolean; theme: Theme; updateChannelNotifyProps: (userId: string, channelId: string, opts: {ignore_channel_mentions: string}) => void; userId: string; } -const IgnoreMentions = ({testID, channelId, ignore, isLandscape, updateChannelNotifyProps, userId, theme}: IgnoreMentionsProps) => { +const IgnoreMentions = ({channelId, ignore, updateChannelNotifyProps, userId, testID, theme}: IgnoreMentionsProps) => { const [mentions, setMentions] = useState(ignore); const handleIgnoreChannelMentions = preventDoubleTap(() => { @@ -41,7 +40,6 @@ const IgnoreMentions = ({testID, channelId, ignore, isLandscape, updateChannelNo textId={t('channel_notifications.ignoreChannelMentions.settings')} togglable={true} theme={theme} - isLandscape={isLandscape} /> ); }; diff --git a/app/screens/channel_info/leave/__snapshots__/leave.test.js.snap b/app/screens/channel_info/leave/__snapshots__/leave.test.js.snap index a9b98343a..9995d302d 100644 --- a/app/screens/channel_info/leave/__snapshots__/leave.test.js.snap +++ b/app/screens/channel_info/leave/__snapshots__/leave.test.js.snap @@ -38,7 +38,6 @@ exports[`ChannelInfo -> Leave should match snapshot for Close DM 1`] = ` defaultMessage="Close Direct Message" icon="close" iconColor="#CA3B27" - isLandscape={false} rightArrow={false} shouldRender={true} textColor="#CA3B27" @@ -115,7 +114,6 @@ exports[`ChannelInfo -> Leave should match snapshot for Close GM 1`] = ` defaultMessage="Close Group Message" icon="close" iconColor="#CA3B27" - isLandscape={false} rightArrow={false} shouldRender={true} textColor="#CA3B27" @@ -192,7 +190,6 @@ exports[`ChannelInfo -> Leave should match snapshot for Leave Private Channel 1` defaultMessage="Leave Channel" icon="exit-to-app" iconColor="#CA3B27" - isLandscape={false} rightArrow={false} shouldRender={true} textColor="#CA3B27" @@ -269,7 +266,6 @@ exports[`ChannelInfo -> Leave should match snapshot for Leave Public Channel 1`] defaultMessage="Leave Channel" icon="exit-to-app" iconColor="#CA3B27" - isLandscape={false} rightArrow={false} shouldRender={true} textColor="#CA3B27" diff --git a/app/screens/channel_info/leave/leave.test.js b/app/screens/channel_info/leave/leave.test.js index 44ba80d26..95e64188a 100644 --- a/app/screens/channel_info/leave/leave.test.js +++ b/app/screens/channel_info/leave/leave.test.js @@ -38,7 +38,6 @@ describe('ChannelInfo -> Leave', () => { isDirectMessage: false, isFavorite: false, isGroupMessage: false, - isLandscape: false, isPublic: true, theme: Preferences.THEMES.default, }; diff --git a/app/screens/channel_info/leave/leave.tsx b/app/screens/channel_info/leave/leave.tsx index 98c3a5e06..120b2c6de 100644 --- a/app/screens/channel_info/leave/leave.tsx +++ b/app/screens/channel_info/leave/leave.tsx @@ -25,7 +25,6 @@ interface LeaveProps { isDirectMessage: boolean; isFavorite: boolean; isGroupMessage: boolean; - isLandscape: boolean; isPublic: boolean; theme: Theme; } @@ -92,7 +91,7 @@ export default class Leave extends PureComponent { }); render() { - const {canLeave, isDirectMessage, isGroupMessage, isLandscape, theme} = this.props; + const {canLeave, isDirectMessage, isGroupMessage, theme} = this.props; if (!canLeave && !isDirectMessage && !isGroupMessage) { return null; @@ -119,7 +118,6 @@ export default class Leave extends PureComponent { textColor='#CA3B27' textId={i18nId} theme={theme} - isLandscape={isLandscape} rightArrow={false} /> ); @@ -133,7 +131,6 @@ export default class Leave extends PureComponent { textColor='#CA3B27' textId={t('navbar.leave')} theme={theme} - isLandscape={isLandscape} rightArrow={false} /> ); diff --git a/app/screens/channel_info/manage_members/__snapshots__/manage_members.test.js.snap b/app/screens/channel_info/manage_members/__snapshots__/manage_members.test.js.snap index 9fd10c03b..ae98206ac 100644 --- a/app/screens/channel_info/manage_members/__snapshots__/manage_members.test.js.snap +++ b/app/screens/channel_info/manage_members/__snapshots__/manage_members.test.js.snap @@ -38,7 +38,6 @@ exports[`ChannelInfo -> Manage Members should match snapshot for Manage Members defaultMessage="Manage Members" detail={10} icon="account-multiple-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_header.manageMembers" @@ -114,7 +113,6 @@ exports[`ChannelInfo -> Manage Members should match snapshot for View Members 1` defaultMessage="View Members" detail={10} icon="account-multiple-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_header.viewMembers" @@ -159,7 +157,6 @@ exports[`ChannelInfo -> Manage Members should match snapshot without separator 1 defaultMessage="Manage Members" detail={10} icon="account-multiple-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_header.manageMembers" diff --git a/app/screens/channel_info/manage_members/manage_members.test.js b/app/screens/channel_info/manage_members/manage_members.test.js index cf11d3858..31c08457a 100644 --- a/app/screens/channel_info/manage_members/manage_members.test.js +++ b/app/screens/channel_info/manage_members/manage_members.test.js @@ -20,7 +20,6 @@ describe('ChannelInfo -> Manage Members', () => { const baseProps = { canManageUsers: true, isDirectMessage: false, - isLandscape: false, membersCount: 10, separator: true, theme: Preferences.THEMES.default, diff --git a/app/screens/channel_info/manage_members/manage_members.tsx b/app/screens/channel_info/manage_members/manage_members.tsx index 8e420ef76..c35b1e237 100644 --- a/app/screens/channel_info/manage_members/manage_members.tsx +++ b/app/screens/channel_info/manage_members/manage_members.tsx @@ -15,7 +15,6 @@ interface ManageMembersProps { testID?: string; canManageUsers: boolean; isDirectMessage: boolean; - isLandscape: boolean; membersCount: number; separator: boolean; theme: Theme; @@ -42,7 +41,7 @@ export default class ManageMembers extends PureComponent { }); render() { - const {testID, isDirectMessage, canManageUsers, isLandscape, membersCount, separator, theme} = this.props; + const {isDirectMessage, canManageUsers, membersCount, separator, testID, theme} = this.props; if (isDirectMessage) { return null; @@ -59,7 +58,6 @@ export default class ManageMembers extends PureComponent { icon='account-multiple-outline' textId={canManageUsers ? t('channel_header.manageMembers') : t('channel_header.viewMembers')} theme={theme} - isLandscape={isLandscape} /> ); diff --git a/app/screens/channel_info/mute/__snapshots__/mute.test.js.snap b/app/screens/channel_info/mute/__snapshots__/mute.test.js.snap index 03a715e37..0ef7c8016 100644 --- a/app/screens/channel_info/mute/__snapshots__/mute.test.js.snap +++ b/app/screens/channel_info/mute/__snapshots__/mute.test.js.snap @@ -6,7 +6,6 @@ exports[`ChannelInfo -> Mute should match snapshot for Muted 1`] = ` defaultMessage="Mute channel" detail={true} icon="bell-off-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_notifications.muteChannel.settings" @@ -49,7 +48,6 @@ exports[`ChannelInfo -> Mute should match snapshot for Not Muted 1`] = ` defaultMessage="Mute channel" detail={false} icon="bell-off-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_notifications.muteChannel.settings" diff --git a/app/screens/channel_info/mute/mute.test.js b/app/screens/channel_info/mute/mute.test.js index 6bea784ad..cb4e08af4 100644 --- a/app/screens/channel_info/mute/mute.test.js +++ b/app/screens/channel_info/mute/mute.test.js @@ -20,7 +20,6 @@ describe('ChannelInfo -> Mute', () => { const baseProps = { channelId: '123', isChannelMuted: false, - isLandscape: false, theme: Preferences.THEMES.default, updateChannelNotifyProps: jest.fn(), userId: 'user-123', diff --git a/app/screens/channel_info/mute/mute.tsx b/app/screens/channel_info/mute/mute.tsx index 864a16470..ee80b1342 100644 --- a/app/screens/channel_info/mute/mute.tsx +++ b/app/screens/channel_info/mute/mute.tsx @@ -12,13 +12,12 @@ interface MuteProps { testID?: string; channelId: string; isChannelMuted: boolean; - isLandscape: boolean; theme: Theme; updateChannelNotifyProps: (userId: string, channelId: string, opts: {mark_unread: string}) => void; userId: string; } -const Mute = ({testID, channelId, isChannelMuted, isLandscape, updateChannelNotifyProps, userId, theme}: MuteProps) => { +const Mute = ({channelId, isChannelMuted, updateChannelNotifyProps, userId, testID, theme}: MuteProps) => { const [muted, setMuted] = useState(isChannelMuted); const handleMuteChannel = preventDoubleTap(() => { @@ -40,7 +39,6 @@ const Mute = ({testID, channelId, isChannelMuted, isLandscape, updateChannelNoti textId={t('channel_notifications.muteChannel.settings')} togglable={true} theme={theme} - isLandscape={isLandscape} /> ); }; diff --git a/app/screens/channel_info/notification_preference/__snapshots__/notification_preference.test.js.snap b/app/screens/channel_info/notification_preference/__snapshots__/notification_preference.test.js.snap index 26b3692b6..b4ea7f4bb 100644 --- a/app/screens/channel_info/notification_preference/__snapshots__/notification_preference.test.js.snap +++ b/app/screens/channel_info/notification_preference/__snapshots__/notification_preference.test.js.snap @@ -6,7 +6,6 @@ exports[`NotificationPreference should match snapshot 1`] = ` defaultMessage="Mobile Notifications" detail="Default" icon="cellphone" - isLandscape={false} rightArrow={true} shouldRender={true} testID="test-id" diff --git a/app/screens/channel_info/notification_preference/notification_preference.test.js b/app/screens/channel_info/notification_preference/notification_preference.test.js index d2bfba623..ba296f420 100644 --- a/app/screens/channel_info/notification_preference/notification_preference.test.js +++ b/app/screens/channel_info/notification_preference/notification_preference.test.js @@ -16,7 +16,6 @@ describe('NotificationPreference', () => { notifyProps: { push: 'default', }, - isLandscape: false, theme: Preferences.THEMES.default, }; diff --git a/app/screens/channel_info/notification_preference/notification_preference.tsx b/app/screens/channel_info/notification_preference/notification_preference.tsx index 1b248857c..df093e7a4 100644 --- a/app/screens/channel_info/notification_preference/notification_preference.tsx +++ b/app/screens/channel_info/notification_preference/notification_preference.tsx @@ -17,7 +17,6 @@ interface NotificationPreferenceProps { channelId: string; userId: string; notifyProps: ChannelNotifyProps; - isLandscape: boolean; theme: Theme; } @@ -66,7 +65,7 @@ export default class NotificationPreference extends PureComponent ); } diff --git a/app/screens/channel_info/pinned/__snapshots__/pinned.test.js.snap b/app/screens/channel_info/pinned/__snapshots__/pinned.test.js.snap index 5a2434860..f280594b0 100644 --- a/app/screens/channel_info/pinned/__snapshots__/pinned.test.js.snap +++ b/app/screens/channel_info/pinned/__snapshots__/pinned.test.js.snap @@ -6,7 +6,6 @@ exports[`ChannelInfo -> Pinned should match snapshot 1`] = ` defaultMessage="Pinned Messages" detail={0} icon="pin-outline" - isLandscape={false} rightArrow={true} shouldRender={true} textId="channel_header.pinnedPosts" diff --git a/app/screens/channel_info/pinned/pinned.test.js b/app/screens/channel_info/pinned/pinned.test.js index 7d7a8a2e9..50ebaa7e8 100644 --- a/app/screens/channel_info/pinned/pinned.test.js +++ b/app/screens/channel_info/pinned/pinned.test.js @@ -20,7 +20,6 @@ describe('ChannelInfo -> Pinned', () => { const baseProps = { channelId: '123', pinnedCount: 0, - isLandscape: false, theme: Preferences.THEMES.default, userId: 'user-123', }; diff --git a/app/screens/channel_info/pinned/pinned.tsx b/app/screens/channel_info/pinned/pinned.tsx index 3187a4a0a..301b397ac 100644 --- a/app/screens/channel_info/pinned/pinned.tsx +++ b/app/screens/channel_info/pinned/pinned.tsx @@ -14,7 +14,6 @@ interface PinnedProps { testID?: string; channelId: string; pinnedCount: number; - isLandscape: boolean; theme: Theme; userId: string; } @@ -39,7 +38,7 @@ export default class Pinned extends PureComponent { }); render() { - const {testID, pinnedCount, isLandscape, theme} = this.props; + const {pinnedCount, testID, theme} = this.props; return ( { icon='pin-outline' textId={t('channel_header.pinnedPosts')} theme={theme} - isLandscape={isLandscape} /> ); } diff --git a/app/screens/channel_members/__snapshots__/channel_members.test.js.snap b/app/screens/channel_members/__snapshots__/channel_members.test.js.snap index 3f057f1c7..6cbd724db 100644 --- a/app/screens/channel_members/__snapshots__/channel_members.test.js.snap +++ b/app/screens/channel_members/__snapshots__/channel_members.test.js.snap @@ -2,18 +2,28 @@ exports[`ChannelMembers should match snapshot 1`] = ` - - + - - + /> + `; diff --git a/app/screens/channel_members/channel_members.js b/app/screens/channel_members/channel_members.js index e02d68896..02b311860 100644 --- a/app/screens/channel_members/channel_members.js +++ b/app/screens/channel_members/channel_members.js @@ -3,34 +3,29 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; -import { - Alert, - Platform, - View, -} from 'react-native'; +import {Alert, View} from 'react-native'; import {intlShape} from 'react-intl'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; +import {popTopScreen, setButtons} from '@actions/navigation'; +import Loading from '@components/loading'; +import CustomList, {FLATLIST, SECTIONLIST} from '@components/custom_list'; +import UserListRow from '@components/custom_list/user_list_row'; +import FormattedText from '@components/formatted_text'; +import KeyboardLayout from '@components/layout/keyboard_layout'; +import SearchBar from '@components/search_bar'; +import StatusBar from '@components/status_bar'; import {debounce} from '@mm-redux/actions/helpers'; import {General} from '@mm-redux/constants'; import {filterProfilesMatchingTerm} from '@mm-redux/utils/user_utils'; - -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; -import Loading from 'app/components/loading'; -import CustomList, {FLATLIST, SECTIONLIST} from 'app/components/custom_list'; -import UserListRow from 'app/components/custom_list/user_list_row'; -import FormattedText from 'app/components/formatted_text'; -import KeyboardLayout from 'app/components/layout/keyboard_layout'; -import SearchBar from 'app/components/search_bar'; -import StatusBar from 'app/components/status_bar'; -import {alertErrorIfInvalidPermissions} from 'app/utils/general'; -import {createProfilesSections, loadingText} from 'app/utils/member_list'; +import {alertErrorIfInvalidPermissions} from '@utils/general'; +import {createProfilesSections, loadingText} from '@utils/member_list'; import { changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; -import {popTopScreen, setButtons} from 'app/actions/navigation'; +} from '@utils/theme'; export default class ChannelMembers extends PureComponent { static propTypes = { @@ -45,7 +40,6 @@ export default class ChannelMembers extends PureComponent { currentChannelMembers: PropTypes.array, currentUserId: PropTypes.string.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -284,7 +278,7 @@ export default class ChannelMembers extends PureComponent { renderNoResults = () => { const {loading} = this.state; - const {theme, isLandscape} = this.props; + const {theme} = this.props; const style = getStyleFromTheme(theme); if (loading || this.page === -1) { @@ -292,7 +286,7 @@ export default class ChannelMembers extends PureComponent { } return ( - + - - - + + + - - + + ); } @@ -416,11 +405,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { searchBar: { marginVertical: 5, height: 38, - ...Platform.select({ - ios: { - paddingLeft: 8, - }, - }), + }, + searchBarInput: { + backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), + color: theme.centerChannelColor, + fontSize: 15, + }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/channel_members/channel_members.test.js b/app/screens/channel_members/channel_members.test.js index 641778d93..035b7c14f 100644 --- a/app/screens/channel_members/channel_members.test.js +++ b/app/screens/channel_members/channel_members.test.js @@ -21,7 +21,6 @@ describe('ChannelMembers', () => { searchProfiles: jest.fn(), }, componentId: 'component-id', - isLandscape: false, }; beforeAll(() => { diff --git a/app/screens/channel_members/index.js b/app/screens/channel_members/index.js index 31e9bbd0e..04c413e4c 100644 --- a/app/screens/channel_members/index.js +++ b/app/screens/channel_members/index.js @@ -10,7 +10,6 @@ import {makeGetProfilesInChannel} from '@mm-redux/selectors/entities/users'; import {getProfilesInChannel, searchProfiles} from '@mm-redux/actions/users'; import {handleRemoveChannelMembers} from 'app/actions/views/channel_members'; -import {isLandscape} from 'app/selectors/device'; import ChannelMembers from './channel_members'; function makeMapStateToProps() { @@ -31,7 +30,6 @@ function makeMapStateToProps() { currentChannelMembers, currentUserId: state.entities.users.currentUserId, theme: getTheme(state), - isLandscape: isLandscape(state), }; }; } diff --git a/app/screens/channel_notification_preference/__snapshots__/channel_notification_preference.test.js.snap b/app/screens/channel_notification_preference/__snapshots__/channel_notification_preference.test.js.snap index 461c12f1f..7f35203c9 100644 --- a/app/screens/channel_notification_preference/__snapshots__/channel_notification_preference.test.js.snap +++ b/app/screens/channel_notification_preference/__snapshots__/channel_notification_preference.test.js.snap @@ -1,49 +1,59 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ChannelNotificationPreference should match snapshot 1`] = ` - - + + - - + + - @@ -61,7 +71,6 @@ exports[`ChannelNotificationPreference should match snapshot 1`] = ` action={[Function]} actionType="select" actionValue="default" - isLandscape={false} label={ - + - - - - + } + /> + + + `; diff --git a/app/screens/channel_notification_preference/channel_notification_preference.ios.js b/app/screens/channel_notification_preference/channel_notification_preference.ios.js index 791b09b89..053e924de 100644 --- a/app/screens/channel_notification_preference/channel_notification_preference.ios.js +++ b/app/screens/channel_notification_preference/channel_notification_preference.ios.js @@ -6,41 +6,40 @@ import { ScrollView, View, } from 'react-native'; -import SafeAreaView from 'app/components/safe_area_view'; +import {SafeAreaView} from 'react-native-safe-area-context'; + import FormattedText from 'app/components/formatted_text'; import StatusBar from 'app/components/status_bar'; import SectionItem from 'app/screens/settings/section_item'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import ChannelNotificationPreferenceBase from './channel_notification_preference_base'; export default class ChannelNotificationPreferenceIos extends ChannelNotificationPreferenceBase { render() { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const style = getStyleSheet(theme); const items = this.getItems(); return ( - - - + + - - + + + + {items.map((item) => ( @@ -57,15 +56,14 @@ export default class ChannelNotificationPreferenceIos extends ChannelNotificatio actionValue={item.value} selected={item.checked} theme={theme} - isLandscape={isLandscape} /> ), )} - - - - - + + + + + ); } } diff --git a/app/screens/channel_notification_preference/channel_notification_preference.test.js b/app/screens/channel_notification_preference/channel_notification_preference.test.js index bec3fb22a..7dff1b34f 100644 --- a/app/screens/channel_notification_preference/channel_notification_preference.test.js +++ b/app/screens/channel_notification_preference/channel_notification_preference.test.js @@ -23,7 +23,6 @@ function makeProps(pushNotificationLevel) { push: pushNotificationLevel, }, theme: Preferences.THEMES.default, - isLandscape: false, }; } diff --git a/app/screens/channel_notification_preference/channel_notification_preference_base.js b/app/screens/channel_notification_preference/channel_notification_preference_base.js index f13bf148b..d59f74f8e 100644 --- a/app/screens/channel_notification_preference/channel_notification_preference_base.js +++ b/app/screens/channel_notification_preference/channel_notification_preference_base.js @@ -17,7 +17,6 @@ export default class ChannelNotificationPreferenceBase extends PureComponent { }), channelId: PropTypes.string.isRequired, globalNotifyProps: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, notifyProps: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, userId: PropTypes.string.isRequired, diff --git a/app/screens/client_upgrade/client_upgrade.js b/app/screens/client_upgrade/client_upgrade.js index 56047413e..3affdd367 100644 --- a/app/screens/client_upgrade/client_upgrade.js +++ b/app/screens/client_upgrade/client_upgrade.js @@ -12,6 +12,7 @@ import { View, } from 'react-native'; import {intlShape} from 'react-intl'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {popTopScreen, dismissModal} from '@actions/navigation'; import CompassIcon from '@components/compass_icon'; @@ -256,7 +257,7 @@ export default class ClientUpgrade extends PureComponent { const styles = getStyleFromTheme(theme); return ( - + {this.renderMessageContent()} - + ); } } diff --git a/app/screens/code/code.js b/app/screens/code/code.js index 54da87cad..59687f491 100644 --- a/app/screens/code/code.js +++ b/app/screens/code/code.js @@ -12,6 +12,7 @@ import { TextInput, View, } from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {getCodeFont} from 'app/utils/markdown'; import { @@ -20,13 +21,11 @@ import { getKeyboardAppearanceFromTheme, } from 'app/utils/theme'; import {popTopScreen} from 'app/actions/navigation'; -import {marginHorizontal as margin} from 'app/components/safe_area_view/iphone_x_spacing'; export default class Code extends React.PureComponent { static propTypes = { theme: PropTypes.object.isRequired, content: PropTypes.string.isRequired, - isLandscape: PropTypes.bool.isRequired, }; componentDidMount() { @@ -47,7 +46,6 @@ export default class Code extends React.PureComponent { }; render() { - const {isLandscape} = this.props; const style = getStyleSheet(this.props.theme); const numberOfLines = this.countLines(this.props.content); @@ -88,23 +86,28 @@ export default class Code extends React.PureComponent { } return ( - - - - {lineNumbers} - - - {textComponent} + + + {lineNumbers} + + + + {textComponent} + - + ); } } diff --git a/app/screens/code/index.js b/app/screens/code/index.js index a8d5fb9f7..153462c6f 100644 --- a/app/screens/code/index.js +++ b/app/screens/code/index.js @@ -5,13 +5,11 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import Code from './code'; function mapStateToProps(state) { return { theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/create_channel/create_channel.js b/app/screens/create_channel/create_channel.js index 412c4a6eb..b8ac47eff 100644 --- a/app/screens/create_channel/create_channel.js +++ b/app/screens/create_channel/create_channel.js @@ -21,8 +21,6 @@ export default class CreateChannel extends PureComponent { static propTypes = { componentId: PropTypes.string, theme: PropTypes.object.isRequired, - deviceWidth: PropTypes.number.isRequired, - deviceHeight: PropTypes.number.isRequired, createChannelRequest: PropTypes.object.isRequired, channelType: PropTypes.string, closeButton: PropTypes.object, @@ -164,11 +162,7 @@ export default class CreateChannel extends PureComponent { }; render() { - const { - theme, - deviceWidth, - deviceHeight, - } = this.props; + const {theme} = this.props; const { error, creating, @@ -190,8 +184,6 @@ export default class CreateChannel extends PureComponent { displayName={displayName} purpose={purpose} header={header} - deviceWidth={deviceWidth} - deviceHeight={deviceHeight} /> ); } diff --git a/app/screens/create_channel/index.js b/app/screens/create_channel/index.js index ba0110c09..4f09f9e4d 100644 --- a/app/screens/create_channel/index.js +++ b/app/screens/create_channel/index.js @@ -7,19 +7,15 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {handleCreateChannel} from 'app/actions/views/create_channel'; -import {getDimensions} from 'app/selectors/device'; import CreateChannel from './create_channel'; function mapStateToProps(state) { const {createChannel: createChannelRequest} = state.requests.channels; - const {deviceWidth, deviceHeight} = getDimensions(state); return { createChannelRequest, theme: getTheme(state), - deviceWidth, - deviceHeight, }; } diff --git a/app/screens/edit_channel/edit_channel.js b/app/screens/edit_channel/edit_channel.js index 6a0a929de..ab60ce10f 100644 --- a/app/screens/edit_channel/edit_channel.js +++ b/app/screens/edit_channel/edit_channel.js @@ -9,7 +9,6 @@ import { InteractionManager, } from 'react-native'; import {Navigation} from 'react-native-navigation'; -import SafeAreaView from 'app/components/safe_area_view'; import {General, RequestStatus} from '@mm-redux/constants'; import EventEmitter from '@mm-redux/utils/event_emitter'; @@ -59,8 +58,6 @@ export default class EditChannel extends PureComponent { }), componentId: PropTypes.string, theme: PropTypes.object.isRequired, - deviceWidth: PropTypes.number.isRequired, - deviceHeight: PropTypes.number.isRequired, channel: PropTypes.object.isRequired, currentTeamUrl: PropTypes.string.isRequired, updateChannelRequest: PropTypes.object.isRequired, @@ -297,8 +294,6 @@ export default class EditChannel extends PureComponent { }, theme, currentTeamUrl, - deviceWidth, - deviceHeight, } = this.props; const { error, @@ -310,35 +305,28 @@ export default class EditChannel extends PureComponent { } = this.state; return ( - - - + ); } } diff --git a/app/screens/edit_channel/index.js b/app/screens/edit_channel/index.js index 22e207a65..ced8ad665 100644 --- a/app/screens/edit_channel/index.js +++ b/app/screens/edit_channel/index.js @@ -10,22 +10,18 @@ import {patchChannel, getChannel} from '@mm-redux/actions/channels'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {setChannelDisplayName} from 'app/actions/views/channel'; -import {getDimensions} from 'app/selectors/device'; import EditChannel from './edit_channel'; function mapStateToProps(state) { const {updateChannel: updateChannelRequest} = state.requests.channels; const channel = getCurrentChannel(state); - const {deviceWidth, deviceHeight} = getDimensions(state); return { channel, currentTeamUrl: getCurrentTeamUrl(state), updateChannelRequest, theme: getTheme(state), - deviceWidth, - deviceHeight, }; } diff --git a/app/screens/edit_post/__snapshots__/edit_post.test.js.snap b/app/screens/edit_post/__snapshots__/edit_post.test.js.snap index e62426d34..513db88fc 100644 --- a/app/screens/edit_post/__snapshots__/edit_post.test.js.snap +++ b/app/screens/edit_post/__snapshots__/edit_post.test.js.snap @@ -2,7 +2,7 @@ exports[`EditPost should match snapshot 1`] = ` - - + - {displayError} - + - + { }, post: {}, theme: Preferences.THEMES.default, - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/edit_post/index.js b/app/screens/edit_post/index.js index d36724da1..04f1e62b5 100644 --- a/app/screens/edit_post/index.js +++ b/app/screens/edit_post/index.js @@ -9,7 +9,7 @@ import {getConfig} from '@mm-redux/selectors/entities/general'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {MAX_MESSAGE_LENGTH_FALLBACK} from '@constants/post_draft'; -import {getDimensions, isLandscape} from '@selectors/device'; +import {getDimensions} from '@selectors/device'; import EditPost from './edit_post'; @@ -18,7 +18,6 @@ function mapStateToProps(state, ownProps) { return { ...getDimensions(state), - isLandscape: isLandscape(state), maxMessageLength: (config && parseInt(config.MaxPostSize || 0, 10)) || MAX_MESSAGE_LENGTH_FALLBACK, post: ownProps.post, theme: getTheme(state), diff --git a/app/screens/edit_profile/edit_profile.js b/app/screens/edit_profile/edit_profile.js index c0c4cefe6..f08c19639 100644 --- a/app/screens/edit_profile/edit_profile.js +++ b/app/screens/edit_profile/edit_profile.js @@ -9,6 +9,7 @@ import RNFetchBlob from 'rn-fetch-blob'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scrollview'; import DocumentPicker from 'react-native-document-picker'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {Client4} from '@mm-redux/client'; import {getFormattedFileSize} from '@mm-redux/utils/file_utils'; @@ -569,10 +570,10 @@ export default class EditProfile extends PureComponent { if (updating) { return ( - + - + ); } @@ -591,7 +592,7 @@ export default class EditProfile extends PureComponent { } return ( - + - + ); } } diff --git a/app/screens/edit_profile/edit_profile.test.js b/app/screens/edit_profile/edit_profile.test.js index 8c5cf9764..7ff6f04d1 100644 --- a/app/screens/edit_profile/edit_profile.test.js +++ b/app/screens/edit_profile/edit_profile.test.js @@ -41,7 +41,6 @@ describe('edit_profile', () => { }, commandType: 'ShowModal', componentId: 'component-id', - isLandscape: false, }; test('should match snapshot', async () => { diff --git a/app/screens/error_teams_list/__snapshots__/error_teams_list.test.js.snap b/app/screens/error_teams_list/__snapshots__/error_teams_list.test.js.snap index 3ec6c7228..3d9ea61eb 100644 --- a/app/screens/error_teams_list/__snapshots__/error_teams_list.test.js.snap +++ b/app/screens/error_teams_list/__snapshots__/error_teams_list.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ErrorTeamsList should match snapshot 1`] = ` - - + `; diff --git a/app/screens/error_teams_list/error_teams_list.js b/app/screens/error_teams_list/error_teams_list.js index 14dd54ecd..45950ac5e 100644 --- a/app/screens/error_teams_list/error_teams_list.js +++ b/app/screens/error_teams_list/error_teams_list.js @@ -4,12 +4,9 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {intlShape} from 'react-intl'; -import { - InteractionManager, - StyleSheet, - View, -} from 'react-native'; +import {InteractionManager, StyleSheet} from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import FailedNetworkAction from 'app/components/failed_network_action'; import Loading from 'app/components/loading'; @@ -86,7 +83,7 @@ export default class ErrorTeamsList extends PureComponent { }); return ( - + - + ); } } diff --git a/app/screens/expanded_announcement_banner/expanded_announcement_banner.js b/app/screens/expanded_announcement_banner/expanded_announcement_banner.js index f5524afab..27f2e5dbf 100644 --- a/app/screens/expanded_announcement_banner/expanded_announcement_banner.js +++ b/app/screens/expanded_announcement_banner/expanded_announcement_banner.js @@ -20,7 +20,6 @@ export default class ExpandedAnnouncementBanner extends React.PureComponent { }).isRequired, allowDismissal: PropTypes.bool.isRequired, bannerText: PropTypes.string.isRequired, - isLandscape: PropTypes.bool, theme: PropTypes.object.isRequired, } @@ -39,7 +38,7 @@ export default class ExpandedAnnouncementBanner extends React.PureComponent { }; render() { - const {allowDismissal, isLandscape, theme} = this.props; + const {allowDismissal, theme} = this.props; const style = getStyleSheet(theme); let dismissButton = null; @@ -61,10 +60,7 @@ export default class ExpandedAnnouncementBanner extends React.PureComponent { } return ( - + - + `; exports[`ForgotPassword should match snapshot 1`] = ` - - + `; exports[`ForgotPassword snapshot for error on failure of email regex 1`] = ` - - + `; diff --git a/app/screens/forgot_password/forgot_password.js b/app/screens/forgot_password/forgot_password.js index 153e5778a..660090d64 100644 --- a/app/screens/forgot_password/forgot_password.js +++ b/app/screens/forgot_password/forgot_password.js @@ -13,6 +13,7 @@ import { TouchableWithoutFeedback, View, } from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import CompassIcon from '@components/compass_icon'; import ErrorText from '@components/error_text'; @@ -147,7 +148,7 @@ export default class ForgotPassword extends PureComponent { ); } return ( - + - + ); } } diff --git a/app/screens/gallery/footer/prepare_file/prepare_file.tsx b/app/screens/gallery/footer/prepare_file/prepare_file.tsx index 41b64abc3..2f67d3ff8 100644 --- a/app/screens/gallery/footer/prepare_file/prepare_file.tsx +++ b/app/screens/gallery/footer/prepare_file/prepare_file.tsx @@ -5,12 +5,12 @@ import React, {forwardRef, useEffect, useRef, useState, useImperativeHandle} fro import {intlShape} from 'react-intl'; import {Alert, Platform, StyleSheet, Text, View, ViewStyle} from 'react-native'; import RNFetchBlob, {FetchBlobResponse, RNFetchBlobConfig, StatefulPromise} from 'rn-fetch-blob'; +import {useSafeAreaInsets} from 'react-native-safe-area-context'; import Share from 'react-native-share'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; import ProgressBar from '@components/progress_bar'; -import {paddingHorizontal} from '@components/safe_area_view/iphone_x_spacing'; import {Client4} from '@mm-redux/client'; import {getLocalPath} from '@utils/file'; import mattermostBucket from 'app/mattermost_bucket'; @@ -48,6 +48,7 @@ const styles = StyleSheet.create({ const PrepareFile = forwardRef(({intl, isLandscape, theme}: PrepareFileProps, ref) => { const containerStyles: Array = [styles.container]; let downloadTask = useRef>().current; + const insets = useSafeAreaInsets(); const [progress, setProgress] = useState(0); const [visible, setVisible] = useState(false); const start = async (file: FileInfo, share = true): Promise => { @@ -164,7 +165,7 @@ const PrepareFile = forwardRef(({intl, isLands } return ( - + { } return ( - + { downloadAction={props.dowloadFile} /> - + ); }; diff --git a/app/screens/gallery/video_controls.tsx b/app/screens/gallery/video_controls.tsx index 80455ef55..eac5d338b 100644 --- a/app/screens/gallery/video_controls.tsx +++ b/app/screens/gallery/video_controls.tsx @@ -3,6 +3,7 @@ import React, {forwardRef, useEffect, useImperativeHandle, useRef, useState} from 'react'; import {Animated, Platform, StyleSheet, Text, TouchableOpacity, View} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import Slider from 'react-native-slider'; import CompassIcon from '@components/compass_icon'; @@ -191,27 +192,33 @@ const VideoControls = forwardRef((props: V /> - - - - - {humanizeVideoDuration(progress)} - - - {humanizeVideoDuration(duration)} - + + + + + + {humanizeVideoDuration(progress)} + + + {humanizeVideoDuration(duration)} + + + - - + ); }); diff --git a/app/screens/index.js b/app/screens/index.js index f65715067..28699605f 100644 --- a/app/screens/index.js +++ b/app/screens/index.js @@ -4,10 +4,10 @@ import React from 'react'; import {Platform} from 'react-native'; import {ThemeProvider} from 'react-native-elements'; -import {Provider} from 'react-redux'; - -import {Navigation} from 'react-native-navigation'; import {gestureHandlerRootHOC} from 'react-native-gesture-handler'; +import {Navigation} from 'react-native-navigation'; +import {Provider} from 'react-redux'; +import {SafeAreaProvider} from 'react-native-safe-area-context'; import RootWrapper from '@components/root'; let store; @@ -25,7 +25,9 @@ const withReduxProvider = (Screen, excludeEvents = true) => (props) => ( - + + + @@ -86,8 +88,8 @@ Navigation.setLazyComponentRegistrator((screenName) => { case 'ExpandedAnnouncementBanner': screen = require('@screens/expanded_announcement_banner').default; break; - case 'FlaggedPosts': - screen = require('@screens/flagged_posts').default; + case 'SavedPosts': + screen = require('@screens/saved_posts').default; break; case 'ForgotPassword': screen = require('@screens/forgot_password').default; diff --git a/app/screens/interactive_dialog/__snapshots__/dialog_introduction_text.test.js.snap b/app/screens/interactive_dialog/__snapshots__/dialog_introduction_text.test.js.snap index 03a888dfd..6fb67710b 100644 --- a/app/screens/interactive_dialog/__snapshots__/dialog_introduction_text.test.js.snap +++ b/app/screens/interactive_dialog/__snapshots__/dialog_introduction_text.test.js.snap @@ -5,12 +5,9 @@ exports[`DialogIntroductionText should not render the component with an empty va exports[`DialogIntroductionText should render the introduction text correctly 1`] = ` - + `; diff --git a/app/screens/interactive_dialog/dialog_element.js b/app/screens/interactive_dialog/dialog_element.js index 9412dcda4..5c09bd9a7 100644 --- a/app/screens/interactive_dialog/dialog_element.js +++ b/app/screens/interactive_dialog/dialog_element.js @@ -28,7 +28,6 @@ export default class DialogElement extends PureComponent { value: PropTypes.any, onChange: PropTypes.func, theme: PropTypes.object, - isLandscape: PropTypes.bool.isRequired, }; constructor(props) { @@ -73,7 +72,6 @@ export default class DialogElement extends PureComponent { theme, dataSource, options, - isLandscape, } = this.props; let {maxLength} = this.props; @@ -118,7 +116,6 @@ export default class DialogElement extends PureComponent { multiline={multiline} keyboardType={keyboardType} secureTextEntry={secureTextEntry} - isLandscape={isLandscape} /> ); } else if (type === 'select') { @@ -136,7 +133,6 @@ export default class DialogElement extends PureComponent { showRequiredAsterisk={true} selected={this.state.selected} roundedBorders={false} - isLandscape={isLandscape} /> ); } else if (type === 'radio') { @@ -150,7 +146,6 @@ export default class DialogElement extends PureComponent { theme={theme} default={value} onChange={this.onChange} - isLandscape={isLandscape} /> ); } else if (type === 'bool') { @@ -165,7 +160,6 @@ export default class DialogElement extends PureComponent { optional={optional} theme={theme} onChange={this.onChange} - isLandscape={isLandscape} /> ); } diff --git a/app/screens/interactive_dialog/dialog_element.test.js b/app/screens/interactive_dialog/dialog_element.test.js index fde052355..bf6e48ce3 100644 --- a/app/screens/interactive_dialog/dialog_element.test.js +++ b/app/screens/interactive_dialog/dialog_element.test.js @@ -14,7 +14,6 @@ describe('DialogElement', () => { displayName: 'Testing', name: 'testing', type: 'text', - isLandscape: false, }; const theme = Preferences.THEMES.default; diff --git a/app/screens/interactive_dialog/dialog_introduction_text.js b/app/screens/interactive_dialog/dialog_introduction_text.js index 2a2b0c823..07e218f7f 100644 --- a/app/screens/interactive_dialog/dialog_introduction_text.js +++ b/app/screens/interactive_dialog/dialog_introduction_text.js @@ -9,20 +9,17 @@ import Markdown from 'app/components/markdown'; import {getMarkdownTextStyles, getMarkdownBlockStyles} from 'app/utils/markdown'; import {makeStyleSheetFromTheme} from 'app/utils/theme'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export default class DialogIntroductionText extends PureComponent { static propTypes = { value: PropTypes.string.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; render() { const { value, theme, - isLandscape, } = this.props; if (value) { @@ -31,7 +28,7 @@ export default class DialogIntroductionText extends PureComponent { const textStyles = getMarkdownTextStyles(theme); return ( - + { const baseProps = { theme: Preferences.THEMES.default, value: '**bold** *italic* [link](https://mattermost.com/)
[link target blank](!https://mattermost.com/)', - isLandscape: false, }; test('should render the introduction text correctly', () => { diff --git a/app/screens/interactive_dialog/interactive_dialog.js b/app/screens/interactive_dialog/interactive_dialog.js index 3e16b5461..860e86db2 100644 --- a/app/screens/interactive_dialog/interactive_dialog.js +++ b/app/screens/interactive_dialog/interactive_dialog.js @@ -3,8 +3,9 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; -import {Dimensions, ScrollView, View} from 'react-native'; +import {ScrollView} from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {checkDialogElementForError, checkIfErrorsMatchElements} from '@mm-redux/utils/integration_utils'; @@ -55,7 +56,6 @@ export default class InteractiveDialog extends PureComponent { values, error: null, errors: {}, - isLandscape: this.isLandscape(), submitting: false, }; @@ -64,20 +64,6 @@ export default class InteractiveDialog extends PureComponent { componentDidMount() { this.navigationEventListener = Navigation.events().bindComponent(this); - Dimensions.addEventListener('change', this.orientationDidChange); - } - - componentWillUnmount() { - Dimensions.removeEventListener('change', this.orientationDidChange); - } - - orientationDidChange = () => { - this.setState({isLandscape: this.isLandscape()}); - } - - isLandscape = () => { - const {height, width} = Dimensions.get('window'); - return width > height; } navigationButtonPressed({buttonId}) { @@ -188,11 +174,11 @@ export default class InteractiveDialog extends PureComponent { render() { const {introductionText, elements, theme} = this.props; - const {error, errors, isLandscape, values} = this.state; + const {error, errors, values} = this.state; const style = getStyleFromTheme(theme); return ( - + } {elements && elements.map((e) => { @@ -230,12 +215,11 @@ export default class InteractiveDialog extends PureComponent { value={values[e.name]} onChange={this.onChange} theme={theme} - isLandscape={isLandscape} /> ); })} - + ); } } diff --git a/app/screens/login/index.js b/app/screens/login/index.js index 5f876cdc9..b3efa9cc1 100644 --- a/app/screens/login/index.js +++ b/app/screens/login/index.js @@ -8,7 +8,6 @@ import {login} from '@actions/views/user'; import {scheduleExpiredNotification} from '@actions/views/session'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getConfig, getLicense} from '@mm-redux/selectors/entities/general'; -import {isLandscape} from '@selectors/device'; import Login from './login.js'; @@ -20,7 +19,6 @@ function mapStateToProps(state) { config, license, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/login/login.js b/app/screens/login/login.js index 76be25c63..31c36f095 100644 --- a/app/screens/login/login.js +++ b/app/screens/login/login.js @@ -17,12 +17,12 @@ import { } from 'react-native'; import Button from 'react-native-button'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scrollview'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {resetToChannel, goToScreen} from '@actions/navigation'; import CompassIcon from '@components/compass_icon'; import ErrorText from '@components/error_text'; import FormattedText from '@components/formatted_text'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import StatusBar from '@components/status_bar'; import {t} from '@utils/i18n'; import {preventDoubleTap} from '@utils/tap'; @@ -43,7 +43,6 @@ export default class Login extends PureComponent { }).isRequired, config: PropTypes.object.isRequired, license: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -369,7 +368,7 @@ export default class Login extends PureComponent { } return ( - + @@ -433,7 +432,7 @@ export default class Login extends PureComponent { {forgotPassword} - + ); } } diff --git a/app/screens/login/login.test.js b/app/screens/login/login.test.js index 2855987d6..48e7ff9e2 100644 --- a/app/screens/login/login.test.js +++ b/app/screens/login/login.test.js @@ -26,7 +26,6 @@ describe('Login', () => { scheduleExpiredNotification: jest.fn(), login: jest.fn(), }, - isLandscape: false, }; test('should show "I forgot my password" with only email login enabled', () => { diff --git a/app/screens/login_options/index.js b/app/screens/login_options/index.js index 1a30ba32c..1552b7f1a 100644 --- a/app/screens/login_options/index.js +++ b/app/screens/login_options/index.js @@ -6,7 +6,6 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getConfig, getLicense} from '@mm-redux/selectors/entities/general'; -import {isLandscape} from 'app/selectors/device'; import LoginOptions from './login_options'; function mapStateToProps(state) { @@ -16,7 +15,6 @@ function mapStateToProps(state) { config, license, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/login_options/login_options.js b/app/screens/login_options/login_options.js index a0cd12d14..301613116 100644 --- a/app/screens/login_options/login_options.js +++ b/app/screens/login_options/login_options.js @@ -12,6 +12,7 @@ import { Text, } from 'react-native'; import Button from 'react-native-button'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {goToScreen} from '@actions/navigation'; import LocalConfig from '@assets/config'; @@ -19,7 +20,6 @@ import gitlab from '@assets/images/gitlab.png'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; import StatusBar from '@components/status_bar'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {ViewTypes} from '@constants'; import globalEventHandler from '@init/global_event_handler'; import {preventDoubleTap} from '@utils/tap'; @@ -30,7 +30,6 @@ export default class LoginOptions extends PureComponent { static propTypes = { config: PropTypes.object.isRequired, license: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -254,36 +253,38 @@ export default class LoginOptions extends PureComponent { render() { return ( - - - - - {this.props.config.SiteName} - - - - {this.renderEmailOption()} - {this.renderLdapOption()} - {this.renderGitlabOption()} - {this.renderSamlOption()} - {this.renderO365Option()} - + + + + + + {this.props.config.SiteName} + + + + {this.renderEmailOption()} + {this.renderLdapOption()} + {this.renderGitlabOption()} + {this.renderSamlOption()} + {this.renderO365Option()} + + ); } } diff --git a/app/screens/long_post/__snapshots__/long_post.test.js.snap b/app/screens/long_post/__snapshots__/long_post.test.js.snap index 77f65ed9b..40f667de0 100644 --- a/app/screens/long_post/__snapshots__/long_post.test.js.snap +++ b/app/screens/long_post/__snapshots__/long_post.test.js.snap @@ -65,7 +65,6 @@ LongPost { "textComponent": "span", "timeZone": null, }, - "isLandscape": false, "postId": "post-id", "theme": Object { "awayIndicator": "#ffbc42", @@ -180,7 +179,6 @@ LongPost { "timeZone": null, } } - isLandscape={false} postId="post-id" theme={ Object { @@ -219,20 +217,17 @@ LongPost { "_newState": null, "_numberOfReRenders": 0, "_renderPhaseUpdates": null, - "_rendered": - , + , "_rendering": false, "_updater": [Circular], "_workInProgressHook": null, diff --git a/app/screens/long_post/index.js b/app/screens/long_post/index.js index 12d059ac9..bea72b5cc 100644 --- a/app/screens/long_post/index.js +++ b/app/screens/long_post/index.js @@ -9,7 +9,6 @@ import {selectPost} from '@mm-redux/actions/posts'; import {makeGetChannel} from '@mm-redux/selectors/entities/channels'; import {getPost} from '@mm-redux/selectors/entities/posts'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from '@selectors/device'; import LongPost from './long_post'; @@ -24,7 +23,6 @@ function makeMapStateToProps() { channelName: channel ? channel.display_name : '', inThreadView: Boolean(state.entities.posts.selectedPostId), theme: getTheme(state), - isLandscape: isLandscape(state), }; }; } diff --git a/app/screens/long_post/long_post.js b/app/screens/long_post/long_post.js index baaf68da8..7c6b8f003 100644 --- a/app/screens/long_post/long_post.js +++ b/app/screens/long_post/long_post.js @@ -16,7 +16,6 @@ import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; import Post from '@components/post'; import SafeAreaView from '@components/safe_area_view'; -import {marginHorizontal as margin} from '@components/safe_area_view/iphone_x_spacing'; import {preventDoubleTap} from '@utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import {goToScreen, dismissModal} from '@actions/navigation'; @@ -51,7 +50,6 @@ export default class LongPost extends PureComponent { onPermalinkPress: PropTypes.func, postId: PropTypes.string.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -115,7 +113,6 @@ export default class LongPost extends PureComponent { onPermalinkPress, postId, theme, - isLandscape, } = this.props; const style = getStyleSheet(theme); const testID = `long_post.post.${postId}`; @@ -126,7 +123,7 @@ export default class LongPost extends PureComponent { excludeHeader={true} footerColor='transparent' > - + { }, postId: 'post-id', theme: Preferences.THEMES.default, - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/mfa/mfa.js b/app/screens/mfa/mfa.js index a9e33d562..c45ace0f5 100644 --- a/app/screens/mfa/mfa.js +++ b/app/screens/mfa/mfa.js @@ -13,6 +13,7 @@ import { View, } from 'react-native'; import Button from 'react-native-button'; +import {SafeAreaView} from 'react-native-safe-area-context'; import CompassIcon from '@components/compass_icon'; import ErrorText from '@components/error_text'; @@ -132,46 +133,48 @@ export default class Mfa extends PureComponent { } return ( - - - - - - - + + + + + + + + + + + {proceed} - - - {proceed} - - - + + + ); } } diff --git a/app/screens/more_channels/__snapshots__/more_channels.test.js.snap b/app/screens/more_channels/__snapshots__/more_channels.test.js.snap index 92dd245fc..9ae65988a 100644 --- a/app/screens/more_channels/__snapshots__/more_channels.test.js.snap +++ b/app/screens/more_channels/__snapshots__/more_channels.test.js.snap @@ -1,21 +1,24 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`MoreChannels should match snapshot 1`] = ` - - - - + + + + - - - - - - - - + - + + + - - } - noResults={null} - onLoadMore={[Function]} - onRowPress={[Function]} - renderItem={[Function]} - shouldRenderSeparator={true} - showNoResults={true} - theme={ - Object { - "awayIndicator": "#ffbc42", - "buttonBg": "#166de0", - "buttonColor": "#ffffff", - "centerChannelBg": "#ffffff", - "centerChannelColor": "#3d3c40", - "codeTheme": "github", - "dndIndicator": "#f74343", - "errorTextColor": "#fd5960", - "linkColor": "#2389d7", - "mentionBg": "#ffffff", - "mentionBj": "#ffffff", - "mentionColor": "#145dbf", - "mentionHighlightBg": "#ffe577", - "mentionHighlightLink": "#166de0", - "newMessageSeparator": "#ff8800", - "onlineIndicator": "#06d6a0", - "sidebarBg": "#145dbf", - "sidebarHeaderBg": "#1153ab", - "sidebarHeaderTextColor": "#ffffff", - "sidebarText": "#ffffff", - "sidebarTextActiveBorder": "#579eff", - "sidebarTextActiveColor": "#ffffff", - "sidebarTextHoverBg": "#4578bf", - "sidebarUnreadText": "#ffffff", - "type": "Mattermost", + > + +
} - } - /> - - + noResults={null} + onLoadMore={[Function]} + onRowPress={[Function]} + renderItem={[Function]} + shouldRenderSeparator={true} + showNoResults={true} + theme={ + Object { + "awayIndicator": "#ffbc42", + "buttonBg": "#166de0", + "buttonColor": "#ffffff", + "centerChannelBg": "#ffffff", + "centerChannelColor": "#3d3c40", + "codeTheme": "github", + "dndIndicator": "#f74343", + "errorTextColor": "#fd5960", + "linkColor": "#2389d7", + "mentionBg": "#ffffff", + "mentionBj": "#ffffff", + "mentionColor": "#145dbf", + "mentionHighlightBg": "#ffe577", + "mentionHighlightLink": "#166de0", + "newMessageSeparator": "#ff8800", + "onlineIndicator": "#06d6a0", + "sidebarBg": "#145dbf", + "sidebarHeaderBg": "#1153ab", + "sidebarHeaderTextColor": "#ffffff", + "sidebarText": "#ffffff", + "sidebarTextActiveBorder": "#579eff", + "sidebarTextActiveColor": "#ffffff", + "sidebarTextHoverBg": "#4578bf", + "sidebarUnreadText": "#ffffff", + "type": "Mattermost", + } + } + /> + + + `; diff --git a/app/screens/more_channels/index.js b/app/screens/more_channels/index.js index 712ae6dae..56635184f 100644 --- a/app/screens/more_channels/index.js +++ b/app/screens/more_channels/index.js @@ -4,23 +4,21 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import {createSelector} from 'reselect'; -import {isLandscape} from 'app/selectors/device'; + +import {handleSelectChannel, setChannelDisplayName} from '@actions/views/channel'; import {General} from '@mm-redux/constants'; import {getArchivedChannels, getChannels, joinChannel, searchChannels} from '@mm-redux/actions/channels'; import {getChannelsInCurrentTeam, getMyChannelMemberships} from '@mm-redux/selectors/entities/channels'; import {getCurrentUserId, getCurrentUserRoles} from '@mm-redux/selectors/entities/users'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; import {showCreateOption} from '@mm-redux/utils/channel_utils'; +import {isMinimumServerVersion} from '@mm-redux/utils/helpers'; import {isAdmin, isSystemAdmin} from '@mm-redux/utils/user_utils'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getConfig, getLicense} from '@mm-redux/selectors/entities/general'; -import {handleSelectChannel, setChannelDisplayName} from 'app/actions/views/channel'; - import MoreChannels from './more_channels'; -import {isMinimumServerVersion} from '@mm-redux/utils/helpers'; - const joinablePublicChannels = createSelector( getChannelsInCurrentTeam, getMyChannelMemberships, @@ -55,7 +53,6 @@ function mapStateToProps(state) { channels, archivedChannels, theme: getTheme(state), - isLandscape: isLandscape(state), canShowArchivedChannels, }; } diff --git a/app/screens/more_channels/more_channels.js b/app/screens/more_channels/more_channels.js index e1628663c..625e8c8d0 100644 --- a/app/screens/more_channels/more_channels.js +++ b/app/screens/more_channels/more_channels.js @@ -4,16 +4,12 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {intlShape} from 'react-intl'; -import {Keyboard, Platform, View, Text} from 'react-native'; +import {Keyboard, View, Text} from 'react-native'; import {Navigation} from 'react-native-navigation'; - -import {debounce} from '@mm-redux/actions/helpers'; -import {General} from '@mm-redux/constants'; -import EventEmitter from '@mm-redux/utils/event_emitter'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {goToScreen, dismissModal, setButtons} from '@actions/navigation'; import CompassIcon from '@components/compass_icon'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import CustomList from '@components/custom_list'; import ChannelListRow from '@components/custom_list/channel_list_row'; import FormattedText from '@components/formatted_text'; @@ -22,6 +18,9 @@ import Loading from '@components/loading'; import SearchBar from '@components/search_bar'; import StatusBar from '@components/status_bar'; import {NavigationTypes} from '@constants'; +import {debounce} from '@mm-redux/actions/helpers'; +import {General} from '@mm-redux/constants'; +import EventEmitter from '@mm-redux/utils/event_emitter'; import {alertErrorWithFallback, emptyFunction} from '@utils/general'; import BottomSheet from '@utils/bottom_sheet'; import { @@ -48,7 +47,6 @@ export default class MoreChannels extends PureComponent { currentUserId: PropTypes.string.isRequired, currentTeamId: PropTypes.string.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, canShowArchivedChannels: PropTypes.bool.isRequired, }; @@ -409,7 +407,7 @@ export default class MoreChannels extends PureComponent { render() { const {formatMessage} = this.context.intl; - const {theme, isLandscape, canShowArchivedChannels} = this.props; + const {theme, canShowArchivedChannels} = this.props; const {adding, channels, archivedChannels, loading, term, typeOfChannels} = this.state; const more = term ? emptyFunction : this.getChannels; const style = getStyleFromTheme(theme); @@ -436,7 +434,7 @@ export default class MoreChannels extends PureComponent { let channelDropdown; if (canShowArchivedChannels) { channelDropdown = ( - + + <> - - - + {channelDropdown} - + ); } return ( - - - {content} - + + + + {content} + + ); } } const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { return { + container: { + flex: 1, + }, searchBar: { marginVertical: 5, height: 38, - ...Platform.select({ - ios: { - paddingLeft: 8, - }, - }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/more_channels/more_channels.test.js b/app/screens/more_channels/more_channels.test.js index 4195168a9..99ef8a70d 100644 --- a/app/screens/more_channels/more_channels.test.js +++ b/app/screens/more_channels/more_channels.test.js @@ -32,7 +32,6 @@ describe('MoreChannels', () => { currentTeamId: 'current_team_id', theme: Preferences.THEMES.default, componentId: 'component-id', - isLandscape: false, canShowArchivedChannels: true, }; diff --git a/app/screens/more_dms/index.js b/app/screens/more_dms/index.js index 272626d51..5475c18e6 100644 --- a/app/screens/more_dms/index.js +++ b/app/screens/more_dms/index.js @@ -4,16 +4,14 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; -import {setChannelDisplayName} from 'app/actions/views/channel'; -import {makeDirectChannel, makeGroupChannel} from 'app/actions/views/more_dms'; -import {isLandscape} from 'app/selectors/device'; +import {setChannelDisplayName} from '@actions/views/channel'; +import {makeDirectChannel, makeGroupChannel} from '@actions/views/more_dms'; import {getProfiles, getProfilesInTeam, searchProfiles} from '@mm-redux/actions/users'; import {General} from '@mm-redux/constants'; import {getConfig} from '@mm-redux/selectors/entities/general'; import {getTeammateNameDisplaySetting, getTheme} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; import {getCurrentUserId, getUsers, getCurrentUser} from '@mm-redux/selectors/entities/users'; - import {isGuest} from '@utils/users'; import MoreDirectMessages from './more_dms'; @@ -32,7 +30,6 @@ function mapStateToProps(state) { currentUserId: getCurrentUserId(state), isGuest: isGuest(currentUser), currentTeamId: getCurrentTeamId(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/more_dms/more_dms.js b/app/screens/more_dms/more_dms.js index d9475693b..c06867868 100644 --- a/app/screens/more_dms/more_dms.js +++ b/app/screens/more_dms/more_dms.js @@ -4,33 +4,32 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {intlShape} from 'react-intl'; -import {Keyboard, Platform, View} from 'react-native'; +import {Keyboard, View} from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; +import {dismissModal, setButtons} from '@actions/navigation'; +import CustomList, {FLATLIST, SECTIONLIST} from '@components/custom_list'; +import UserListRow from '@components/custom_list/user_list_row'; +import FormattedText from '@components/formatted_text'; +import KeyboardLayout from '@components/layout/keyboard_layout'; +import Loading from '@components/loading'; +import SearchBar from '@components/search_bar'; +import StatusBar from '@components/status_bar'; +import {NavigationTypes} from '@constants'; import {debounce} from '@mm-redux/actions/helpers'; import {General} from '@mm-redux/constants'; import EventEmitter from '@mm-redux/utils/event_emitter'; import {getGroupDisplayNameFromUserIds} from '@mm-redux/utils/channel_utils'; import {displayUsername, filterProfilesMatchingTerm} from '@mm-redux/utils/user_utils'; - -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; -import CustomList, {FLATLIST, SECTIONLIST} from 'app/components/custom_list'; -import UserListRow from 'app/components/custom_list/user_list_row'; -import FormattedText from 'app/components/formatted_text'; -import KeyboardLayout from 'app/components/layout/keyboard_layout'; -import Loading from 'app/components/loading'; -import SearchBar from 'app/components/search_bar'; -import StatusBar from 'app/components/status_bar'; -import {NavigationTypes} from 'app/constants'; -import {alertErrorWithFallback} from 'app/utils/general'; -import {createProfilesSections, loadingText} from 'app/utils/member_list'; +import {alertErrorWithFallback} from '@utils/general'; +import {t} from '@utils/i18n'; +import {createProfilesSections, loadingText} from '@utils/member_list'; import { changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; -import {t} from 'app/utils/i18n'; -import {dismissModal, setButtons} from 'app/actions/navigation'; +} from '@utils/theme'; import SelectedUsers from './selected_users'; @@ -56,7 +55,6 @@ export default class MoreDirectMessages extends PureComponent { restrictDirectMessage: PropTypes.bool.isRequired, teammateNameDisplay: PropTypes.string, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -414,7 +412,7 @@ export default class MoreDirectMessages extends PureComponent { render() { const {formatMessage} = this.context.intl; - const {isGuest, currentUserId, theme, isLandscape} = this.props; + const {isGuest, currentUserId, theme} = this.props; const { loading, profiles, @@ -477,10 +475,10 @@ export default class MoreDirectMessages extends PureComponent { } return ( - - - - + + + + - - - - + + + + ); } } @@ -535,11 +532,6 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { searchBar: { marginVertical: 5, height: 38, - ...Platform.select({ - ios: { - paddingLeft: 8, - }, - }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/options_modal/__snapshots__/options_modal_list.test.js.snap b/app/screens/options_modal/__snapshots__/options_modal_list.test.js.snap index 24d8456c9..bbd313281 100644 --- a/app/screens/options_modal/__snapshots__/options_modal_list.test.js.snap +++ b/app/screens/options_modal/__snapshots__/options_modal_list.test.js.snap @@ -141,24 +141,18 @@ exports[`OptionModalList should match snapshot for Android 1`] = ` exports[`OptionModalList should match snapshot for iOS 1`] = ` @@ -166,161 +160,179 @@ exports[`OptionModalList should match snapshot for iOS 1`] = ` style={ Array [ Object { - "alignItems": "center", "alignSelf": "stretch", - "flexDirection": "row", - "justifyContent": "space-between", - "padding": 15, - }, - Object { - "borderBottomColor": "rgba(0, 0, 0, 0.1)", - "borderBottomWidth": 1, + "backgroundColor": "white", + "borderRadius": 12, + "marginBottom": 20, + "marginHorizontal": 20, }, ] } > - - test - - - - - - - - - - + test + + + - - -
+ > + + +
+
+ + + + + +
-
- - - - + > + +
+
`; diff --git a/app/screens/options_modal/index.js b/app/screens/options_modal/index.js index acecbd45a..0c73b392b 100644 --- a/app/screens/options_modal/index.js +++ b/app/screens/options_modal/index.js @@ -3,14 +3,13 @@ import {connect} from 'react-redux'; -import {getDimensions, isLandscape} from 'app/selectors/device'; +import {getDimensions} from 'app/selectors/device'; import OptionsModal from './options_modal'; function mapStateToProps(state) { return { ...getDimensions(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/options_modal/options_modal.js b/app/screens/options_modal/options_modal.js index 69d5357f4..09a7ce52c 100644 --- a/app/screens/options_modal/options_modal.js +++ b/app/screens/options_modal/options_modal.js @@ -32,7 +32,6 @@ export default class OptionsModal extends PureComponent { PropTypes.string, PropTypes.object, ]), - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -87,7 +86,6 @@ export default class OptionsModal extends PureComponent { const { items, title, - isLandscape, } = this.props; return ( @@ -99,7 +97,6 @@ export default class OptionsModal extends PureComponent { onCancelPress={this.handleCancel} onItemPress={this.onItemPress} title={title} - isLandscape={isLandscape} />
diff --git a/app/screens/options_modal/options_modal_list.ios.js b/app/screens/options_modal/options_modal_list.ios.js index d2cdea439..abd53c027 100644 --- a/app/screens/options_modal/options_modal_list.ios.js +++ b/app/screens/options_modal/options_modal_list.ios.js @@ -11,7 +11,6 @@ import { } from 'react-native'; import CompassIcon from '@components/compass_icon'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import FormattedText from '@components/formatted_text'; import {preventDoubleTap} from '@utils/tap'; @@ -24,7 +23,6 @@ export default class OptionsModalList extends PureComponent { PropTypes.string, PropTypes.object, ]), - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -121,21 +119,23 @@ export default class OptionsModalList extends PureComponent { render() { return ( - - - {this.renderOptions()} - - - - - + + + + {this.renderOptions()} + + + + + + ); @@ -149,6 +149,7 @@ const style = StyleSheet.create({ flexDirection: 'row', justifyContent: 'space-between', padding: 15, + width: '100%', }, optionBorder: { borderBottomWidth: 1, @@ -180,9 +181,13 @@ const style = StyleSheet.create({ flex: 1, textAlign: 'center', }, - wrapper: { + container: { flex: 1, alignItems: 'center', justifyContent: 'flex-end', }, + wrapper: { + maxWidth: 450, + width: '100%', + }, }); diff --git a/app/screens/options_modal/options_modal_list.test.js b/app/screens/options_modal/options_modal_list.test.js index 6add24151..703558226 100644 --- a/app/screens/options_modal/options_modal_list.test.js +++ b/app/screens/options_modal/options_modal_list.test.js @@ -25,7 +25,6 @@ describe('OptionModalList', () => { }], onCancelPress: jest.fn(), title: 'test', - isLandscape: false, }; test('should match snapshot for iOS', async () => { diff --git a/app/screens/permalink/__snapshots__/permalink.test.js.snap b/app/screens/permalink/__snapshots__/permalink.test.js.snap index 3f5ed920c..421f18d03 100644 --- a/app/screens/permalink/__snapshots__/permalink.test.js.snap +++ b/app/screens/permalink/__snapshots__/permalink.test.js.snap @@ -1,20 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Permalink should match snapshot 1`] = ` - - + `; exports[`Permalink should match snapshot 2`] = ` diff --git a/app/screens/permalink/index.js b/app/screens/permalink/index.js index f54da2e0b..fe2f0f156 100644 --- a/app/screens/permalink/index.js +++ b/app/screens/permalink/index.js @@ -14,7 +14,6 @@ import {makeGetPostIdsAroundPost, getPost} from '@mm-redux/selectors/entities/po import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; import {getCurrentUserId} from '@mm-redux/selectors/entities/users'; -import {isLandscape} from '@selectors/device'; import Permalink from './permalink'; @@ -48,7 +47,6 @@ function makeMapStateToProps() { myMembers: getMyChannelMemberships(state), postIds, theme: getTheme(state), - isLandscape: isLandscape(state), }; }; } diff --git a/app/screens/permalink/permalink.js b/app/screens/permalink/permalink.js index 7ebbca941..beba8ccb7 100644 --- a/app/screens/permalink/permalink.js +++ b/app/screens/permalink/permalink.js @@ -26,7 +26,6 @@ import Loading from '@components/loading'; import PostList from '@components/post_list'; import PostListRetry from '@components/post_list_retry'; import SafeAreaView from '@components/safe_area_view'; -import {marginHorizontal as margin} from '@components/safe_area_view/iphone_x_spacing'; import {General} from '@mm-redux/constants'; import EventEmitter from '@mm-redux/utils/event_emitter'; import {getLastPostIndex} from '@mm-redux/utils/post_list'; @@ -73,7 +72,6 @@ export default class Permalink extends PureComponent { onClose: PropTypes.func, postIds: PropTypes.array, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, error: PropTypes.string, }; @@ -287,7 +285,7 @@ export default class Permalink extends PureComponent { }; render() { - const {channelName, currentUserId, focusedPostId, isLandscape, postIds, theme} = this.props; + const {channelName, currentUserId, focusedPostId, postIds, theme} = this.props; const {error, loading, retry, title} = this.state; const style = getStyleSheet(theme); @@ -335,7 +333,7 @@ export default class Permalink extends PureComponent { footerColor='transparent' > { postIds: ['post_id_1', 'focused_post_id', 'post_id_3'], theme: Preferences.THEMES.default, componentId: 'component-id', - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/pinned_posts/__snapshots__/pinned_posts.test.js.snap b/app/screens/pinned_posts/__snapshots__/pinned_posts.test.js.snap index c0725051c..508af3d6c 100644 --- a/app/screens/pinned_posts/__snapshots__/pinned_posts.test.js.snap +++ b/app/screens/pinned_posts/__snapshots__/pinned_posts.test.js.snap @@ -1,7 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`PinnedPosts should match snapshot 1`] = ` - - + `; exports[`PinnedPosts should match snapshot when component waiting for response 1`] = ` - - + `; exports[`PinnedPosts should match snapshot when getPinnedPosts failed 1`] = ` - - + `; diff --git a/app/screens/pinned_posts/pinned_posts.js b/app/screens/pinned_posts/pinned_posts.js index fafde3eae..13ad2a5cc 100644 --- a/app/screens/pinned_posts/pinned_posts.js +++ b/app/screens/pinned_posts/pinned_posts.js @@ -9,9 +9,9 @@ import { Keyboard, FlatList, StyleSheet, - View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {dismissModal, goToScreen, showSearchModal} from '@actions/navigation'; import ChannelLoader from '@components/channel_loader'; @@ -223,10 +223,13 @@ export default class PinnedPosts extends PureComponent { } return ( - + {component} - + ); } } diff --git a/app/screens/post_options/__snapshots__/post_options.test.js.snap b/app/screens/post_options/__snapshots__/post_options.test.js.snap index 72b6f5059..bf255a1d0 100644 --- a/app/screens/post_options/__snapshots__/post_options.test.js.snap +++ b/app/screens/post_options/__snapshots__/post_options.test.js.snap @@ -52,7 +52,6 @@ exports[`PostOptions should match snapshot, no option for system message to user diff --git a/app/screens/post_options/post_options.js b/app/screens/post_options/post_options.js index f69e24a2f..ed835b9e5 100644 --- a/app/screens/post_options/post_options.js +++ b/app/screens/post_options/post_options.js @@ -49,7 +49,6 @@ export default class PostOptions extends PureComponent { isFlagged: PropTypes.bool, post: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -74,7 +73,7 @@ export default class PostOptions extends PureComponent { getOption = (key, icon, message, onPress, destructive = false) => { const {formatMessage} = this.context.intl; - const {isLandscape, theme} = this.props; + const {theme} = this.props; const testID = `post.options.${key}.action`; return ( @@ -84,7 +83,6 @@ export default class PostOptions extends PureComponent { icon={icon} text={formatMessage(message)} onPress={onPress} - isLandscape={isLandscape} destructive={destructive} theme={theme} /> @@ -218,7 +216,7 @@ export default class PostOptions extends PureComponent { }; getMarkAsUnreadOption = () => { - const {post, isLandscape, theme} = this.props; + const {post, theme} = this.props; const {formatMessage} = this.context.intl; if (!isSystemMessage(post) && this.props.canMarkAsUnread) { @@ -229,7 +227,6 @@ export default class PostOptions extends PureComponent { icon='mark-as-unread' text={formatMessage({id: 'mobile.post_info.mark_unread', defaultMessage: 'Mark as Unread'})} onPress={this.handleMarkUnread} - isLandscape={isLandscape} theme={theme} /> ); diff --git a/app/screens/post_options/post_options.test.js b/app/screens/post_options/post_options.test.js index 87f47eb7e..724854887 100644 --- a/app/screens/post_options/post_options.test.js +++ b/app/screens/post_options/post_options.test.js @@ -51,7 +51,6 @@ describe('PostOptions', () => { post, showAddReaction: true, theme: Preferences.THEMES.default, - isLandscape: false, }; function getWrapper(props = {}) { diff --git a/app/screens/reaction_list/__snapshots__/reaction_header.test.js.snap b/app/screens/reaction_list/__snapshots__/reaction_header.test.js.snap index a833dc8d3..c5683ef9d 100644 --- a/app/screens/reaction_list/__snapshots__/reaction_header.test.js.snap +++ b/app/screens/reaction_list/__snapshots__/reaction_header.test.js.snap @@ -9,7 +9,9 @@ exports[`ReactionHeader should match snapshot 1`] = ` "borderTopLeftRadius": 10, "borderTopRightRadius": 10, "height": 36.5, + "maxWidth": 450, "paddingHorizontal": 0, + "width": "100%", } } > @@ -17,7 +19,6 @@ exports[`ReactionHeader should match snapshot 1`] = ` alwaysBounceHorizontal={false} horizontal={true} overScrollMode="never" - style={null} > - - - - { @@ -57,7 +55,6 @@ export default class ReactionHeader extends PureComponent { alwaysBounceHorizontal={false} horizontal={true} overScrollMode='never' - style={padding(this.props.isLandscape, -10)} > {this.renderReactionHeaderItems()} @@ -73,6 +70,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { backgroundColor: theme.centerChannelBg, height: 36.5, paddingHorizontal: 0, + width: '100%', + maxWidth: 450, ...Platform.select({ android: { borderTopRightRadius: 2, diff --git a/app/screens/reaction_list/reaction_header.test.js b/app/screens/reaction_list/reaction_header.test.js index c50fecf75..175ec2d76 100644 --- a/app/screens/reaction_list/reaction_header.test.js +++ b/app/screens/reaction_list/reaction_header.test.js @@ -14,7 +14,6 @@ describe('ReactionHeader', () => { onSelectReaction: jest.fn(), reactions: [{name: 'smile', count: 2}, {name: '+1', count: 1}], theme: Preferences.THEMES.default, - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/reaction_list/reaction_list.js b/app/screens/reaction_list/reaction_list.js index 726b86e34..a9b91d3a4 100644 --- a/app/screens/reaction_list/reaction_list.js +++ b/app/screens/reaction_list/reaction_list.js @@ -30,11 +30,11 @@ export default class ReactionList extends PureComponent { actions: PropTypes.shape({ getMissingProfilesByIds: PropTypes.func.isRequired, }).isRequired, + isLandscape: PropTypes.bool, reactions: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, teammateNameDisplay: PropTypes.string, userProfiles: PropTypes.array, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -165,7 +165,7 @@ export default class ReactionList extends PureComponent { }; renderHeader = (forwardedRef) => { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const {selected, sortedReactionsForHeader} = this.state; return ( @@ -175,13 +175,12 @@ export default class ReactionList extends PureComponent { reactions={sortedReactionsForHeader} theme={theme} forwardedRef={forwardedRef} - isLandscape={isLandscape} /> ); }; render() { - const {theme} = this.props; + const {isLandscape, theme} = this.props; const style = getStyleSheet(theme); return ( @@ -192,6 +191,7 @@ export default class ReactionList extends PureComponent { initialPosition={0.55} header={this.renderHeader} headerHeight={37.5} + key={`landscape-${isLandscape}`} theme={theme} > {this.renderReactionRows()} diff --git a/app/screens/reaction_list/reaction_row/__snapshots__/reaction_row.test.js.snap b/app/screens/reaction_list/reaction_row/__snapshots__/reaction_row.test.js.snap index 6a46253aa..13056447b 100644 --- a/app/screens/reaction_list/reaction_row/__snapshots__/reaction_row.test.js.snap +++ b/app/screens/reaction_list/reaction_row/__snapshots__/reaction_row.test.js.snap @@ -14,13 +14,10 @@ exports[`ReactionRow should match snapshot, renderContent 1`] = ` > { + const {user, theme} = this.props; + const {formatMessage} = this.context.intl; + const screen = 'UserProfile'; + const title = formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'}); + const passProps = { + userId: user.id, + }; + + if (!this.closeButton) { + this.closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor); + } + + const options = { + topBar: { + leftButtons: [{ + id: 'close-settings', + icon: this.closeButton, + }], + }, + }; + + showModal(screen, title, passProps, options); + }; + + render() { + const { + emojiName, + teammateNameDisplay, + user, + theme, + } = this.props; + + if (!user.id) { + return null; + } + + const {id, username} = user; + const usernameDisplay = '@' + username; + + const style = getStyleSheet(theme); + + return ( + + + + + + + + + + + {usernameDisplay} + + {' '} + + {displayUsername(user, teammateNameDisplay)} + + + + + + + ); + } } -export default connect(mapStateToProps)(ReactionRow); +const getStyleSheet = makeStyleSheetFromTheme((theme) => { + return { + container: { + flexDirection: 'row', + justifyContent: 'flex-start', + height: 44, + width: '100%', + alignItems: 'center', + }, + profileContainer: { + alignItems: 'center', + width: '13%', + }, + profile: { + paddingTop: 3, + }, + textContainer: { + width: '74%', + flexDirection: 'row', + }, + username: { + fontSize: 14, + paddingRight: 5, + color: theme.centerChannelColor, + }, + displayName: { + fontSize: 14, + color: changeOpacity(theme.centerChannelColor, 0.5), + }, + emoji: { + alignItems: 'center', + width: '13%', + justifyContent: 'center', + }, + emojiText: { + color: '#000', + fontWeight: 'bold', + }, + }; +}); diff --git a/app/screens/reaction_list/reaction_row/reaction_row.js b/app/screens/reaction_list/reaction_row/reaction_row.js deleted file mode 100644 index e9a465620..000000000 --- a/app/screens/reaction_list/reaction_row/reaction_row.js +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React from 'react'; -import PropTypes from 'prop-types'; -import {intlShape} from 'react-intl'; -import { - Text, - TouchableOpacity, - View, -} from 'react-native'; - -import {displayUsername} from '@mm-redux/utils/user_utils'; - -import {showModal} from '@actions/navigation'; -import CompassIcon from '@components/compass_icon'; -import ProfilePicture from '@components/profile_picture'; -import Emoji from '@components/emoji'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; -import {preventDoubleTap} from '@utils/tap'; -import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; - -export default class ReactionRow extends React.PureComponent { - static propTypes = { - emojiName: PropTypes.string.isRequired, - teammateNameDisplay: PropTypes.string.isRequired, - theme: PropTypes.object.isRequired, - user: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, - }; - - static defaultProps = { - user: {}, - }; - - static contextTypes = { - intl: intlShape, - }; - - goToUserProfile = async () => { - const {user, theme} = this.props; - const {formatMessage} = this.context.intl; - const screen = 'UserProfile'; - const title = formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'}); - const passProps = { - userId: user.id, - }; - - if (!this.closeButton) { - this.closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor); - } - - const options = { - topBar: { - leftButtons: [{ - id: 'close-settings', - icon: this.closeButton, - }], - }, - }; - - showModal(screen, title, passProps, options); - }; - - render() { - const { - emojiName, - teammateNameDisplay, - user, - isLandscape, - theme, - } = this.props; - - if (!user.id) { - return null; - } - - const {id, username} = user; - const usernameDisplay = '@' + username; - - const style = getStyleSheet(theme); - - return ( - - - - - - - - - - - {usernameDisplay} - - {' '} - - {displayUsername(user, teammateNameDisplay)} - - - - - - - ); - } -} - -const getStyleSheet = makeStyleSheetFromTheme((theme) => { - return { - container: { - flexDirection: 'row', - justifyContent: 'flex-start', - height: 44, - width: '100%', - alignItems: 'center', - }, - profileContainer: { - alignItems: 'center', - width: '13%', - }, - profile: { - paddingTop: 3, - }, - textContainer: { - width: '74%', - flexDirection: 'row', - }, - username: { - fontSize: 14, - paddingRight: 5, - color: theme.centerChannelColor, - }, - displayName: { - fontSize: 14, - color: changeOpacity(theme.centerChannelColor, 0.5), - }, - emoji: { - alignItems: 'center', - width: '13%', - justifyContent: 'center', - }, - emojiText: { - color: '#000', - fontWeight: 'bold', - }, - }; -}); diff --git a/app/screens/reaction_list/reaction_row/reaction_row.test.js b/app/screens/reaction_list/reaction_row/reaction_row.test.js index d8ccd9f84..ba705fe2a 100644 --- a/app/screens/reaction_list/reaction_row/reaction_row.test.js +++ b/app/screens/reaction_list/reaction_row/reaction_row.test.js @@ -5,7 +5,7 @@ import {shallow} from 'enzyme'; import Preferences from '@mm-redux/constants/preferences'; -import ReactionRow from './reaction_row'; +import ReactionRow from './index'; describe('ReactionRow', () => { const baseProps = { @@ -13,7 +13,6 @@ describe('ReactionRow', () => { teammateNameDisplay: 'username', theme: Preferences.THEMES.default, user: {id: 'user_id', username: 'username'}, - isLandscape: false, }; test('should match snapshot, renderContent', () => { diff --git a/app/screens/recent_mentions/__snapshots__/recent_mentions.test.js.snap b/app/screens/recent_mentions/__snapshots__/recent_mentions.test.js.snap index 72c7170c8..9daf267d7 100644 --- a/app/screens/recent_mentions/__snapshots__/recent_mentions.test.js.snap +++ b/app/screens/recent_mentions/__snapshots__/recent_mentions.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`RecentMentions should match snapshot 1`] = ` - - + `; exports[`RecentMentions should match snapshot when component waiting for response 1`] = ` - - + `; exports[`RecentMentions should match snapshot when getRecentMentions failed 1`] = ` - - + `; diff --git a/app/screens/recent_mentions/recent_mentions.js b/app/screens/recent_mentions/recent_mentions.js index c57c73eb9..41e0c9e76 100644 --- a/app/screens/recent_mentions/recent_mentions.js +++ b/app/screens/recent_mentions/recent_mentions.js @@ -12,6 +12,7 @@ import { View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {dismissModal, goToScreen, showSearchModal} from '@actions/navigation'; import ChannelLoader from '@components/channel_loader'; @@ -222,13 +223,13 @@ export default class RecentMentions extends PureComponent { } return ( - {component} - + ); } } diff --git a/app/screens/flagged_posts/__snapshots__/flagged_posts.test.js.snap b/app/screens/saved_posts/__snapshots__/saved_posts.test.js.snap similarity index 81% rename from app/screens/flagged_posts/__snapshots__/flagged_posts.test.js.snap rename to app/screens/saved_posts/__snapshots__/saved_posts.test.js.snap index b6efda175..7de6e8f4f 100644 --- a/app/screens/flagged_posts/__snapshots__/flagged_posts.test.js.snap +++ b/app/screens/saved_posts/__snapshots__/saved_posts.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`FlaggedPosts should match snapshot 1`] = ` - - + `; -exports[`FlaggedPosts should match snapshot when component waiting for response 1`] = ` - - + `; -exports[`FlaggedPosts should match snapshot when getFlaggedPosts failed 1`] = ` - - + `; diff --git a/app/screens/flagged_posts/index.js b/app/screens/saved_posts/index.js similarity index 95% rename from app/screens/flagged_posts/index.js rename to app/screens/saved_posts/index.js index 9f4eb060e..90b5be9b6 100644 --- a/app/screens/flagged_posts/index.js +++ b/app/screens/saved_posts/index.js @@ -11,7 +11,7 @@ import {clearSearch, getFlaggedPosts} from '@mm-redux/actions/search'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {makePreparePostIdsForSearchPosts} from '@selectors/post_list'; -import FlaggedPosts from './flagged_posts'; +import SavedPosts from './saved_posts'; function makeMapStateToProps() { const preparePostIds = makePreparePostIdsForSearchPosts(); @@ -37,4 +37,4 @@ function mapDispatchToProps(dispatch) { }; } -export default connect(makeMapStateToProps, mapDispatchToProps)(FlaggedPosts); +export default connect(makeMapStateToProps, mapDispatchToProps)(SavedPosts); diff --git a/app/screens/flagged_posts/flagged_posts.js b/app/screens/saved_posts/saved_posts.js similarity index 97% rename from app/screens/flagged_posts/flagged_posts.js rename to app/screens/saved_posts/saved_posts.js index d61f86657..34ac5c0f8 100644 --- a/app/screens/flagged_posts/flagged_posts.js +++ b/app/screens/saved_posts/saved_posts.js @@ -12,6 +12,7 @@ import { View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {dismissModal, goToScreen, showSearchModal} from '@actions/navigation'; import ChannelLoader from '@components/channel_loader'; @@ -25,7 +26,7 @@ import SearchResultPost from '@screens/search/search_result_post'; import ChannelDisplayName from '@screens/search/channel_display_name'; import mattermostManaged from 'app/mattermost_managed'; -export default class FlaggedPosts extends PureComponent { +export default class SavedPosts extends PureComponent { static propTypes = { actions: PropTypes.shape({ clearSearch: PropTypes.func.isRequired, @@ -227,10 +228,10 @@ export default class FlaggedPosts extends PureComponent { } return ( - + {component} - + ); } } diff --git a/app/screens/flagged_posts/flagged_posts.test.js b/app/screens/saved_posts/saved_posts.test.js similarity index 92% rename from app/screens/flagged_posts/flagged_posts.test.js rename to app/screens/saved_posts/saved_posts.test.js index ddcb6952a..ec065d3bc 100644 --- a/app/screens/flagged_posts/flagged_posts.test.js +++ b/app/screens/saved_posts/saved_posts.test.js @@ -8,9 +8,9 @@ import Preferences from '@mm-redux/constants/preferences'; import * as NavigationActions from 'app/actions/navigation'; import {shallowWithIntl} from 'test/intl-test-helper'; -import FlaggedPosts from './flagged_posts'; +import SavedPosts from './saved_posts'; -describe('FlaggedPosts', () => { +describe('SavedPosts', () => { const baseProps = { actions: { clearSearch: jest.fn(), @@ -24,7 +24,7 @@ describe('FlaggedPosts', () => { test('should match snapshot', () => { const wrapper = shallowWithIntl( - , + , ); expect(wrapper.getElement()).toMatchSnapshot(); @@ -41,7 +41,7 @@ describe('FlaggedPosts', () => { }, }; const wrapper = shallowWithIntl( - , + , ); await wrapper.instance().getFlaggedPosts(); @@ -60,7 +60,7 @@ describe('FlaggedPosts', () => { }, }; const wrapper = shallowWithIntl( - , + , ); wrapper.instance().getFlaggedPosts(); @@ -75,7 +75,7 @@ describe('FlaggedPosts', () => { const hashtag = 'test'; const wrapper = shallowWithIntl( - , + , ); dismissModal.mockImplementation(async () => { diff --git a/app/screens/search/__snapshots__/modifier.test.js.snap b/app/screens/search/__snapshots__/modifier.test.js.snap index f11ec63ba..d5e1afac0 100644 --- a/app/screens/search/__snapshots__/modifier.test.js.snap +++ b/app/screens/search/__snapshots__/modifier.test.js.snap @@ -17,14 +17,11 @@ exports[`Search RecentItem should match snapshot and respond to events 1`] = ` > {displayName} + {displayName} ); } } diff --git a/app/screens/search/channel_display_name/index.js b/app/screens/search/channel_display_name/index.js index 18de26c16..781b3e073 100644 --- a/app/screens/search/channel_display_name/index.js +++ b/app/screens/search/channel_display_name/index.js @@ -6,7 +6,6 @@ import {connect} from 'react-redux'; import {makeGetChannel} from '@mm-redux/selectors/entities/channels'; import {getPost} from '@mm-redux/selectors/entities/posts'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import ChannelDisplayName from './channel_display_name'; function makeMapStateToProps() { @@ -18,7 +17,6 @@ function makeMapStateToProps() { return { displayName: channel ? channel.display_name : '', theme: getTheme(state), - isLandscape: isLandscape(state), }; }; } diff --git a/app/screens/search/index.js b/app/screens/search/index.js index ad2412336..fb6ac9b2a 100644 --- a/app/screens/search/index.js +++ b/app/screens/search/index.js @@ -17,7 +17,6 @@ import {isTimezoneEnabled} from '@mm-redux/selectors/entities/timezone'; import {isMinimumServerVersion} from '@mm-redux/utils/helpers'; import {getUserCurrentTimezone} from '@mm-redux/utils/timezone_utils'; import {getCurrentUser} from '@mm-redux/selectors/entities/users'; -import {isLandscape} from '@selectors/device'; import {makePreparePostIdsForSearchPosts} from '@selectors/post_list'; import {getDeviceUtcOffset, getUtcOffsetForTimeZone} from '@utils/timezone'; @@ -57,7 +56,6 @@ function makeMapStateToProps() { return { currentTeamId, currentChannelId, - isLandscape: isLandscape(state), postIds, archivedPostIds, recent: recent[currentTeamId], diff --git a/app/screens/search/modifier.js b/app/screens/search/modifier.js index 2609053cb..88c02aa29 100644 --- a/app/screens/search/modifier.js +++ b/app/screens/search/modifier.js @@ -5,7 +5,6 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {Text, TouchableHighlight, View} from 'react-native'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; export const MODIFIER_LABEL_HEIGHT = 68; @@ -15,11 +14,6 @@ export default class Modifier extends PureComponent { item: PropTypes.object.isRequired, setModifierValue: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, - }; - - static defaultProps = { - isLandscape: false, }; handlePress = () => { @@ -29,7 +23,7 @@ export default class Modifier extends PureComponent { }; render() { - const {item, theme, isLandscape} = this.props; + const {item, theme} = this.props; const style = getStyleFromTheme(theme); return ( @@ -42,7 +36,7 @@ export default class Modifier extends PureComponent { testID={item.testID} style={style.modifierItemContainer} > - + { @@ -36,7 +30,7 @@ export default class RecentItem extends PureComponent { }; render() { - const {item, theme, isLandscape} = this.props; + const {item, theme} = this.props; const style = getStyleFromTheme(theme); return ( @@ -46,7 +40,7 @@ export default class RecentItem extends PureComponent { onPress={this.handlePress} > { const recentLabelsHeight = recent.length * RECENT_LABEL_HEIGHT; @@ -380,20 +374,19 @@ export default class Search extends PureComponent { }; renderModifiers = ({item}) => { - const {theme, isLandscape} = this.props; + const {theme} = this.props; return ( ); }; renderPost = ({item, index}) => { - const {postIds, theme, isLandscape} = this.props; + const {postIds, theme} = this.props; const style = getStyleFromTheme(theme); if (item.id) { @@ -420,7 +413,7 @@ export default class Search extends PureComponent { } return ( - + {this.archivedIndicator(postIds[index], style)} { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const {title} = section; const style = getStyleFromTheme(theme); @@ -457,7 +450,7 @@ export default class Search extends PureComponent { return ( - + {title} @@ -469,7 +462,7 @@ export default class Search extends PureComponent { }; renderRecentItem = ({item}) => { - const {theme, isLandscape} = this.props; + const {theme} = this.props; return ( ); }; @@ -565,7 +557,6 @@ export default class Search extends PureComponent { render() { const { - isLandscape, postIds, theme, isSearchGettingMore, @@ -714,25 +705,14 @@ export default class Search extends PureComponent { fontSize: 15, }; - const paddingRes = padding(isLandscape); - if (paddingRes) { - // Without this the default paddingLeft in style.header - // overrides the paddingHorizontal value gotten from padding(isLandscape) - paddingRes.paddingLeft = null; - - if (isLandscape) { - paddingRes.paddingTop = 14; - } - } - return ( - - - - + + + + - + + + - - - + + + ); } } diff --git a/app/screens/search/search_result_post/index.js b/app/screens/search/search_result_post/index.js index 73582e5f1..71aa25f40 100644 --- a/app/screens/search/search_result_post/index.js +++ b/app/screens/search/search_result_post/index.js @@ -12,7 +12,7 @@ function mapStateToProps(state, ownProps) { const post = getPost(state, ownProps.postId); return { - isDeleted: post && post.state === Posts.POST_DELETED, + isDeleted: post?.state === Posts.POST_DELETED, }; } diff --git a/app/screens/search/search_result_post/search_result_post.js b/app/screens/search/search_result_post/search_result_post.js index 6092822ca..15c06cf50 100644 --- a/app/screens/search/search_result_post/search_result_post.js +++ b/app/screens/search/search_result_post/search_result_post.js @@ -4,7 +4,7 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; -import Post from 'app/components/post'; +import Post from '@components/post'; export default class SearchResultPost extends PureComponent { static propTypes = { diff --git a/app/screens/select_server/select_server.js b/app/screens/select_server/select_server.js index e3e1d4612..44c19f335 100644 --- a/app/screens/select_server/select_server.js +++ b/app/screens/select_server/select_server.js @@ -12,7 +12,6 @@ import { Keyboard, KeyboardAvoidingView, Platform, - SafeAreaView, StatusBar, StyleSheet, Text, @@ -21,6 +20,7 @@ import { View, } from 'react-native'; import Button from 'react-native-button'; +import {SafeAreaView} from 'react-native-safe-area-context'; import RNFetchBlob from 'rn-fetch-blob'; import merge from 'deepmerge'; import urlParse from 'url-parse'; diff --git a/app/screens/select_team/__snapshots__/select_team.test.js.snap b/app/screens/select_team/__snapshots__/select_team.test.js.snap index aa39d09dd..6f792a6b7 100644 --- a/app/screens/select_team/__snapshots__/select_team.test.js.snap +++ b/app/screens/select_team/__snapshots__/select_team.test.js.snap @@ -36,7 +36,7 @@ exports[`SelectTeam should match snapshot for fail of teams 1`] = ` `; exports[`SelectTeam should match snapshot for teams 1`] = ` - @@ -89,7 +86,6 @@ exports[`SelectTeam should match snapshot for teams 1`] = ` canRefresh={true} data={Array []} extraData={false} - isLandscape={false} listType="flat" loading={false} loadingComponent={ @@ -143,7 +139,7 @@ exports[`SelectTeam should match snapshot for teams 1`] = ` } } /> - + `; exports[`SelectTeam should match snapshot when user is a guest 1`] = ` diff --git a/app/screens/select_team/index.js b/app/screens/select_team/index.js index 664dc7bce..e7712518c 100644 --- a/app/screens/select_team/index.js +++ b/app/screens/select_team/index.js @@ -12,7 +12,6 @@ import {getCurrentUser} from '@mm-redux/selectors/entities/users'; import {logout} from 'app/actions/views/user'; import {handleTeamChange} from 'app/actions/views/select_team'; -import {isLandscape} from 'app/selectors/device'; import {isGuest} from 'app/utils/users'; import SelectTeam from './select_team.js'; @@ -25,7 +24,6 @@ function mapStateToProps(state) { return { currentUserId: currentUser && currentUser.id, currentUserIsGuest, - isLandscape: isLandscape(state), teamsRequest: state.requests.teams.getTeams, teams: getSortedJoinableTeams(state, locale), theme: getTheme(state), diff --git a/app/screens/select_team/select_team.js b/app/screens/select_team/select_team.js index 74f9d6aa2..305e946ca 100644 --- a/app/screens/select_team/select_team.js +++ b/app/screens/select_team/select_team.js @@ -11,6 +11,7 @@ import { View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {RequestStatus} from '@mm-redux/constants'; import EventEmitter from '@mm-redux/utils/event_emitter'; @@ -19,7 +20,6 @@ import FormattedText from 'app/components/formatted_text'; import Loading from 'app/components/loading'; import StatusBar from 'app/components/status_bar'; import CustomList from 'app/components/custom_list'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import TeamIcon from 'app/components/team_icon'; import {NavigationTypes} from 'app/constants'; import {resetToChannel, dismissModal} from 'app/actions/navigation'; @@ -44,7 +44,6 @@ export default class SelectTeam extends PureComponent { teams: PropTypes.array.isRequired, theme: PropTypes.object, teamsRequest: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -157,7 +156,7 @@ export default class SelectTeam extends PureComponent { } renderItem = ({item}) => { - const {currentUrl, theme, isLandscape} = this.props; + const {currentUrl, theme} = this.props; const style = getStyleFromTheme(theme); if (item.id === 'mobile.select_team.no_teams') { @@ -175,7 +174,7 @@ export default class SelectTeam extends PureComponent { } return ( - + this.onSelectTeam(item))} > @@ -209,7 +208,7 @@ export default class SelectTeam extends PureComponent { }; render() { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const {teams} = this.state; const style = getStyleFromTheme(theme); @@ -244,10 +243,10 @@ export default class SelectTeam extends PureComponent { } return ( - + - + - + ); } } @@ -300,7 +299,7 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, line: { backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), - width: '100%', + flex: 1, height: 1, }, footer: { diff --git a/app/screens/select_team/select_team.test.js b/app/screens/select_team/select_team.test.js index 8a42af1f0..f37bfb8cf 100644 --- a/app/screens/select_team/select_team.test.js +++ b/app/screens/select_team/select_team.test.js @@ -44,7 +44,6 @@ describe('SelectTeam', () => { status: RequestStatus.FAILURE, }, componentId: 'component-id', - isLandscape: false, serverVersion: '5.18', }; diff --git a/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap b/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap index 9568c2437..6487fab2e 100644 --- a/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap +++ b/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`SelectorScreen should match snapshot for channels 1`] = ` - - - - + } + keyboardAppearance="light" + keyboardShouldPersist={false} + keyboardType="default" + onBlur={[Function]} + onCancelButtonPress={[Function]} + onChangeText={[Function]} + onSearchButtonPress={[Function]} + onSelectionChange={[Function]} + placeholder="Search" + placeholderTextColor="rgba(61,60,64,0.5)" + returnKeyType="search" + searchBarRightMargin={0} + searchIconSize={24} + showArrow={false} + showCancel={true} + tintColorDelete="rgba(61,60,64,0.5)" + tintColorSearch="rgba(61,60,64,0.5)" + titleCancelColor="#3d3c40" + value="" + /> - + `; exports[`SelectorScreen should match snapshot for channels 2`] = ` - - - - + } + keyboardAppearance="light" + keyboardShouldPersist={false} + keyboardType="default" + onBlur={[Function]} + onCancelButtonPress={[Function]} + onChangeText={[Function]} + onSearchButtonPress={[Function]} + onSelectionChange={[Function]} + placeholder="Search" + placeholderTextColor="rgba(61,60,64,0.5)" + returnKeyType="search" + searchBarRightMargin={0} + searchIconSize={24} + showArrow={false} + showCancel={true} + tintColorDelete="rgba(61,60,64,0.5)" + tintColorSearch="rgba(61,60,64,0.5)" + titleCancelColor="#3d3c40" + value="" + /> - + `; exports[`SelectorScreen should match snapshot for explicit options 1`] = ` - - - - + } + keyboardAppearance="light" + keyboardShouldPersist={false} + keyboardType="default" + onBlur={[Function]} + onCancelButtonPress={[Function]} + onChangeText={[Function]} + onSearchButtonPress={[Function]} + onSelectionChange={[Function]} + placeholder="Search" + placeholderTextColor="rgba(61,60,64,0.5)" + returnKeyType="search" + searchBarRightMargin={0} + searchIconSize={24} + showArrow={false} + showCancel={true} + tintColorDelete="rgba(61,60,64,0.5)" + tintColorSearch="rgba(61,60,64,0.5)" + titleCancelColor="#3d3c40" + value="" + /> - + `; exports[`SelectorScreen should match snapshot for searching 1`] = ` - - - - + } + keyboardAppearance="light" + keyboardShouldPersist={false} + keyboardType="default" + onBlur={[Function]} + onCancelButtonPress={[Function]} + onChangeText={[Function]} + onSearchButtonPress={[Function]} + onSelectionChange={[Function]} + placeholder="Search" + placeholderTextColor="rgba(61,60,64,0.5)" + returnKeyType="search" + searchBarRightMargin={0} + searchIconSize={24} + showArrow={false} + showCancel={true} + tintColorDelete="rgba(61,60,64,0.5)" + tintColorSearch="rgba(61,60,64,0.5)" + titleCancelColor="#3d3c40" + value="name2" + /> - + `; exports[`SelectorScreen should match snapshot for users 1`] = ` - - - - + } + keyboardAppearance="light" + keyboardShouldPersist={false} + keyboardType="default" + onBlur={[Function]} + onCancelButtonPress={[Function]} + onChangeText={[Function]} + onSearchButtonPress={[Function]} + onSelectionChange={[Function]} + placeholder="Search" + placeholderTextColor="rgba(61,60,64,0.5)" + returnKeyType="search" + searchBarRightMargin={0} + searchIconSize={24} + showArrow={false} + showCancel={true} + tintColorDelete="rgba(61,60,64,0.5)" + tintColorSearch="rgba(61,60,64,0.5)" + titleCancelColor="#3d3c40" + value="" + /> - + `; exports[`SelectorScreen should match snapshot for users 2`] = ` - - - - + } + keyboardAppearance="light" + keyboardShouldPersist={false} + keyboardType="default" + onBlur={[Function]} + onCancelButtonPress={[Function]} + onChangeText={[Function]} + onSearchButtonPress={[Function]} + onSelectionChange={[Function]} + placeholder="Search" + placeholderTextColor="rgba(61,60,64,0.5)" + returnKeyType="search" + searchBarRightMargin={0} + searchIconSize={24} + showArrow={false} + showCancel={true} + tintColorDelete="rgba(61,60,64,0.5)" + tintColorSearch="rgba(61,60,64,0.5)" + titleCancelColor="#3d3c40" + value="" + /> - + `; diff --git a/app/screens/selector_screen/index.js b/app/screens/selector_screen/index.js index 6a282e6a7..c526698a0 100644 --- a/app/screens/selector_screen/index.js +++ b/app/screens/selector_screen/index.js @@ -8,7 +8,6 @@ import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getProfiles, searchProfiles} from '@mm-redux/actions/users'; import {getChannels, searchChannels} from '@mm-redux/actions/channels'; -import {isLandscape} from 'app/selectors/device'; import SelectorScreen from './selector_screen'; function mapStateToProps(state) { @@ -22,7 +21,6 @@ function mapStateToProps(state) { dataSource: menuAction.dataSource, onSelect: menuAction.onSelect, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/selector_screen/selector_screen.js b/app/screens/selector_screen/selector_screen.js index d919294d9..2d6290cf0 100644 --- a/app/screens/selector_screen/selector_screen.js +++ b/app/screens/selector_screen/selector_screen.js @@ -8,31 +8,29 @@ import { Platform, View, } from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; +import {popTopScreen} from '@actions/navigation'; +import CustomList, {FLATLIST, SECTIONLIST} from '@components/custom_list'; +import UserListRow from '@components/custom_list/user_list_row'; +import ChannelListRow from '@components/custom_list/channel_list_row'; +import OptionListRow from '@components/custom_list/option_list_row'; +import FormattedText from '@components/formatted_text'; +import SearchBar from '@components/search_bar'; +import StatusBar from '@components/status_bar'; +import {ViewTypes} from '@constants'; import {debounce} from '@mm-redux/actions/helpers'; import {General} from '@mm-redux/constants'; import {filterProfilesMatchingTerm} from '@mm-redux/utils/user_utils'; import {filterChannelsMatchingTerm} from '@mm-redux/utils/channel_utils'; import {memoizeResult} from '@mm-redux/utils/helpers'; - -import CustomList, {FLATLIST, SECTIONLIST} from 'app/components/custom_list'; -import UserListRow from 'app/components/custom_list/user_list_row'; -import ChannelListRow from 'app/components/custom_list/channel_list_row'; -import OptionListRow from 'app/components/custom_list/option_list_row'; -import FormattedText from 'app/components/formatted_text'; -import SearchBar from 'app/components/search_bar'; -import StatusBar from 'app/components/status_bar'; -import {ViewTypes} from 'app/constants'; -import {createProfilesSections, loadingText} from 'app/utils/member_list'; +import {t} from '@utils/i18n'; +import {createProfilesSections, loadingText} from '@utils/member_list'; import { changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; -import {t} from 'app/utils/i18n'; -import {popTopScreen} from 'app/actions/navigation'; - -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; +} from '@utils/theme'; export default class SelectorScreen extends PureComponent { static propTypes = { @@ -47,7 +45,6 @@ export default class SelectorScreen extends PureComponent { dataSource: PropTypes.string, onSelect: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -296,7 +293,7 @@ export default class SelectorScreen extends PureComponent { render() { const {formatMessage} = this.context.intl; - const {theme, dataSource, isLandscape} = this.props; + const {theme, dataSource} = this.props; const {loading, term} = this.state; const style = getStyleFromTheme(theme); @@ -318,29 +315,27 @@ export default class SelectorScreen extends PureComponent { const {data, listType} = this.getDataResults(); return ( - + - - - + - + ); } } diff --git a/app/screens/selector_screen/selector_screen.test.js b/app/screens/selector_screen/selector_screen.test.js index 3f4a5332e..e1a078dac 100644 --- a/app/screens/selector_screen/selector_screen.test.js +++ b/app/screens/selector_screen/selector_screen.test.js @@ -60,7 +60,6 @@ describe('SelectorScreen', () => { data: [{text: 'text', value: 'value'}], dataSource: null, theme: Preferences.THEMES.default, - isLandscape: false, }; beforeAll(() => { diff --git a/app/screens/settings/advanced_settings/advanced_settings.js b/app/screens/settings/advanced_settings/advanced_settings.js index 1e61c2e8a..7cd439e1d 100644 --- a/app/screens/settings/advanced_settings/advanced_settings.js +++ b/app/screens/settings/advanced_settings/advanced_settings.js @@ -12,6 +12,7 @@ import { Text, View, } from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import * as Sentry from '@sentry/react-native'; import {dismissAllModals} from '@actions/navigation'; @@ -31,7 +32,6 @@ class AdvancedSettings extends Component { }).isRequired, intl: intlShape.isRequired, theme: PropTypes.object, - isLandscape: PropTypes.bool.isRequired, }; state = { @@ -110,7 +110,7 @@ class AdvancedSettings extends Component { return null; } - const {theme, isLandscape} = this.props; + const {theme} = this.props; const style = getStyleSheet(theme); return ( @@ -122,7 +122,6 @@ class AdvancedSettings extends Component { separator={false} showArrow={false} theme={theme} - isLandscape={isLandscape} /> @@ -140,11 +138,14 @@ class AdvancedSettings extends Component { }; render() { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const style = getStyleSheet(theme); return ( - + {this.renderSentryDebugOptions()} - + ); } } diff --git a/app/screens/settings/advanced_settings/index.js b/app/screens/settings/advanced_settings/index.js index d65046800..c46329c7e 100644 --- a/app/screens/settings/advanced_settings/index.js +++ b/app/screens/settings/advanced_settings/index.js @@ -6,13 +6,11 @@ import {connect} from 'react-redux'; import {purgeOfflineStore} from 'app/actions/views/root'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import AdvancedSettings from './advanced_settings'; function mapStateToProps(state) { return { theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/clock_display/clock_display.ios.js b/app/screens/settings/clock_display/clock_display.ios.js index 02846c992..7994107b0 100644 --- a/app/screens/settings/clock_display/clock_display.ios.js +++ b/app/screens/settings/clock_display/clock_display.ios.js @@ -4,6 +4,7 @@ import React from 'react'; import { View, } from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import StatusBar from 'app/components/status_bar'; import Section from 'app/screens/settings/section'; @@ -17,12 +18,15 @@ import ClockDisplayBase from './clock_display_base'; export default class ClockDisplay extends ClockDisplayBase { render() { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const {newMilitaryTime} = this.state; const style = getStyleSheet(theme); return ( - +
-
+ ); } } diff --git a/app/screens/settings/clock_display/index.js b/app/screens/settings/clock_display/index.js index 7802ded45..9b77d66c6 100644 --- a/app/screens/settings/clock_display/index.js +++ b/app/screens/settings/clock_display/index.js @@ -8,7 +8,6 @@ import {getTheme, get as getPreference} from '@mm-redux/selectors/entities/prefe import {getCurrentUserId} from '@mm-redux/selectors/entities/users'; import {savePreferences} from '@mm-redux/actions/preferences'; import Preferences from '@mm-redux/constants/preferences'; -import {isLandscape} from 'app/selectors/device'; import ClockDisplay from './clock_display'; function mapStateToProps(state) { @@ -19,7 +18,6 @@ function mapStateToProps(state) { userId: currentUserId, theme: getTheme(state), militaryTime, - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/display_settings/__snapshots__/display_settings.test.js.snap b/app/screens/settings/display_settings/__snapshots__/display_settings.test.js.snap index 60c8566ec..45a182026 100644 --- a/app/screens/settings/display_settings/__snapshots__/display_settings.test.js.snap +++ b/app/screens/settings/display_settings/__snapshots__/display_settings.test.js.snap @@ -1,7 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`DisplaySettings should match snapshot 1`] = ` - -
+ `; exports[`DisplaySettings should match snapshot on Tablet devices 1`] = ` - -
+ `; diff --git a/app/screens/settings/display_settings/display_settings.js b/app/screens/settings/display_settings/display_settings.js index a496ed9b9..9ce52bd0c 100644 --- a/app/screens/settings/display_settings/display_settings.js +++ b/app/screens/settings/display_settings/display_settings.js @@ -5,21 +5,21 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {intlShape} from 'react-intl'; import {Platform, View} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; -import {DeviceTypes} from 'app/constants'; -import StatusBar from 'app/components/status_bar'; -import ClockDisplay from 'app/screens/settings/clock_display'; -import SettingsItem from 'app/screens/settings/settings_item'; -import {preventDoubleTap} from 'app/utils/tap'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import {goToScreen} from 'app/actions/navigation'; +import {goToScreen} from '@actions/navigation'; +import {DeviceTypes} from '@constants'; +import StatusBar from '@components/status_bar'; +import ClockDisplay from '@screens/settings/clock_display'; +import SettingsItem from '@screens/settings/settings_item'; +import {preventDoubleTap} from '@utils/tap'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; export default class DisplaySettings extends PureComponent { static propTypes = { theme: PropTypes.object.isRequired, enableTheme: PropTypes.bool.isRequired, enableTimezone: PropTypes.bool.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -73,7 +73,7 @@ export default class DisplaySettings extends PureComponent { }); render() { - const {theme, enableTimezone, enableTheme, isLandscape} = this.props; + const {theme, enableTimezone, enableTheme} = this.props; const {showClockDisplaySettings} = this.state; const style = getStyleSheet(theme); const showArrow = Platform.OS === 'ios'; @@ -101,7 +101,6 @@ export default class DisplaySettings extends PureComponent { separator={false} showArrow={showArrow} theme={theme} - isLandscape={isLandscape} /> ); } @@ -117,13 +116,15 @@ export default class DisplaySettings extends PureComponent { separator={true} showArrow={showArrow} theme={theme} - isLandscape={isLandscape} /> ); } return ( - + @@ -137,7 +138,6 @@ export default class DisplaySettings extends PureComponent { separator={true} showArrow={showArrow} theme={theme} - isLandscape={isLandscape} /> )} {timezoneOption} {clockDisplayModal} - + ); } } diff --git a/app/screens/settings/display_settings/display_settings.test.js b/app/screens/settings/display_settings/display_settings.test.js index b6670062c..ffa6f0ce7 100644 --- a/app/screens/settings/display_settings/display_settings.test.js +++ b/app/screens/settings/display_settings/display_settings.test.js @@ -19,7 +19,6 @@ describe('DisplaySettings', () => { enableTheme: false, enableTimezone: false, componentId: 'component-id', - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/settings/display_settings/index.js b/app/screens/settings/display_settings/index.js index 379a2e02d..8cd05387c 100644 --- a/app/screens/settings/display_settings/index.js +++ b/app/screens/settings/display_settings/index.js @@ -5,10 +5,8 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {isTimezoneEnabled} from '@mm-redux/selectors/entities/timezone'; - -import {getAllowedThemes} from 'app/selectors/theme'; -import {isThemeSwitchingEnabled} from 'app/utils/theme'; -import {isLandscape} from 'app/selectors/device'; +import {getAllowedThemes} from '@selectors/theme'; +import {isThemeSwitchingEnabled} from '@utils/theme'; import DisplaySettings from './display_settings'; function mapStateToProps(state) { @@ -19,7 +17,6 @@ function mapStateToProps(state) { enableTheme, enableTimezone, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/general/index.js b/app/screens/settings/general/index.js index b0b71a9b2..af0d4dffd 100644 --- a/app/screens/settings/general/index.js +++ b/app/screens/settings/general/index.js @@ -10,7 +10,6 @@ import {getJoinableTeams} from '@mm-redux/selectors/entities/teams'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {purgeOfflineStore} from 'app/actions/views/root'; -import {isLandscape} from 'app/selectors/device'; import {removeProtocol} from 'app/utils/url'; import Settings from './settings'; @@ -26,7 +25,6 @@ function mapStateToProps(state) { currentTeamId: state.entities.teams.currentTeamId, currentUrl: removeProtocol(getCurrentUrl(state)), joinableTeams: getJoinableTeams(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/general/settings.js b/app/screens/settings/general/settings.js index c61bbae53..41ff15f10 100644 --- a/app/screens/settings/general/settings.js +++ b/app/screens/settings/general/settings.js @@ -13,6 +13,7 @@ import { } from 'react-native'; import DeviceInfo from 'react-native-device-info'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {goToScreen, dismissModal} from '@actions/navigation'; import LocalConfig from '@assets/config'; @@ -37,7 +38,6 @@ class Settings extends PureComponent { intl: intlShape.isRequired, joinableTeams: PropTypes.array.isRequired, theme: PropTypes.object, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -176,7 +176,7 @@ class Settings extends PureComponent { }); render() { - const {config, joinableTeams, theme, isLandscape} = this.props; + const {config, joinableTeams, theme} = this.props; const style = getStyleSheet(theme); const showTeams = joinableTeams.length > 0; const showHelp = isValidUrl(config.HelpLink); @@ -189,7 +189,8 @@ class Settings extends PureComponent { } return ( - @@ -208,7 +209,6 @@ class Settings extends PureComponent { showArrow={showArrow} theme={theme} separator={true} - isLandscape={isLandscape} /> {showTeams && - - } {LocalConfig.EnableMobileClientUpgrade && LocalConfig.EnableMobileClientUpgradeUserSetting && - - } {showHelp && - - } - + ); } } diff --git a/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap b/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap index 0ed78be2b..6c722a026 100644 --- a/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap +++ b/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap @@ -69,7 +69,6 @@ NotificationSettings { "textComponent": "span", "timeZone": null, }, - "isLandscape": false, "theme": Object { "awayIndicator": "#ffbc42", "buttonBg": "#166de0", @@ -193,7 +192,6 @@ NotificationSettings { "timeZone": null, } } - isLandscape={false} theme={ Object { "awayIndicator": "#ffbc42", @@ -232,7 +230,13 @@ NotificationSettings { "_newState": null, "_numberOfReRenders": 0, "_renderPhaseUpdates": null, - "_rendered": - , + , "_rendering": false, "_updater": [Circular], "_workInProgressHook": null, diff --git a/app/screens/settings/notification_settings/notification_settings.js b/app/screens/settings/notification_settings/notification_settings.js index c5f8852ff..003c7e296 100644 --- a/app/screens/settings/notification_settings/notification_settings.js +++ b/app/screens/settings/notification_settings/notification_settings.js @@ -11,6 +11,7 @@ import { View, } from 'react-native'; import deepEqual from 'deep-equal'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {General, RequestStatus} from '@mm-redux/constants'; @@ -33,7 +34,6 @@ export default class NotificationSettings extends PureComponent { updateMeRequest: PropTypes.object.isRequired, currentUserStatus: PropTypes.string.isRequired, enableAutoResponder: PropTypes.bool.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -175,7 +175,7 @@ export default class NotificationSettings extends PureComponent { }; render() { - const {theme, enableAutoResponder, isLandscape} = this.props; + const {theme, enableAutoResponder} = this.props; const style = getStyleSheet(theme); const showArrow = Platform.OS === 'ios'; @@ -191,13 +191,13 @@ export default class NotificationSettings extends PureComponent { separator={false} showArrow={showArrow} theme={theme} - isLandscape={isLandscape} /> ); } return ( - @@ -215,7 +215,6 @@ export default class NotificationSettings extends PureComponent { separator={true} showArrow={showArrow} theme={theme} - isLandscape={isLandscape} /> {autoResponder} - + ); } } diff --git a/app/screens/settings/notification_settings/notification_settings.test.js b/app/screens/settings/notification_settings/notification_settings.test.js index 1ab8b145a..3367f7f5b 100644 --- a/app/screens/settings/notification_settings/notification_settings.test.js +++ b/app/screens/settings/notification_settings/notification_settings.test.js @@ -23,7 +23,6 @@ describe('NotificationSettings', () => { updateMeRequest: {}, currentUserStatus: 'status', enableAutoResponder: false, - isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/settings/notification_settings_auto_responder/index.js b/app/screens/settings/notification_settings_auto_responder/index.js index 4753460e2..48ef14232 100644 --- a/app/screens/settings/notification_settings_auto_responder/index.js +++ b/app/screens/settings/notification_settings_auto_responder/index.js @@ -5,7 +5,6 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getCurrentUserId, getStatusForUserId} from '@mm-redux/selectors/entities/users'; -import {isLandscape} from 'app/selectors/device'; import NotificationSettingsAutoResponder from './notification_settings_auto_responder'; function mapStateToProps(state) { @@ -15,7 +14,6 @@ function mapStateToProps(state) { return { theme: getTheme(state), currentUserStatus, - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/notification_settings_auto_responder/notification_settings_auto_responder.js b/app/screens/settings/notification_settings_auto_responder/notification_settings_auto_responder.js index d23a1e748..c8a7ee35a 100644 --- a/app/screens/settings/notification_settings_auto_responder/notification_settings_auto_responder.js +++ b/app/screens/settings/notification_settings_auto_responder/notification_settings_auto_responder.js @@ -8,9 +8,9 @@ import { View, } from 'react-native'; import {intlShape} from 'react-intl'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {General} from '@mm-redux/constants'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import FormattedText from 'app/components/formatted_text'; import StatusBar from 'app/components/status_bar'; import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_localized_placeholder'; @@ -31,7 +31,6 @@ export default class NotificationSettingsAutoResponder extends PureComponent { onBack: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, currentUserStatus: PropTypes.string.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -97,7 +96,7 @@ export default class NotificationSettingsAutoResponder extends PureComponent { }; render() { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const { auto_responder_active: autoResponderActive, auto_responder_message: autoResponderMessage, @@ -112,13 +111,15 @@ export default class NotificationSettingsAutoResponder extends PureComponent { ); return ( - +
{autoResponderActive === 'true' && ( @@ -134,7 +134,6 @@ export default class NotificationSettingsAutoResponder extends PureComponent { headerId={t('mobile.notification_settings.auto_responder.message_title')} headerDefaultMessage='CUSTOM MESSAGE' theme={theme} - isLandscape={isLandscape} > -
+
); } } diff --git a/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.ios.test.js.snap b/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.ios.test.js.snap index bacbf9e20..cf4dbe852 100644 --- a/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.ios.test.js.snap +++ b/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.ios.test.js.snap @@ -7,7 +7,6 @@ exports[`NotificationSettingsEmailIos should match snapshot, renderEmailSection footerId="user.settings.notifications.emailInfo" headerDefaultMessage="SEND EMAIL NOTIFICATIONS" headerId="mobile.notification_settings.email.send" - isLandscape={false} theme={ Object { "awayIndicator": "#ffbc42", @@ -43,7 +42,6 @@ exports[`NotificationSettingsEmailIos should match snapshot, renderEmailSection action={[Function]} actionType="select" actionValue="30" - isLandscape={false} label={ {sendEmailNotifications && @@ -54,7 +52,6 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { actionValue={Preferences.INTERVAL_IMMEDIATE.toString()} selected={newInterval === Preferences.INTERVAL_IMMEDIATE.toString()} theme={theme} - isLandscape={isLandscape} /> {enableEmailBatching && @@ -71,7 +68,6 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { actionValue={Preferences.INTERVAL_FIFTEEN_MINUTES.toString()} selected={newInterval === Preferences.INTERVAL_FIFTEEN_MINUTES.toString()} theme={theme} - isLandscape={isLandscape} /> @@ -103,7 +98,6 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { actionValue={Preferences.INTERVAL_NEVER.toString()} selected={newInterval === Preferences.INTERVAL_NEVER.toString()} theme={theme} - isLandscape={isLandscape} /> } @@ -111,7 +105,7 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { } @@ -123,7 +117,10 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { const style = getStyleSheet(theme); return ( - + {this.renderEmailSection()} - + ); } } diff --git a/app/screens/settings/notification_settings_email/notification_settings_email.ios.test.js b/app/screens/settings/notification_settings_email/notification_settings_email.ios.test.js index 6a173bfd0..a3285d62a 100644 --- a/app/screens/settings/notification_settings_email/notification_settings_email.ios.test.js +++ b/app/screens/settings/notification_settings_email/notification_settings_email.ios.test.js @@ -33,7 +33,6 @@ describe('NotificationSettingsEmailIos', () => { sendEmailNotifications: true, theme: Preferences.THEMES.default, componentId: 'component-id', - isLandscape: false, }; test('should match snapshot, renderEmailSection', () => { diff --git a/app/screens/settings/notification_settings_mentions/index.js b/app/screens/settings/notification_settings_mentions/index.js index 7215b7bb6..1d5e46718 100644 --- a/app/screens/settings/notification_settings_mentions/index.js +++ b/app/screens/settings/notification_settings_mentions/index.js @@ -4,14 +4,12 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import NotificationSettingsMentions from './notification_settings_mentions'; function mapStateToProps(state) { return { theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/notification_settings_mentions/notification_settings_mentions.ios.js b/app/screens/settings/notification_settings_mentions/notification_settings_mentions.ios.js index 776cc89ca..ee8299532 100644 --- a/app/screens/settings/notification_settings_mentions/notification_settings_mentions.ios.js +++ b/app/screens/settings/notification_settings_mentions/notification_settings_mentions.ios.js @@ -8,14 +8,15 @@ import { View, } from 'react-native'; import {injectIntl} from 'react-intl'; +import {SafeAreaView} from 'react-native-safe-area-context'; -import FormattedText from 'app/components/formatted_text'; -import StatusBar from 'app/components/status_bar'; -import Section from 'app/screens/settings/section'; -import SectionItem from 'app/screens/settings/section_item'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import {t} from 'app/utils/i18n'; -import {goToScreen} from 'app/actions/navigation'; +import FormattedText from '@components/formatted_text'; +import StatusBar from '@components/status_bar'; +import Section from '@screens/settings/section'; +import SectionItem from '@screens/settings/section_item'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {t} from '@utils/i18n'; +import {goToScreen} from '@actions/navigation'; import NotificationSettingsMentionsBase from './notification_settings_mention_base'; @@ -35,7 +36,7 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { }; renderMentionSection(style) { - const {currentUser, theme, isLandscape} = this.props; + const {currentUser, theme} = this.props; let mentionKeysComponent; if (this.state.mention_keys) { @@ -54,7 +55,6 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { headerId={t('mobile.notification_settings_mentions.wordsTrigger')} headerDefaultMessage='WORDS THAT TRIGGER MENTIONS' theme={theme} - isLandscape={isLandscape} > {currentUser.first_name?.length > 0 && @@ -74,7 +74,6 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { actionType='toggle' selected={this.state.first_name === 'true'} theme={theme} - isLandscape={isLandscape} /> @@ -95,7 +94,6 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { action={this.toggleUsernameMention} actionType='toggle' theme={theme} - isLandscape={isLandscape} /> ); } renderReplySection(style) { - const {theme, isLandscape} = this.props; + const {theme} = this.props; return (
); @@ -197,7 +189,10 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { const style = getStyleSheet(theme); return ( - + - + ); } } diff --git a/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap b/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap index c1c44a184..0dd0f5d37 100644 --- a/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap +++ b/app/screens/settings/notification_settings_mentions_keywords/__snapshots__/notification_settings_mentions_keywords.test.js.snap @@ -36,7 +36,6 @@ NotificationSettingsMentionsKeywords { "textComponent": "span", "timeZone": null, }, - "isLandscape": false, "keywords": "", "onBack": [MockFunction], "theme": Object { @@ -122,7 +121,6 @@ NotificationSettingsMentionsKeywords { "timeZone": null, } } - isLandscape={false} keywords="" onBack={[MockFunction]} theme={ @@ -162,7 +160,13 @@ NotificationSettingsMentionsKeywords { "_newState": null, "_numberOfReRenders": 0, "_renderPhaseUpdates": null, - "_rendered": -
, + , "_rendering": false, "_updater": [Circular], "_workInProgressHook": null, diff --git a/app/screens/settings/notification_settings_mentions_keywords/index.js b/app/screens/settings/notification_settings_mentions_keywords/index.js index 13aeca0e5..8cc78e202 100644 --- a/app/screens/settings/notification_settings_mentions_keywords/index.js +++ b/app/screens/settings/notification_settings_mentions_keywords/index.js @@ -4,14 +4,12 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from 'app/selectors/device'; import NotificationSettingsMentionsKeywords from './notification_settings_mentions_keywords'; function mapStateToProps(state) { return { theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.js b/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.js index 10b174836..142bc65f7 100644 --- a/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.js +++ b/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.js @@ -4,24 +4,23 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {ScrollView, View} from 'react-native'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; -import FormattedText from 'app/components/formatted_text'; -import StatusBar from 'app/components/status_bar'; -import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_localized_placeholder'; +import {popTopScreen} from '@actions/navigation'; +import FormattedText from '@components/formatted_text'; +import StatusBar from '@components/status_bar'; +import TextInputWithLocalizedPlaceholder from '@components/text_input_with_localized_placeholder'; import { changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; -import {popTopScreen} from 'app/actions/navigation'; +} from '@utils/theme'; export default class NotificationSettingsMentionsKeywords extends PureComponent { static propTypes = { keywords: PropTypes.string, onBack: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; constructor(props) { @@ -59,12 +58,15 @@ export default class NotificationSettingsMentionsKeywords extends PureComponent }; render() { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const {keywords} = this.state; const style = getStyleSheet(theme); return ( - + - + - + ); } } diff --git a/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.test.js b/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.test.js index 79a5e0914..3152c3b24 100644 --- a/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.test.js +++ b/app/screens/settings/notification_settings_mentions_keywords/notification_settings_mentions_keywords.test.js @@ -13,7 +13,6 @@ describe('NotificationSettingsMentionsKeywords', () => { const baseProps = { componentId: 'component-id', keywords: '', - isLandscape: false, onBack: jest.fn(), theme: Preferences.THEMES.default, }; diff --git a/app/screens/settings/notification_settings_mobile/index.js b/app/screens/settings/notification_settings_mobile/index.js index ce2e1f506..66899aa07 100644 --- a/app/screens/settings/notification_settings_mobile/index.js +++ b/app/screens/settings/notification_settings_mobile/index.js @@ -7,7 +7,6 @@ import {connect} from 'react-redux'; import {getConfig} from '@mm-redux/selectors/entities/general'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getCurrentUser} from '@mm-redux/selectors/entities/users'; -import {isLandscape} from 'app/selectors/device'; import {updateMe} from '@mm-redux/actions/users'; import NotificationSettingsMobile from './notification_settings_mobile'; @@ -23,7 +22,6 @@ function mapStateToProps(state) { theme, updateMeRequest, currentUser, - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/notification_settings_mobile/notification_settings_mobile.ios.js b/app/screens/settings/notification_settings_mobile/notification_settings_mobile.ios.js index d239888db..0c641fbe2 100644 --- a/app/screens/settings/notification_settings_mobile/notification_settings_mobile.ios.js +++ b/app/screens/settings/notification_settings_mobile/notification_settings_mobile.ios.js @@ -7,20 +7,20 @@ import { ScrollView, View, } from 'react-native'; -import SafeAreaView from 'app/components/safe_area_view'; -import FormattedText from 'app/components/formatted_text'; -import StatusBar from 'app/components/status_bar'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import {t} from 'app/utils/i18n'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; -import Section from 'app/screens/settings/section'; -import SectionItem from 'app/screens/settings/section_item'; + +import SafeAreaView from '@components/safe_area_view'; +import FormattedText from '@components/formatted_text'; +import StatusBar from '@components/status_bar'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; +import {t} from '@utils/i18n'; +import Section from '@screens/settings/section'; +import SectionItem from '@screens/settings/section_item'; import NotificationSettingsMobileBase from './notification_settings_mobile_base'; class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { renderMobilePushSection(style) { - const {config, theme, isLandscape} = this.props; + const {config, theme} = this.props; const pushNotificationsEnabled = config.SendPushNotifications === 'true'; return ( @@ -28,7 +28,6 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { headerId={t('mobile.notification_settings_mobile.push_activity')} headerDefaultMessage='SEND NOTIFICATIONS' theme={theme} - isLandscape={isLandscape} > {pushNotificationsEnabled && @@ -45,7 +44,6 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { actionValue='all' selected={this.state.push === 'all'} theme={theme} - isLandscape={isLandscape} /> } @@ -85,7 +81,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { } @@ -93,7 +89,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { } renderMobilePushStatusSection(style) { - const {config, theme, isLandscape} = this.props; + const {config, theme} = this.props; const showSection = config.SendPushNotifications === 'true' && this.state.push !== 'none'; if (!showSection) { @@ -105,7 +101,6 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { headerId={t('mobile.notification_settings_mobile.push_status')} headerDefaultMessage='TRIGGER PUSH NOTIFICATIONS WHEN' theme={theme} - isLandscape={isLandscape} > ); diff --git a/app/screens/settings/section.js b/app/screens/settings/section.js index b1834cf77..5f52aa4c5 100644 --- a/app/screens/settings/section.js +++ b/app/screens/settings/section.js @@ -9,7 +9,6 @@ import { import FormattedText from 'app/components/formatted_text'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import {marginHorizontal as margin} from 'app/components/safe_area_view/iphone_x_spacing'; function section(props) { const { @@ -23,7 +22,6 @@ function section(props) { headerId, headerValues, theme, - isLandscape, } = props; const style = getStyleSheet(theme); @@ -35,7 +33,7 @@ function section(props) { id={headerId} defaultMessage={headerDefaultMessage} values={headerValues} - style={[style.header, margin(isLandscape)]} + style={style.header} /> } @@ -46,7 +44,7 @@ function section(props) { id={footerId} defaultMessage={footerDefaultMessage} values={footerValues} - style={[style.footer, margin(isLandscape)]} + style={style.footer} /> } @@ -64,7 +62,6 @@ section.propTypes = { headerId: PropTypes.string, headerValues: PropTypes.object, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; const getStyleSheet = makeStyleSheetFromTheme((theme) => { diff --git a/app/screens/settings/section_item.js b/app/screens/settings/section_item.js index fff61f20b..05ffbc57c 100644 --- a/app/screens/settings/section_item.js +++ b/app/screens/settings/section_item.js @@ -10,7 +10,6 @@ import { } from 'react-native'; import CompassIcon from '@components/compass_icon'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; const ActionTypes = { @@ -30,7 +29,6 @@ function sectionItem(props) { theme, selected, description, - isLandscape, } = props; const style = getStyleSheet(theme); @@ -76,7 +74,7 @@ function sectionItem(props) { const component = ( {labelComponent} diff --git a/app/screens/settings/settings_item/index.js b/app/screens/settings/settings_item/index.js index d4225d12a..f81e05d9a 100644 --- a/app/screens/settings/settings_item/index.js +++ b/app/screens/settings/settings_item/index.js @@ -6,7 +6,6 @@ import PropTypes from 'prop-types'; import {Text, TouchableOpacity, View} from 'react-native'; import CompassIcon from '@components/compass_icon'; -import {paddingRight, paddingLeft} from '@components/safe_area_view/iphone_x_spacing'; import FormattedText from '@components/formatted_text'; import {changeOpacity} from '@utils/theme'; @@ -27,13 +26,11 @@ export default class SettingsItem extends PureComponent { separator: PropTypes.bool, showArrow: PropTypes.bool, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { isDestructor: false, separator: true, - isLandscape: false, isLink: false, }; @@ -86,7 +83,6 @@ export default class SettingsItem extends PureComponent { separator, showArrow, theme, - isLandscape, isDestructor, } = this.props; const style = getStyleSheet(theme); @@ -131,14 +127,14 @@ export default class SettingsItem extends PureComponent { testID={testID} onPress={onPress} > - + {icon && {icon} } - + {this.renderText()} {Boolean(additionalComponent) && diff --git a/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap b/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap index 8d8386915..b0b831d1d 100644 --- a/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap +++ b/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap @@ -3,7 +3,13 @@ exports[`SidebarSettings should match, full snapshot 1`] = `null`; exports[`SidebarSettings should match, full snapshot 2`] = ` -
} - isLandscape={false} label={
-
+ `; diff --git a/app/screens/settings/sidebar/index.js b/app/screens/settings/sidebar/index.js index 0a23aeefb..1f5a23834 100644 --- a/app/screens/settings/sidebar/index.js +++ b/app/screens/settings/sidebar/index.js @@ -9,6 +9,7 @@ import { } from 'react-native'; import {intlShape} from 'react-intl'; import AsyncStorage from '@react-native-community/async-storage'; +import {SafeAreaView} from 'react-native-safe-area-context'; import EventEmitter from '@mm-redux/utils/event_emitter'; @@ -22,7 +23,6 @@ import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; export default class SidebarSettings extends PureComponent { static propTypes = { theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -51,21 +51,20 @@ export default class SidebarSettings extends PureComponent { return null; } - const { - theme, - isLandscape, - } = this.props; + const {theme} = this.props; const {enabled} = this.state; const style = getStyleSheet(theme); return ( - +
-
+ ); } } diff --git a/app/screens/settings/sidebar/sidebar.test.js b/app/screens/settings/sidebar/sidebar.test.js index eb567eb6d..f302689cc 100644 --- a/app/screens/settings/sidebar/sidebar.test.js +++ b/app/screens/settings/sidebar/sidebar.test.js @@ -19,7 +19,6 @@ jest.mock('app/mattermost_managed', () => ({ describe('SidebarSettings', () => { const baseProps = { theme: Preferences.THEMES.default, - isLandscape: false, }; test('should match, full snapshot', async () => { diff --git a/app/screens/settings/theme/__snapshots__/theme.test.js.snap b/app/screens/settings/theme/__snapshots__/theme.test.js.snap index 191c96da5..464c3b1f2 100644 --- a/app/screens/settings/theme/__snapshots__/theme.test.js.snap +++ b/app/screens/settings/theme/__snapshots__/theme.test.js.snap @@ -41,7 +41,6 @@ exports[`Theme should match snapshot 1`] = ` "testUri": "../../../dist/assets/images/themes/mattermost.png", } } - isLandscape={false} isTablet={false} label={ @@ -87,7 +86,6 @@ exports[`Theme should match snapshot 1`] = ` "testUri": "../../../dist/assets/images/themes/organization.png", } } - isLandscape={false} isTablet={false} label={ @@ -133,7 +131,6 @@ exports[`Theme should match snapshot 1`] = ` "testUri": "../../../dist/assets/images/themes/mattermost_dark.png", } } - isLandscape={false} isTablet={false} label={ @@ -179,7 +176,6 @@ exports[`Theme should match snapshot 1`] = ` "testUri": "../../../dist/assets/images/themes/windows_dark.png", } } - isLandscape={false} isTablet={false} label={ diff --git a/app/screens/settings/theme/theme.js b/app/screens/settings/theme/theme.js index 092fcd943..0db929f41 100644 --- a/app/screens/settings/theme/theme.js +++ b/app/screens/settings/theme/theme.js @@ -5,6 +5,7 @@ import React from 'react'; import {Text, View} from 'react-native'; import PropTypes from 'prop-types'; import {intlShape} from 'react-intl'; +import {SafeAreaView} from 'react-native-safe-area-context'; import Preferences from '@mm-redux/constants/preferences'; @@ -125,14 +126,18 @@ export default class Theme extends React.PureComponent { {this.renderAllowedThemeTiles()} - {customTheme && -
- {this.renderCustomThemeRow({item: customTheme})} -
+
+ {this.renderCustomThemeRow({item: customTheme})} +
+ }
diff --git a/app/screens/settings/theme/theme.test.js b/app/screens/settings/theme/theme.test.js index 2256b54d1..37689dbad 100644 --- a/app/screens/settings/theme/theme.test.js +++ b/app/screens/settings/theme/theme.test.js @@ -22,7 +22,6 @@ describe('Theme', () => { savePreferences: jest.fn(), }, allowedThemes, - isLandscape: false, isTablet: false, teamId: 'test-team', theme: Preferences.THEMES.default, diff --git a/app/screens/settings/timezone/index.js b/app/screens/settings/timezone/index.js index e8f21ed96..cccca84c7 100644 --- a/app/screens/settings/timezone/index.js +++ b/app/screens/settings/timezone/index.js @@ -9,7 +9,6 @@ import {getSupportedTimezones as getTimezones} from '@mm-redux/selectors/entitie import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getUserTimezone} from '@mm-redux/selectors/entities/timezone'; import {getCurrentUser} from '@mm-redux/selectors/entities/users'; -import {isLandscape} from 'app/selectors/device'; import {updateUser} from 'app/actions/views/edit_profile'; import Timezone from './timezone'; @@ -24,7 +23,6 @@ function mapStateToProps(state) { theme: getTheme(state), userTimezone, timezones, - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/timezone/select_timezone/index.js b/app/screens/settings/timezone/select_timezone/index.js index 117f51980..a130068ce 100644 --- a/app/screens/settings/timezone/select_timezone/index.js +++ b/app/screens/settings/timezone/select_timezone/index.js @@ -6,7 +6,6 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; import {getSupportedTimezones} from '@mm-redux/selectors/entities/general'; -import {isLandscape} from 'app/selectors/device'; import SelectTimezone from './select_timezone'; function mapStateToProps(state, props) { @@ -24,7 +23,6 @@ function mapStateToProps(state, props) { theme: getTheme(state), timezones: supportedTimezones, initialScrollIndex: index, - isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/timezone/select_timezone/select_timezone.js b/app/screens/settings/timezone/select_timezone/select_timezone.js index 497c76c3c..d5ed58395 100644 --- a/app/screens/settings/timezone/select_timezone/select_timezone.js +++ b/app/screens/settings/timezone/select_timezone/select_timezone.js @@ -8,20 +8,19 @@ import { FlatList, Platform, } from 'react-native'; -import {getTimezoneRegion} from '@mm-redux/utils/timezone_utils'; import {intlShape} from 'react-intl'; +import {SafeAreaView} from 'react-native-safe-area-context'; -import SearchBar from 'app/components/search_bar'; -import StatusBar from 'app/components/status_bar'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; - -import {ListTypes} from 'app/constants'; +import SearchBar from '@components/search_bar'; +import StatusBar from '@components/status_bar'; +import {ListTypes} from '@constants'; +import {getTimezoneRegion} from '@mm-redux/utils/timezone_utils'; import { changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme, -} from 'app/utils/theme'; -import {popTopScreen} from 'app/actions/navigation'; +} from '@utils/theme'; +import {popTopScreen} from '@actions/navigation'; import SelectTimezoneRow from './select_timezone_row'; @@ -35,7 +34,6 @@ export default class Timezone extends PureComponent { timezones: PropTypes.array.isRequired, onBack: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -92,13 +90,12 @@ export default class Timezone extends PureComponent { timezone={timezone} selectedTimezone={this.props.selectedTimezone} onPress={this.timezoneSelected} - isLandscape={this.props.isLandscape} /> ); }; render() { - const {theme, initialScrollIndex, isLandscape} = this.props; + const {theme, initialScrollIndex} = this.props; const {value} = this.state; const {intl} = this.context; const style = getStyleSheet(theme); @@ -110,30 +107,31 @@ export default class Timezone extends PureComponent { }; return ( - + - - - + - + ); } } diff --git a/app/screens/settings/timezone/select_timezone/select_timezone_row.js b/app/screens/settings/timezone/select_timezone/select_timezone_row.js index a72326476..33c2e605d 100644 --- a/app/screens/settings/timezone/select_timezone/select_timezone_row.js +++ b/app/screens/settings/timezone/select_timezone/select_timezone_row.js @@ -10,7 +10,6 @@ import { } from 'react-native'; import CompassIcon from '@components/compass_icon'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import {makeStyleSheetFromTheme} from '@utils/theme'; const ITEM_HEIGHT = 45; @@ -21,7 +20,6 @@ export default class SelectTimezoneRow extends PureComponent { timezone: PropTypes.string.isRequired, selectedTimezone: PropTypes.string, onPress: PropTypes.func.isRequired, - isLandscape: PropTypes.bool.isRequired, }; timezoneSelected = () => { @@ -30,7 +28,7 @@ export default class SelectTimezoneRow extends PureComponent { }; render() { - const {theme, timezone, selectedTimezone, isLandscape} = this.props; + const {theme, timezone, selectedTimezone} = this.props; const styles = getStyleSheet(theme); const selected = timezone === selectedTimezone && ( @@ -43,7 +41,7 @@ export default class SelectTimezoneRow extends PureComponent { return ( diff --git a/app/screens/settings/timezone/timezone.js b/app/screens/settings/timezone/timezone.js index 7a6537824..027bec249 100644 --- a/app/screens/settings/timezone/timezone.js +++ b/app/screens/settings/timezone/timezone.js @@ -9,6 +9,7 @@ import { Platform, } from 'react-native'; import {intlShape} from 'react-intl'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {getTimezoneRegion} from '@mm-redux/utils/timezone_utils'; @@ -34,7 +35,6 @@ export default class Timezone extends PureComponent { getSupportedTimezones: PropTypes.func.isRequired, updateUser: PropTypes.func.isRequired, }).isRequired, - isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -139,19 +139,20 @@ export default class Timezone extends PureComponent { automaticTimezone, manualTimezone, }, - isLandscape, } = this.props; const {useAutomaticTimezone} = this.state; const style = getStyleSheet(theme); return ( - +
{!useAutomaticTimezone && ( @@ -191,14 +191,13 @@ export default class Timezone extends PureComponent { action={this.goToSelectTimezone} actionType='arrow' theme={theme} - isLandscape={isLandscape} /> )}
-
+ ); } } diff --git a/app/screens/sso/index.js b/app/screens/sso/index.js index 70d34963c..0a9aa2434 100644 --- a/app/screens/sso/index.js +++ b/app/screens/sso/index.js @@ -7,7 +7,6 @@ import {connect} from 'react-redux'; import {ssoLogin} from '@actions/views/user'; import {scheduleExpiredNotification} from '@actions/views/session'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {isLandscape} from '@selectors/device'; import SSO from './sso'; @@ -15,7 +14,6 @@ function mapStateToProps(state) { return { ...state.views.selectServer, theme: getTheme(state), - isLandscape: isLandscape(state), }; } diff --git a/app/screens/sso/sso.js b/app/screens/sso/sso.js index bad3f7028..b1ee42783 100644 --- a/app/screens/sso/sso.js +++ b/app/screens/sso/sso.js @@ -11,13 +11,13 @@ import { } from 'react-native'; import {WebView} from 'react-native-webview'; import CookieManager from 'react-native-cookies'; +import {SafeAreaView} from 'react-native-safe-area-context'; import urlParse from 'url-parse'; import {Client4} from '@mm-redux/client'; import {ViewTypes} from 'app/constants'; import Loading from 'app/components/loading'; -import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import StatusBar from 'app/components/status_bar'; import {resetToChannel} from 'app/actions/navigation'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; @@ -66,7 +66,6 @@ class SSO extends PureComponent { ssoLogin: PropTypes.func.isRequired, }).isRequired, intl: intlShape.isRequired, - isLandscape: PropTypes.bool.isRequired, serverUrl: PropTypes.string.isRequired, ssoType: PropTypes.string.isRequired, theme: PropTypes.object, @@ -237,7 +236,7 @@ class SSO extends PureComponent { }; render() { - const {theme, isLandscape} = this.props; + const {theme} = this.props; const {error, messagingEnabled, renderWebView, jsCode} = this.state; const style = getStyleSheet(theme); @@ -270,10 +269,10 @@ class SSO extends PureComponent { } return ( - + {content} - + ); } } diff --git a/app/screens/table/index.js b/app/screens/table/index.js index 4483ad0eb..91d8c4902 100644 --- a/app/screens/table/index.js +++ b/app/screens/table/index.js @@ -1,6 +1,70 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import Table from './table'; +import PropTypes from 'prop-types'; +import React from 'react'; +import {Platform, ScrollView} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; -export default Table; +import {makeStyleSheetFromTheme} from 'app/utils/theme'; + +export default class Table extends React.PureComponent { + static propTypes = { + renderRows: PropTypes.func.isRequired, + tableWidth: PropTypes.number.isRequired, + renderAsFlex: PropTypes.bool.isRequired, + }; + + render() { + const style = getStyleSheet(); + const content = this.props.renderRows(true); + const viewStyle = this.props.renderAsFlex ? style.displayFlex : {width: this.props.tableWidth}; + + let container; + if (Platform.OS === 'android') { + container = ( + + + {content} + + + ); + } else { + container = ( + + + {content} + + + ); + } + return container; + } +} + +const getStyleSheet = makeStyleSheetFromTheme(() => { + return { + container: { + flex: 1, + }, + fullHeight: { + height: '100%', + }, + displayFlex: { + ...Platform.select({ + android: { + flex: 1, + }, + ios: { + flex: 0, + }, + }), + }, + }; +}); diff --git a/app/screens/table/table.js b/app/screens/table/table.js deleted file mode 100644 index 9a97d6e1b..000000000 --- a/app/screens/table/table.js +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import PropTypes from 'prop-types'; -import React from 'react'; -import { - Platform, - ScrollView, - SafeAreaView, -} from 'react-native'; -import {makeStyleSheetFromTheme} from 'app/utils/theme'; - -export default class Table extends React.PureComponent { - static propTypes = { - renderRows: PropTypes.func.isRequired, - tableWidth: PropTypes.number.isRequired, - renderAsFlex: PropTypes.bool.isRequired, - }; - - render() { - const style = getStyleSheet(); - const content = this.props.renderRows(true); - const viewStyle = this.props.renderAsFlex ? style.displayFlex : {width: this.props.tableWidth}; - - let container; - if (Platform.OS === 'android') { - container = ( - - - {content} - - - ); - } else { - container = ( - - - {content} - - - ); - } - return container; - } -} - -const getStyleSheet = makeStyleSheetFromTheme(() => { - return { - fullHeight: { - height: '100%', - }, - displayFlex: { - ...Platform.select({ - android: { - flex: 1, - }, - ios: { - flex: 0, - }, - }), - }, - }; -}); diff --git a/app/screens/terms_of_service/__snapshots__/terms_of_service.test.js.snap b/app/screens/terms_of_service/__snapshots__/terms_of_service.test.js.snap index 20ff33564..d3200dfad 100644 --- a/app/screens/terms_of_service/__snapshots__/terms_of_service.test.js.snap +++ b/app/screens/terms_of_service/__snapshots__/terms_of_service.test.js.snap @@ -1,7 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`TermsOfService should enable/disable navigator buttons on setNavigatorButtons true/false 1`] = ` - + - + `; exports[`TermsOfService should enable/disable navigator buttons on setNavigatorButtons true/false 2`] = ` - + - + `; exports[`TermsOfService should match snapshot 1`] = ` @@ -331,7 +343,13 @@ exports[`TermsOfService should match snapshot for get terms 1`] = ` `; exports[`TermsOfService should match snapshot on enableNavigatorLogout 1`] = ` - + - + `; diff --git a/app/screens/terms_of_service/terms_of_service.js b/app/screens/terms_of_service/terms_of_service.js index cf6763a95..d013eb2f8 100644 --- a/app/screens/terms_of_service/terms_of_service.js +++ b/app/screens/terms_of_service/terms_of_service.js @@ -10,6 +10,7 @@ import { } from 'react-native'; import {intlShape} from 'react-intl'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import {dismissModal, setButtons} from '@actions/navigation'; import FailedNetworkAction from '@components/failed_network_action'; @@ -247,7 +248,7 @@ export default class TermsOfService extends PureComponent { } return ( - + - + ); } } diff --git a/app/screens/thread/__snapshots__/thread.ios.test.js.snap b/app/screens/thread/__snapshots__/thread.ios.test.js.snap index 39823cb2b..d39023eaa 100644 --- a/app/screens/thread/__snapshots__/thread.ios.test.js.snap +++ b/app/screens/thread/__snapshots__/thread.ios.test.js.snap @@ -2,7 +2,7 @@ exports[`thread should match snapshot, has root post 1`] = ` - @@ -49,7 +49,7 @@ exports[`thread should match snapshot, has root post 1`] = ` /> - + - @@ -95,7 +95,7 @@ exports[`thread should match snapshot, no root post, loading 1`] = ` size="large" style={Object {}} /> - + @@ -159,7 +159,7 @@ exports[`thread should match snapshot, render footer 2`] = ` exports[`thread should match snapshot, render footer 3`] = ` - @@ -177,7 +177,7 @@ exports[`thread should match snapshot, render footer 3`] = ` size="large" style={Object {}} /> - + diff --git a/app/screens/user_profile/__snapshots__/user_profile.test.js.snap b/app/screens/user_profile/__snapshots__/user_profile.test.js.snap index 2e030d4fe..c261ba98e 100644 --- a/app/screens/user_profile/__snapshots__/user_profile.test.js.snap +++ b/app/screens/user_profile/__snapshots__/user_profile.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`user_profile should match snapshot 1`] = ` - - - - fred - - - - nick @@ -199,7 +109,6 @@ exports[`user_profile should match snapshot 1`] = ` icon="send" iconColor="rgba(0, 0, 0, 0.7)" iconSize={24} - isLandscape={false} textColor="#000" textId="mobile.routes.user_profile.send_message" theme={ @@ -234,5 +143,5 @@ exports[`user_profile should match snapshot 1`] = ` togglable={false} /> - + `; diff --git a/app/screens/user_profile/index.js b/app/screens/user_profile/index.js index 5ca2bcb29..dcd297a53 100644 --- a/app/screens/user_profile/index.js +++ b/app/screens/user_profile/index.js @@ -4,9 +4,8 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; -import {setChannelDisplayName} from 'app/actions/views/channel'; -import {makeDirectChannel} from 'app/actions/views/more_dms'; -import {isLandscape} from 'app/selectors/device'; +import {setChannelDisplayName} from '@actions/views/channel'; +import {makeDirectChannel} from '@actions/views/more_dms'; import {getConfig} from '@mm-redux/selectors/entities/general'; import {getTeammateNameDisplaySetting, getTheme, getBool} from '@mm-redux/selectors/entities/preferences'; import {isTimezoneEnabled} from '@mm-redux/selectors/entities/timezone'; @@ -34,7 +33,6 @@ function mapStateToProps(state, ownProps) { militaryTime, theme: getTheme(state), isMyUser: getCurrentUserId(state) === ownProps.userId, - isLandscape: isLandscape(state), }; } diff --git a/app/screens/user_profile/user_profile.js b/app/screens/user_profile/user_profile.js index a8ad75393..70058b902 100644 --- a/app/screens/user_profile/user_profile.js +++ b/app/screens/user_profile/user_profile.js @@ -11,6 +11,7 @@ import { } from 'react-native'; import {intlShape} from 'react-intl'; import {Navigation} from 'react-native-navigation'; +import {SafeAreaView} from 'react-native-safe-area-context'; import { goToScreen, @@ -22,7 +23,6 @@ import Config from '@assets/config'; import FormattedTime from '@components/formatted_time'; import ProfilePicture from '@components/profile_picture'; import FormattedText from '@components/formatted_text'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import StatusBar from '@components/status_bar'; import {BotTag, GuestTag} from '@components/tag'; import {displayUsername} from '@mm-redux/utils/user_utils'; @@ -51,7 +51,6 @@ export default class UserProfile extends PureComponent { militaryTime: PropTypes.bool.isRequired, enableTimezone: PropTypes.bool.isRequired, isMyUser: PropTypes.bool.isRequired, - isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -86,6 +85,12 @@ export default class UserProfile extends PureComponent { } } + componentWillUnmount() { + if (this.navigationEventListener) { + this.navigationEventListener.remove(); + } + } + navigationButtonPressed({buttonId}) { switch (buttonId) { case this.rightButton.id: @@ -102,12 +107,13 @@ export default class UserProfile extends PureComponent { }; getDisplayName = () => { - const {theme, teammateNameDisplay, user} = this.props; + const {config, theme, teammateNameDisplay, user} = this.props; const style = createStyleSheet(theme); const displayName = displayUsername(user, teammateNameDisplay); + const showGuest = isGuest(user); - if (displayName) { + if (displayName && (config.ShowFullName === 'true' || user.is_bot || showGuest)) { return ( @@ -118,7 +124,7 @@ export default class UserProfile extends PureComponent { theme={theme} /> @@ -130,7 +136,7 @@ export default class UserProfile extends PureComponent { buildDisplayBlock = (property) => { const {formatMessage} = this.context.intl; - const {theme, user, isLandscape} = this.props; + const {theme, user} = this.props; const style = createStyleSheet(theme); let label; @@ -154,8 +160,8 @@ export default class UserProfile extends PureComponent { return ( - {label} - {user[property]} + {label} + {user[property]} ); } @@ -164,7 +170,7 @@ export default class UserProfile extends PureComponent { }; buildTimezoneBlock = () => { - const {theme, user, militaryTime, isLandscape} = this.props; + const {theme, user, militaryTime} = this.props; const style = createStyleSheet(theme); const currentTimezone = getUserCurrentTimezone(user.timezone); @@ -178,9 +184,9 @@ export default class UserProfile extends PureComponent { - + + {'DESCRIPTION'} {this.props.bot.description || ''} @@ -302,7 +308,7 @@ export default class UserProfile extends PureComponent { } render() { - const {theme, user, isLandscape} = this.props; + const {theme, user} = this.props; const style = createStyleSheet(theme); if (!user) { @@ -310,7 +316,7 @@ export default class UserProfile extends PureComponent { } return ( - + {this.renderAdditionalOptions()} - + ); } } diff --git a/app/screens/user_profile/user_profile.test.js b/app/screens/user_profile/user_profile.test.js index 18a55e027..6d7d2f663 100644 --- a/app/screens/user_profile/user_profile.test.js +++ b/app/screens/user_profile/user_profile.test.js @@ -37,7 +37,6 @@ describe('user_profile', () => { militaryTime: false, isMyUser: false, componentId: 'component-id', - isLandscape: false, }; const user = { diff --git a/app/screens/user_profile/user_profile_row.js b/app/screens/user_profile/user_profile_row.js index 30d8942c2..9912c1053 100644 --- a/app/screens/user_profile/user_profile_row.js +++ b/app/screens/user_profile/user_profile_row.js @@ -11,7 +11,6 @@ import { import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; -import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing'; import TouchableWithFeedback from '@components/touchable_with_feedback'; import {makeStyleSheetFromTheme} from '@utils/theme'; @@ -58,7 +57,7 @@ function createTouchableComponent(children, action) { } function userProfileRow(props) { - const {action, defaultMessage, detail, icon, textId, togglable, theme, iconSize, shouldRender = true, isLandscape} = props; + const {action, defaultMessage, detail, icon, textId, togglable, theme, iconSize, shouldRender = true} = props; if (!shouldRender) { return null; @@ -76,7 +75,7 @@ function userProfileRow(props) { const RowComponent = ( - + {iconComponent} { getVersion: () => '0.0.0', getBuildNumber: () => '0', getModel: () => 'iPhone X', + hasNotch: () => true, isTablet: () => false, getApplicationName: () => 'Mattermost', }; @@ -204,6 +205,7 @@ jest.mock('react-native-image-picker', () => ({ jest.mock('react-native-navigation', () => { const RNN = jest.requireActual('react-native-navigation'); RNN.Navigation.setLazyComponentRegistrator = jest.fn(); + RNN.Navigation.setDefaultOptions = jest.fn(); return { ...RNN, Navigation: {