Ability to remove DM's from channel drawer (#171)

* Ability to remove DM's from channel drawer

* review feedback

* Adding confirmation on removal
This commit is contained in:
enahum 2017-01-23 12:26:19 -03:00 committed by Harrison Healey
parent bc63b9e8bb
commit a6b735ba28
7 changed files with 102 additions and 7 deletions

View file

@ -7,6 +7,7 @@ import {ViewTypes} from 'app/constants';
import {fetchMyChannelsAndMembers, getMyChannelMembers, selectChannel} from 'service/actions/channels';
import {getPosts} from 'service/actions/posts';
import {savePreferences, deletePreferences} from 'service/actions/preferences';
import {getTeamMembersByIds} from 'service/actions/teams';
import {Constants, UsersTypes} from 'service/constants';
import {getChannelByName, getDirectChannelName} from 'service/utils/channel_utils';
@ -114,3 +115,31 @@ export function handlePostDraftChanged(postDraft) {
}, getState);
};
}
export function closeDMChannel(channel) {
return async(dispatch, getState) => {
const state = getState();
const userId = state.entities.users.currentId;
const dm = [{
user_id: userId,
category: Constants.CATEGORY_DIRECT_CHANNEL_SHOW,
name: channel.teammate_id,
value: 'false'
}];
if (channel.isFavorite) {
const fav = [{
user_id: userId,
category: Constants.CATEGORY_FAVORITE_CHANNEL,
name: channel.id
}];
deletePreferences(fav)(dispatch, getState);
}
savePreferences(dm)(dispatch, getState).then(() => {
if (channel.isCurrent) {
selectInitialChannel(state.entities.teams.currentId)(dispatch, getState);
}
});
};
}

View file

