diff --git a/web/avatars/avatar.css b/web/avatars/avatar.css --- a/web/avatars/avatar.css +++ b/web/avatars/avatar.css @@ -1,3 +1,14 @@ +.avatarContainer { + position: relative; + display: flex; + justify-content: center; + align-items: center; +} + +.editAvatarLoadingSpinner { + position: absolute; +} + .emojiContainer { display: flex; align-items: center; diff --git a/web/avatars/avatar.react.js b/web/avatars/avatar.react.js --- a/web/avatars/avatar.react.js +++ b/web/avatars/avatar.react.js @@ -6,14 +6,16 @@ import type { ResolvedClientAvatar } from 'lib/types/avatar-types.js'; import css from './avatar.css'; +import LoadingIndicator from '../loading-indicator.react.js'; type Props = { +avatarInfo: ResolvedClientAvatar, +size: 'micro' | 'small' | 'large' | 'profile', + +showSpinner?: boolean, }; function Avatar(props: Props): React.Node { - const { avatarInfo, size } = props; + const { avatarInfo, size, showSpinner } = props; const containerSizeClassName = classnames({ [css.imgContainer]: avatarInfo.type === 'image', @@ -63,7 +65,32 @@ emojiSizeClassName, ]); - return avatar; + let loadingIndicatorSize; + if (size === 'micro') { + loadingIndicatorSize = 'small'; + } else if (size === 'small') { + loadingIndicatorSize = 'small'; + } else if (size === 'large') { + loadingIndicatorSize = 'medium'; + } else { + loadingIndicatorSize = 'large'; + } + + const loadingIndicator = React.useMemo( + () => ( +
+ +
+ ), + [loadingIndicatorSize], + ); + + return ( +
+ {showSpinner ? loadingIndicator : null} + {avatar} +
+ ); } export default Avatar; diff --git a/web/avatars/emoji-avatar-selection-modal.react.js b/web/avatars/emoji-avatar-selection-modal.react.js --- a/web/avatars/emoji-avatar-selection-modal.react.js +++ b/web/avatars/emoji-avatar-selection-modal.react.js @@ -114,7 +114,11 @@
- +