Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/libs/actions/PersonalDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,15 +326,15 @@ function setAvatar(file) {
}

/**
* Deletes the user's avatar image
* Replaces the user's avatar image with a default avatar
*
* @param {String} login
* @param {String} defaultAvatarURL
*/
function deleteAvatar(login) {
function deleteAvatar(defaultAvatarURL) {
// We don't want to save the default avatar URL in the backend since we don't want to allow
// users the option of removing the default avatar, instead we'll save an empty string
API.PersonalDetails_Update({details: JSON.stringify({avatar: ''})});
mergeLocalPersonalDetails({avatar: OptionsListUtils.getDefaultAvatar(login)});
mergeLocalPersonalDetails({avatar: defaultAvatarURL});
}

// When the app reconnects from being offline, fetch all of the personal details
Expand Down
65 changes: 22 additions & 43 deletions src/pages/settings/Profile/ProfilePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,15 @@ class ProfilePage extends Component {
selectedTimezone: lodashGet(props.myPersonalDetails.timezone, 'selected', CONST.DEFAULT_TIME_ZONE.selected),
isAutomaticTimezone: lodashGet(props.myPersonalDetails.timezone, 'automatic', CONST.DEFAULT_TIME_ZONE.automatic),
logins: this.getLogins(props.user.loginList),
avatarImage: null,
avatarPreviewURL: lodashGet(this.props.myPersonalDetails, 'avatar', this.defaultAvatar),
isAvatarUpdated: false,
avatar: {uri: lodashGet(this.props.myPersonalDetails, 'avatar', OptionsListUtils.getDefaultAvatar(this.props.myPersonalDetails.login))},
isAvatarChanged: false,
};

this.getLogins = this.getLogins.bind(this);
this.setAutomaticTimezone = this.setAutomaticTimezone.bind(this);
this.updatePersonalDetails = this.updatePersonalDetails.bind(this);
this.validateInputs = this.validateInputs.bind(this);
this.setAvatar = this.setAvatar.bind(this);
this.removeAvatar = this.removeAvatar.bind(this);
this.updateAvatar = this.updateAvatar.bind(this);
}

componentDidUpdate(prevProps) {
Expand All @@ -105,10 +103,6 @@ class ProfilePage extends Component {
stateToUpdate = {...stateToUpdate, logins: this.getLogins(this.props.user.loginList)};
}

if (this.props.myPersonalDetails.avatar !== this.state.avatarPreviewURL && this.props.myPersonalDetails.avatar !== prevProps.myPersonalDetails.avatar) {
stateToUpdate = {...stateToUpdate, isAvatarUpdated: true};
}

if (_.isEmpty(stateToUpdate)) {
return;
}
Expand Down Expand Up @@ -160,22 +154,11 @@ class ProfilePage extends Component {
}

/**
* Set avatar image
* @param {Object} img
*/
setAvatar(img) {
this.setState({avatarImage: img, avatarPreviewURL: img.uri, isAvatarUpdated: false});
}

/**
* Remove the avatar image
* Updates the user's avatar image.
* @param {Object} avatar
*/
removeAvatar() {
this.setState({
avatarPreviewURL: this.defaultAvatar,
avatarImage: null,
isAvatarUpdated: false,
});
updateAvatar(avatar) {
this.setState({avatar: _.isUndefined(avatar) ? {uri: OptionsListUtils.getDefaultAvatar(this.props.myPersonalDetails.login)} : avatar, isAvatarChanged: true});
}

/**
Expand All @@ -186,14 +169,17 @@ class ProfilePage extends Component {
return;
}

if (this.state.avatarImage) {
PersonalDetails.setAvatar(this.state.avatarImage);
}
// Check if the user has modified their avatar
if ((this.props.myPersonalDetails.avatar !== this.state.avatar.uri) && this.state.isAvatarChanged) {
// If the user removed their profile photo, replace it accordingly with the default avatar
if (this.state.avatar.uri.includes('/images/avatars/avatar')) {
PersonalDetails.deleteAvatar(this.state.avatar.uri);
} else {
PersonalDetails.setAvatar(this.state.avatar);
}

// Checks if the user already has an avatar and removePhoto is triggered
// Avatar having `/images/avatars/avatar` in URL means a profile picture exists for the user
if (!this.props.myPersonalDetails.avatar.includes('/images/avatars/avatar') && this.state.avatarPreviewURL === this.defaultAvatar) {
PersonalDetails.deleteAvatar(this.props.myPersonalDetails.login);
// Reset the changed state
this.setState({isAvatarChanged: false});
}

PersonalDetails.setPersonalDetails({
Expand Down Expand Up @@ -226,20 +212,13 @@ class ProfilePage extends Component {
value: `${CONST.PRONOUNS.PREFIX}${key}`,
}));

// Determines if the pronouns/selected pronouns have changed
const arePronounsUnchanged = this.props.myPersonalDetails.pronouns === this.state.pronouns.trim();

// Determine if the avatar is changed or finished uploading
const disableSaveWhenAvatarIsProcessed = this.props.myPersonalDetails.avatar === this.state.avatarPreviewURL
|| this.state.isAvatarUpdated
|| this.props.myPersonalDetails.avatarUploading;

// Disables button if none of the form values have changed
const isButtonDisabled = (this.props.myPersonalDetails.firstName === this.state.firstName.trim())
&& (this.props.myPersonalDetails.lastName === this.state.lastName.trim())
&& (this.props.myPersonalDetails.timezone.selected === this.state.selectedTimezone)
&& (this.props.myPersonalDetails.timezone.automatic === this.state.isAutomaticTimezone)
&& arePronounsUnchanged && disableSaveWhenAvatarIsProcessed;
&& (this.props.myPersonalDetails.pronouns === this.state.pronouns.trim())
&& (!this.state.isAvatarChanged || this.props.myPersonalDetails.avatarUploading);

const pronounsPickerValue = this.state.hasSelfSelectedPronouns ? CONST.PRONOUNS.SELF_SELECT : this.state.pronouns;

Expand All @@ -256,9 +235,9 @@ class ProfilePage extends Component {
<AvatarWithImagePicker
isUploading={this.props.myPersonalDetails.avatarUploading}
isUsingDefaultAvatar={this.props.myPersonalDetails.avatar.includes('/images/avatars/avatar')}
avatarURL={this.state.avatarPreviewURL}
onImageSelected={this.setAvatar}
onImageRemoved={this.removeAvatar}
avatarURL={this.state.avatar.uri}
onImageSelected={this.updateAvatar}
onImageRemoved={this.updateAvatar}
anchorPosition={styles.createMenuPositionProfile}
size={CONST.AVATAR_SIZE.LARGE}
/>
Expand Down