@ -14,6 +14,7 @@ export default class ChannelDrawer extends React.Component {
actions: React.PropTypes.shape({
selectChannel: React.PropTypes.func.isRequired,
viewChannel: React.PropTypes.func.isRequired,
closeDMChannel: React.PropTypes.func.isRequired,
closeChannelDrawer: React.PropTypes.func.isRequired
}).isRequired,
currentTeam: React.PropTypes.object,
@ -93,6 +94,7 @@ export default class ChannelDrawer extends React.Component {
theme={theme}
onSelectChannel={this.props.actions.selectChannel}
onViewChannel={this.props.actions.viewChannel}
handleCloseDM={this.props.actions.closeDMChannel}
closeChannelDrawer={this.props.actions.closeChannelDrawer}
/>
}

View file

@ -5,6 +5,7 @@ import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {selectChannel, viewChannel} from 'service/actions/channels';
import {closeDMChannel} from 'app/actions/views/channel';
import {getChannelsByCategory} from 'service/selectors/entities/channels';
import {closeChannelDrawer} from 'app/actions/views/drawer';
import ChannelDrawer from './channel_drawer';
@ -25,6 +26,7 @@ function mapDispatchToProps(dispatch) {
actions: bindActionCreators({
selectChannel,
viewChannel,
closeDMChannel,
closeChannelDrawer
}, dispatch)
};

View file

@ -16,6 +16,7 @@ export default class ChannelItem extends React.Component {
static propTypes = {
channel: React.PropTypes.object.isRequired,
onSelectChannel: React.PropTypes.func.isRequired,
handleClose: React.PropTypes.func,
isActive: React.PropTypes.bool.isRequired,
hasUnread: React.PropTypes.bool.isRequired,
mentions: React.PropTypes.number.isRequired,
@ -28,7 +29,8 @@ export default class ChannelItem extends React.Component {
theme,
mentions,
hasUnread,
isActive
isActive,
handleClose
} = this.props;
let iconColor = changeOpacity(theme.centerChannelColor, 0.7);
@ -39,7 +41,7 @@ export default class ChannelItem extends React.Component {
if (mentions && !isActive) {
const badgeStyle = {
position: 'absolute',
top: 10,
top: 12,
right: 10,
flexDirection: 'row',
backgroundColor: theme.mentionBj
@ -63,7 +65,7 @@ export default class ChannelItem extends React.Component {
const itemStyle = {
alignItems: 'center',
height: 40,
height: 45,
paddingLeft: 20,
paddingRight: 10,
flex: 1,
@ -73,12 +75,13 @@ export default class ChannelItem extends React.Component {
const style = {
marginLeft: 5,
opacity: 0.6,
fontSize: 15,
color: theme.sidebarText
};
const activeStyle = {
width: 5,
height: 40,
height: 45,
backgroundColor: theme.sidebarTextActiveBorder,
position: 'absolute'
};
@ -149,6 +152,33 @@ export default class ChannelItem extends React.Component {
}
}
let closeButton = null;
if (handleClose && !badge) {
const closeStyle = {
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
opacity: 0.4,
width: 50,
height: 50,
right: 0,
flexDirection: 'row'
};
closeButton = (
<TouchableHighlight
style={closeStyle}
onPress={() => handleClose(channel)}
>
<Icon
name='times'
size={13}
color={theme.sidebarText}
/>
</TouchableHighlight>
);
}
return (
<TouchableHighlight
underlayColor={changeOpacity(theme.sidebarTextHoverBg, 0.3)}
@ -166,6 +196,7 @@ export default class ChannelItem extends React.Component {
{channel.display_name}
</Text>
{badge}
{closeButton}
</View>
</View>
</TouchableHighlight>

View file

@ -3,8 +3,10 @@
import React from 'react';
import {StyleSheet, Text, View, ListView} from 'react-native';
import {Alert, StyleSheet, Text, View, ListView} from 'react-native';
import {injectIntl, intlShape} from 'react-intl';
import {buildDisplayNameAndTypeComparable} from 'service/utils/channel_utils';
import {Constants} from 'service/constants';
import LineDivider from 'app/components/line_divider';
import ChannelItem from './channel_item';
import FormattedText from 'app/components/formatted_text';
@ -48,8 +50,9 @@ const Styles = StyleSheet.create({
}
});
export default class ChannelList extends React.Component {
class ChannelList extends React.Component {
static propTypes = {
intl: intlShape.isRequired,
currentTeam: React.PropTypes.object.isRequired,
currentChannel: React.PropTypes.object,
channels: React.PropTypes.object.isRequired,
@ -57,6 +60,7 @@ export default class ChannelList extends React.Component {
theme: React.PropTypes.object.isRequired,
onSelectChannel: React.PropTypes.func.isRequired,
onViewChannel: React.PropTypes.func.isRequired,
handleCloseDM: React.PropTypes.func.isRequired,
closeChannelDrawer: React.PropTypes.func.isRequired
};
@ -140,6 +144,25 @@ export default class ChannelList extends React.Component {
this.props.closeChannelDrawer();
};
handleClose = (channel) => {
const {formatMessage} = this.props.intl;
Alert.alert(
formatMessage({id: 'mobile.channel_list.alertTitleCloseDM', defaultMessage: 'Close Direct Message'}),
formatMessage({
id: 'mobile.channel_list.alertMessageCloseDM',
defaultMessage: 'Are you sure you want to close the DM with {username}'
}, {
username: channel.display_name
}),
[
{text: formatMessage({id: 'mobile.channel_list.alertNo', defaultMessage: 'No'})},
{
text: formatMessage({id: 'mobile.channel_list.alertYes', defaultMessage: 'Yes'}),
onPress: () => this.props.handleCloseDM(channel)
}]
);
};
getUnreadMessages = (channel) => {
const member = this.props.channelMembers[channel.id];
let mentions = 0;
@ -186,6 +209,7 @@ export default class ChannelList extends React.Component {
hasUnread={unread}
mentions={mentions}
onSelectChannel={this.onSelectChannel}
handleClose={channel.type === Constants.DM_CHANNEL ? this.handleClose : null}
isActive={channel.isCurrent}
theme={this.props.theme}
/>
@ -336,3 +360,5 @@ export default class ChannelList extends React.Component {
);
}
}
export default injectIntl(ChannelList);

View file

@ -1480,6 +1480,10 @@
"member_list.noUsersAdd": "No users to add.",
"members_popover.msg": "Message",
"members_popover.title": "Members",
"mobile.channel_list.alertTitleCloseDM": "Close Direct Message",
"mobile.channel_list.alertMessageCloseDM": "Are you sure you want to close the DM with {username}",
"mobile.channel_list.alertNo": "No",
"mobile.channel_list.alertYes": "Yes",
"mobile.components.channels_list_view.yourChannels": "Your channels:",
"mobile.components.select_server_view.enterServerUrl": "Enter Server URL",
"mobile.components.select_server_view.continue": "Continue",

View file

@ -98,7 +98,8 @@ function isDirectChannelVisible(userId, myPreferences, channel) {
function isFavoriteChannel(myPreferences, channel) {
const fav = myPreferences[`${Constants.CATEGORY_FAVORITE_CHANNEL}--${channel.id}`];
return fav && fav.value === 'true';
channel.isFavorite = fav && fav.value === 'true';
return channel.isFavorite;
}
function createMissingDirectChannels(currentUserId, allChannels, myPreferences) {