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 9ac3bb32f..fb9a3a48f 100644 --- a/app/components/announcement_banner/__snapshots__/announcement_banner.test.js.snap +++ b/app/components/announcement_banner/__snapshots__/announcement_banner.test.js.snap @@ -22,11 +22,14 @@ exports[`AnnouncementBanner should match snapshot 1`] = ` activeOpacity={0.2} onPress={[Function]} style={ - Object { - "alignItems": "center", - "flex": 1, - "flexDirection": "row", - } + Array [ + Object { + "alignItems": "center", + "flex": 1, + "flexDirection": "row", + }, + null, + ] } > { bannerText: 'Banner Text', bannerTextColor: '#fff', theme: Preferences.THEMES.default, + isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/components/announcement_banner/index.js b/app/components/announcement_banner/index.js index f06d6eea1..346f08acc 100644 --- a/app/components/announcement_banner/index.js +++ b/app/components/announcement_banner/index.js @@ -8,6 +8,7 @@ import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {goToScreen} from 'app/actions/navigation'; +import {isLandscape} from 'app/selectors/device'; import AnnouncementBanner from './announcement_banner'; @@ -23,6 +24,7 @@ function mapStateToProps(state) { 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 7b8fafaee..c3b0d0de0 100644 --- a/app/components/autocomplete/at_mention/at_mention.js +++ b/app/components/autocomplete/at_mention/at_mention.js @@ -35,6 +35,7 @@ export default class AtMention extends PureComponent { teamMembers: PropTypes.array, theme: PropTypes.object.isRequired, value: PropTypes.string, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -178,6 +179,7 @@ export default class AtMention extends PureComponent { id={section.id} defaultMessage={section.defaultMessage} theme={this.props.theme} + isLandscape={this.props.isLandscape} /> ); }; diff --git a/app/components/autocomplete/at_mention/index.js b/app/components/autocomplete/at_mention/index.js index 87f5bd21c..33b8ab5cd 100644 --- a/app/components/autocomplete/at_mention/index.js +++ b/app/components/autocomplete/at_mention/index.js @@ -7,6 +7,7 @@ import {connect} from 'react-redux'; import {autocompleteUsers} from 'mattermost-redux/actions/users'; import {getCurrentChannelId, getDefaultChannel} from 'mattermost-redux/selectors/entities/channels'; import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; +import {isLandscape} from 'app/selectors/device'; import { filterMembersInChannel, @@ -45,6 +46,7 @@ function mapStateToProps(state, ownProps) { outChannel, requestStatus: state.requests.users.autocompleteUsers.status, theme: getTheme(state), + isLandscape: isLandscape(state), }; } 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 b24a83290..fcdb6573e 100644 --- a/app/components/autocomplete/at_mention_item/at_mention_item.js +++ b/app/components/autocomplete/at_mention_item/at_mention_item.js @@ -13,6 +13,7 @@ import ProfilePicture from 'app/components/profile_picture'; import BotTag from 'app/components/bot_tag'; import GuestTag from 'app/components/guest_tag'; import {makeStyleSheetFromTheme} from 'app/utils/theme'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export default class AtMentionItem extends PureComponent { static propTypes = { @@ -24,6 +25,7 @@ export default class AtMentionItem extends PureComponent { isGuest: PropTypes.bool, isBot: PropTypes.bool, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -44,6 +46,7 @@ export default class AtMentionItem extends PureComponent { username, theme, isBot, + isLandscape, isGuest, } = this.props; @@ -54,7 +57,7 @@ export default class AtMentionItem extends PureComponent { - + ); }; diff --git a/app/components/autocomplete/channel_mention/index.js b/app/components/autocomplete/channel_mention/index.js index 9c2898ae0..7bc6974b8 100644 --- a/app/components/autocomplete/channel_mention/index.js +++ b/app/components/autocomplete/channel_mention/index.js @@ -7,6 +7,7 @@ import {connect} from 'react-redux'; import {searchChannels, autocompleteChannelsForSearch} from 'mattermost-redux/actions/channels'; import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/channels'; import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; +import {isLandscape} from 'app/selectors/device'; import { filterMyChannels, @@ -52,6 +53,7 @@ function mapStateToProps(state, ownProps) { requestStatus: state.requests.channels.getChannels.status, theme: getTheme(state), serverVersion: state.entities.general.serverVersion, + 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 606de102f..cbf2f95c4 100644 --- a/app/components/autocomplete/channel_mention_item/channel_mention_item.js +++ b/app/components/autocomplete/channel_mention_item/channel_mention_item.js @@ -10,6 +10,7 @@ import { import {General} from 'mattermost-redux/constants'; import BotTag from 'app/components/bot_tag'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import GuestTag from 'app/components/guest_tag'; import {makeStyleSheetFromTheme} from 'app/utils/theme'; @@ -24,6 +25,7 @@ export default class ChannelMentionItem extends PureComponent { isGuest: PropTypes.bool.isRequired, onPress: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; completeMention = () => { @@ -43,6 +45,7 @@ export default class ChannelMentionItem extends PureComponent { theme, type, isBot, + isLandscape, isGuest, } = this.props; @@ -56,7 +59,7 @@ export default class ChannelMentionItem extends PureComponent { {'@' + displayName} {displayName} {` (~${name})`} diff --git a/app/components/autocomplete/channel_mention_item/index.js b/app/components/autocomplete/channel_mention_item/index.js index a1b57f86a..3bf635684 100644 --- a/app/components/autocomplete/channel_mention_item/index.js +++ b/app/components/autocomplete/channel_mention_item/index.js @@ -15,6 +15,8 @@ import ChannelMentionItem from './channel_mention_item'; import {getUser} from 'mattermost-redux/selectors/entities/users'; +import {isLandscape} from 'app/selectors/device'; + function mapStateToProps(state, ownProps) { const channel = getChannel(state, ownProps.channelId); const displayName = getChannelNameForSearchAutocomplete(state, ownProps.channelId); @@ -33,6 +35,7 @@ function mapStateToProps(state, ownProps) { type: channel.type, isBot, 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 123b2fefc..7a00252d7 100644 --- a/app/components/autocomplete/slash_suggestion/index.js +++ b/app/components/autocomplete/slash_suggestion/index.js @@ -9,6 +9,7 @@ import {getAutocompleteCommands} from 'mattermost-redux/actions/integrations'; import {getAutocompleteCommandsList} from 'mattermost-redux/selectors/entities/integrations'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; +import {isLandscape} from 'app/selectors/device'; import SlashSuggestion from './slash_suggestion'; @@ -31,6 +32,7 @@ function mapStateToProps(state) { commandsRequest: state.requests.integrations.getAutocompleteCommands, currentTeamId: getCurrentTeamId(state), theme: getTheme(state), + isLandscape: isLandscape(state), }; } diff --git a/app/components/autocomplete/slash_suggestion/slash_suggestion.js b/app/components/autocomplete/slash_suggestion/slash_suggestion.js index b3bf07eba..bbf8c1da0 100644 --- a/app/components/autocomplete/slash_suggestion/slash_suggestion.js +++ b/app/components/autocomplete/slash_suggestion/slash_suggestion.js @@ -32,6 +32,7 @@ export default class SlashSuggestion extends Component { onChangeText: PropTypes.func.isRequired, onResultCountChange: PropTypes.func.isRequired, value: PropTypes.string, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -145,6 +146,7 @@ export default class SlashSuggestion extends Component { onPress={this.completeSuggestion} theme={this.props.theme} trigger={item.trigger} + 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 85681ec0c..667637fa4 100644 --- a/app/components/autocomplete/slash_suggestion/slash_suggestion_item.js +++ b/app/components/autocomplete/slash_suggestion/slash_suggestion_item.js @@ -9,6 +9,7 @@ import { } from 'react-native'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export default class SlashSuggestionItem extends PureComponent { static propTypes = { @@ -17,6 +18,7 @@ export default class SlashSuggestionItem extends PureComponent { onPress: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, trigger: PropTypes.string, + isLandscape: PropTypes.bool.isRequired, }; completeSuggestion = () => { @@ -30,6 +32,7 @@ export default class SlashSuggestionItem extends PureComponent { hint, theme, trigger, + isLandscape, } = this.props; const style = getStyleFromTheme(theme); @@ -37,7 +40,7 @@ export default class SlashSuggestionItem extends PureComponent { return ( {`/${trigger} ${hint}`} {description} diff --git a/app/components/channel_intro/channel_intro.js b/app/components/channel_intro/channel_intro.js index 658b53177..2ff50fa9c 100644 --- a/app/components/channel_intro/channel_intro.js +++ b/app/components/channel_intro/channel_intro.js @@ -11,7 +11,7 @@ import { import {getFullName} from 'mattermost-redux/utils/user_utils'; import {General} from 'mattermost-redux/constants'; import {injectIntl, intlShape} from 'react-intl'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import ProfilePicture from 'app/components/profile_picture'; import BotTag from 'app/components/bot_tag'; import GuestTag from 'app/components/guest_tag'; @@ -30,6 +30,7 @@ class ChannelIntro extends PureComponent { currentChannelMembers: PropTypes.array.isRequired, intl: intlShape.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -307,7 +308,7 @@ class ChannelIntro extends PureComponent { }; render() { - const {currentChannel, theme} = this.props; + const {currentChannel, theme, isLandscape} = this.props; const style = getStyleSheet(theme); const channelType = currentChannel.type; @@ -315,10 +316,10 @@ class ChannelIntro extends PureComponent { if (channelType === General.DM_CHANNEL || channelType === General.GM_CHANNEL) { profiles = ( - + {this.buildProfiles()} - + {this.buildNames()} @@ -328,7 +329,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 8d6ccf49e..aa10a1525 100644 --- a/app/components/channel_intro/index.js +++ b/app/components/channel_intro/index.js @@ -10,7 +10,7 @@ import {makeGetChannel} from 'mattermost-redux/selectors/entities/channels'; import {getCurrentUserId, getUser, makeGetProfilesInChannel} from 'mattermost-redux/selectors/entities/users'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; - +import {isLandscape} from 'app/selectors/device'; import {goToScreen} from 'app/actions/navigation'; import {getChannelMembersForDm} from 'app/selectors/channel'; @@ -50,6 +50,7 @@ function makeMapStateToProps() { currentChannel, currentChannelMembers, theme: getTheme(state), + isLandscape: isLandscape(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 d440ab175..e59927f00 100644 --- a/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap +++ b/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap @@ -9,6 +9,7 @@ exports[`ChannelLoader should match snapshot 1`] = ` "flex": 1, }, undefined, + null, Object { "backgroundColor": "#ffffff", }, diff --git a/app/components/channel_loader/channel_loader.js b/app/components/channel_loader/channel_loader.js index f92042df7..ad550cde6 100644 --- a/app/components/channel_loader/channel_loader.js +++ b/app/components/channel_loader/channel_loader.js @@ -15,6 +15,7 @@ import EventEmitter from 'mattermost-redux/utils/event_emitter'; 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'; const {View: AnimatedView} = Animated; @@ -33,6 +34,7 @@ export default class ChannelLoader extends PureComponent { style: CustomPropTypes.Style, theme: PropTypes.object.isRequired, height: PropTypes.number, + isLandscape: PropTypes.bool.isRequired, }; constructor(props) { @@ -156,6 +158,7 @@ export default class ChannelLoader extends PureComponent { channelIsLoading, style: styleProp, theme, + isLandscape, } = this.props; if (!channelIsLoading) { @@ -167,7 +170,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 f742cc385..1591d1fac 100644 --- a/app/components/channel_loader/channel_loader.test.js +++ b/app/components/channel_loader/channel_loader.test.js @@ -20,6 +20,7 @@ describe('ChannelLoader', () => { handleSelectChannel: jest.fn(), setChannelLoading: jest.fn(), }, + isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/components/channel_loader/index.js b/app/components/channel_loader/index.js index 397413b19..aa7d9b53f 100644 --- a/app/components/channel_loader/index.js +++ b/app/components/channel_loader/index.js @@ -10,6 +10,8 @@ import {handleSelectChannel, setChannelLoading} from 'app/actions/views/channel' import ChannelLoader from './channel_loader'; +import {isLandscape} from 'app/selectors/device'; + function mapStateToProps(state, ownProps) { const channelIsLoading = ownProps.hasOwnProperty('channelIsLoading') ? ownProps.channelIsLoading : @@ -18,6 +20,7 @@ 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 79bcda2bf..38087a1d3 100644 --- a/app/components/custom_list/__snapshots__/index.test.js.snap +++ b/app/components/custom_list/__snapshots__/index.test.js.snap @@ -117,10 +117,13 @@ 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 5375d71e7..01feaf7a0 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 @@ -18,6 +18,7 @@ export default class ChannelListRow extends React.PureComponent { theme: PropTypes.object.isRequired, channel: PropTypes.object.isRequired, ...CustomListRow.propTypes, + isLandscape: PropTypes.bool.isRequired, }; onPress = () => { @@ -47,6 +48,7 @@ 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 980103e48..113da9f39 100644 --- a/app/components/custom_list/channel_list_row/index.js +++ b/app/components/custom_list/channel_list_row/index.js @@ -6,7 +6,7 @@ import {connect} from 'react-redux'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {makeGetChannel} from 'mattermost-redux/selectors/entities/channels'; - +import {isLandscape} from 'app/selectors/device'; import ChannelListRow from './channel_list_row'; function makeMapStateToProps() { @@ -16,6 +16,7 @@ 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 6f16d17b5..3caec1af7 100644 --- a/app/components/custom_list/custom_list_row.js +++ b/app/components/custom_list/custom_list_row.js @@ -8,7 +8,7 @@ import { View, } from 'react-native'; import Icon from 'react-native-vector-icons/FontAwesome'; - +import {paddingLeft as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import ConditionalTouchable from 'app/components/conditional_touchable'; import CustomPropTypes from 'app/constants/custom_prop_types'; @@ -20,10 +20,12 @@ export default class CustomListRow extends React.PureComponent { selected: PropTypes.bool, children: CustomPropTypes.Children, item: PropTypes.object, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { enabled: true, + isLandscape: false, }; render() { @@ -33,7 +35,7 @@ export default class CustomListRow extends React.PureComponent { onPress={this.props.onPress} style={style.touchable} > - + {this.props.selectable && diff --git a/app/components/custom_list/index.js b/app/components/custom_list/index.js index c8b825d9b..42ae0461d 100644 --- a/app/components/custom_list/index.js +++ b/app/components/custom_list/index.js @@ -7,6 +7,7 @@ import {FlatList, Keyboard, Platform, SectionList, Text, View} from 'react-nativ 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'; @@ -30,12 +31,14 @@ export default class CustomList extends PureComponent { selectable: PropTypes.bool, theme: PropTypes.object.isRequired, shouldRenderSeparator: PropTypes.bool, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { listType: FLATLIST, showNoResults: true, shouldRenderSeparator: true, + isLandscape: false, }; constructor(props) { @@ -148,12 +151,13 @@ export default class CustomList extends PureComponent { }; renderSectionHeader = ({section}) => { - const style = getStyleFromTheme(this.props.theme); + const {theme, isLandscape} = this.props; + const style = getStyleFromTheme(theme); return ( - {section.id} + {section.id} ); 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 741210df8..fdb73806e 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,6 +14,7 @@ exports[`UserListRow should match snapshot 1`] = ` { }, theme: Preferences.THEMES.default, teammateNameDisplay: 'test', + isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/components/edit_channel_info/edit_channel_info.js b/app/components/edit_channel_info/edit_channel_info.js index 70871ab9a..bcf2a9be8 100644 --- a/app/components/edit_channel_info/edit_channel_info.js +++ b/app/components/edit_channel_info/edit_channel_info.js @@ -23,6 +23,7 @@ import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_lo import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; import {getShortenedURL} from 'app/utils/url'; import {t} from 'app/utils/i18n'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export default class EditChannelInfo extends PureComponent { static propTypes = { @@ -51,6 +52,7 @@ export default class EditChannelInfo extends PureComponent { oldChannelURL: PropTypes.string, oldHeader: PropTypes.string, oldPurpose: PropTypes.string, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -181,6 +183,7 @@ export default class EditChannelInfo extends PureComponent { channelURL, header, purpose, + isLandscape, } = this.props; const {error, saving} = this.props; const fullUrl = currentTeamUrl + '/channels'; @@ -204,7 +207,7 @@ export default class EditChannelInfo extends PureComponent { if (error) { displayError = ( - + @@ -225,12 +228,12 @@ export default class EditChannelInfo extends PureComponent { - + - + - + - + - + )} - + - + diff --git a/app/components/edit_channel_info/index.js b/app/components/edit_channel_info/index.js index a523704f5..156b13db2 100644 --- a/app/components/edit_channel_info/index.js +++ b/app/components/edit_channel_info/index.js @@ -8,9 +8,15 @@ import { dismissModal, popTopScreen, } from 'app/actions/navigation'; - +import {isLandscape} from 'app/selectors/device'; import EditChannelInfo from './edit_channel_info'; +function mapStateToProps(state) { + return { + isLandscape: isLandscape(state), + }; +} + function mapDispatchToProps(dispatch) { return { actions: bindActionCreators({ @@ -20,4 +26,4 @@ function mapDispatchToProps(dispatch) { }; } -export default connect(null, mapDispatchToProps)(EditChannelInfo); +export default connect(mapStateToProps, mapDispatchToProps)(EditChannelInfo); diff --git a/app/components/emoji_picker/emoji_picker.js b/app/components/emoji_picker/emoji_picker.js index c3565b04c..66663cef5 100644 --- a/app/components/emoji_picker/emoji_picker.js +++ b/app/components/emoji_picker/emoji_picker.js @@ -26,7 +26,7 @@ import SearchBar from 'app/components/search_bar'; import {DeviceTypes} from 'app/constants'; import {emptyFunction} from 'app/utils/general'; import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import EmojiPickerRow from './emoji_picker_row'; const EMOJI_SIZE = 30; @@ -210,7 +210,8 @@ export default class EmojiPicker extends PureComponent { }; getNumberOfColumns = (deviceWidth) => { - return Math.floor(Number(((deviceWidth - (SECTION_MARGIN * 2)) / (EMOJI_SIZE + (EMOJI_GUTTER * 2))))); + const shorten = DeviceTypes.IS_IPHONE_X && this.props.isLandscape ? 4 : 2; + return Math.floor(Number(((deviceWidth - (SECTION_MARGIN * shorten)) / (EMOJI_SIZE + (EMOJI_GUTTER * shorten))))); }; renderItem = ({item}) => { @@ -235,7 +236,7 @@ export default class EmojiPicker extends PureComponent { onPress={() => this.props.onEmojiPress(item)} style={style.flatListRow} > - + - + { onCloseChannel: jest.fn(), cursorPositionEvent: '', valueEvent: '', + isLandscape: false, }; test('should match, full snapshot', () => { diff --git a/app/components/post_textbox/post_textbox_base.js b/app/components/post_textbox/post_textbox_base.js index 249129f45..8a26972e4 100644 --- a/app/components/post_textbox/post_textbox_base.js +++ b/app/components/post_textbox/post_textbox_base.js @@ -32,6 +32,7 @@ import {NOTIFY_ALL_MEMBERS} from 'app/constants/view'; import {t} from 'app/utils/i18n'; import {confirmOutOfOfficeDisabled} from 'app/utils/status'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; const {RNTextInputReset} = NativeModules; @@ -77,6 +78,7 @@ export default class PostTextBoxBase extends PureComponent { enableConfirmNotificationsToChannel: PropTypes.bool, isTimezoneEnabled: PropTypes.bool, currentChannel: PropTypes.object, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -146,7 +148,7 @@ export default class PostTextBoxBase extends PureComponent { numberOfTimezones = async () => { const {data} = await this.props.actions.getChannelTimezones(this.props.channelId); return data?.length || 0; - } + }; canSend = () => { const {files, maxMessageLength, uploadFileRequestStatus} = this.props; @@ -408,6 +410,7 @@ export default class PostTextBoxBase extends PureComponent { const {files} = this.props; const {intl} = this.context; const {value} = this.state; + if (files.length === 0 && !value) { Alert.alert( intl.formatMessage({ @@ -681,7 +684,7 @@ export default class PostTextBoxBase extends PureComponent { renderTextBox = () => { const {intl} = this.context; - const {channelDisplayName, channelIsArchived, channelIsLoading, channelIsReadOnly, theme} = this.props; + const {channelDisplayName, channelIsArchived, channelIsLoading, channelIsReadOnly, theme, isLandscape} = this.props; const style = getStyleSheet(theme); if (channelIsArchived) { @@ -694,7 +697,7 @@ export default class PostTextBoxBase extends PureComponent { return ( {this.getAttachmentButton()} diff --git a/app/components/safe_area_view/iphone_x_spacing/index.js b/app/components/safe_area_view/iphone_x_spacing/index.js new file mode 100644 index 000000000..9460b5e2e --- /dev/null +++ b/app/components/safe_area_view/iphone_x_spacing/index.js @@ -0,0 +1,20 @@ +// 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_X && isLandscape ? {paddingHorizontal: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; +}; + +export const paddingLeft = (isLandscape, modifier = 0) => { + return DeviceTypes.IS_IPHONE_X && isLandscape ? {paddingLeft: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; +}; + +export const paddingRight = (isLandscape, modifier = 0) => { + return DeviceTypes.IS_IPHONE_X && isLandscape ? {paddingRight: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; +}; + +export const marginHorizontal = (isLandscape, modifier = 0) => { + return DeviceTypes.IS_IPHONE_X && isLandscape ? {marginHorizontal: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + modifier} : null; +}; \ 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 index 00d73702a..9b1c4dc12 100644 --- a/app/components/safe_area_view/safe_area_view.ios.js +++ b/app/components/safe_area_view/safe_area_view.ios.js @@ -25,10 +25,12 @@ export default class SafeAreaIos extends PureComponent { navBarBackgroundColor: PropTypes.string, headerComponent: PropTypes.node, theme: PropTypes.object.isRequired, + useLandscapeMargin: PropTypes.bool.isRequired, }; static defaultProps = { keyboardOffset: 0, + useLandscapeMargin: false, }; constructor(props) { @@ -150,7 +152,7 @@ export default class SafeAreaIos extends PureComponent { }; render() { - const {backgroundColor, children, footerColor, footerComponent, keyboardOffset, theme} = this.props; + const {backgroundColor, children, footerColor, footerComponent, keyboardOffset, theme, useLandscapeMargin} = this.props; const {keyboard, safeAreaInsets} = this.state; let bgColor = theme.centerChannelBg; @@ -173,6 +175,8 @@ export default class SafeAreaIos extends PureComponent { style={{ flex: 1, backgroundColor: bgColor, + marginLeft: useLandscapeMargin ? safeAreaInsets.left : 0, + marginRight: useLandscapeMargin ? safeAreaInsets.right : 0, }} > {this.renderTopBar()} diff --git a/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap b/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap index 1bfdb0263..821ee00ee 100644 --- a/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap +++ b/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap @@ -17,6 +17,7 @@ exports[`ChannelItem should match snapshot 1`] = ` "height": 44, }, undefined, + null, ] } > @@ -118,6 +119,7 @@ exports[`ChannelItem should match snapshot for current user i.e currentUser (you "height": 44, }, undefined, + null, ] } > @@ -230,6 +232,7 @@ exports[`ChannelItem should match snapshot for current user i.e currentUser (you "height": 44, }, undefined, + null, ] } > @@ -342,6 +345,7 @@ exports[`ChannelItem should match snapshot for deactivated user and is currentCh "height": 44, }, undefined, + null, ] } > @@ -454,6 +458,7 @@ exports[`ChannelItem should match snapshot for deactivated user and is searchRes "height": 44, }, undefined, + null, ] } > @@ -561,6 +566,7 @@ exports[`ChannelItem should match snapshot with draft 1`] = ` "height": 44, }, undefined, + null, ] } > @@ -664,6 +670,7 @@ 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 e5af091d4..1131f50bf 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 @@ -13,7 +13,7 @@ import {intlShape} from 'react-intl'; import {Navigation} from 'react-native-navigation'; import {General} from 'mattermost-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'; @@ -40,6 +40,7 @@ export default class ChannelItem extends PureComponent { isSearchResult: PropTypes.bool, isBot: PropTypes.bool.isRequired, previewChannel: PropTypes.func, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -98,6 +99,7 @@ export default class ChannelItem extends PureComponent { isSearchResult, channel, isBot, + isLandscape, } = this.props; const isArchived = channel.delete_at > 0; @@ -194,7 +196,7 @@ export default class ChannelItem extends PureComponent { onPress={this.onPress} onPressIn={this.onPreview} > - + {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 b9ced6211..5b0fa7558 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 @@ -38,6 +38,7 @@ 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 0649de1af..c5a11e534 100644 --- a/app/components/sidebars/main/channels_list/channel_item/index.js +++ b/app/components/sidebars/main/channels_list/channel_item/index.js @@ -14,7 +14,7 @@ import {getTheme, getTeammateNameDisplaySetting} from 'mattermost-redux/selector import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users'; import {getUserIdFromChannelName, isChannelMuted} from 'mattermost-redux/utils/channel_utils'; import {displayUsername} from 'mattermost-redux/utils/user_utils'; - +import {isLandscape} from 'app/selectors/device'; import {getDraftForChannel} from 'app/selectors/views'; import {isGuest as isGuestUser} from 'app/utils/users'; @@ -84,6 +84,7 @@ function makeMapStateToProps() { theme: getTheme(state), unreadMsgs, isBot, + isLandscape: isLandscape(state), isGuest, }; }; diff --git a/app/components/sidebars/main/channels_list/channels_list.js b/app/components/sidebars/main/channels_list/channels_list.js index d597cade0..38c4e359f 100644 --- a/app/components/sidebars/main/channels_list/channels_list.js +++ b/app/components/sidebars/main/channels_list/channels_list.js @@ -12,7 +12,7 @@ import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; import SearchBar from 'app/components/search_bar'; import {ViewTypes} from 'app/constants'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; import List from './list'; @@ -31,6 +31,7 @@ export default class ChannelsList extends PureComponent { theme: PropTypes.object.isRequired, drawerOpened: PropTypes.bool, previewChannel: PropTypes.func, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -90,6 +91,7 @@ export default class ChannelsList extends PureComponent { onShowTeams, theme, previewChannel, + isLandscape, } = this.props; const {searching, term} = this.state; @@ -127,7 +129,7 @@ export default class ChannelsList extends PureComponent { }; const title = ( - + { divider: { backgroundColor: changeOpacity(theme.sidebarText, 0.1), height: 1, + width: '100%', }, actionContainer: { alignItems: 'center', 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 d37d56c42..d956fc760 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 @@ -21,9 +21,9 @@ import {General} from 'mattermost-redux/constants'; import {sortChannelsByDisplayName} from 'mattermost-redux/utils/channel_utils'; import {displayUsername} from 'mattermost-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 {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; const VIEWABILITY_CONFIG = ListTypes.VISIBILITY_CONFIG_DEFAULTS; @@ -55,6 +55,7 @@ class FilteredList extends Component { term: PropTypes.string, theme: PropTypes.object.isRequired, previewChannel: PropTypes.func, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -400,7 +401,7 @@ class FilteredList extends Component { {topDivider && this.renderDivider(styles, 0)} - + {formatMessage({id, defaultMessage}).toUpperCase()} {action && this.renderSectionAction(styles, action)} 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 a9dac6a0f..ad5d2544b 100644 --- a/app/components/sidebars/main/channels_list/filtered_list/index.js +++ b/app/components/sidebars/main/channels_list/filtered_list/index.js @@ -20,7 +20,7 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general'; import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams'; import {getCurrentUserId, getProfilesInCurrentTeam, getUsers, getUserIdsInChannels, getUserStatuses} from 'mattermost-redux/selectors/entities/users'; import {getDirectShowPreferences, getTeammateNameDisplaySetting, getTheme} from 'mattermost-redux/selectors/entities/preferences'; - +import {isLandscape} from 'app/selectors/device'; import Config from 'assets/config'; import FilteredList from './filtered_list'; @@ -124,6 +124,7 @@ 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 0ae75dd47..5613c86ba 100644 --- a/app/components/sidebars/main/channels_list/index.js +++ b/app/components/sidebars/main/channels_list/index.js @@ -4,12 +4,13 @@ import {connect} from 'react-redux'; import {getTheme} from 'mattermost-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 01aa8ab45..d907cb118 100644 --- a/app/components/sidebars/main/channels_list/list/index.js +++ b/app/components/sidebars/main/channels_list/list/index.js @@ -21,7 +21,7 @@ import {haveITeamPermission} from 'mattermost-redux/selectors/entities/roles'; import Permissions from 'mattermost-redux/constants/permissions'; import {showModal} from 'app/actions/navigation'; - +import {isLandscape} from 'app/selectors/device'; import {DeviceTypes, ViewTypes} from 'app/constants'; import List from './list'; @@ -78,6 +78,7 @@ 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 c117574d9..11587f56c 100644 --- a/app/components/sidebars/main/channels_list/list/list.js +++ b/app/components/sidebars/main/channels_list/list/list.js @@ -20,13 +20,15 @@ import {General} from 'mattermost-redux/constants'; import {debounce} from 'mattermost-redux/actions/helpers'; import ChannelItem from 'app/components/sidebars/main/channels_list/channel_item'; -import {DeviceTypes, ListTypes} from 'app/constants'; +import {DeviceTypes, ListTypes, ViewTypes} from 'app/constants'; import {SidebarSectionTypes} from 'app/constants/view'; import {t} from 'app/utils/i18n'; import {preventDoubleTap} from 'app/utils/tap'; import {changeOpacity} from 'app/utils/theme'; +import {paddingLeft as padding} from 'app/components/safe_area_view/iphone_x_spacing'; + const VIEWABILITY_CONFIG = { ...ListTypes.VISIBILITY_CONFIG_DEFAULTS, waitForInteraction: true, @@ -45,6 +47,7 @@ export default class List extends PureComponent { theme: PropTypes.object.isRequired, orderedChannelIds: PropTypes.array.isRequired, previewChannel: PropTypes.func, + isLandscape: PropTypes.bool.isRequired, actions: PropTypes.shape({ showModal: PropTypes.func.isRequired, }).isRequired, @@ -342,7 +345,7 @@ export default class List extends PureComponent { }; renderSectionHeader = ({section}) => { - const {styles} = this.props; + const {styles, isLandscape} = this.props; const {intl} = this.context; const { action, @@ -355,7 +358,7 @@ export default class List extends PureComponent { return ( {topSeparator && this.renderSectionSeparator()} - + {intl.formatMessage({id, defaultMessage}).toUpperCase()} @@ -418,11 +421,15 @@ export default class List extends PureComponent { }; render() { - const {styles, theme} = this.props; + const {styles, theme, isLandscape} = this.props; const {sections, width, showIndicator} = this.state; const paddingBottom = this.listContentPadding(); + const unreadBarStyles = DeviceTypes.IS_IPHONE_X && isLandscape ? {width: width - 32, marginLeft: ViewTypes.IOS_HORIZONTAL_LANDSCAPE + 16} : {width}; + + const unreadTextStyles = DeviceTypes.IS_IPHONE_X && isLandscape ? {marginLeft: -44} : null; + return ( diff --git a/app/components/sidebars/main/channels_list/unread_indicator/index.js b/app/components/sidebars/main/channels_list/unread_indicator/index.js index 1e761f704..787ab9bf5 100644 --- a/app/components/sidebars/main/channels_list/unread_indicator/index.js +++ b/app/components/sidebars/main/channels_list/unread_indicator/index.js @@ -19,6 +19,7 @@ export default class UnreadIndicator extends PureComponent { style: ViewPropTypes.style, onPress: PropTypes.func, theme: PropTypes.object.isRequired, + textStyle: ViewPropTypes.style, }; static defaultProps = { @@ -40,7 +41,7 @@ export default class UnreadIndicator extends PureComponent { style={[style.container, this.props.style]} > @@ -64,7 +65,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { flexDirection: 'row', position: 'absolute', borderRadius: 15, - marginHorizontal: 15, + marginHorizontal: 25, height: 25, }, indicatorText: { 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 961f0fbdd..611d4a533 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,6 +6,8 @@ import {connect} from 'react-redux'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getCurrentTeamId, getTeam, makeGetBadgeCountForTeamId} from 'mattermost-redux/selectors/entities/teams'; +import {isLandscape} from 'app/selectors/device'; + import TeamsListItem from './teams_list_item.js'; function makeMapStateToProps() { @@ -20,6 +22,7 @@ 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 7978cfd76..e8e04c015 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,7 @@ import IonIcon from 'react-native-vector-icons/Ionicons'; import Badge from 'app/components/badge'; import TeamIcon from 'app/components/team_icon'; - +import {paddingLeft as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import {preventDoubleTap} from 'app/utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; @@ -26,6 +26,7 @@ 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(() => { @@ -41,6 +42,7 @@ export default class TeamsListItem extends React.PureComponent { name, teamId, theme, + isLandscape, } = this.props; const styles = getStyleSheet(theme); @@ -70,7 +72,7 @@ export default class TeamsListItem extends React.PureComponent { underlayColor={changeOpacity(theme.sidebarTextHoverBg, 0.5)} onPress={this.selectTeam} > - + height) ? width - ViewTypes.IOS_HORIZONTAL_LANDSCAPE : width; let style; if (DeviceTypes.IS_IPHONE_X) { style = { bottom, - width, + drawerWidth, }; } else { style = { diff --git a/app/components/widgets/settings/text_setting.js b/app/components/widgets/settings/text_setting.js index 772382083..10df31e04 100644 --- a/app/components/widgets/settings/text_setting.js +++ b/app/components/widgets/settings/text_setting.js @@ -12,6 +12,7 @@ import { import FormattedText from 'app/components/formatted_text'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export default class TextSetting extends PureComponent { static propTypes = { @@ -35,6 +36,7 @@ export default class TextSetting extends PureComponent { value: PropTypes.string.isRequired, multiline: PropTypes.bool, showRequiredAsterisk: PropTypes.bool, + isLandscape: PropTypes.bool.isRequired, keyboardType: PropTypes.oneOf([ 'default', 'number-pad', @@ -53,6 +55,7 @@ export default class TextSetting extends PureComponent { multiline: false, showRequiredAsterisk: false, keyboardType: 'default', + isLandscape: false, secureTextEntry: false, }; @@ -74,6 +77,7 @@ export default class TextSetting extends PureComponent { value, multiline, showRequiredAsterisk, + isLandscape, secureTextEntry, } = this.props; const style = getStyleSheet(theme); @@ -142,15 +146,17 @@ export default class TextSetting extends PureComponent { ); } + const noediting = disabled ? style.disabled : null; + return ( - + {labelContent} {asterisk} {optionalContent} - - + + - {disabledTextContent} - {helpTextContent} - {errorTextContent} + + {disabledTextContent} + {helpTextContent} + {errorTextContent} + ); } diff --git a/app/constants/view.js b/app/constants/view.js index 0f50aa7f9..730d69923 100644 --- a/app/constants/view.js +++ b/app/constants/view.js @@ -107,7 +107,7 @@ export default { MAX_CHANNELNAME_LENGTH: 22, ANDROID_TOP_LANDSCAPE: 46, ANDROID_TOP_PORTRAIT: 56, - IOS_TOP_LANDSCAPE: 32, + IOS_TOP_LANDSCAPE: 40, IOS_TOP_PORTRAIT: 64, IOSX_TOP_PORTRAIT: 88, STATUS_BAR_HEIGHT: 20, @@ -117,4 +117,5 @@ export default { DATA_SOURCE_CHANNELS: 'channels', NotificationLevels, SidebarSectionTypes, + IOS_HORIZONTAL_LANDSCAPE: 44, }; diff --git a/app/screens/about/about.js b/app/screens/about/about.js index 2417768c1..dc5f96efa 100644 --- a/app/screens/about/about.js +++ b/app/screens/about/about.js @@ -15,7 +15,7 @@ import DeviceInfo from 'react-native-device-info'; import FormattedText from 'app/components/formatted_text'; import StatusBar from 'app/components/status_bar'; import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import AppIcon from 'app/components/app_icon'; import Config from 'assets/config'; @@ -27,6 +27,7 @@ export default class About extends PureComponent { config: PropTypes.object.isRequired, license: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; componentWillReceiveProps(nextProps) { @@ -60,7 +61,7 @@ export default class About extends PureComponent { } render() { - const {theme, config, license} = this.props; + const {theme, config, license, isLandscape} = this.props; const style = getStyleSheet(theme); let title = ( @@ -218,7 +219,7 @@ export default class About extends PureComponent { diff --git a/app/screens/about/index.js b/app/screens/about/index.js index 7a35177d9..f2a3b69ff 100644 --- a/app/screens/about/index.js +++ b/app/screens/about/index.js @@ -5,6 +5,7 @@ import {connect} from 'react-redux'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general'; +import {isLandscape} from 'app/selectors/device'; import About from './about'; @@ -16,6 +17,7 @@ function mapStateToProps(state) { config, license, theme: getTheme(state), + isLandscape: isLandscape(state), }; } diff --git a/app/screens/channel/channel.ios.js b/app/screens/channel/channel.ios.js index 5e9189102..9d1c87543 100644 --- a/app/screens/channel/channel.ios.js +++ b/app/screens/channel/channel.ios.js @@ -38,6 +38,7 @@ export default class ChannelIOS extends ChannelBase { const {height} = Dimensions.get('window'); const { currentChannelId, + isLandscape, } = this.props; const channelLoaderStyle = [style.channelLoader, {height}]; @@ -45,8 +46,40 @@ export default class ChannelIOS extends ChannelBase { channelLoaderStyle.push(style.iOSHomeIndicator); } - const drawerContent = ( - + let safeViewContent; + if (DeviceTypes.IS_IPHONE_X && isLandscape) { + safeViewContent = ( + + + + + + + + + + + + {LocalConfig.EnableMobileClientUpgrade && } + + + ); + } else { + safeViewContent = ( @@ -73,6 +106,12 @@ export default class ChannelIOS extends ChannelBase { /> {LocalConfig.EnableMobileClientUpgrade && } + ); + } + + const drawerContent = ( + + {safeViewContent} + - + ); 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 0684d5685..c5df7b106 100644 --- a/app/screens/channel_add_members/channel_add_members.test.js +++ b/app/screens/channel_add_members/channel_add_members.test.js @@ -25,6 +25,7 @@ describe('ChannelAddMembers', () => { profilesNotInChannel: [], theme: Preferences.THEMES.default, componentId: 'component-id', + isLandscape: false, }; test('should render without error and call functions on mount', () => { diff --git a/app/screens/channel_add_members/index.js b/app/screens/channel_add_members/index.js index c2efa8625..431db3cea 100644 --- a/app/screens/channel_add_members/index.js +++ b/app/screens/channel_add_members/index.js @@ -13,7 +13,7 @@ import {getCurrentUserId, getProfilesNotInCurrentChannel} from 'mattermost-redux import {setButtons, popTopScreen} from 'app/actions/navigation'; import {handleAddChannelMembers} from 'app/actions/views/channel_add_members'; - +import {isLandscape} from 'app/selectors/device'; import ChannelAddMembers from './channel_add_members'; function mapStateToProps(state) { @@ -26,6 +26,7 @@ function mapStateToProps(state) { currentUserId: getCurrentUserId(state), profilesNotInChannel: getProfilesNotInCurrentChannel(state), theme: getTheme(state), + isLandscape: isLandscape(state), }; } diff --git a/app/screens/channel_info/channel_info.js b/app/screens/channel_info/channel_info.js index 027661a2c..d023aa688 100644 --- a/app/screens/channel_info/channel_info.js +++ b/app/screens/channel_info/channel_info.js @@ -65,6 +65,7 @@ export default class ChannelInfo extends PureComponent { canEditChannel: PropTypes.bool.isRequired, ignoreChannelMentions: PropTypes.bool.isRequired, isBot: PropTypes.bool.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -362,6 +363,7 @@ export default class ChannelInfo extends PureComponent { canEditChannel, theme, currentChannel, + isLandscape, } = this.props; if (channelIsArchived) { @@ -374,6 +376,7 @@ export default class ChannelInfo extends PureComponent { icon='users' textId={canManageUsers ? t('channel_header.manageMembers') : t('channel_header.viewMembers')} theme={theme} + isLandscape={isLandscape} /> ); @@ -389,6 +392,7 @@ export default class ChannelInfo extends PureComponent { textId={t('mobile.routes.channelInfo.favorite')} togglable={true} theme={theme} + isLandscape={isLandscape} /> { @@ -441,6 +448,7 @@ export default class ChannelInfo extends PureComponent { icon='users' textId={canManageUsers ? t('channel_header.manageMembers') : t('channel_header.viewMembers')} theme={theme} + isLandscape={isLandscape} /> } @@ -453,6 +461,7 @@ export default class ChannelInfo extends PureComponent { icon='user-plus' textId={t('channel_header.addMembers')} theme={theme} + isLandscape={isLandscape} /> } @@ -465,6 +474,7 @@ export default class ChannelInfo extends PureComponent { icon='edit' textId={t('mobile.channel_info.edit')} theme={theme} + isLandscape={isLandscape} /> )} @@ -482,6 +492,7 @@ export default class ChannelInfo extends PureComponent { status, theme, isBot, + isLandscape, } = this.props; const style = getStyleSheet(theme); @@ -535,12 +546,13 @@ export default class ChannelInfo extends PureComponent { icon='sign-out' textId={t('navbar.leave')} theme={theme} + isLandscape={isLandscape} /> } {this.renderLeaveOrDeleteChannelRow() && canDeleteChannel && !channelIsArchived && - + } {this.renderCloseDirect() && - + } diff --git a/app/screens/channel_info/channel_info_header.js b/app/screens/channel_info/channel_info_header.js index d24921c9f..44831040c 100644 --- a/app/screens/channel_info/channel_info_header.js +++ b/app/screens/channel_info/channel_info_header.js @@ -9,6 +9,7 @@ import { Text, TouchableHighlight, View, + SafeAreaView, } from 'react-native'; import {intlShape} from 'react-intl'; @@ -142,99 +143,101 @@ export default class ChannelInfoHeader extends React.PureComponent { style.detail; return ( - - - - - {displayName} - + + + + + + {displayName} + + + {this.renderHasGuestText(style)} + {purpose.length > 0 && + + + + + + + + + } + {header.length > 0 && + + + + + + + + + } + {isGroupConstrained && + + + + } + {creator && + + + + + } - {this.renderHasGuestText(style)} - {purpose.length > 0 && - - - - - - - - - } - {header.length > 0 && - - - - - - - - - } - {isGroupConstrained && - - - - } - {creator && - - - - - } - + ); } } @@ -282,5 +285,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { row: { paddingHorizontal: 15, }, + safeAreaView: { + backgroundColor: 'white', + }, }; }); diff --git a/app/screens/channel_info/channel_info_row.js b/app/screens/channel_info/channel_info_row.js index a8c59fc23..06657859f 100644 --- a/app/screens/channel_info/channel_info_row.js +++ b/app/screens/channel_info/channel_info_row.js @@ -14,6 +14,7 @@ import Icon from 'react-native-vector-icons/FontAwesome'; import FormattedText from 'app/components/formatted_text'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; function createTouchableComponent(children, action) { return ( @@ -24,7 +25,7 @@ function createTouchableComponent(children, action) { } function channelInfoRow(props) { - const {action, defaultMessage, detail, icon, iconColor, image, imageTintColor, textColor, textId, togglable, theme, shouldRender} = props; + const {action, defaultMessage, detail, icon, iconColor, image, imageTintColor, textColor, textId, togglable, theme, shouldRender, isLandscape} = props; if (!shouldRender) { return null; @@ -52,7 +53,7 @@ function channelInfoRow(props) { } const RowComponent = ( - + {iconElement} { const {loading} = this.state; - const {theme} = this.props; + const {theme, isLandscape} = this.props; const style = getStyleFromTheme(theme); if (loading || this.page === -1) { @@ -287,7 +288,7 @@ export default class ChannelMembers extends PureComponent { } return ( - + - + ); diff --git a/app/screens/channel_members/channel_members.test.js b/app/screens/channel_members/channel_members.test.js index 4ad691310..1c4aa2e29 100644 --- a/app/screens/channel_members/channel_members.test.js +++ b/app/screens/channel_members/channel_members.test.js @@ -23,6 +23,7 @@ describe('ChannelMembers', () => { popTopScreen: jest.fn(), }, componentId: 'component-id', + isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/channel_members/index.js b/app/screens/channel_members/index.js index 5c6b54f50..06d383feb 100644 --- a/app/screens/channel_members/index.js +++ b/app/screens/channel_members/index.js @@ -11,7 +11,7 @@ import {getProfilesInChannel, searchProfiles} from 'mattermost-redux/actions/use import {setButtons, popTopScreen} from 'app/actions/navigation'; import {handleRemoveChannelMembers} from 'app/actions/views/channel_members'; - +import {isLandscape} from 'app/selectors/device'; import ChannelMembers from './channel_members'; function makeMapStateToProps() { @@ -32,6 +32,7 @@ function makeMapStateToProps() { currentChannelMembers, currentUserId: state.entities.users.currentUserId, theme: getTheme(state), + isLandscape: isLandscape(state), }; }; } diff --git a/app/screens/edit_channel/edit_channel.js b/app/screens/edit_channel/edit_channel.js index d3f70a24a..a38b0090a 100644 --- a/app/screens/edit_channel/edit_channel.js +++ b/app/screens/edit_channel/edit_channel.js @@ -9,7 +9,7 @@ import { InteractionManager, } from 'react-native'; import {Navigation} from 'react-native-navigation'; - +import SafeAreaView from 'app/components/safe_area_view'; import {General, RequestStatus} from 'mattermost-redux/constants'; import EventEmitter from 'mattermost-redux/utils/event_emitter'; @@ -295,29 +295,31 @@ export default class EditChannel extends PureComponent { } = this.state; return ( - + + + ); } } diff --git a/app/screens/edit_post/edit_post.js b/app/screens/edit_post/edit_post.js index 741a94776..871814904 100644 --- a/app/screens/edit_post/edit_post.js +++ b/app/screens/edit_post/edit_post.js @@ -15,6 +15,7 @@ import StatusBar from 'app/components/status_bar'; import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_localized_placeholder'; import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme'; import {t} from 'app/utils/i18n'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import {RequestStatus} from 'mattermost-redux/constants'; @@ -32,6 +33,7 @@ export default class EditPost extends PureComponent { editPostRequest: PropTypes.object.isRequired, post: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -146,7 +148,7 @@ export default class EditPost extends PureComponent { }; render() { - const {deviceHeight, deviceWidth, theme} = this.props; + const {deviceHeight, deviceWidth, theme, isLandscape} = this.props; const {editing, message, error} = this.state; const style = getStyleSheet(theme); @@ -178,7 +180,7 @@ export default class EditPost extends PureComponent { {displayError} - + { const {formatMessage} = this.context.intl; - const {firstNameDisabled, theme} = this.props; + const {firstNameDisabled, theme, isLandscape} = this.props; const {firstName} = this.state; return ( @@ -337,13 +337,14 @@ export default class EditProfile extends PureComponent { onChange={this.updateField} theme={theme} value={firstName} + isLandscape={isLandscape} /> ); }; renderLastNameSettings = () => { const {formatMessage} = this.context.intl; - const {lastNameDisabled, theme} = this.props; + const {lastNameDisabled, theme, isLandscape} = this.props; const {lastName} = this.state; return ( @@ -359,6 +360,7 @@ export default class EditProfile extends PureComponent { onChange={this.updateField} theme={theme} value={lastName} + isLandscape={isLandscape} /> ); @@ -366,7 +368,7 @@ export default class EditProfile extends PureComponent { renderUsernameSettings = () => { const {formatMessage} = this.context.intl; - const {currentUser, theme} = this.props; + const {currentUser, theme, isLandscape} = this.props; const {username} = this.state; const disabled = currentUser.auth_service !== ''; @@ -383,13 +385,14 @@ export default class EditProfile extends PureComponent { onChange={this.updateField} theme={theme} value={username} + isLandscape={isLandscape} /> ); }; renderEmailSettings = () => { const {formatMessage} = this.context.intl; - const {currentUser, theme} = this.props; + const {currentUser, theme, isLandscape} = this.props; const {email} = this.state; let helpText; @@ -444,6 +447,7 @@ export default class EditProfile extends PureComponent { onChange={this.updateField} theme={theme} value={email} + isLandscape={isLandscape} /> ); @@ -451,7 +455,7 @@ export default class EditProfile extends PureComponent { renderNicknameSettings = () => { const {formatMessage} = this.context.intl; - const {nicknameDisabled, theme} = this.props; + const {nicknameDisabled, theme, isLandscape} = this.props; const {nickname} = this.state; return ( @@ -467,13 +471,14 @@ export default class EditProfile extends PureComponent { onChange={this.updateField} theme={theme} value={nickname} + isLandscape={isLandscape} /> ); }; renderPositionSettings = () => { const {formatMessage} = this.context.intl; - const {positionDisabled, theme} = this.props; + const {positionDisabled, theme, isLandscape} = this.props; const {position} = this.state; return ( @@ -489,6 +494,7 @@ export default class EditProfile extends PureComponent { onChange={this.updateField} theme={theme} value={position} + isLandscape={isLandscape} /> ); }; diff --git a/app/screens/edit_profile/edit_profile.test.js b/app/screens/edit_profile/edit_profile.test.js index 71bd67850..f84dcb230 100644 --- a/app/screens/edit_profile/edit_profile.test.js +++ b/app/screens/edit_profile/edit_profile.test.js @@ -43,6 +43,7 @@ describe('edit_profile', () => { }, commandType: 'ShowModal', componentId: 'component-id', + isLandscape: false, }; test('should match snapshot', async () => { diff --git a/app/screens/edit_profile/index.js b/app/screens/edit_profile/index.js index 21eb519c7..70f3db182 100644 --- a/app/screens/edit_profile/index.js +++ b/app/screens/edit_profile/index.js @@ -7,7 +7,7 @@ import {bindActionCreators} from 'redux'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers'; - +import {isLandscape} from 'app/selectors/device'; import {popTopScreen, dismissModal, setButtons} from 'app/actions/navigation'; import {setProfileImageUri, removeProfileImage, updateUser} from 'app/actions/views/edit_profile'; @@ -41,6 +41,7 @@ function mapStateToProps(state, ownProps) { nicknameDisabled, positionDisabled, theme: getTheme(state), + isLandscape: isLandscape(state), }; } diff --git a/app/screens/expanded_announcement_banner/expanded_announcement_banner.js b/app/screens/expanded_announcement_banner/expanded_announcement_banner.js index 3fb7a31ae..0b10ea863 100644 --- a/app/screens/expanded_announcement_banner/expanded_announcement_banner.js +++ b/app/screens/expanded_announcement_banner/expanded_announcement_banner.js @@ -5,10 +5,9 @@ import PropTypes from 'prop-types'; import React from 'react'; import {ScrollView, View} from 'react-native'; import Button from 'react-native-button'; - import FormattedText from 'app/components/formatted_text'; import Markdown from 'app/components/markdown'; - +import SafeAreaView from 'app/components/safe_area_view'; import {getMarkdownTextStyles, getMarkdownBlockStyles} from 'app/utils/markdown'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; @@ -59,21 +58,23 @@ export default class ExpandedAnnouncementBanner extends React.PureComponent { } return ( - - - - - {dismissButton} - + + + + + + {dismissButton} + + ); } } diff --git a/app/screens/flagged_posts/flagged_posts.js b/app/screens/flagged_posts/flagged_posts.js index bb8a03e52..e5d757006 100644 --- a/app/screens/flagged_posts/flagged_posts.js +++ b/app/screens/flagged_posts/flagged_posts.js @@ -8,7 +8,6 @@ import { Keyboard, FlatList, StyleSheet, - SafeAreaView, View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; @@ -227,12 +226,10 @@ export default class FlaggedPosts extends PureComponent { } return ( - - - - {component} - - + + + {component} + ); } } diff --git a/app/screens/login/index.js b/app/screens/login/index.js index 5ec265094..077d7744b 100644 --- a/app/screens/login/index.js +++ b/app/screens/login/index.js @@ -7,7 +7,7 @@ import {connect} from 'react-redux'; import {login} from 'mattermost-redux/actions/users'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general'; - +import {isLandscape} from 'app/selectors/device'; import {resetToChannel, goToScreen} from 'app/actions/navigation'; import LoginActions from 'app/actions/views/login'; @@ -23,6 +23,7 @@ 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 3fcd0e81d..0ab5e4386 100644 --- a/app/screens/login/login.js +++ b/app/screens/login/login.js @@ -20,7 +20,7 @@ import Button from 'react-native-button'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; import {RequestStatus} from 'mattermost-redux/constants'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import ErrorText from 'app/components/error_text'; import FormattedText from 'app/components/formatted_text'; import StatusBar from 'app/components/status_bar'; @@ -52,6 +52,7 @@ export default class Login extends PureComponent { loginId: PropTypes.string.isRequired, password: PropTypes.string.isRequired, loginRequest: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -357,7 +358,7 @@ export default class Login extends PureComponent { diff --git a/app/screens/login/login.test.js b/app/screens/login/login.test.js index 3a3998d4f..fda355286 100644 --- a/app/screens/login/login.test.js +++ b/app/screens/login/login.test.js @@ -33,6 +33,7 @@ describe('Login', () => { resetToChannel: jest.fn(), goToScreen: 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 e29cd446a..d7ac6975b 100644 --- a/app/screens/login_options/index.js +++ b/app/screens/login_options/index.js @@ -8,7 +8,7 @@ import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general'; import {goToScreen} from 'app/actions/navigation'; - +import {isLandscape} from 'app/selectors/device'; import LoginOptions from './login_options'; function mapStateToProps(state) { @@ -18,6 +18,7 @@ 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 9df26aa0f..ca078eb43 100644 --- a/app/screens/login_options/login_options.js +++ b/app/screens/login_options/login_options.js @@ -22,6 +22,7 @@ import {preventDoubleTap} from 'app/utils/tap'; import LocalConfig from 'assets/config'; import gitlab from 'assets/images/gitlab.png'; import logo from 'assets/images/logo.png'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export default class LoginOptions extends PureComponent { static propTypes = { @@ -30,6 +31,7 @@ export default class LoginOptions extends PureComponent { }).isRequired, config: PropTypes.object.isRequired, license: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -253,7 +255,7 @@ export default class LoginOptions extends PureComponent { return ( diff --git a/app/screens/long_post/index.js b/app/screens/long_post/index.js index eb3a3b58f..03ea3f150 100644 --- a/app/screens/long_post/index.js +++ b/app/screens/long_post/index.js @@ -11,7 +11,7 @@ import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {dismissModal, goToScreen} from 'app/actions/navigation'; import {loadThreadIfNecessary} from 'app/actions/views/channel'; - +import {isLandscape} from 'app/selectors/device'; import LongPost from './long_post'; function makeMapStateToProps() { @@ -29,6 +29,7 @@ function makeMapStateToProps() { inThreadView: Boolean(state.entities.posts.selectedPostId), fileIds: post ? post.file_ids : false, 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 d05937850..9ef136f1c 100644 --- a/app/screens/long_post/long_post.js +++ b/app/screens/long_post/long_post.js @@ -21,6 +21,7 @@ import SafeAreaView from 'app/components/safe_area_view'; import {emptyFunction} from 'app/utils/general'; import {preventDoubleTap} from 'app/utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import {marginHorizontal as margin} from 'app/components/safe_area_view/iphone_x_spacing'; Animatable.initializeRegistryWithDefinitions({ growOut: { @@ -57,6 +58,7 @@ export default class LongPost extends PureComponent { onPermalinkPress: PropTypes.func, postId: PropTypes.string.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -163,6 +165,7 @@ export default class LongPost extends PureComponent { onPermalinkPress, postId, theme, + isLandscape, } = this.props; const style = getStyleSheet(theme); @@ -183,7 +186,7 @@ export default class LongPost extends PureComponent { footerColor='transparent' forceTop={44} > - + true : this.getChannels; const style = getStyleFromTheme(theme); @@ -342,7 +343,7 @@ export default class MoreChannels extends PureComponent { content = ( - + { currentTeamId: 'current_team_id', theme: Preferences.THEMES.default, componentId: 'component-id', + isLandscape: false, }; test('should match snapshot', () => { diff --git a/app/screens/more_dms/index.js b/app/screens/more_dms/index.js index 0f92b9b0a..dc0f17866 100644 --- a/app/screens/more_dms/index.js +++ b/app/screens/more_dms/index.js @@ -6,7 +6,7 @@ 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 {getProfiles, getProfilesInTeam, searchProfiles} from 'mattermost-redux/actions/users'; import {General} from 'mattermost-redux/constants'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; @@ -30,6 +30,7 @@ function mapStateToProps(state) { currentDisplayName: state.views.channel.displayName, currentUserId: getCurrentUserId(state), 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 3f1640020..15dcfc2d7 100644 --- a/app/screens/more_dms/more_dms.js +++ b/app/screens/more_dms/more_dms.js @@ -12,6 +12,7 @@ import {General} from 'mattermost-redux/constants'; import EventEmitter from 'mattermost-redux/utils/event_emitter'; import {getGroupDisplayNameFromUserIds} from 'mattermost-redux/utils/channel_utils'; import {displayUsername, filterProfilesMatchingTerm} from 'mattermost-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'; @@ -50,6 +51,7 @@ export default class MoreDirectMessages extends PureComponent { restrictDirectMessage: PropTypes.bool.isRequired, teammateNameDisplay: PropTypes.string, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -394,7 +396,7 @@ export default class MoreDirectMessages extends PureComponent { render() { const {formatMessage} = this.context.intl; - const {currentUserId, theme} = this.props; + const {currentUserId, theme, isLandscape} = this.props; const { loading, profiles, @@ -452,7 +454,7 @@ export default class MoreDirectMessages extends PureComponent { return ( - + { }], onCancelPress: jest.fn(), title: 'test', + isLandscape: false, }; test('should match snapshot for iOS', async () => { diff --git a/app/screens/options_modal/options_modal.js b/app/screens/options_modal/options_modal.js index dd3ff952d..b1935b768 100644 --- a/app/screens/options_modal/options_modal.js +++ b/app/screens/options_modal/options_modal.js @@ -34,6 +34,7 @@ export default class OptionsModal extends PureComponent { PropTypes.string, PropTypes.object, ]), + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -86,6 +87,7 @@ export default class OptionsModal extends PureComponent { const { items, title, + isLandscape, } = this.props; return ( @@ -97,6 +99,7 @@ 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 e80a69cc7..67a9bbf08 100644 --- a/app/screens/options_modal/options_modal_list.ios.js +++ b/app/screens/options_modal/options_modal_list.ios.js @@ -10,7 +10,7 @@ import { View, } from 'react-native'; import IconFont from 'react-native-vector-icons/FontAwesome'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import FormattedText from 'app/components/formatted_text'; import {preventDoubleTap} from 'app/utils/tap'; @@ -23,6 +23,7 @@ export default class OptionsModalList extends PureComponent { PropTypes.string, PropTypes.object, ]), + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -119,7 +120,7 @@ export default class OptionsModalList extends PureComponent { render() { return ( - + {this.renderOptions()} diff --git a/app/screens/permalink/__snapshots__/permalink.test.js.snap b/app/screens/permalink/__snapshots__/permalink.test.js.snap index e1bf1fd77..2569bba47 100644 --- a/app/screens/permalink/__snapshots__/permalink.test.js.snap +++ b/app/screens/permalink/__snapshots__/permalink.test.js.snap @@ -9,10 +9,13 @@ exports[`Permalink should match snapshot 1`] = ` > { 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/pinned_posts.js b/app/screens/pinned_posts/pinned_posts.js index b76c18b93..8197e1a6e 100644 --- a/app/screens/pinned_posts/pinned_posts.js +++ b/app/screens/pinned_posts/pinned_posts.js @@ -8,7 +8,6 @@ import { Keyboard, FlatList, StyleSheet, - SafeAreaView, View, } from 'react-native'; import {Navigation} from 'react-native-navigation'; @@ -224,12 +223,10 @@ export default class PinnedPosts extends PureComponent { } return ( - - - - {component} - - + + + {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 991f11d36..dfc9b7257 100644 --- a/app/screens/post_options/__snapshots__/post_options.test.js.snap +++ b/app/screens/post_options/__snapshots__/post_options.test.js.snap @@ -16,21 +16,25 @@ exports[`PostOptions should match snapshot, no option for system message to user > @@ -54,27 +58,32 @@ exports[`PostOptions should match snapshot, showing Delete option only for syste > @@ -98,27 +107,32 @@ exports[`PostOptions should match snapshot, showing all possible options 1`] = ` > diff --git a/app/screens/post_options/index.js b/app/screens/post_options/index.js index e6120ef8e..cbfa74ec5 100644 --- a/app/screens/post_options/index.js +++ b/app/screens/post_options/index.js @@ -24,7 +24,7 @@ import {canEditPost} from 'mattermost-redux/utils/post_utils'; import {THREAD} from 'app/constants/screen'; import {dismissModal, showModal} from 'app/actions/navigation'; import {addReaction} from 'app/actions/views/emoji'; -import {getDimensions} from 'app/selectors/device'; +import {getDimensions, isLandscape} from 'app/selectors/device'; import PostOptions from './post_options'; @@ -109,6 +109,7 @@ export function mapStateToProps(state, ownProps) { currentTeamUrl: getCurrentTeamUrl(state), isMyPost: currentUserId === post.user_id, theme: getTheme(state), + isLandscape: isLandscape(state), }; } diff --git a/app/screens/post_options/index.test.js b/app/screens/post_options/index.test.js index 6ae7de39c..b3b8cff04 100644 --- a/app/screens/post_options/index.test.js +++ b/app/screens/post_options/index.test.js @@ -21,6 +21,7 @@ commonSelectors.getCurrentChannelId = jest.fn(); teamSelectors.getCurrentTeamId = jest.fn(); teamSelectors.getCurrentTeamUrl = jest.fn(); deviceSelectors.getDimensions = jest.fn(); +deviceSelectors.isLandscape = jest.fn(); preferencesSelectors.getTheme = jest.fn(); describe('mapStateToProps', () => { diff --git a/app/screens/post_options/post_option.js b/app/screens/post_options/post_option.js index b3bf422bd..a095db0e9 100644 --- a/app/screens/post_options/post_option.js +++ b/app/screens/post_options/post_option.js @@ -12,7 +12,7 @@ import { TouchableNativeFeedback, View, } from 'react-native'; - +import {paddingLeft as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import copy from 'assets/images/post_menu/copy.png'; import edit from 'assets/images/post_menu/edit.png'; import emoji from 'assets/images/post_menu/emoji.png'; @@ -39,6 +39,7 @@ export default class PostOption extends PureComponent { icon: PropTypes.string.isRequired, onPress: PropTypes.func.isRequired, text: PropTypes.string.isRequired, + isLandscape: PropTypes.bool.isRequired, }; handleOnPress = () => { @@ -49,7 +50,7 @@ export default class PostOption extends PureComponent { }; render() { - const {destructive, icon, text} = this.props; + const {destructive, icon, text, isLandscape} = this.props; const image = icons[icon]; const Touchable = Platform.select({ @@ -74,7 +75,7 @@ export default class PostOption extends PureComponent { diff --git a/app/screens/post_options/post_options.js b/app/screens/post_options/post_options.js index 64c934ebd..732c6e885 100644 --- a/app/screens/post_options/post_options.js +++ b/app/screens/post_options/post_options.js @@ -43,6 +43,7 @@ export default class PostOptions extends PureComponent { isMyPost: PropTypes.bool, post: PropTypes.object.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -63,7 +64,7 @@ export default class PostOptions extends PureComponent { getAddReactionOption = () => { const {formatMessage} = this.context.intl; - const {canAddReaction} = this.props; + const {canAddReaction, isLandscape} = this.props; if (canAddReaction) { return ( @@ -72,6 +73,7 @@ export default class PostOptions extends PureComponent { icon='emoji' text={formatMessage({id: 'mobile.post_info.add_reaction', defaultMessage: 'Add Reaction'})} onPress={this.handleAddReaction} + isLandscape={isLandscape} /> ); } @@ -81,7 +83,7 @@ export default class PostOptions extends PureComponent { getReplyOption = () => { const {formatMessage} = this.context.intl; - const {canReply} = this.props; + const {canReply, isLandscape} = this.props; if (canReply) { return ( @@ -90,6 +92,7 @@ export default class PostOptions extends PureComponent { icon='reply' text={formatMessage({id: 'mobile.post_info.reply', defaultMessage: 'Reply'})} onPress={this.handleReply} + isLandscape={isLandscape} /> ); } @@ -99,7 +102,7 @@ export default class PostOptions extends PureComponent { getCopyPermalink = () => { const {formatMessage} = this.context.intl; - const {canCopyPermalink} = this.props; + const {canCopyPermalink, isLandscape} = this.props; if (canCopyPermalink) { return ( @@ -108,6 +111,7 @@ export default class PostOptions extends PureComponent { icon='link' text={formatMessage({id: 'get_post_link_modal.title', defaultMessage: 'Copy Permalink'})} onPress={this.handleCopyPermalink} + isLandscape={isLandscape} /> ); } @@ -117,7 +121,7 @@ export default class PostOptions extends PureComponent { getCopyText = () => { const {formatMessage} = this.context.intl; - const {canCopyText} = this.props; + const {canCopyText, isLandscape} = this.props; if (canCopyText) { return ( @@ -126,6 +130,7 @@ export default class PostOptions extends PureComponent { icon='copy' text={formatMessage({id: 'mobile.post_info.copy_text', defaultMessage: 'Copy Text'})} onPress={this.handleCopyText} + isLandscape={isLandscape} /> ); } @@ -135,7 +140,7 @@ export default class PostOptions extends PureComponent { getDeleteOption = () => { const {formatMessage} = this.context.intl; - const {canDelete} = this.props; + const {canDelete, isLandscape} = this.props; if (canDelete) { return ( @@ -145,6 +150,7 @@ export default class PostOptions extends PureComponent { icon='trash' text={formatMessage({id: 'post_info.del', defaultMessage: 'Delete'})} onPress={this.handlePostDelete} + isLandscape={isLandscape} /> ); } @@ -154,7 +160,7 @@ export default class PostOptions extends PureComponent { getEditOption = () => { const {formatMessage} = this.context.intl; - const {canEdit, canEditUntil} = this.props; + const {canEdit, canEditUntil, isLandscape} = this.props; if (canEdit && (canEditUntil === -1 || canEditUntil > Date.now())) { return ( @@ -163,6 +169,7 @@ export default class PostOptions extends PureComponent { icon='edit' text={formatMessage({id: 'post_info.edit', defaultMessage: 'Edit'})} onPress={this.handlePostEdit} + isLandscape={isLandscape} /> ); } @@ -172,7 +179,7 @@ export default class PostOptions extends PureComponent { getFlagOption = () => { const {formatMessage} = this.context.intl; - const {canFlag, isFlagged} = this.props; + const {canFlag, isFlagged, isLandscape} = this.props; if (!canFlag) { return null; @@ -185,6 +192,7 @@ export default class PostOptions extends PureComponent { icon='flag' text={formatMessage({id: 'mobile.post_info.unflag', defaultMessage: 'Unflag'})} onPress={this.handleUnflagPost} + isLandscape={isLandscape} /> ); } @@ -195,13 +203,14 @@ export default class PostOptions extends PureComponent { icon='flag' text={formatMessage({id: 'mobile.post_info.flag', defaultMessage: 'Flag'})} onPress={this.handleFlagPost} + isLandscape={isLandscape} /> ); }; getPinOption = () => { const {formatMessage} = this.context.intl; - const {canPin, post} = this.props; + const {canPin, post, isLandscape} = this.props; if (!canPin) { return null; @@ -214,6 +223,7 @@ export default class PostOptions extends PureComponent { icon='pin' text={formatMessage({id: 'mobile.post_info.unpin', defaultMessage: 'Unpin from Channel'})} onPress={this.handleUnpinPost} + isLandscape={isLandscape} /> ); } @@ -224,6 +234,7 @@ export default class PostOptions extends PureComponent { icon='pin' text={formatMessage({id: 'mobile.post_info.pin', defaultMessage: 'Pin to Channel'})} onPress={this.handlePinPost} + isLandscape={isLandscape} /> ); }; diff --git a/app/screens/post_options/post_options.test.js b/app/screens/post_options/post_options.test.js index cd742c97f..277bddda9 100644 --- a/app/screens/post_options/post_options.test.js +++ b/app/screens/post_options/post_options.test.js @@ -57,6 +57,7 @@ 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 506d03653..a668c3c3f 100644 --- a/app/screens/reaction_list/__snapshots__/reaction_header.test.js.snap +++ b/app/screens/reaction_list/__snapshots__/reaction_header.test.js.snap @@ -17,6 +17,7 @@ exports[`ReactionHeader should match snapshot 1`] = ` alwaysBounceHorizontal={false} horizontal={true} overScrollMode="never" + style={null} > { @@ -51,6 +52,7 @@ export default class ReactionHeader extends PureComponent { alwaysBounceHorizontal={false} horizontal={true} overScrollMode='never' + style={padding(this.props.isLandscape, -10)} > {this.renderReactionHeaderItems()} diff --git a/app/screens/reaction_list/reaction_header.test.js b/app/screens/reaction_list/reaction_header.test.js index e965faecb..f59d42659 100644 --- a/app/screens/reaction_list/reaction_header.test.js +++ b/app/screens/reaction_list/reaction_header.test.js @@ -14,6 +14,7 @@ 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 c409104c5..338797090 100644 --- a/app/screens/reaction_list/reaction_list.js +++ b/app/screens/reaction_list/reaction_list.js @@ -34,6 +34,7 @@ export default class ReactionList extends PureComponent { theme: PropTypes.object.isRequired, teammateNameDisplay: PropTypes.string, userProfiles: PropTypes.array, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -164,7 +165,7 @@ export default class ReactionList extends PureComponent { }; renderHeader = (forwardedRef) => { - const {theme} = this.props; + const {theme, isLandscape} = this.props; const {selected, sortedReactionsForHeader} = this.state; return ( @@ -174,6 +175,7 @@ export default class ReactionList extends PureComponent { reactions={sortedReactionsForHeader} theme={theme} forwardedRef={forwardedRef} + isLandscape={isLandscape} /> ); }; diff --git a/app/screens/reaction_list/reaction_list.test.js b/app/screens/reaction_list/reaction_list.test.js index 86f5646d9..12626a479 100644 --- a/app/screens/reaction_list/reaction_list.test.js +++ b/app/screens/reaction_list/reaction_list.test.js @@ -23,6 +23,7 @@ describe('ReactionList', () => { teammateNameDisplay: 'username', userProfiles: [{id: 'user_id_1', username: 'username_1'}, {id: 'user_id_2', username: 'username_2'}], componentId: 'component-id', + isLandscape: false, }; test('should match snapshot', () => { 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 04056f9e6..6b15ce349 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,10 +14,13 @@ exports[`ReactionRow should match snapshot, renderContent 1`] = ` > - + { 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/recent_mentions.js b/app/screens/recent_mentions/recent_mentions.js index 9fd2ba7a1..226d95c64 100644 --- a/app/screens/recent_mentions/recent_mentions.js +++ b/app/screens/recent_mentions/recent_mentions.js @@ -7,7 +7,6 @@ import {intlShape} from 'react-intl'; import { Keyboard, FlatList, - SafeAreaView, StyleSheet, View, } from 'react-native'; @@ -225,12 +224,10 @@ export default class RecentMentions extends PureComponent { } return ( - - - - {component} - - + + + {component} + ); } } diff --git a/app/screens/search/__snapshots__/modifier.test.js.snap b/app/screens/search/__snapshots__/modifier.test.js.snap index f55b3a0a2..7b3b9076b 100644 --- a/app/screens/search/__snapshots__/modifier.test.js.snap +++ b/app/screens/search/__snapshots__/modifier.test.js.snap @@ -19,11 +19,14 @@ 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 9a08008f9..d62660a79 100644 --- a/app/screens/search/channel_display_name/index.js +++ b/app/screens/search/channel_display_name/index.js @@ -6,7 +6,7 @@ import {connect} from 'react-redux'; import {makeGetChannel} from 'mattermost-redux/selectors/entities/channels'; import {getPost} from 'mattermost-redux/selectors/entities/posts'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; - +import {isLandscape} from 'app/selectors/device'; import ChannelDisplayName from './channel_display_name'; function makeMapStateToProps() { @@ -18,6 +18,7 @@ function makeMapStateToProps() { return { displayName: channel ? channel.display_name : '', theme: getTheme(state), + isLandscape: isLandscape(state), }; }; } diff --git a/app/screens/search/modifier.js b/app/screens/search/modifier.js index bd7a58501..822deaab8 100644 --- a/app/screens/search/modifier.js +++ b/app/screens/search/modifier.js @@ -7,6 +7,7 @@ import {Text, TouchableHighlight, View} from 'react-native'; import AwesomeIcon from 'react-native-vector-icons/FontAwesome'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; export const MODIFIER_LABEL_HEIGHT = 58; @@ -15,6 +16,11 @@ 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 = () => { @@ -24,7 +30,7 @@ export default class Modifier extends PureComponent { }; render() { - const {item, theme} = this.props; + const {item, theme, isLandscape} = this.props; const style = getStyleFromTheme(theme); return ( @@ -34,7 +40,7 @@ export default class Modifier extends PureComponent { onPress={this.handlePress} > - + { @@ -30,7 +36,7 @@ export default class RecentItem extends PureComponent { }; render() { - const {item, theme} = this.props; + const {item, theme, isLandscape} = this.props; const style = getStyleFromTheme(theme); return ( @@ -40,7 +46,7 @@ export default class RecentItem extends PureComponent { onPress={this.handlePress} > { - const {theme} = this.props; + const {theme, isLandscape} = this.props; return ( ); }; renderPost = ({item, index}) => { - const {postIds, theme} = this.props; + const {postIds, theme, isLandscape} = this.props; const style = getStyleFromTheme(theme); if (item.id) { @@ -374,7 +376,7 @@ export default class Search extends PureComponent { } return ( - + {this.archivedIndicator(postIds[index], style)} { - const {theme} = this.props; + const {theme, isLandscape} = this.props; const {title} = section; const style = getStyleFromTheme(theme); @@ -411,7 +413,7 @@ export default class Search extends PureComponent { return ( - + {title} @@ -423,7 +425,7 @@ export default class Search extends PureComponent { }; renderRecentItem = ({item}) => { - const {theme} = this.props; + const {theme, isLandscape} = this.props; return ( ); }; @@ -685,7 +688,7 @@ export default class Search extends PureComponent { > - + - - - - - - - + + + + + + + + + + + + - - - - - - + + + ); } } 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 bae4affb8..9efe63707 100644 --- a/app/screens/select_team/__snapshots__/select_team.test.js.snap +++ b/app/screens/select_team/__snapshots__/select_team.test.js.snap @@ -60,9 +60,12 @@ exports[`SelectTeam should match snapshot for teams 1`] = ` > { - const {currentUrl, theme} = this.props; + const {currentUrl, theme, isLandscape} = this.props; const style = getStyleFromTheme(theme); if (item.id === 'mobile.select_team.no_teams') { @@ -178,7 +179,7 @@ export default class SelectTeam extends PureComponent { } return ( - + this.onSelectTeam(item))} > @@ -212,7 +213,7 @@ export default class SelectTeam extends PureComponent { }; render() { - const {theme} = this.props; + const {theme, isLandscape} = this.props; const {teams} = this.state; const style = getStyleFromTheme(theme); @@ -250,7 +251,7 @@ export default class SelectTeam extends PureComponent { - + { status: RequestStatus.FAILURE, }, componentId: 'component-id', + isLandscape: false, }; test('should match snapshot for fail of teams', async () => { 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 653605baa..9b3065cff 100644 --- a/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap +++ b/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap @@ -49,6 +49,7 @@ exports[`SelectorScreen should match snapshot for channels 1`] = ` @@ -134,7 +137,7 @@ class AdvancedSettings extends PureComponent { }; render() { - const {theme} = this.props; + const {theme, isLandscape} = this.props; const style = getStyleSheet(theme); return ( @@ -156,6 +159,7 @@ class AdvancedSettings extends PureComponent { showArrow={false} rightComponent={this.renderCacheFileSize()} theme={theme} + isLandscape={isLandscape} /> {this.renderSentryDebugOptions()} diff --git a/app/screens/settings/advanced_settings/index.js b/app/screens/settings/advanced_settings/index.js index d02580632..0655ea903 100644 --- a/app/screens/settings/advanced_settings/index.js +++ b/app/screens/settings/advanced_settings/index.js @@ -6,12 +6,13 @@ import {connect} from 'react-redux'; import {purgeOfflineStore} from 'app/actions/views/root'; import {getTheme} from 'mattermost-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 b209ed259..02846c992 100644 --- a/app/screens/settings/clock_display/clock_display.ios.js +++ b/app/screens/settings/clock_display/clock_display.ios.js @@ -17,7 +17,7 @@ import ClockDisplayBase from './clock_display_base'; export default class ClockDisplay extends ClockDisplayBase { render() { - const {theme} = this.props; + const {theme, isLandscape} = this.props; const {newMilitaryTime} = this.state; const style = getStyleSheet(theme); @@ -30,6 +30,7 @@ export default class ClockDisplay extends ClockDisplayBase { footerId={t('user.settings.display.preferTime')} footerDefaultMessage='Select how you prefer time displayed.' theme={theme} + isLandscape={isLandscape} > - + @@ -76,5 +79,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { flex: 1, paddingTop: 35, }, + divider: { + backgroundColor: changeOpacity(theme.centerChannelColor, 0.1), + height: 1, + }, }; }); diff --git a/app/screens/settings/clock_display/index.js b/app/screens/settings/clock_display/index.js index f9a5e0534..0ff012eac 100644 --- a/app/screens/settings/clock_display/index.js +++ b/app/screens/settings/clock_display/index.js @@ -8,7 +8,7 @@ import {getTheme, get as getPreference} from 'mattermost-redux/selectors/entitie import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; import {savePreferences} from 'mattermost-redux/actions/preferences'; import Preferences from 'mattermost-redux/constants/preferences'; - +import {isLandscape} from 'app/selectors/device'; import ClockDisplay from './clock_display'; function mapStateToProps(state) { @@ -19,6 +19,7 @@ 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 5ad51bbf2..763e89815 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 @@ -33,6 +33,7 @@ exports[`DisplaySettings should match snapshot 1`] = ` iconName="ios-time" iconType="ion" isDestructor={false} + isLandscape={false} onPress={[Function]} separator={false} showArrow={false} @@ -110,6 +111,7 @@ exports[`DisplaySettings should match snapshot on Tablet devices 1`] = ` iconName="columns" iconType="fontawesome" isDestructor={false} + isLandscape={false} onPress={[Function]} separator={true} showArrow={false} @@ -148,6 +150,7 @@ exports[`DisplaySettings should match snapshot on Tablet devices 1`] = ` iconName="ios-time" iconType="ion" isDestructor={false} + isLandscape={false} onPress={[Function]} separator={false} showArrow={false} diff --git a/app/screens/settings/display_settings/display_settings.js b/app/screens/settings/display_settings/display_settings.js index c134f7997..85b77760e 100644 --- a/app/screens/settings/display_settings/display_settings.js +++ b/app/screens/settings/display_settings/display_settings.js @@ -27,6 +27,7 @@ export default class DisplaySettings extends PureComponent { theme: PropTypes.object.isRequired, enableTheme: PropTypes.bool.isRequired, enableTimezone: PropTypes.bool.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -92,7 +93,7 @@ export default class DisplaySettings extends PureComponent { }); render() { - const {theme, enableTimezone, enableTheme} = this.props; + const {theme, enableTimezone, enableTheme, isLandscape} = this.props; const {showClockDisplaySettings} = this.state; const style = getStyleSheet(theme); @@ -120,6 +121,7 @@ export default class DisplaySettings extends PureComponent { separator={false} showArrow={false} theme={theme} + isLandscape={isLandscape} /> ); } @@ -136,6 +138,7 @@ export default class DisplaySettings extends PureComponent { separator={true} showArrow={false} theme={theme} + isLandscape={isLandscape} /> ); } @@ -156,6 +159,7 @@ export default class DisplaySettings extends PureComponent { separator={true} showArrow={false} theme={theme} + isLandscape={isLandscape} /> )} {timezoneOption} diff --git a/app/screens/settings/display_settings/display_settings.test.js b/app/screens/settings/display_settings/display_settings.test.js index 8f485108d..aaff3296f 100644 --- a/app/screens/settings/display_settings/display_settings.test.js +++ b/app/screens/settings/display_settings/display_settings.test.js @@ -23,6 +23,7 @@ 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 ab325072a..3eb65215e 100644 --- a/app/screens/settings/display_settings/index.js +++ b/app/screens/settings/display_settings/index.js @@ -10,7 +10,7 @@ import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone'; import {applyTheme, goToScreen} from 'app/actions/navigation'; import {getAllowedThemes} from 'app/selectors/theme'; import {isThemeSwitchingEnabled} from 'app/utils/theme'; - +import {isLandscape} from 'app/selectors/device'; import DisplaySettings from './display_settings'; function mapStateToProps(state) { @@ -21,6 +21,7 @@ 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 146d2b866..1aa52bbb8 100644 --- a/app/screens/settings/general/index.js +++ b/app/screens/settings/general/index.js @@ -11,6 +11,7 @@ import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {applyTheme, goToScreen, dismissModal} from 'app/actions/navigation'; import {purgeOfflineStore} from 'app/actions/views/root'; +import {isLandscape} from 'app/selectors/device'; import {removeProtocol} from 'app/utils/url'; import Settings from './settings'; @@ -26,6 +27,7 @@ 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 65f18e67b..3377d0754 100644 --- a/app/screens/settings/general/settings.js +++ b/app/screens/settings/general/settings.js @@ -40,6 +40,7 @@ class Settings extends PureComponent { intl: intlShape.isRequired, joinableTeams: PropTypes.array.isRequired, theme: PropTypes.object, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -169,7 +170,7 @@ class Settings extends PureComponent { }); render() { - const {config, joinableTeams, theme} = this.props; + const {config, joinableTeams, theme, isLandscape} = this.props; const style = getStyleSheet(theme); const showTeams = joinableTeams.length > 0; const showHelp = isValidUrl(config.HelpLink); @@ -191,6 +192,8 @@ class Settings extends PureComponent { onPress={this.goToNotifications} showArrow={showArrow} theme={theme} + separator={true} + isLandscape={isLandscape} /> {showTeams && - + + + } {showHelp && - + + + } {LocalConfig.EnableMobileClientUpgrade && LocalConfig.EnableMobileClientUpgradeUserSetting && - + + + } diff --git a/app/screens/settings/notification_settings/index.js b/app/screens/settings/notification_settings/index.js index 0196b84d1..4c98954eb 100644 --- a/app/screens/settings/notification_settings/index.js +++ b/app/screens/settings/notification_settings/index.js @@ -8,7 +8,7 @@ import {getCurrentUser, getStatusForUserId} from 'mattermost-redux/selectors/ent import {getConfig} from 'mattermost-redux/selectors/entities/general'; import {getMyPreferences, getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers'; - +import {isLandscape} from 'app/selectors/device'; import {updateMe} from 'mattermost-redux/actions/users'; import {goToScreen} from 'app/actions/navigation'; @@ -30,6 +30,7 @@ function mapStateToProps(state) { updateMeRequest: state.requests.users.updateMe, theme: getTheme(state), enableAutoResponder, + isLandscape: isLandscape(state), }; } diff --git a/app/screens/settings/notification_settings/notification_settings.js b/app/screens/settings/notification_settings/notification_settings.js index 47bd57e12..c15a1bef7 100644 --- a/app/screens/settings/notification_settings/notification_settings.js +++ b/app/screens/settings/notification_settings/notification_settings.js @@ -35,6 +35,7 @@ class NotificationSettings extends PureComponent { updateMeRequest: PropTypes.object.isRequired, currentUserStatus: PropTypes.string.isRequired, enableAutoResponder: PropTypes.bool.isRequired, + isLandscape: PropTypes.bool.isRequired, }; componentWillReceiveProps(nextProps) { @@ -175,7 +176,7 @@ class NotificationSettings extends PureComponent { }; render() { - const {theme, enableAutoResponder} = this.props; + const {theme, enableAutoResponder, isLandscape} = this.props; const style = getStyleSheet(theme); const showArrow = Platform.OS === 'ios'; @@ -192,6 +193,7 @@ class NotificationSettings extends PureComponent { separator={false} showArrow={showArrow} theme={theme} + isLandscape={isLandscape} /> ); } @@ -213,6 +215,7 @@ class NotificationSettings extends PureComponent { separator={true} showArrow={showArrow} theme={theme} + isLandscape={isLandscape} /> {autoResponder} diff --git a/app/screens/settings/notification_settings_auto_responder/index.js b/app/screens/settings/notification_settings_auto_responder/index.js index 41258439d..e8a7105ea 100644 --- a/app/screens/settings/notification_settings_auto_responder/index.js +++ b/app/screens/settings/notification_settings_auto_responder/index.js @@ -5,7 +5,7 @@ import {connect} from 'react-redux'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getCurrentUserId, getStatusForUserId} from 'mattermost-redux/selectors/entities/users'; - +import {isLandscape} from 'app/selectors/device'; import NotificationSettingsAutoResponder from './notification_settings_auto_responder'; function mapStateToProps(state) { @@ -15,6 +15,7 @@ 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 9bf28d12d..84c6c9e45 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 @@ -10,7 +10,7 @@ import { import {intlShape} from 'react-intl'; import {General} from 'mattermost-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'; @@ -27,6 +27,7 @@ export default class NotificationSettingsAutoResponder extends PureComponent { onBack: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, currentUserStatus: PropTypes.string.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -80,7 +81,7 @@ export default class NotificationSettingsAutoResponder extends PureComponent { }; render() { - const {theme} = this.props; + const {theme, isLandscape} = this.props; const { auto_responder_active: autoResponderActive, auto_responder_message: autoResponderMessage, @@ -101,6 +102,7 @@ export default class NotificationSettingsAutoResponder extends PureComponent {
{autoResponderActive === 'true' && ( @@ -115,6 +118,7 @@ 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 d7c64d230..6b4777560 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 @@ -12,6 +12,7 @@ exports[`NotificationSettingsEmailIos should match snapshot, renderEmailSection } headerDefaultMessage="SEND EMAIL NOTIFICATIONS" headerId="mobile.notification_settings.email.send" + isLandscape={false} theme={ Object { "awayIndicator": "#ffbc42", @@ -46,6 +47,7 @@ exports[`NotificationSettingsEmailIos should match snapshot, renderEmailSection action={[Function]} actionType="select" actionValue="30" + isLandscape={false} label={ {sendEmailNotifications && @@ -55,6 +56,7 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { actionValue={Preferences.INTERVAL_IMMEDIATE.toString()} selected={newInterval === Preferences.INTERVAL_IMMEDIATE.toString()} theme={theme} + isLandscape={isLandscape} /> {enableEmailBatching && @@ -71,6 +73,7 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { actionValue={Preferences.INTERVAL_FIFTEEN_MINUTES.toString()} selected={newInterval === Preferences.INTERVAL_FIFTEEN_MINUTES.toString()} theme={theme} + isLandscape={isLandscape} /> @@ -101,6 +105,7 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { actionValue={Preferences.INTERVAL_NEVER.toString()} selected={newInterval === Preferences.INTERVAL_NEVER.toString()} theme={theme} + isLandscape={isLandscape} /> } @@ -108,7 +113,7 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { } 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 5c5cee410..1fd757a61 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 @@ -37,6 +37,7 @@ describe('NotificationSettingsEmailIos', () => { siteName: 'Mattermost', 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 5a4083b5f..c0fbfb402 100644 --- a/app/screens/settings/notification_settings_mentions/index.js +++ b/app/screens/settings/notification_settings_mentions/index.js @@ -5,7 +5,7 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; - +import {isLandscape} from 'app/selectors/device'; import {goToScreen} from 'app/actions/navigation'; import NotificationSettingsMentions from './notification_settings_mentions'; @@ -13,6 +13,7 @@ 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 681996552..39a8cd97a 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,7 +8,6 @@ import { View, } from 'react-native'; import {injectIntl} from 'react-intl'; - import FormattedText from 'app/components/formatted_text'; import StatusBar from 'app/components/status_bar'; import Section from 'app/screens/settings/section'; @@ -34,7 +33,7 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { }; renderMentionSection(style) { - const {currentUser, theme} = this.props; + const {currentUser, theme, isLandscape} = this.props; let mentionKeysComponent; if (this.state.mention_keys) { @@ -53,6 +52,7 @@ 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 && @@ -72,6 +72,7 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { actionType='toggle' selected={this.state.first_name === 'true'} theme={theme} + isLandscape={isLandscape} /> @@ -92,6 +93,7 @@ class NotificationSettingsMentionsIos extends NotificationSettingsMentionsBase { action={this.toggleUsernameMention} actionType='toggle' theme={theme} + isLandscape={isLandscape} /> ); } renderReplySection(style) { - const {theme} = this.props; + const {theme, isLandscape} = this.props; return (
); diff --git a/app/screens/settings/notification_settings_mentions_keywords/index.js b/app/screens/settings/notification_settings_mentions_keywords/index.js index f3a886bb0..767384d74 100644 --- a/app/screens/settings/notification_settings_mentions_keywords/index.js +++ b/app/screens/settings/notification_settings_mentions_keywords/index.js @@ -5,7 +5,7 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; - +import {isLandscape} from 'app/selectors/device'; import {popTopScreen} from 'app/actions/navigation'; import NotificationSettingsMentionsKeywords from './notification_settings_mentions_keywords'; @@ -13,6 +13,7 @@ import NotificationSettingsMentionsKeywords from './notification_settings_mentio 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 f6ab36b92..9173336ce 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,7 +4,7 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {ScrollView, View} from 'react-native'; import {Navigation} from 'react-native-navigation'; - +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'; @@ -19,6 +19,7 @@ export default class NotificationSettingsMentionsKeywords extends PureComponent keywords: PropTypes.string, onBack: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; constructor(props) { @@ -56,11 +57,10 @@ export default class NotificationSettingsMentionsKeywords extends PureComponent } render() { - const {theme} = this.props; + const {theme, isLandscape} = this.props; const {keywords} = this.state; const style = getStyleSheet(theme); - return ( @@ -78,7 +78,7 @@ export default class NotificationSettingsMentionsKeywords extends PureComponent onSubmitEditing={this.handleSubmit} multiline={true} numberOfLines={1} - style={style.input} + style={[style.input, padding(isLandscape)]} autoCapitalize='none' autoCorrect={false} placeholder={{id: 'mobile.notification_settings_mentions.keywordsDescription', defaultMessage: 'Other words that trigger a mention'}} @@ -86,7 +86,7 @@ export default class NotificationSettingsMentionsKeywords extends PureComponent returnKeyType='done' /> - + { color: theme.centerChannelColor, fontSize: 15, height: 150, - paddingHorizontal: 15, paddingVertical: 10, }, helpContainer: { diff --git a/app/screens/settings/notification_settings_mobile/index.js b/app/screens/settings/notification_settings_mobile/index.js index f7087364e..a3b0603fa 100644 --- a/app/screens/settings/notification_settings_mobile/index.js +++ b/app/screens/settings/notification_settings_mobile/index.js @@ -7,7 +7,7 @@ import {connect} from 'react-redux'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getCurrentUser} from 'mattermost-redux/selectors/entities/users'; - +import {isLandscape} from 'app/selectors/device'; import {updateMe} from 'mattermost-redux/actions/users'; import NotificationSettingsMobile from './notification_settings_mobile'; @@ -23,6 +23,7 @@ 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 2c897b2c8..9825058db 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,12 +7,12 @@ 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'; @@ -20,7 +20,7 @@ import NotificationSettingsMobileBase from './notification_settings_mobile_base' class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { renderMobilePushSection(style) { - const {config, theme} = this.props; + const {config, theme, isLandscape} = this.props; const pushNotificationsEnabled = config.SendPushNotifications === 'true'; return ( @@ -28,6 +28,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { headerId={t('mobile.notification_settings_mobile.push_activity')} headerDefaultMessage='SEND NOTIFICATIONS' theme={theme} + isLandscape={isLandscape} > {pushNotificationsEnabled && @@ -43,6 +44,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { actionValue='all' selected={this.state.push === 'all'} theme={theme} + isLandscape={isLandscape} /> } @@ -78,7 +82,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { } @@ -86,7 +90,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { } renderMobilePushStatusSection(style) { - const {config, theme} = this.props; + const {config, theme, isLandscape} = this.props; const showSection = config.SendPushNotifications === 'true' && this.state.push !== 'none'; if (!showSection) { @@ -98,6 +102,7 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { headerId={t('mobile.notification_settings_mobile.push_status')} headerDefaultMessage='TRIGGER PUSH NOTIFICATIONS WHEN' theme={theme} + isLandscape={isLandscape} > ); @@ -149,17 +157,19 @@ class NotificationSettingsMobileIos extends NotificationSettingsMobileBase { const style = getStyleSheet(theme); return ( - - - - {this.renderMobilePushSection(style)} - {this.renderMobilePushStatusSection(style)} - - + + + + + {this.renderMobilePushSection(style)} + {this.renderMobilePushStatusSection(style)} + + + ); } } diff --git a/app/screens/settings/section.js b/app/screens/settings/section.js index bafbf5056..b132af8d4 100644 --- a/app/screens/settings/section.js +++ b/app/screens/settings/section.js @@ -9,6 +9,7 @@ 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 { @@ -22,6 +23,7 @@ function section(props) { headerId, headerValues, theme, + isLandscape, } = props; const style = getStyleSheet(theme); @@ -33,7 +35,7 @@ function section(props) { id={headerId} defaultMessage={headerDefaultMessage} values={headerValues} - style={style.header} + style={[style.header, margin(isLandscape)]} /> } @@ -44,7 +46,7 @@ function section(props) { id={footerId} defaultMessage={footerDefaultMessage} values={footerValues} - style={style.footer} + style={[style.footer, margin(isLandscape)]} /> } @@ -62,6 +64,7 @@ section.propTypes = { headerId: PropTypes.string, headerValues: PropTypes.object, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; const getStyleSheet = makeStyleSheetFromTheme((theme) => { @@ -83,7 +86,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { borderBottomColor: changeOpacity(theme.centerChannelColor, 0.1), }, footer: { - marginHorizontal: 15, marginTop: 10, fontSize: 12, color: changeOpacity(theme.centerChannelColor, 0.5), diff --git a/app/screens/settings/section_item.js b/app/screens/settings/section_item.js index 37707f785..2bb81037e 100644 --- a/app/screens/settings/section_item.js +++ b/app/screens/settings/section_item.js @@ -9,7 +9,7 @@ import { View, } from 'react-native'; import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import CheckMark from 'app/components/checkmark'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; @@ -29,6 +29,7 @@ function sectionItem(props) { theme, selected, description, + isLandscape, } = props; const style = getStyleSheet(theme); @@ -72,7 +73,7 @@ function sectionItem(props) { } const component = ( - + {labelComponent} {descriptionComponent} diff --git a/app/screens/settings/settings_item/index.js b/app/screens/settings/settings_item/index.js index c5a952bd7..28d9ed73a 100644 --- a/app/screens/settings/settings_item/index.js +++ b/app/screens/settings/settings_item/index.js @@ -5,7 +5,7 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {Text, TouchableOpacity, View} from 'react-native'; import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome'; - +import {paddingRight, paddingLeft} from 'app/components/safe_area_view/iphone_x_spacing'; import FormattedText from 'app/components/formatted_text'; import VectorIcon from 'app/components/vector_icon.js'; @@ -25,11 +25,13 @@ 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, }; renderText = () => { @@ -76,6 +78,7 @@ export default class SettingsItem extends PureComponent { separator, showArrow, theme, + isLandscape, } = this.props; const style = getStyleSheet(theme); @@ -112,14 +115,14 @@ export default class SettingsItem extends PureComponent { - + {icon && {icon} } - + {this.renderText()} {Boolean(additionalComponent) && diff --git a/app/screens/settings/settings_item/style.ios.js b/app/screens/settings/settings_item/style.ios.js index bebbcfe96..65513be77 100644 --- a/app/screens/settings/settings_item/style.ios.js +++ b/app/screens/settings/settings_item/style.ios.js @@ -57,5 +57,8 @@ export default makeStyleSheetFromTheme((theme) => { destructor: { color: theme.errorTextColor, }, + safeAreaView: { + backgroundColor: 'white', + }, }; }); diff --git a/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap b/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap index 861ccb1f1..836af5ec8 100644 --- a/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap +++ b/app/screens/settings/sidebar/__snapshots__/sidebar.test.js.snap @@ -23,6 +23,7 @@ exports[`SidebarSettings should match, full snapshot 2`] = ` >
} + isLandscape={false} label={
diff --git a/app/screens/settings/sidebar/sidebar.test.js b/app/screens/settings/sidebar/sidebar.test.js index 96f85384d..2acf53742 100644 --- a/app/screens/settings/sidebar/sidebar.test.js +++ b/app/screens/settings/sidebar/sidebar.test.js @@ -18,6 +18,7 @@ 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/timezone/index.js b/app/screens/settings/timezone/index.js index 8b015bc5a..a27919eda 100644 --- a/app/screens/settings/timezone/index.js +++ b/app/screens/settings/timezone/index.js @@ -9,7 +9,7 @@ import {getSupportedTimezones as getTimezones} from 'mattermost-redux/selectors/ import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getUserTimezone} from 'mattermost-redux/selectors/entities/timezone'; import {getCurrentUser} from 'mattermost-redux/selectors/entities/users'; - +import {isLandscape} from 'app/selectors/device'; import {goToScreen} from 'app/actions/navigation'; import {updateUser} from 'app/actions/views/edit_profile'; @@ -25,6 +25,7 @@ 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 4def5ad3e..681f264c4 100644 --- a/app/screens/settings/timezone/select_timezone/index.js +++ b/app/screens/settings/timezone/select_timezone/index.js @@ -8,7 +8,7 @@ import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import {getSupportedTimezones} from 'mattermost-redux/selectors/entities/general'; import {popTopScreen} from 'app/actions/navigation'; - +import {isLandscape} from 'app/selectors/device'; import SelectTimezone from './select_timezone'; function mapStateToProps(state, props) { @@ -26,6 +26,7 @@ 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 79f3a20ce..755ebd904 100644 --- a/app/screens/settings/timezone/select_timezone/select_timezone.js +++ b/app/screens/settings/timezone/select_timezone/select_timezone.js @@ -17,6 +17,7 @@ import SelectTimezoneRow from './select_timezone_row'; import {ListTypes} from 'app/constants'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; const ITEM_HEIGHT = 45; const VIEWABILITY_CONFIG = ListTypes.VISIBILITY_CONFIG_DEFAULTS; @@ -31,6 +32,7 @@ export default class Timezone extends PureComponent { timezones: PropTypes.array.isRequired, onBack: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -83,12 +85,13 @@ export default class Timezone extends PureComponent { timezone={timezone} selectedTimezone={this.props.selectedTimezone} onPress={this.timezoneSelected} + isLandscape={this.props.isLandscape} /> ); }; render() { - const {theme, initialScrollIndex} = this.props; + const {theme, initialScrollIndex, isLandscape} = this.props; const {value} = this.state; const {intl} = this.context; const style = getStyleSheet(theme); @@ -102,7 +105,7 @@ export default class Timezone extends PureComponent { return ( - + { @@ -28,7 +30,7 @@ export default class SelectTimezoneRow extends PureComponent { }; render() { - const {theme, timezone, selectedTimezone} = this.props; + const {theme, timezone, selectedTimezone, isLandscape} = this.props; const styles = getStyleSheet(theme); const selected = timezone === selectedTimezone && ( @@ -41,7 +43,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 1badd938e..e04d35bbb 100644 --- a/app/screens/settings/timezone/timezone.js +++ b/app/screens/settings/timezone/timezone.js @@ -33,6 +33,7 @@ export default class Timezone extends PureComponent { getSupportedTimezones: PropTypes.func.isRequired, updateUser: PropTypes.func.isRequired, }).isRequired, + isLandscape: PropTypes.bool.isRequired, }; static defaultProps = { @@ -138,6 +139,7 @@ export default class Timezone extends PureComponent { automaticTimezone, manualTimezone, }, + isLandscape, } = this.props; const {useAutomaticTimezone} = this.state; const style = getStyleSheet(theme); @@ -149,6 +151,7 @@ export default class Timezone extends PureComponent {
{!useAutomaticTimezone && ( @@ -187,6 +191,7 @@ export default class Timezone extends PureComponent { action={this.goToSelectTimezone} actionType='arrow' theme={theme} + isLandscape={isLandscape} /> )} 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 15f733c44..fbbb22f04 100644 --- a/app/screens/user_profile/__snapshots__/user_profile.test.js.snap +++ b/app/screens/user_profile/__snapshots__/user_profile.test.js.snap @@ -137,23 +137,29 @@ exports[`user_profile should match snapshot 1`] = ` USERNAME fred @@ -162,23 +168,29 @@ exports[`user_profile should match snapshot 1`] = ` NICKNAME nick @@ -192,6 +204,7 @@ exports[`user_profile should match snapshot 1`] = ` iconColor="rgba(0, 0, 0, 0.7)" iconSize={15} iconType="fontawesome" + isLandscape={false} textColor="#000" textId="mobile.routes.user_profile.send_message" theme={ diff --git a/app/screens/user_profile/index.js b/app/screens/user_profile/index.js index 01c5c91e6..4010b31fb 100644 --- a/app/screens/user_profile/index.js +++ b/app/screens/user_profile/index.js @@ -6,7 +6,7 @@ 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 {getConfig} from 'mattermost-redux/selectors/entities/general'; import {getTeammateNameDisplaySetting, getTheme, getBool} from 'mattermost-redux/selectors/entities/preferences'; import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone'; @@ -42,6 +42,7 @@ 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 5bc47ee7d..067a7b927 100644 --- a/app/screens/user_profile/user_profile.js +++ b/app/screens/user_profile/user_profile.js @@ -11,10 +11,9 @@ import { } from 'react-native'; import {intlShape} from 'react-intl'; import {Navigation} from 'react-native-navigation'; - import {displayUsername} from 'mattermost-redux/utils/user_utils'; import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils'; - +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; import ProfilePicture from 'app/components/profile_picture'; import FormattedText from 'app/components/formatted_text'; import FormattedTime from 'app/components/formatted_time'; @@ -52,6 +51,7 @@ export default class UserProfile extends PureComponent { enableTimezone: PropTypes.bool.isRequired, isMyUser: PropTypes.bool.isRequired, fromSettings: PropTypes.bool, + isLandscape: PropTypes.bool.isRequired, }; static contextTypes = { @@ -142,14 +142,14 @@ export default class UserProfile extends PureComponent { }; buildDisplayBlock = (property) => { - const {theme, user} = this.props; + const {theme, user, isLandscape} = this.props; const style = createStyleSheet(theme); if (user.hasOwnProperty(property) && user[property].length > 0) { return ( - {property.toUpperCase()} - {user[property]} + {property.toUpperCase()} + {user[property]} ); } @@ -158,7 +158,7 @@ export default class UserProfile extends PureComponent { }; buildTimezoneBlock = () => { - const {theme, user, militaryTime} = this.props; + const {theme, user, militaryTime, isLandscape} = this.props; const style = createStyleSheet(theme); const currentTimezone = getUserCurrentTimezone(user.timezone); @@ -172,9 +172,9 @@ export default class UserProfile extends PureComponent { - + + {'DESCRIPTION'} {this.props.bot.description || ''} @@ -295,7 +296,7 @@ export default class UserProfile extends PureComponent { } render() { - const {theme, user} = this.props; + const {theme, user, isLandscape} = this.props; const style = createStyleSheet(theme); if (!user) { @@ -326,6 +327,7 @@ export default class UserProfile extends PureComponent { iconType='fontawesome' textId={t('mobile.routes.user_profile.send_message')} theme={theme} + isLandscape={isLandscape} /> {this.renderAdditionalOptions()} diff --git a/app/screens/user_profile/user_profile.test.js b/app/screens/user_profile/user_profile.test.js index 4f8bc98d2..a3524e65a 100644 --- a/app/screens/user_profile/user_profile.test.js +++ b/app/screens/user_profile/user_profile.test.js @@ -41,6 +41,7 @@ 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 5efb7338a..e08628cbb 100644 --- a/app/screens/user_profile/user_profile_row.js +++ b/app/screens/user_profile/user_profile_row.js @@ -13,6 +13,7 @@ import { import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; import FormattedText from 'app/components/formatted_text'; import VectorIcon from 'app/components/vector_icon.js'; +import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing'; const createStyleSheet = makeStyleSheetFromTheme((theme) => { return { @@ -61,7 +62,7 @@ function createTouchableComponent(children, action) { } function userProfileRow(props) { - const {action, defaultMessage, detail, icon, textId, togglable, theme, iconType, iconSize, shouldRender = true} = props; + const {action, defaultMessage, detail, icon, textId, togglable, theme, iconType, iconSize, shouldRender = true, isLandscape} = props; if (!shouldRender) { return null; @@ -71,7 +72,7 @@ function userProfileRow(props) { const RowComponent = ( - + state.device.dimension.deviceHeight; } export function isTablet(state) {