-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Refactor PersonalDetails_Update with a few new commands
#9696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
faea1c4
6057115
50ba9ec
d5836f2
fd71758
9f8d7f0
0472768
35a24ed
70ce913
f8beb46
816ed7a
3ebc476
1c23ade
0a05600
259e877
0ec78f2
4821dec
9f51973
74935e2
f6736b1
8b6dd2a
67acb89
4aeee66
3792cc8
21655be
d37051b
c2f5de5
40b05a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -262,6 +262,48 @@ function setPersonalDetails(details, shouldGrowl) { | |
| }); | ||
| } | ||
|
|
||
| function updateProfile(firstName, lastName, pronouns, timezone) { | ||
| const myPersonalDetails = personalDetails[currentUserEmail]; | ||
| API.write('UpdateProfile', { | ||
| // 'details' is an old param that will be removed in https://github.com/Expensify/Expensify/issues/220321 | ||
| details: JSON.stringify({firstName, lastName, pronouns}), | ||
|
Beamanator marked this conversation as resolved.
|
||
| firstName, | ||
| lastName, | ||
| pronouns, | ||
| timezone: JSON.stringify(timezone), | ||
| }, { | ||
| optimisticData: [{ | ||
| onyxMethod: CONST.ONYX.METHOD.MERGE, | ||
| key: ONYXKEYS.PERSONAL_DETAILS, | ||
| value: { | ||
| [currentUserEmail]: { | ||
| firstName, | ||
| lastName, | ||
| pronouns, | ||
| timezone, | ||
| displayName: getDisplayName(currentUserEmail, { | ||
| firstName, | ||
| lastName, | ||
| }), | ||
|
Comment on lines
+284
to
+287
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI this will need to be added in Web-E so that all clients get updated with this displayName, I plan to add this requirement in this issue: https://github.com/Expensify/Expensify/issues/220321
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, but we should not get any problems when sending this. It will get updated for other users when their refresh, but it is not included in the Pusher update you saying?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right right exactly @mountiny - nothing will break, only the client making the change will get these updates automatically, others will get it after refresh 👍 |
||
| }, | ||
| }, | ||
| }], | ||
| failureData: [{ | ||
| onyxMethod: CONST.ONYX.METHOD.MERGE, | ||
| key: ONYXKEYS.PERSONAL_DETAILS, | ||
| value: { | ||
| [currentUserEmail]: { | ||
| firstName: myPersonalDetails.firstName, | ||
| lastName: myPersonalDetails.lastName, | ||
| pronouns: myPersonalDetails.pronouns, | ||
| timezone: myPersonalDetails.timeZone, | ||
| displayName: myPersonalDetails.displayName, | ||
| }, | ||
| }, | ||
| }], | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Fetches the local currency based on location and sets currency code/symbol to Onyx | ||
| */ | ||
|
|
@@ -295,14 +337,30 @@ function setAvatar(file) { | |
|
|
||
| /** | ||
| * Replaces the user's avatar image with a default avatar | ||
| * | ||
| * @param {String} defaultAvatarURL | ||
| */ | ||
| 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 | ||
| DeprecatedAPI.PersonalDetails_Update({details: JSON.stringify({avatar: ''})}); | ||
| mergeLocalPersonalDetails({avatar: defaultAvatarURL}); | ||
| function deleteAvatar() { | ||
| const defaultAvatar = ReportUtils.getDefaultAvatar(currentUserEmail); | ||
|
|
||
| API.write('DeleteUserAvatar', {}, { | ||
| optimisticData: [{ | ||
| onyxMethod: CONST.ONYX.METHOD.MERGE, | ||
| key: ONYXKEYS.PERSONAL_DETAILS, | ||
| value: { | ||
| [currentUserEmail]: { | ||
| avatar: defaultAvatar, | ||
|
Beamanator marked this conversation as resolved.
|
||
| }, | ||
| }, | ||
| }], | ||
| failureData: [{ | ||
| onyxMethod: CONST.ONYX.METHOD.MERGE, | ||
| key: ONYXKEYS.PERSONAL_DETAILS, | ||
| value: { | ||
| [currentUserEmail]: { | ||
| avatar: personalDetails[currentUserEmail].avatar, | ||
| }, | ||
| }, | ||
| }], | ||
| }); | ||
| } | ||
|
|
||
| export { | ||
|
|
@@ -315,4 +373,5 @@ export { | |
| openIOUModalPage, | ||
| getMaxCharacterError, | ||
| extractFirstAndLastNameFromAvailableDetails, | ||
| updateProfile, | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,20 +66,19 @@ class ProfilePage extends Component { | |
| constructor(props) { | ||
| super(props); | ||
|
|
||
| this.defaultAvatar = ReportUtils.getDefaultAvatar(this.props.currentUserPersonalDetails.login); | ||
|
|
||
| const currentUserDetails = this.props.currentUserPersonalDetails || {}; | ||
| this.state = { | ||
| firstName: this.props.currentUserPersonalDetails.firstName, | ||
| firstName: currentUserDetails.firstName || '', | ||
| hasFirstNameError: false, | ||
| lastName: this.props.currentUserPersonalDetails.lastName, | ||
| lastName: currentUserDetails.lastName || '', | ||
| hasLastNameError: false, | ||
| pronouns: this.props.currentUserPersonalDetails.pronouns, | ||
| pronouns: currentUserDetails.pronouns || '', | ||
| hasPronounError: false, | ||
| hasSelfSelectedPronouns: !_.isEmpty(this.props.currentUserPersonalDetails.pronouns) && !this.props.currentUserPersonalDetails.pronouns.startsWith(CONST.PRONOUNS.PREFIX), | ||
| selectedTimezone: lodashGet(this.props.currentUserPersonalDetails, 'timezone.selected', CONST.DEFAULT_TIME_ZONE.selected), | ||
| isAutomaticTimezone: lodashGet(this.props.currentUserPersonalDetails, 'timezone.automatic', CONST.DEFAULT_TIME_ZONE.automatic), | ||
| hasSelfSelectedPronouns: !_.isEmpty(currentUserDetails.pronouns) && !currentUserDetails.pronouns.startsWith(CONST.PRONOUNS.PREFIX), | ||
| selectedTimezone: lodashGet(currentUserDetails, 'timezone.selected', CONST.DEFAULT_TIME_ZONE.selected), | ||
| isAutomaticTimezone: lodashGet(currentUserDetails, 'timezone.automatic', CONST.DEFAULT_TIME_ZONE.automatic), | ||
| logins: this.getLogins(props.loginList), | ||
| avatar: {uri: lodashGet(this.props.currentUserPersonalDetails, 'avatar', ReportUtils.getDefaultAvatar(this.props.currentUserPersonalDetails.login))}, | ||
| avatar: {uri: currentUserDetails.avatar || ReportUtils.getDefaultAvatar(currentUserDetails.login)}, | ||
| isAvatarChanged: false, | ||
| }; | ||
|
|
||
|
|
@@ -88,6 +87,7 @@ class ProfilePage extends Component { | |
| this.updatePersonalDetails = this.updatePersonalDetails.bind(this); | ||
| this.validateInputs = this.validateInputs.bind(this); | ||
| this.updateAvatar = this.updateAvatar.bind(this); | ||
| this.deleteAvatar = this.deleteAvatar.bind(this); | ||
| } | ||
|
|
||
| componentDidUpdate(prevProps) { | ||
|
|
@@ -130,7 +130,7 @@ class ProfilePage extends Component { | |
| const login = Str.removeSMSDomain(currentLogin.partnerUserID); | ||
|
|
||
| // If there's already a login type that's validated and/or currentLogin isn't valid then return early | ||
| if ((login !== this.props.currentUserPersonalDetails.login) && !_.isEmpty(logins[type]) | ||
| if ((login !== lodashGet(this.props.currentUserPersonalDetails, 'login')) && !_.isEmpty(logins[type]) | ||
| && (logins[type].validatedDate || !currentLogin.validatedDate)) { | ||
| return logins; | ||
| } | ||
|
|
@@ -153,7 +153,15 @@ class ProfilePage extends Component { | |
| * @param {Object} avatar | ||
| */ | ||
| updateAvatar(avatar) { | ||
| this.setState({avatar: _.isUndefined(avatar) ? {uri: ReportUtils.getDefaultAvatar(this.props.currentUserPersonalDetails.login)} : avatar, isAvatarChanged: true}); | ||
| this.setState({avatar, isAvatarChanged: true}); | ||
| } | ||
|
|
||
| /** | ||
| * Replaces the user's current avatar image with a default avatar. | ||
| */ | ||
| deleteAvatar() { | ||
| PersonalDetails.deleteAvatar(); | ||
| this.setState({avatar: {uri: ReportUtils.getDefaultAvatar(lodashGet(this.props.currentUserPersonalDetails, 'login'))}}); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -165,27 +173,22 @@ class ProfilePage extends Component { | |
| } | ||
|
|
||
| // Check if the user has modified their avatar | ||
| if ((this.props.currentUserPersonalDetails.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); | ||
| } | ||
| if ((lodashGet(this.props.currentUserPersonalDetails, 'avatar') !== this.state.avatar.uri) && this.state.isAvatarChanged) { | ||
| PersonalDetails.setAvatar(this.state.avatar); | ||
|
|
||
| // Reset the changed state | ||
| this.setState({isAvatarChanged: false}); | ||
| } | ||
|
|
||
| PersonalDetails.setPersonalDetails({ | ||
| firstName: this.state.firstName.trim(), | ||
| lastName: this.state.lastName.trim(), | ||
| pronouns: this.state.pronouns.trim(), | ||
| timezone: { | ||
| PersonalDetails.updateProfile( | ||
| this.state.firstName.trim(), | ||
| this.state.lastName.trim(), | ||
| this.state.pronouns.trim(), | ||
| { | ||
| automatic: this.state.isAutomaticTimezone, | ||
| selected: this.state.selectedTimezone, | ||
| }, | ||
| }, true); | ||
| ); | ||
|
Comment on lines
+183
to
+191
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This tiny change gave rise to #10215 Note: The main issue is opacity being incorrect, not the Growl being missing |
||
| } | ||
|
|
||
| validateInputs() { | ||
|
|
@@ -208,12 +211,13 @@ class ProfilePage extends Component { | |
| })); | ||
|
|
||
| // Disables button if none of the form values have changed | ||
| const isButtonDisabled = (this.props.currentUserPersonalDetails.firstName === this.state.firstName.trim()) | ||
| && (this.props.currentUserPersonalDetails.lastName === this.state.lastName.trim()) | ||
| && (this.props.currentUserPersonalDetails.timezone.selected === this.state.selectedTimezone) | ||
| && (this.props.currentUserPersonalDetails.timezone.automatic === this.state.isAutomaticTimezone) | ||
| && (this.props.currentUserPersonalDetails.pronouns === this.state.pronouns.trim()) | ||
| && (!this.state.isAvatarChanged || this.props.currentUserPersonalDetails.avatarUploading); | ||
| const currentUserDetails = this.props.currentUserPersonalDetails || {}; | ||
| const isButtonDisabled = (currentUserDetails.firstName === this.state.firstName.trim()) | ||
| && (currentUserDetails.lastName === this.state.lastName.trim()) | ||
| && (lodashGet(currentUserDetails, 'timezone.selected') === this.state.selectedTimezone) | ||
| && (lodashGet(currentUserDetails, 'timezone.automatic') === this.state.isAutomaticTimezone) | ||
| && (currentUserDetails.pronouns === this.state.pronouns.trim()) | ||
| && (!this.state.isAvatarChanged || currentUserDetails.avatarUploading); | ||
|
|
||
| const pronounsPickerValue = this.state.hasSelfSelectedPronouns ? CONST.PRONOUNS.SELF_SELECT : this.state.pronouns; | ||
|
|
||
|
|
@@ -228,11 +232,11 @@ class ProfilePage extends Component { | |
| /> | ||
| <ScrollView style={styles.flex1} contentContainerStyle={styles.p5}> | ||
| <AvatarWithImagePicker | ||
| isUploading={this.props.currentUserPersonalDetails.avatarUploading} | ||
| isUploading={currentUserDetails.avatarUploading} | ||
| isUsingDefaultAvatar={this.state.avatar.uri.includes('/images/avatars/avatar')} | ||
| avatarURL={this.state.avatar.uri} | ||
| onImageSelected={this.updateAvatar} | ||
| onImageRemoved={this.updateAvatar} | ||
| onImageRemoved={this.deleteAvatar} | ||
| anchorPosition={styles.createMenuPositionProfile} | ||
| size={CONST.AVATAR_SIZE.LARGE} | ||
| /> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed with Alex in DM, I think this function does not work as expected with the VPNs and it does not set you to the timezone of the area. However, that is how we have it now and I would argue it is better as in the chat you want others to see your actual timezone and not the VPN timezone.