diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js
index ce11e28e6..990e30482 100644
--- a/app/actions/views/channel.js
+++ b/app/actions/views/channel.js
@@ -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);
+ }
+ });
+ };
+}
diff --git a/app/components/channel_drawer/channel_drawer.js b/app/components/channel_drawer/channel_drawer.js
index 3b5f1d1a8..3cb2a1a48 100644
--- a/app/components/channel_drawer/channel_drawer.js
+++ b/app/components/channel_drawer/channel_drawer.js
@@ -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}
/>
}
diff --git a/app/components/channel_drawer/channel_drawer_container.js b/app/components/channel_drawer/channel_drawer_container.js
index 0893da2c5..bbcc094dc 100644
--- a/app/components/channel_drawer/channel_drawer_container.js
+++ b/app/components/channel_drawer/channel_drawer_container.js
@@ -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)
};
diff --git a/app/components/channel_drawer/channel_item.js b/app/components/channel_drawer/channel_item.js
index ef5a739b4..95642dc99 100644
--- a/app/components/channel_drawer/channel_item.js
+++ b/app/components/channel_drawer/channel_item.js
@@ -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 = (
+ handleClose(channel)}
+ >
+
+
+ );
+ }
+
return (
{badge}
+ {closeButton}
diff --git a/app/components/channel_drawer/channel_list.js b/app/components/channel_drawer/channel_list.js
index f13ee8c6c..78458aa10 100644
--- a/app/components/channel_drawer/channel_list.js
+++ b/app/components/channel_drawer/channel_list.js
@@ -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);
diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json
index 0709b14bf..e1e72238b 100644
--- a/assets/base/i18n/en.json
+++ b/assets/base/i18n/en.json
@@ -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",
diff --git a/service/utils/channel_utils.js b/service/utils/channel_utils.js
index cc0e25d9b..0378a7733 100644
--- a/service/utils/channel_utils.js
+++ b/service/utils/channel_utils.js
@@ -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) {