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:
parent
bc63b9e8bb
commit
a6b735ba28
7 changed files with 102 additions and 7 deletions
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue