use profile image from local after editing a profile image (#1990)
This commit is contained in:
parent
b59092e1e8
commit
669f0ea1cd
9 changed files with 93 additions and 20 deletions
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
import {updateMe} from 'mattermost-redux/actions/users';
|
||||
|
||||
import {ViewTypes} from 'app/constants';
|
||||
|
||||
export function updateUser(user, success, error) {
|
||||
return async (dispatch, getState) => {
|
||||
const result = await updateMe(user)(dispatch, getState);
|
||||
|
|
@ -15,3 +17,15 @@ export function updateUser(user, success, error) {
|
|||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
export function setProfileImageUri(imageUri = '') {
|
||||
return {
|
||||
type: ViewTypes.SET_PROFILE_IMAGE_URI,
|
||||
imageUri,
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
updateUser,
|
||||
setProfileImageUri,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ import {connect} from 'react-redux';
|
|||
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getStatusesByIdsBatchedDebounced} from 'mattermost-redux/actions/users';
|
||||
import {getStatusForUserId, getUser} from 'mattermost-redux/selectors/entities/users';
|
||||
import {getCurrentUserId, getStatusForUserId, getUser} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {setProfileImageUri} from 'app/actions/views/edit_profile';
|
||||
import {getProfileImageUri} from 'app/selectors/views';
|
||||
|
||||
import ProfilePicture from './profile_picture';
|
||||
|
||||
|
|
@ -17,8 +20,16 @@ function mapStateToProps(state, ownProps) {
|
|||
status = getStatusForUserId(state, ownProps.userId);
|
||||
}
|
||||
|
||||
const isCurrentUser = getCurrentUserId(state) === ownProps.userId;
|
||||
let profileImageUri = '';
|
||||
if (isCurrentUser) {
|
||||
profileImageUri = getProfileImageUri(state);
|
||||
}
|
||||
|
||||
return {
|
||||
isCurrentUser,
|
||||
theme: getTheme(state),
|
||||
profileImageUri,
|
||||
status,
|
||||
user,
|
||||
};
|
||||
|
|
@ -27,6 +38,7 @@ function mapStateToProps(state, ownProps) {
|
|||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
setProfileImageUri,
|
||||
getStatusForId: getStatusesByIdsBatchedDebounced,
|
||||
}, dispatch),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ const STATUS_BUFFER = Platform.select({
|
|||
|
||||
export default class ProfilePicture extends PureComponent {
|
||||
static propTypes = {
|
||||
isCurrentUser: PropTypes.bool.isRequired,
|
||||
size: PropTypes.number,
|
||||
statusSize: PropTypes.number,
|
||||
user: PropTypes.object,
|
||||
|
|
@ -29,9 +30,11 @@ export default class ProfilePicture extends PureComponent {
|
|||
status: PropTypes.string,
|
||||
edit: PropTypes.bool,
|
||||
imageUri: PropTypes.string,
|
||||
profileImageUri: PropTypes.string,
|
||||
theme: PropTypes.object.isRequired,
|
||||
actions: PropTypes.shape({
|
||||
getStatusForId: PropTypes.func.isRequired,
|
||||
setProfileImageUri: PropTypes.func.isRequired,
|
||||
}),
|
||||
};
|
||||
|
||||
|
|
@ -47,12 +50,14 @@ export default class ProfilePicture extends PureComponent {
|
|||
};
|
||||
|
||||
componentWillMount() {
|
||||
const {edit, imageUri, user} = this.props;
|
||||
const {edit, imageUri, profileImageUri, user} = this.props;
|
||||
|
||||
if (edit && imageUri) {
|
||||
if (profileImageUri) {
|
||||
this.setImageURL(profileImageUri);
|
||||
} else if (edit && imageUri) {
|
||||
this.setImageURL(imageUri);
|
||||
} else if (user) {
|
||||
ImageCacheManager.cache('', Client4.getProfilePictureUrl(user.id, user.last_picture_update), this.setImageURL);
|
||||
ImageCacheManager.cache('', Client4.getProfilePictureUrl(user.id, user.last_picture_update), this.setImageURL).then(this.clearProfileImageUri).catch(emptyFunction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -66,22 +71,21 @@ export default class ProfilePicture extends PureComponent {
|
|||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.mounted) {
|
||||
if (nextProps.edit && nextProps.imageUri && nextProps.imageUri !== this.props.imageUri) {
|
||||
this.setImageURL(nextProps.imageUri);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextProps.profileImageUri !== '' && nextProps.profileImageUri !== this.props.profileImageUri) {
|
||||
this.setImageURL(nextProps.profileImageUri);
|
||||
}
|
||||
|
||||
const url = this.props.user ? Client4.getProfilePictureUrl(this.props.user.id, this.props.user.last_picture_update) : null;
|
||||
const nextUrl = nextProps.user ? Client4.getProfilePictureUrl(nextProps.user.id, nextProps.user.last_picture_update) : null;
|
||||
|
||||
if (url !== nextUrl) {
|
||||
this.setState({
|
||||
pictureUrl: null,
|
||||
});
|
||||
|
||||
if (nextUrl) {
|
||||
// empty function is so that promise unhandled is not triggered in dev mode
|
||||
ImageCacheManager.cache('', nextUrl, this.setImageURL).then(emptyFunction).catch(emptyFunction);
|
||||
}
|
||||
}
|
||||
|
||||
if (nextProps.edit && nextProps.imageUri !== this.props.imageUri) {
|
||||
this.setImageURL(nextProps.imageUri);
|
||||
if (nextUrl && url !== nextUrl) {
|
||||
// empty function is so that promise unhandled is not triggered in dev mode
|
||||
ImageCacheManager.cache('', nextUrl, this.setImageURL).then(this.clearProfileImageUri).catch(emptyFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,6 +100,12 @@ export default class ProfilePicture extends PureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
clearProfileImageUri = () => {
|
||||
if (this.props.isCurrentUser && this.props.profileImageUri !== '') {
|
||||
this.props.actions.setProfileImageUri('');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {edit, showStatus, theme} = this.props;
|
||||
const {pictureUrl} = this.state;
|
||||
|
|
@ -139,13 +149,18 @@ export default class ProfilePicture extends PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
const otherImageProps = {};
|
||||
if (!this.props.edit) {
|
||||
otherImageProps.defaultSource = placeholder;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{width: this.props.size + STATUS_BUFFER, height: this.props.size + STATUS_BUFFER}}>
|
||||
<Image
|
||||
key={pictureUrl}
|
||||
style={{width: this.props.size, height: this.props.size, borderRadius: this.props.size / 2}}
|
||||
source={source}
|
||||
defaultSource={placeholder}
|
||||
{...otherImageProps}
|
||||
/>
|
||||
{(showStatus || edit) &&
|
||||
<View style={[style.statusWrapper, statusStyle, {borderRadius: this.props.statusSize / 2}]}>
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ const ViewTypes = keyMirror({
|
|||
LAUNCH_CHANNEL: null,
|
||||
|
||||
SET_DEEP_LINK_URL: null,
|
||||
|
||||
SET_PROFILE_IMAGE_URI: null,
|
||||
});
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import search from './search';
|
|||
import selectServer from './select_server';
|
||||
import team from './team';
|
||||
import thread from './thread';
|
||||
import user from './user';
|
||||
import emoji from './emoji';
|
||||
|
||||
export default combineReducers({
|
||||
|
|
@ -30,5 +31,6 @@ export default combineReducers({
|
|||
selectServer,
|
||||
team,
|
||||
thread,
|
||||
user,
|
||||
emoji,
|
||||
});
|
||||
|
|
|
|||
20
app/reducers/views/user.js
Normal file
20
app/reducers/views/user.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
import {ViewTypes} from 'app/constants';
|
||||
|
||||
function profileImageUri(state = '', action) {
|
||||
switch (action.type) {
|
||||
case ViewTypes.SET_PROFILE_IMAGE_URI: {
|
||||
return action.imageUri;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default combineReducers({
|
||||
profileImageUri,
|
||||
});
|
||||
|
|
@ -53,6 +53,7 @@ const holders = {
|
|||
export default class EditProfile extends PureComponent {
|
||||
static propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
setProfileImageUri: PropTypes.func.isRequired,
|
||||
updateUser: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
config: PropTypes.object.isRequired,
|
||||
|
|
@ -166,13 +167,15 @@ export default class EditProfile extends PureComponent {
|
|||
position,
|
||||
email,
|
||||
};
|
||||
const {actions} = this.props;
|
||||
|
||||
if (profileImage) {
|
||||
actions.setProfileImageUri(profileImage.uri);
|
||||
this.uploadProfileImage().catch(this.handleUploadError);
|
||||
}
|
||||
|
||||
if (this.canUpdate()) {
|
||||
const {error} = await this.props.actions.updateUser(user);
|
||||
const {error} = await actions.updateUser(user);
|
||||
if (error) {
|
||||
this.handleRequestError(error);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {bindActionCreators} from 'redux';
|
|||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {updateUser} from 'app/actions/views/edit_profile';
|
||||
import {setProfileImageUri, updateUser} from 'app/actions/views/edit_profile';
|
||||
|
||||
import EditProfile from './edit_profile';
|
||||
|
||||
|
|
@ -21,6 +21,7 @@ function mapStateToProps(state) {
|
|||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
setProfileImageUri,
|
||||
updateUser,
|
||||
}, dispatch),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,3 +33,7 @@ export const getThreadDraft = createSelector(
|
|||
return drafts[rootId] || emptyDraft;
|
||||
}
|
||||
);
|
||||
|
||||
export function getProfileImageUri(state) {
|
||||
return state.views.user.profileImageUri;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue