Channel info leave (#211)

* Setup for leaving a channel (does not include navigating once successfully leaving)

* Initial setup to navigate from leaving a channel

* Conditionally render leave channel row based on default channel

* Use setInitial from inside the action

* Refactor navigating after leave

* Ensure that channel is not DM

* Rename to shouldRender
This commit is contained in:
Chris Duarte 2017-02-02 12:52:27 -08:00 committed by Harrison Healey
parent c28d64c8da
commit 89ebae1108
5 changed files with 78 additions and 12 deletions

View file

@ -2,7 +2,6 @@
// See License.txt for license information.
import {batchActions} from 'redux-batched-actions';
import {ViewTypes} from 'app/constants';
import {updateStorage} from 'app/actions/storage';
@ -186,11 +185,11 @@ export function unmarkFavorite(channelId) {
};
}
export function leaveChannel(channel) {
export function leaveChannel(channel, reset = false) {
return async (dispatch, getState) => {
const {currentId: teamId} = getState().entities.teams;
serviceLeaveChannel(teamId, channel.id)(dispatch, getState).then(() => {
if (channel.isCurrent) {
if (channel.isCurrent || reset) {
selectInitialChannel(teamId)(dispatch, getState);
}
});

View file

@ -2,7 +2,9 @@
// See License.txt for license information.
import React, {PropTypes, PureComponent} from 'react';
import {injectIntl, intlShape} from 'react-intl';
import {
Alert,
ScrollView,
StyleSheet,
View
@ -10,6 +12,7 @@ import {
import ChannelInfoHeader from './channel_info_header';
import ChannelInfoRow from './channel_info_row';
import {Constants} from 'service/constants';
const style = StyleSheet.create({
container: {
@ -32,18 +35,22 @@ const style = StyleSheet.create({
}
});
export default class ChannelInfo extends PureComponent {
class ChannelInfo extends PureComponent {
static propTypes = {
intl: intlShape.isRequired,
currentChannel: PropTypes.object.isRequired,
currentChannelCreatorName: PropTypes.string,
currentChannelMemberCount: PropTypes.number,
isFavorite: PropTypes.bool.isRequired,
leaveChannelRequest: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
actions: PropTypes.shape({
getChannelStats: PropTypes.func.isRequired,
goToChannelMembers: PropTypes.func.isRequired,
markFavorite: PropTypes.func.isRequired,
unmarkFavorite: PropTypes.func.isRequired
unmarkFavorite: PropTypes.func.isRequired,
goBack: PropTypes.func.isRequired,
leaveChannel: PropTypes.func.isRequired
})
}
@ -55,15 +62,25 @@ export default class ChannelInfo extends PureComponent {
};
}
componentDidMount() {
this.props.actions.getChannelStats(this.props.currentChannel.team_id, this.props.currentChannel.id);
}
componentWillReceiveProps(nextProps) {
const isFavorite = nextProps.isFavorite;
if (isFavorite !== this.state.isFavorite) {
this.setState({isFavorite});
}
this.navigateAfterLeave(nextProps.leaveChannelRequest);
}
componentDidMount() {
this.props.actions.getChannelStats(this.props.currentChannel.team_id, this.props.currentChannel.id);
navigateAfterLeave(leaveChannelRequest) {
if (
leaveChannelRequest !== this.props.leaveChannelRequest &&
leaveChannelRequest.status === 'success'
) {
this.props.actions.goBack();
}
}
handleFavorite = () => {
@ -74,6 +91,40 @@ export default class ChannelInfo extends PureComponent {
toggleFavorite(currentChannel.id);
}
handleLeave() {
const {formatMessage} = this.props.intl;
const channel = this.props.currentChannel;
const term = channel.type === Constants.OPEN_CHANNEL ?
formatMessage({id: 'mobile.channel_info.publicChannel', defaultMessage: 'Public Channel'}) :
formatMessage({id: 'mobile.channel_info.privateChannel', defaultMessage: 'Private Channel'});
Alert.alert(
formatMessage({id: 'mobile.channel_info.alertTitleLeaveChannel', defaultMessage: 'Leave {term}'}, {term}),
formatMessage({
id: 'mobile.channel_info.alertMessageLeaveChannel',
defaultMessage: 'Are you sure you want to leave the {term} with {name}?'
}, {
term: term.toLowerCase(),
name: channel.display_name
}),
[{
text: formatMessage({id: 'mobile.channel_info.alertNo', defaultMessage: 'No'})
}, {
text: formatMessage({id: 'mobile.channel_info.alertYes', defaultMessage: 'Yes'}),
onPress: () => {
this.props.actions.leaveChannel(channel, true);
}
}]
);
}
renderLeaveChannelRow() {
const channel = this.props.currentChannel;
const isDefaultChannel = channel.name === Constants.DEFAULT_CHANNEL;
const isDirectMessage = channel.type === 'D';
return !isDefaultChannel && !isDirectMessage;
}
render() {
const {
currentChannel,
@ -135,10 +186,11 @@ export default class ChannelInfo extends PureComponent {
<View style={[style.separator, {backgroundColor: this.props.theme.centerChannelBg}]}/>
</View>
<ChannelInfoRow
action={() => true}
action={() => this.handleLeave()}
defaultMessage='Leave Channel'
icon='sign-out'
textId='navbar.leave'
shouldRender={this.renderLeaveChannelRow()}
/>
<View style={style.footer}>
<ChannelInfoRow
@ -155,3 +207,5 @@ export default class ChannelInfo extends PureComponent {
);
}
}
export default injectIntl(ChannelInfo);

View file

@ -4,9 +4,9 @@
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {goToChannelMembers} from 'app/actions/navigation';
import {goToChannelMembers, goBack} from 'app/actions/navigation';
import {getChannelStats} from 'service/actions/channels';
import {markFavorite, unmarkFavorite} from 'app/actions/views/channel';
import {markFavorite, unmarkFavorite, leaveChannel} from 'app/actions/views/channel';
import {getCurrentChannel, getCurrentChannelStats, getChannelsByCategory} from 'service/selectors/entities/channels';
import {getTheme} from 'service/selectors/entities/preferences';
import {getUser} from 'service/selectors/entities/users';
@ -20,6 +20,7 @@ function mapStateToProps(state, ownProps) {
const currentChannelMemberCount = getCurrentChannelStats(state) && getCurrentChannelStats(state).member_count;
const favoriteChannels = getChannelsByCategory(state).favoriteChannels.map((f) => f.id);
const isFavorite = favoriteChannels.indexOf(currentChannel.id) > -1;
const leaveChannelRequest = state.requests.channels.leaveChannel;
return {
...ownProps,
@ -27,6 +28,7 @@ function mapStateToProps(state, ownProps) {
currentChannelCreatorName,
currentChannelMemberCount,
isFavorite,
leaveChannelRequest,
theme: getTheme(state)
};
}
@ -37,7 +39,9 @@ function mapDispatchToProps(dispatch) {
getChannelStats,
goToChannelMembers,
markFavorite,
unmarkFavorite
unmarkFavorite,
leaveChannel,
goBack
}, dispatch)
};
}

View file

@ -45,8 +45,11 @@ function createTouchableComponent(children, action) {
}
function channelInfoRow(props) {
const {action, defaultMessage, detail, icon, iconColor, textColor, textId, togglable} = props;
const {action, defaultMessage, detail, icon, iconColor, textColor, textId, togglable, shouldRender = true} = props;
if (!shouldRender) {
return null;
}
const RowComponent = (
<View style={style.container}>
<Icon

View file

@ -1482,6 +1482,12 @@
"member_list.noUsersAdd": "No users to add.",
"members_popover.msg": "Message",
"members_popover.title": "Members",
"mobile.channel_info.publicChannel": "Public Channel",
"mobile.channel_info.privateChannel": "Private Channel",
"mobile.channel_info.alertTitleLeaveChannel": "Leave {term}",
"mobile.channel_info.alertMessageLeaveChannel": "Are you sure you want to leave the {term} with {name}?",
"mobile.channel_info.alertNo": "No",
"mobile.channel_info.alertYes": "Yes",
"mobile.channel_list.alertTitleLeaveChannel": "Leave {term}",
"mobile.channel_list.alertMessageLeaveChannel": "Are you sure you want to leave the {term} with {name}?",
"mobile.channel_list.alertNo": "No",