From 9f92824dae674a9d4f0df4b59eb0a4d6f24bab5f Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Mon, 9 Sep 2019 10:12:23 -0300 Subject: [PATCH] MM-18223 Fix channel actions on combined sidebar (#3221) --- .../sidebars/main/channels_list/list/index.js | 26 +++-- .../sidebars/main/channels_list/list/list.js | 108 ++++++++---------- .../options_modal_list.android.js | 2 +- 3 files changed, 65 insertions(+), 71 deletions(-) diff --git a/app/components/sidebars/main/channels_list/list/index.js b/app/components/sidebars/main/channels_list/list/index.js index eaca23964..70bc4e60c 100644 --- a/app/components/sidebars/main/channels_list/list/index.js +++ b/app/components/sidebars/main/channels_list/list/index.js @@ -16,7 +16,9 @@ import {getTheme, getFavoritesPreferences, getSidebarPreferences} from 'mattermo import {showCreateOption} from 'mattermost-redux/utils/channel_utils'; import {memoizeResult} from 'mattermost-redux/utils/helpers'; import {isAdmin as checkIsAdmin, isSystemAdmin as checkIsSystemAdmin} from 'mattermost-redux/utils/user_utils'; -import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general'; +import {getConfig, getLicense, hasNewPermissions} from 'mattermost-redux/selectors/entities/general'; +import {haveITeamPermission} from 'mattermost-redux/selectors/entities/roles'; +import Permissions from 'mattermost-redux/constants/permissions'; import {showModal} from 'app/actions/navigation'; @@ -53,16 +55,20 @@ function mapStateToProps(state) { sidebarPrefs.favorite_at_top === 'true' && favoriteChannelIds.length, )); + let canJoinPublicChannels = true; + if (hasNewPermissions(state)) { + canJoinPublicChannels = haveITeamPermission(state, { + team: currentTeamId, + permission: Permissions.JOIN_PUBLIC_CHANNELS, + }); + } + const canCreatePublicChannels = showCreateOption(state, config, license, currentTeamId, General.OPEN_CHANNEL, isAdmin, isSystemAdmin); + const canCreatePrivateChannels = showCreateOption(state, config, license, currentTeamId, General.PRIVATE_CHANNEL, isAdmin, isSystemAdmin); + return { - canCreatePrivateChannels: showCreateOption( - state, - config, - license, - currentTeamId, - General.PRIVATE_CHANNEL, - isAdmin, - isSystemAdmin - ), + canJoinPublicChannels, + canCreatePrivateChannels, + canCreatePublicChannels, favoriteChannelIds, theme: getTheme(state), unreadChannelIds, diff --git a/app/components/sidebars/main/channels_list/list/list.js b/app/components/sidebars/main/channels_list/list/list.js index defbb4b2e..0af6b4380 100644 --- a/app/components/sidebars/main/channels_list/list/list.js +++ b/app/components/sidebars/main/channels_list/list/list.js @@ -5,6 +5,7 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import { Dimensions, + findNodeHandle, InteractionManager, Keyboard, Platform, @@ -23,6 +24,7 @@ import ChannelItem from 'app/components/sidebars/main/channels_list/channel_item import {DeviceTypes, ListTypes} from 'app/constants'; import {SidebarSectionTypes} from 'app/constants/view'; +import BottomSheet from 'app/utils/bottom_sheet'; import {t} from 'app/utils/i18n'; import {preventDoubleTap} from 'app/utils/tap'; import {changeOpacity} from 'app/utils/theme'; @@ -39,7 +41,9 @@ export default class List extends PureComponent { actions: PropTypes.shape({ showModal: PropTypes.func.isRequired, }).isRequired, + canJoinPublicChannels: PropTypes.bool.isRequired, canCreatePrivateChannels: PropTypes.bool.isRequired, + canCreatePublicChannels: PropTypes.bool.isRequired, favoriteChannelIds: PropTypes.array.isRequired, onSelectChannel: PropTypes.func.isRequired, unreadChannelIds: PropTypes.array.isRequired, @@ -56,6 +60,8 @@ export default class List extends PureComponent { constructor(props) { super(props); + this.combinedActionsRef = React.createRef(); + this.state = { sections: this.buildSections(props), showIndicator: false, @@ -164,72 +170,51 @@ export default class List extends PureComponent { }; showCreateChannelOptions = () => { + const {formatMessage} = this.context.intl; const { + canJoinPublicChannels, canCreatePrivateChannels, - actions, + canCreatePublicChannels, } = this.props; - const items = []; - const moreChannels = { - action: this.goToMoreChannels, - text: { - id: 'more_channels.title', - defaultMessage: 'More Channels', - }, - }; - const createPublicChannel = { - action: this.goToCreatePublicChannel, - text: { - id: 'mobile.create_channel.public', - defaultMessage: 'New Public Channel', - }, - }; - const createPrivateChannel = { - action: this.goToCreatePrivateChannel, - text: { - id: 'mobile.create_channel.private', - defaultMessage: 'New Private Channel', - }, - }; - const newConversation = { - action: this.goToDirectMessages, - text: { - id: 'mobile.more_dms.title', - defaultMessage: 'New Conversation', - }, - }; + const moreChannelsText = formatMessage({id: 'more_channels.title', defaultMessage: 'More Channels'}); + const newPublicChannelText = formatMessage({id: 'mobile.create_channel.public', defaultMessage: 'New Public Channel'}); + const newPrivateChannelText = formatMessage({id: 'mobile.create_channel.private', defaultMessage: 'New Private Channel'}); + const newDirectChannelText = formatMessage({id: 'mobile.more_dms.title', defaultMessage: 'New Conversation'}); + const cancelText = formatMessage({id: 'mobile.post.cancel', defaultMessage: 'Cancel'}); + const options = []; + const actions = []; - items.push(moreChannels, createPublicChannel); - if (canCreatePrivateChannels) { - items.push(createPrivateChannel); + if (canJoinPublicChannels) { + actions.push(this.goToMoreChannels); + options.push(moreChannelsText); } - items.push(newConversation); - const screen = 'OptionsModal'; - const title = ''; - const passProps = { - items, - }; - const options = { - modalPresentationStyle: 'overCurrentContext', - layout: { - backgroundColor: 'transparent', - }, - topBar: { - visible: false, - height: 0, - }, - animations: { - showModal: { - enable: false, - }, - dismissModal: { - enable: false, - }, - }, - }; + if (canCreatePublicChannels) { + actions.push(this.goToCreatePublicChannel); + options.push(newPublicChannelText); + } - actions.showModal(screen, title, passProps, options); + if (canCreatePrivateChannels) { + actions.push(this.goToCreatePrivateChannel); + options.push(newPrivateChannelText); + } + + actions.push(this.goToDirectMessages); + options.push(newDirectChannelText); + options.push(cancelText); + + const cancelButtonIndex = options.length - 1; + + BottomSheet.showBottomSheetWithOptions({ + anchor: this.combinedActionsRef?.current ? findNodeHandle(this.combinedActionsRef.current) : null, + options, + cancelButtonIndex, + }, (value) => { + if (value !== cancelButtonIndex) { + actions[value](); + } + }); }; goToCreatePublicChannel = preventDoubleTap(() => { @@ -303,7 +288,7 @@ export default class List extends PureComponent { this.setState({width: width - 40}); }; - renderSectionAction = (styles, action) => { + renderSectionAction = (styles, action, anchor) => { const {theme} = this.props; return ( @@ -351,6 +337,8 @@ export default class List extends PureComponent { topSeparator, } = section; + const anchor = (id === 'sidebar.types.recent' || id === 'mobile.channel_list.channels'); + return ( {topSeparator && this.renderSectionSeparator()} @@ -358,7 +346,7 @@ export default class List extends PureComponent { {intl.formatMessage({id, defaultMessage}).toUpperCase()} - {action && this.renderSectionAction(styles, action)} + {action && this.renderSectionAction(styles, action, anchor)} {bottomSeparator && this.renderSectionSeparator()} diff --git a/app/screens/options_modal/options_modal_list.android.js b/app/screens/options_modal/options_modal_list.android.js index f41de39a1..2f9edefa3 100644 --- a/app/screens/options_modal/options_modal_list.android.js +++ b/app/screens/options_modal/options_modal_list.android.js @@ -37,7 +37,7 @@ export default class OptionsModalList extends PureComponent { if (typeof action === 'function') { action(); } - }, 100); + }, 250); }); renderOptions = () => {