RN-239 show error messages for join/delete channel and create dms (#668)
* RN-239 show error messages for join/delete channel and create dms * Feedback review
This commit is contained in:
parent
c36260cdce
commit
6c03d3b8e6
19 changed files with 232 additions and 99 deletions
|
|
@ -20,11 +20,13 @@ export function makeDirectChannel(otherUserId) {
|
|||
if (channel && myMembers[channel.id]) {
|
||||
toggleDMChannel(otherUserId, 'true')(dispatch, getState);
|
||||
handleSelectChannel(channel.id)(dispatch, getState);
|
||||
} else {
|
||||
const created = await createDirectChannel(currentUserId, otherUserId)(dispatch, getState);
|
||||
if (created) {
|
||||
handleSelectChannel(created.id)(dispatch, getState);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const created = await createDirectChannel(currentUserId, otherUserId)(dispatch, getState);
|
||||
if (created) {
|
||||
handleSelectChannel(created.id)(dispatch, getState);
|
||||
}
|
||||
|
||||
return created;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {makeDirectChannel} from 'app/actions/views/more_dms';
|
||||
|
||||
export function handleSendMessage(otherUserId) {
|
||||
return async (dispatch, getState) => {
|
||||
await makeDirectChannel(otherUserId)(dispatch, getState);
|
||||
};
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import {
|
|||
} from 'react-native';
|
||||
|
||||
import Drawer from 'app/components/drawer';
|
||||
import {alertErrorWithFallback} from 'app/utils/general';
|
||||
|
||||
import ChannelsList from './channels_list';
|
||||
import Swiper from './swiper';
|
||||
|
|
@ -29,15 +30,18 @@ export default class ChannelDrawer extends PureComponent {
|
|||
viewChannel: PropTypes.func.isRequired,
|
||||
makeDirectChannel: PropTypes.func.isRequired,
|
||||
markChannelAsRead: PropTypes.func.isRequired,
|
||||
setChannelDisplayName: PropTypes.func.isRequired,
|
||||
setChannelLoading: PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
blurPostTextBox: PropTypes.func.isRequired,
|
||||
children: PropTypes.node,
|
||||
channels: PropTypes.object,
|
||||
currentChannel: PropTypes.object,
|
||||
currentDisplayName: PropTypes.string,
|
||||
channelMembers: PropTypes.object,
|
||||
currentTeam: PropTypes.object,
|
||||
currentUserId: PropTypes.string.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
myTeamMembers: PropTypes.object.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
theme: PropTypes.object.isRequired
|
||||
|
|
@ -162,12 +166,14 @@ export default class ChannelDrawer extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
joinChannel = (channel) => {
|
||||
joinChannel = async (channel) => {
|
||||
const {
|
||||
actions,
|
||||
currentChannel,
|
||||
currentDisplayName,
|
||||
currentTeam,
|
||||
currentUserId
|
||||
currentUserId,
|
||||
intl
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
|
|
@ -175,27 +181,46 @@ export default class ChannelDrawer extends PureComponent {
|
|||
joinChannel,
|
||||
makeDirectChannel,
|
||||
markChannelAsRead,
|
||||
setChannelDisplayName,
|
||||
setChannelLoading,
|
||||
viewChannel
|
||||
} = actions;
|
||||
|
||||
markChannelAsRead(currentChannel.id);
|
||||
setChannelLoading();
|
||||
viewChannel(currentChannel.id);
|
||||
setChannelDisplayName(channel.display_name);
|
||||
|
||||
const displayValue = {displayName: channel.display_name};
|
||||
|
||||
if (channel.type === General.DM_CHANNEL) {
|
||||
markChannelAsRead(currentChannel.id);
|
||||
setChannelLoading();
|
||||
viewChannel(currentChannel.id);
|
||||
this.closeChannelDrawer();
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
makeDirectChannel(channel.id);
|
||||
});
|
||||
const result = await makeDirectChannel(channel.id);
|
||||
if (result.error) {
|
||||
const dmFailedMessage = {
|
||||
id: 'mobile.open_dm.error',
|
||||
defaultMessage: "We couldn't open a direct message with {displayName}. Please check your connection and try again."
|
||||
};
|
||||
setChannelDisplayName(currentDisplayName);
|
||||
alertErrorWithFallback(intl, result.error, dmFailedMessage, displayValue);
|
||||
} else {
|
||||
this.closeChannelDrawer();
|
||||
}
|
||||
} else {
|
||||
markChannelAsRead(currentChannel.id);
|
||||
setChannelLoading();
|
||||
viewChannel(currentChannel.id);
|
||||
joinChannel(currentUserId, currentTeam.id, channel.id);
|
||||
this.closeChannelDrawer();
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
handleSelectChannel(channel.id);
|
||||
});
|
||||
const result = await joinChannel(currentUserId, currentTeam.id, channel.id);
|
||||
|
||||
if (result.error) {
|
||||
const joinFailedMessage = {
|
||||
id: 'mobile.join_channel.error',
|
||||
defaultMessage: "We couldn't join the channel {displayName}. Please check your connection and try again."
|
||||
};
|
||||
setChannelDisplayName(currentDisplayName);
|
||||
alertErrorWithFallback(intl, result.error, joinFailedMessage, displayValue);
|
||||
} else {
|
||||
this.closeChannelDrawer();
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
handleSelectChannel(channel.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ class ChannelDrawerList extends Component {
|
|||
actions: PropTypes.shape({
|
||||
makeGroupMessageVisibleIfNecessary: PropTypes.func.isRequired,
|
||||
searchChannels: PropTypes.func.isRequired,
|
||||
searchProfiles: PropTypes.func.isRequired,
|
||||
setChannelDisplayName: PropTypes.func.isRequired
|
||||
searchProfiles: PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
channels: PropTypes.object.isRequired,
|
||||
channelMembers: PropTypes.object,
|
||||
|
|
@ -40,7 +39,6 @@ class ChannelDrawerList extends Component {
|
|||
myPreferences: PropTypes.object,
|
||||
myTeamMembers: PropTypes.object.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
onJoinChannel: PropTypes.func.isRequired,
|
||||
onSearchEnds: PropTypes.func.isRequired,
|
||||
onSearchStart: PropTypes.func.isRequired,
|
||||
onSelectChannel: PropTypes.func.isRequired,
|
||||
|
|
@ -88,12 +86,8 @@ class ChannelDrawerList extends Component {
|
|||
}
|
||||
|
||||
onSelectChannel = (channel) => {
|
||||
const {
|
||||
makeGroupMessageVisibleIfNecessary,
|
||||
setChannelDisplayName
|
||||
} = this.props.actions;
|
||||
const {makeGroupMessageVisibleIfNecessary} = this.props.actions;
|
||||
|
||||
setChannelDisplayName(channel.display_name);
|
||||
if (channel.type === General.GM_CHANNEL) {
|
||||
makeGroupMessageVisibleIfNecessary(channel.id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ import {getUserIdsInChannels, getUsers, getUserStatuses} from 'mattermost-redux/
|
|||
import {getGroupChannels, getOtherChannels} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getMyPreferences} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {setChannelDisplayName} from 'app/actions/views/channel';
|
||||
|
||||
import FilteredList from './filtered_list';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
|
|
@ -35,8 +33,7 @@ function mapDispatchToProps(dispatch) {
|
|||
actions: bindActionCreators({
|
||||
makeGroupMessageVisibleIfNecessary,
|
||||
searchChannels,
|
||||
searchProfiles,
|
||||
setChannelDisplayName
|
||||
searchProfiles
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {getTeams} from 'mattermost-redux/actions/teams';
|
|||
import {getChannelsWithUnreadSection, getCurrentChannel} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getCurrentTeam, getTeamMemberships} from 'mattermost-redux/selectors/entities/teams';
|
||||
|
||||
import {handleSelectChannel, setChannelLoading} from 'app/actions/views/channel';
|
||||
import {handleSelectChannel, setChannelDisplayName, setChannelLoading} from 'app/actions/views/channel';
|
||||
import {makeDirectChannel} from 'app/actions/views/more_dms';
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
|
||||
|
|
@ -22,6 +22,7 @@ function mapStateToProps(state, ownProps) {
|
|||
...ownProps,
|
||||
currentTeam: getCurrentTeam(state),
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentDisplayName: state.views.channel.displayName,
|
||||
currentUserId,
|
||||
channels: getChannelsWithUnreadSection(state),
|
||||
channelMembers: state.entities.channels.myMembers,
|
||||
|
|
@ -39,6 +40,7 @@ function mapDispatchToProps(dispatch) {
|
|||
viewChannel,
|
||||
makeDirectChannel,
|
||||
markChannelAsRead,
|
||||
setChannelDisplayName,
|
||||
setChannelLoading
|
||||
}, dispatch)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ class Channel extends PureComponent {
|
|||
const {
|
||||
currentTeam,
|
||||
currentChannel,
|
||||
intl,
|
||||
navigator,
|
||||
theme
|
||||
} = this.props;
|
||||
|
|
@ -186,6 +187,7 @@ class Channel extends PureComponent {
|
|||
return (
|
||||
<ChannelDrawer
|
||||
blurPostTextBox={this.blurPostTextBox}
|
||||
intl={intl}
|
||||
navigator={navigator}
|
||||
>
|
||||
<StatusBar/>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class ChannelPostList extends PureComponent {
|
|||
channel: PropTypes.object.isRequired,
|
||||
channelIsLoading: PropTypes.bool,
|
||||
channelIsRefreshing: PropTypes.bool,
|
||||
channelName: PropTypes.string,
|
||||
currentChannelId: PropTypes.string,
|
||||
intl: intlShape.isRequired,
|
||||
loadingPosts: PropTypes.bool,
|
||||
myMember: PropTypes.object.isRequired,
|
||||
|
|
@ -60,7 +60,7 @@ class ChannelPostList extends PureComponent {
|
|||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show the loader if the channel names change
|
||||
if (this.props.channelName !== nextProps.channelName) {
|
||||
if (this.props.currentChannelId !== nextProps.currentChannelId) {
|
||||
this.setState({
|
||||
loaderOpacity: new Animated.Value(1)
|
||||
});
|
||||
|
|
@ -146,7 +146,7 @@ class ChannelPostList extends PureComponent {
|
|||
const {channelLoaded, loaderOpacity} = this.state;
|
||||
|
||||
let component;
|
||||
if (!posts.length && channel.total_msg_count > 0 && !networkOnline) {
|
||||
if (!posts.length && channel.total_msg_count > 0 && (!channelIsLoading || !networkOnline)) {
|
||||
// If no posts has been loaded and we are offline
|
||||
component = (
|
||||
<PostListRetry
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {connect} from 'react-redux';
|
|||
import {selectPost} from 'mattermost-redux/actions/posts';
|
||||
import {RequestStatus} from 'mattermost-redux/constants';
|
||||
import {makeGetPostsInChannel} from 'mattermost-redux/selectors/entities/posts';
|
||||
import {getMyCurrentChannelMembership} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getCurrentChannelId, getMyCurrentChannelMembership} from 'mattermost-redux/selectors/entities/channels';
|
||||
|
||||
import {loadPostsIfNecessary, increasePostVisibility} from 'app/actions/views/channel';
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
|
|
@ -19,14 +19,14 @@ function makeMapStateToProps() {
|
|||
|
||||
return function mapStateToProps(state, ownProps) {
|
||||
const channelId = ownProps.channel.id;
|
||||
const {displayName, refreshing} = state.views.channel;
|
||||
const {refreshing} = state.views.channel;
|
||||
const {getPosts} = state.requests.posts;
|
||||
const posts = getPostsInChannel(state, channelId) || [];
|
||||
|
||||
return {
|
||||
channelIsLoading: (getPosts.status === RequestStatus.STARTED),
|
||||
channelIsRefreshing: refreshing,
|
||||
channelName: displayName,
|
||||
currentChannelId: getCurrentChannelId(state),
|
||||
posts,
|
||||
postVisibility: state.views.channel.postVisibility[channelId],
|
||||
loadingPosts: state.views.channel.loadingPosts[channelId],
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
import {alertErrorWithFallback} from 'app/utils/general';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
|
|
@ -130,10 +131,23 @@ class ChannelInfo extends PureComponent {
|
|||
id: 'mobile.channel_info.alertMessageDeleteChannel',
|
||||
defaultMessage: 'Are you sure you want to delete the {term} {name}?'
|
||||
};
|
||||
onPressAction = () => {
|
||||
this.props.actions.deleteChannel(channel.id).then(() => {
|
||||
onPressAction = async () => {
|
||||
const result = await this.props.actions.deleteChannel(channel.id);
|
||||
if (result.error) {
|
||||
alertErrorWithFallback(
|
||||
this.props.intl,
|
||||
result.error,
|
||||
{
|
||||
id: 'mobile.channel_info.delete_failed',
|
||||
defaultMessage: "We couldn't delete the channel {displayName}. Please check your connection and try again."
|
||||
},
|
||||
{
|
||||
displayName: channel.display_name
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {connect} from 'react-redux';
|
|||
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
import {getChannels, joinChannel, searchChannels} from 'mattermost-redux/actions/channels';
|
||||
import {getOtherChannels} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getChannelsInCurrentTeam, getMyChannelMemberships} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getCurrentUserRoles} from 'mattermost-redux/selectors/entities/users';
|
||||
import {showCreateOption} from 'mattermost-redux/utils/channel_utils';
|
||||
import {isAdmin, isSystemAdmin} from 'mattermost-redux/utils/user_utils';
|
||||
|
|
@ -22,7 +22,10 @@ function mapStateToProps(state, ownProps) {
|
|||
const {getChannels: requestStatus} = state.requests.channels;
|
||||
const {config, license} = state.entities.general;
|
||||
const roles = getCurrentUserRoles(state);
|
||||
const channels = getOtherChannels(state);
|
||||
const myMembers = getMyChannelMemberships(state);
|
||||
const channels = getChannelsInCurrentTeam(state).filter((c) => {
|
||||
return (!myMembers[c.id] && c.type === General.OPEN_CHANNEL);
|
||||
});
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import ChannelListRow from 'app/components/custom_list/channel_list_row';
|
|||
import Loading from 'app/components/loading';
|
||||
import SearchBar from 'app/components/search_bar';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import {alertErrorWithFallback} from 'app/utils/general';
|
||||
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
|
||||
|
||||
class MoreChannels extends PureComponent {
|
||||
|
|
@ -202,25 +203,42 @@ class MoreChannels extends PureComponent {
|
|||
};
|
||||
|
||||
onSelectChannel = async (id) => {
|
||||
const {actions, currentTeamId, currentUserId} = this.props;
|
||||
const {actions, currentTeamId, currentUserId, intl} = this.props;
|
||||
const {channels} = this.state;
|
||||
|
||||
this.emitCanCreateChannel(false);
|
||||
this.setState({adding: true});
|
||||
await actions.joinChannel(currentUserId, currentTeamId, id);
|
||||
|
||||
const channel = channels.find((c) => c.id === id);
|
||||
if (channel) {
|
||||
actions.setChannelDisplayName(channel.display_name);
|
||||
} else {
|
||||
actions.setChannelDisplayName('');
|
||||
}
|
||||
await actions.handleSelectChannel(id);
|
||||
const result = await actions.joinChannel(currentUserId, currentTeamId, id);
|
||||
|
||||
EventEmitter.emit('close_channel_drawer');
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.close();
|
||||
});
|
||||
if (result.error) {
|
||||
alertErrorWithFallback(
|
||||
intl,
|
||||
result.error,
|
||||
{
|
||||
id: 'mobile.join_channel.error',
|
||||
defaultMessage: "We couldn't join the channel {displayName}. Please check your connection and try again."
|
||||
},
|
||||
{
|
||||
displayName: channel ? channel.display_name : ''
|
||||
}
|
||||
);
|
||||
this.emitCanCreateChannel(true);
|
||||
this.setState({adding: false});
|
||||
} else {
|
||||
if (channel) {
|
||||
actions.setChannelDisplayName(channel.display_name);
|
||||
} else {
|
||||
actions.setChannelDisplayName('');
|
||||
}
|
||||
await actions.handleSelectChannel(id);
|
||||
|
||||
EventEmitter.emit('close_channel_drawer');
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onCreateChannel = () => {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import MoreDirectMessages from './more_dms';
|
|||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const {getProfiles: requestStatus, searchProfiles: searchRequest} = state.requests.users;
|
||||
const {createChannel: createChannelRequest} = state.requests.channels;
|
||||
|
||||
function getUsers() {
|
||||
const {profiles, currentUserId} = state.entities.users;
|
||||
|
|
@ -32,6 +33,8 @@ function mapStateToProps(state, ownProps) {
|
|||
preferences: getMyPreferences(state),
|
||||
profiles: getUsers(),
|
||||
theme: getTheme(state),
|
||||
currentDisplayName: state.views.channel.displayName,
|
||||
createChannelRequest,
|
||||
requestStatus,
|
||||
searchRequest
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,16 +18,19 @@ import Loading from 'app/components/loading';
|
|||
import MemberList from 'app/components/custom_list';
|
||||
import SearchBar from 'app/components/search_bar';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import {alertErrorWithFallback} from 'app/utils/general';
|
||||
import {createMembersSections, loadingText, renderMemberRow} from 'app/utils/member_list';
|
||||
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
|
||||
|
||||
class MoreDirectMessages extends PureComponent {
|
||||
static propTypes = {
|
||||
currentDisplayName: PropTypes.string,
|
||||
intl: intlShape.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
preferences: PropTypes.object.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
profiles: PropTypes.array,
|
||||
createChannelRequest: PropTypes.object.isRequired,
|
||||
requestStatus: PropTypes.object.isRequired,
|
||||
searchRequest: PropTypes.object.isRequired,
|
||||
actions: PropTypes.shape({
|
||||
|
|
@ -60,11 +63,11 @@ class MoreDirectMessages extends PureComponent {
|
|||
nextProps.requestStatus.status === RequestStatus.SUCCESS) {
|
||||
const {page} = this.state;
|
||||
const profiles = nextProps.profiles.splice(0, (page + 1) * General.PROFILE_CHUNK_SIZE);
|
||||
this.setState({profiles, showNoResults: true});
|
||||
this.setState({profiles, showNoResults: true, error: null});
|
||||
} else if (this.state.searching &&
|
||||
nextProps.searchRequest.status === RequestStatus.SUCCESS) {
|
||||
const results = filterProfilesMatchingTerm(nextProps.profiles, this.state.term);
|
||||
this.setState({profiles: results, showNoResults: true});
|
||||
this.setState({profiles: results, showNoResults: true, error: null});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +112,7 @@ class MoreDirectMessages extends PureComponent {
|
|||
this.setState({
|
||||
searching: false,
|
||||
term: null,
|
||||
error: null,
|
||||
page: 0,
|
||||
profiles: this.props.profiles
|
||||
});
|
||||
|
|
@ -132,22 +136,44 @@ class MoreDirectMessages extends PureComponent {
|
|||
};
|
||||
|
||||
onSelectMember = async (id) => {
|
||||
const {actions, preferences, profiles} = this.props;
|
||||
const {actions, currentDisplayName, intl, preferences, profiles} = this.props;
|
||||
const user = profiles.find((p) => p.id === id);
|
||||
|
||||
this.setState({adding: true});
|
||||
|
||||
// save the current channel display name in case it fails
|
||||
const currentChannelDisplayName = currentDisplayName;
|
||||
|
||||
const userDisplayName = displayUsername(user, preferences);
|
||||
|
||||
if (user) {
|
||||
actions.setChannelDisplayName(displayUsername(user, preferences));
|
||||
actions.setChannelDisplayName(userDisplayName);
|
||||
} else {
|
||||
actions.setChannelDisplayName('');
|
||||
}
|
||||
await actions.makeDirectChannel(id);
|
||||
|
||||
EventEmitter.emit('close_channel_drawer');
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.close();
|
||||
});
|
||||
const result = await actions.makeDirectChannel(id);
|
||||
|
||||
if (result.error) {
|
||||
actions.setChannelDisplayName(currentChannelDisplayName);
|
||||
alertErrorWithFallback(
|
||||
intl,
|
||||
result.error,
|
||||
{
|
||||
id: 'mobile.open_dm.error',
|
||||
defaultMessage: "We couldn't open a direct message with {displayName}. Please check your connection and try again."
|
||||
},
|
||||
{
|
||||
displayName: userDisplayName
|
||||
}
|
||||
);
|
||||
this.setState({adding: false});
|
||||
} else {
|
||||
EventEmitter.emit('close_channel_drawer');
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ import {bindActionCreators} from 'redux';
|
|||
import {connect} from 'react-redux';
|
||||
|
||||
import {setChannelDisplayName} from 'app/actions/views/channel';
|
||||
import {handleSendMessage} from 'app/actions/views/user_profile';
|
||||
import {makeDirectChannel} from 'app/actions/views/more_dms';
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
|
||||
import {getCurrentChannel} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getMyPreferences} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
|
|
@ -15,10 +16,14 @@ import UserProfile from './user_profile';
|
|||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const {config} = state.entities.general;
|
||||
const {createChannel: createChannelRequest} = state.requests.channels;
|
||||
|
||||
return {
|
||||
navigator: ownProps.navigator,
|
||||
config,
|
||||
createChannelRequest,
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentDisplayName: state.views.channel.displayName,
|
||||
currentUserId: getCurrentUserId(state),
|
||||
user: state.entities.users.profiles[ownProps.userId],
|
||||
myPreferences: getMyPreferences(state),
|
||||
|
|
@ -29,7 +34,7 @@ function mapStateToProps(state, ownProps) {
|
|||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
handleSendMessage,
|
||||
makeDirectChannel,
|
||||
setChannelDisplayName
|
||||
}, dispatch)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,28 +9,42 @@ import {
|
|||
Text,
|
||||
View
|
||||
} from 'react-native';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
|
||||
import {getDirectChannelName} from 'mattermost-redux/utils/channel_utils';
|
||||
import {displayUsername} from 'mattermost-redux/utils/user_utils';
|
||||
|
||||
import ProfilePicture from 'app/components/profile_picture';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import {alertErrorWithFallback} from 'app/utils/general';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
import {displayUsername} from 'mattermost-redux/utils/user_utils';
|
||||
|
||||
import UserProfileRow from './user_profile_row';
|
||||
|
||||
export default class UserProfile extends PureComponent {
|
||||
class UserProfile extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
handleSendMessage: PropTypes.func.isRequired,
|
||||
makeDirectChannel: PropTypes.func.isRequired,
|
||||
setChannelDisplayName: PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
config: PropTypes.object.isRequired,
|
||||
currentChannel: PropTypes.object.isRequired,
|
||||
currentDisplayName: PropTypes.string,
|
||||
currentUserId: PropTypes.string.isRequired,
|
||||
createChannelRequest: PropTypes.object.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
myPreferences: PropTypes.object,
|
||||
theme: PropTypes.object.isRequired,
|
||||
user: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
displaySendMessageOption = () => {
|
||||
const {currentChannel, currentUserId, user} = this.props;
|
||||
|
||||
return currentUserId !== user.id && currentChannel.name !== getDirectChannelName(currentUserId, user.id);
|
||||
};
|
||||
|
||||
getDisplayName = () => {
|
||||
const {theme, myPreferences, user} = this.props;
|
||||
const style = createStyleSheet(theme);
|
||||
|
|
@ -60,17 +74,38 @@ export default class UserProfile extends PureComponent {
|
|||
return null;
|
||||
};
|
||||
|
||||
sendMessage = () => {
|
||||
const {actions, myPreferences, navigator, user} = this.props;
|
||||
actions.setChannelDisplayName(displayUsername(user, myPreferences));
|
||||
actions.handleSendMessage(user.id);
|
||||
navigator.pop({
|
||||
animated: true
|
||||
});
|
||||
sendMessage = async () => {
|
||||
const {actions, currentDisplayName, intl, myPreferences, navigator, user} = this.props;
|
||||
|
||||
// save the current channel display name in case it fails
|
||||
const currentChannelDisplayName = currentDisplayName;
|
||||
|
||||
const userDisplayName = displayUsername(user, myPreferences);
|
||||
actions.setChannelDisplayName(userDisplayName);
|
||||
|
||||
const result = await actions.makeDirectChannel(user.id);
|
||||
if (result.error) {
|
||||
actions.setChannelDisplayName(currentChannelDisplayName);
|
||||
alertErrorWithFallback(
|
||||
intl,
|
||||
result.error,
|
||||
{
|
||||
id: 'mobile.open_dm.error',
|
||||
defaultMessage: "We couldn't open a direct message with {displayName}. Please check your connection and try again."
|
||||
},
|
||||
{
|
||||
displayName: userDisplayName
|
||||
}
|
||||
);
|
||||
} else {
|
||||
navigator.pop({
|
||||
animated: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {config, currentUserId, theme, user} = this.props;
|
||||
const {config, theme, user} = this.props;
|
||||
const style = createStyleSheet(theme);
|
||||
|
||||
return (
|
||||
|
|
@ -95,14 +130,14 @@ export default class UserProfile extends PureComponent {
|
|||
{config.ShowEmailAddress === 'true' && this.buildDisplayBlock('email')}
|
||||
{this.buildDisplayBlock('position')}
|
||||
</View>
|
||||
{currentUserId !== user.id &&
|
||||
<UserProfileRow
|
||||
action={this.sendMessage}
|
||||
defaultMessage='Send Message'
|
||||
icon='paper-plane-o'
|
||||
textId='mobile.routes.user_profile.send_message'
|
||||
theme={theme}
|
||||
/>
|
||||
{this.displaySendMessageOption() &&
|
||||
<UserProfileRow
|
||||
action={this.sendMessage}
|
||||
defaultMessage='Send Message'
|
||||
icon='paper-plane-o'
|
||||
textId='mobile.routes.user_profile.send_message'
|
||||
theme={theme}
|
||||
/>
|
||||
}
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
|
@ -152,3 +187,5 @@ const createStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
export default injectIntl(UserProfile);
|
||||
|
|
|
|||
12
app/utils/general.js
Normal file
12
app/utils/general.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {Alert} from 'react-native';
|
||||
|
||||
export function alertErrorWithFallback(intl, error, fallback, values) {
|
||||
let msg = error.message;
|
||||
if (!msg || msg === 'Network request failed') {
|
||||
msg = intl.formatMessage(fallback, values);
|
||||
}
|
||||
Alert.alert('', msg);
|
||||
}
|
||||
|
|
@ -1691,6 +1691,7 @@
|
|||
"mobile.channel_info.alertTitleDeleteChannel": "Delete {term}",
|
||||
"mobile.channel_info.alertTitleLeaveChannel": "Leave {term}",
|
||||
"mobile.channel_info.alertYes": "Yes",
|
||||
"mobile.channel_info.delete_failed": "We couldn't delete the channel {displayName}. Please check your connection and try again.",
|
||||
"mobile.channel_info.privateChannel": "Private Channel",
|
||||
"mobile.channel_info.publicChannel": "Public Channel",
|
||||
"mobile.channel_list.alertMessageLeaveChannel": "Are you sure you want to leave the {term} {name}?",
|
||||
|
|
@ -1728,6 +1729,7 @@
|
|||
"mobile.intro_messages.DM": "This is the start of your direct message history with {teammate}. Direct messages and files shared here are not shown to people outside this area.",
|
||||
"mobile.intro_messages.default_message": "This is the first channel teammates see when they sign up - use it for posting updates everyone needs to know.",
|
||||
"mobile.intro_messages.default_welcome": "Welcome to {name}!",
|
||||
"mobile.join_channel.error": "We couldn't join the channel {displayName}. Please check your connection and try again.",
|
||||
"mobile.loading_channels": "Loading Channels...",
|
||||
"mobile.loading_members": "Loading Members...",
|
||||
"mobile.loading_posts": "Loading Messages...",
|
||||
|
|
@ -1736,6 +1738,7 @@
|
|||
"mobile.offlineIndicator.connected": "Connected",
|
||||
"mobile.offlineIndicator.connecting": "Connecting...",
|
||||
"mobile.offlineIndicator.offline": "No internet connection",
|
||||
"mobile.open_dm.error": "We couldn't open a direct message with {displayName}. Please check your connection and try again.",
|
||||
"mobile.post.cancel": "Cancel",
|
||||
"mobile.post.delete_question": "Are you sure you want to delete this post?",
|
||||
"mobile.post.delete_title": "Delete Post",
|
||||
|
|
|
|||
|
|
@ -3645,7 +3645,7 @@ makeerror@1.0.x:
|
|||
|
||||
mattermost-redux@mattermost/mattermost-redux#master:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/86454a4eafa5f5676748cfbfa883539be1e6ce90"
|
||||
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/b21461562fefc6abe2e31373045059652d814ad1"
|
||||
dependencies:
|
||||
deep-equal "1.0.1"
|
||||
harmony-reflect "1.5.1"
|
||||
|
|
|
|||
Loading…
Reference in a new issue