diff --git a/src/containers/ProfileSettingsForm/ProfileSettingsForm.css b/src/containers/ProfileSettingsForm/ProfileSettingsForm.css index 5097c3fc..c7237f23 100644 --- a/src/containers/ProfileSettingsForm/ProfileSettingsForm.css +++ b/src/containers/ProfileSettingsForm/ProfileSettingsForm.css @@ -223,6 +223,13 @@ padding-bottom: 100%; } +.avatarInvisible { + visibility: hidden; + position: absolute; + top: -1000px; + left: -1000px; +} + .tip { @apply --marketplaceDefaultFontStyles; color: var(--matterColorAnti); diff --git a/src/containers/ProfileSettingsForm/ProfileSettingsForm.js b/src/containers/ProfileSettingsForm/ProfileSettingsForm.js index 7a8dce18..31c96688 100644 --- a/src/containers/ProfileSettingsForm/ProfileSettingsForm.js +++ b/src/containers/ProfileSettingsForm/ProfileSettingsForm.js @@ -1,4 +1,4 @@ -import React, { PropTypes } from 'react'; +import React, { Component, PropTypes } from 'react'; import { compose } from 'redux'; import { FormattedMessage, injectIntl, intlShape } from 'react-intl'; import { Field, reduxForm, propTypes as formPropTypes } from 'redux-form'; @@ -10,6 +10,7 @@ import { Avatar, Button, ImageFromFile, SpinnerIcon, TextInputField } from '../. import css from './ProfileSettingsForm.css'; const ACCEPT_IMAGES = 'image/*'; +const UPLOAD_CHANGE_DELAY = 2000; // Show spinner so that browser has time to load img srcset const RenderAvatar = props => { const { accept, id, input, label, type, disabled, uploadImageError } = props; @@ -58,149 +59,190 @@ RenderAvatar.propTypes = { uploadImageError: instanceOf(Error), }; -const ProfileSettingsFormComponent = props => { - const { - className, - currentUser, - form, - handleSubmit, - intl, - invalid, - onImageUpload, - pristine, - profileImage, - rootClassName, - submitting, - updateInProgress, - updateProfileError, - uploadImageError, - uploadInProgress, - } = props; +class ProfileSettingsFormComponent extends Component { + constructor(props) { + super(props); - const user = ensureCurrentUser(currentUser); + this.uploadDelayTimeoutId = null; + this.state = { uploadDelay: false }; + } - // First name - const firstNameLabel = intl.formatMessage({ - id: 'ProfileSettingsForm.firstNameLabel', - }); - const firstNamePlaceholder = intl.formatMessage({ - id: 'ProfileSettingsForm.firstNamePlaceholder', - }); - const firstNameRequiredMessage = intl.formatMessage({ - id: 'ProfileSettingsForm.firstNameRequired', - }); - const firstNameRequired = validators.required(firstNameRequiredMessage); + componentWillReceiveProps(nextProps) { + // Upload delay is additional time window where Avatar is added to the DOM, + // but not yet visible (time to load image URL from srcset) + if (this.props.uploadInProgress && !nextProps.uploadInProgress) { + this.setState({ uploadDelay: true }); + this.uploadDelayTimeoutId = window.setTimeout( + () => { + this.setState({ uploadDelay: false }); + }, + UPLOAD_CHANGE_DELAY + ); + } + } - // Last name - const lastNameLabel = intl.formatMessage({ - id: 'ProfileSettingsForm.lastNameLabel', - }); - const lastNamePlaceholder = intl.formatMessage({ - id: 'ProfileSettingsForm.lastNamePlaceholder', - }); - const lastNameRequiredMessage = intl.formatMessage({ - id: 'ProfileSettingsForm.lastNameRequired', - }); - const lastNameRequired = validators.required(lastNameRequiredMessage); + componentWillUnmount() { + window.clearTimeout(this.blurTimeoutId); + } - const uploadingOverlay = uploadInProgress - ?