From 668c9f4841e7118b98bb31d8e68640689be99830 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sat, 22 Aug 2020 13:54:56 +0300
Subject: refactor!: simplify file operations

---
 src/containers/Profile/ProfileInfo.tsx | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

(limited to 'src/containers/Profile/ProfileInfo.tsx')

diff --git a/src/containers/Profile/ProfileInfo.tsx b/src/containers/Profile/ProfileInfo.tsx
index c9831f3..fbd6272 100644
--- a/src/containers/Profile/ProfileInfo.tsx
+++ b/src/containers/Profile/ProfileInfo.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useCallback } from 'react';
 import { Badge, Typography } from '@material-ui/core/';
 import { makeStyles } from '@material-ui/core/styles';
 import { User } from 'which-types';
@@ -6,10 +6,11 @@ import CameraAltIcon from '@material-ui/icons/CameraAlt';
 import VerifiedIcon from '@material-ui/icons/CheckCircleOutline';
 import Skeleton from '@material-ui/lab/Skeleton';
 import Highlight from './Highlight';
-import AttachLink from '../../components/AttachLink/AttachLink';
+import FileUpload from '../../components/FileUpload/FileUpload';
 import Avatar from '../../components/Avatar/Avatar';
 import { patch } from '../../requests';
 import { useAuth } from '../../hooks/useAuth';
+import uploadFileToS3 from '../../utils/uploadFileToS3';
 
 
 interface PropTypes {
@@ -88,14 +89,16 @@ const ProfileInfo: React.FC<PropTypes> = ({
 }) => {
   const classes = useStyles();
   const { user } = useAuth();
+
   const dateSince = new Date(userInfo?.createdAt || '').toLocaleDateString();
 
-  const patchAvatar = (url: string) => {
-    const id = user?._id;
-    patch(`/users/${id}`, { avatarUrl: url }).then(res => {
-      setUserInfo(res.data);
-    });
-  };
+  const handleUpdateAvatar = useCallback(async (file: File) => {
+    if (user) {
+      uploadFileToS3(file, 1)
+        .then(avatarUrl => patch(`/users/${user._id}`, { avatarUrl }))
+        .then(response => setUserInfo(response.data));
+    }
+  }, [user, setUserInfo]);
 
   return (
     <div className={classes.root}>
@@ -104,7 +107,7 @@ const ProfileInfo: React.FC<PropTypes> = ({
           ? <Skeleton animation="wave" variant="circle" width={150} height={150} className={classes.avatar} />
           : userInfo?._id === user?._id
             ? (
-              <AttachLink callback={patchAvatar}>
+              <FileUpload callback={handleUpdateAvatar}>
                 <div className={classes.avatarContainer}>
                   <Badge
                     overlap="circle"
@@ -121,7 +124,7 @@ const ProfileInfo: React.FC<PropTypes> = ({
                     <Avatar className={classes.avatar} user={userInfo} />
                   </Badge>
                 </div>
-              </AttachLink>
+              </FileUpload>
             )
             : <Avatar className={classes.avatar} user={userInfo} />
       }
-- 
cgit v1.2.3


From 0abfd51fea30e2f305648e63df2cab8ba872c963 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sat, 22 Aug 2020 14:32:26 +0300
Subject: feat: display avatar upload progress

---
 src/containers/Profile/ProfileInfo.tsx | 64 ++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 27 deletions(-)

(limited to 'src/containers/Profile/ProfileInfo.tsx')

diff --git a/src/containers/Profile/ProfileInfo.tsx b/src/containers/Profile/ProfileInfo.tsx
index fbd6272..e2fb0a9 100644
--- a/src/containers/Profile/ProfileInfo.tsx
+++ b/src/containers/Profile/ProfileInfo.tsx
@@ -1,10 +1,10 @@
-import React, { useCallback } from 'react';
-import { Badge, Typography } from '@material-ui/core/';
+import React, { useState, useCallback } from 'react';
+import { Badge, Typography, CircularProgress } from '@material-ui/core/';
+import { CameraAlt, CheckCircleOutline } from '@material-ui/icons/';
 import { makeStyles } from '@material-ui/core/styles';
-import { User } from 'which-types';
-import CameraAltIcon from '@material-ui/icons/CameraAlt';
-import VerifiedIcon from '@material-ui/icons/CheckCircleOutline';
 import Skeleton from '@material-ui/lab/Skeleton';
+import { User } from 'which-types';
+
 import Highlight from './Highlight';
 import FileUpload from '../../components/FileUpload/FileUpload';
 import Avatar from '../../components/Avatar/Avatar';
@@ -12,7 +12,6 @@ import { patch } from '../../requests';
 import { useAuth } from '../../hooks/useAuth';
 import uploadFileToS3 from '../../utils/uploadFileToS3';
 
-
 interface PropTypes {
   savedPolls: number;
   totalVotes: number;
@@ -67,7 +66,9 @@ const useStyles = makeStyles(theme => ({
   },
   avatarContainer: {
     position: 'relative',
-    textAlign: 'center'
+    display: 'flex',
+    justifyContent: 'center',
+    alignItems: 'center'
   },
   menuNumber: {
     fontWeight: 800,
@@ -79,8 +80,11 @@ const useStyles = makeStyles(theme => ({
   skeleton: {
     margin: '10px auto',
     borderRadius: 2
+  },
+  progress: {
+    position: 'absolute',
+    color: 'white'
   }
-
 }));
 
 
@@ -89,14 +93,16 @@ const ProfileInfo: React.FC<PropTypes> = ({
 }) => {
   const classes = useStyles();
   const { user } = useAuth();
+  const [progress, setProgress] = useState<number>(0);
 
   const dateSince = new Date(userInfo?.createdAt || '').toLocaleDateString();
 
   const handleUpdateAvatar = useCallback(async (file: File) => {
     if (user) {
-      uploadFileToS3(file, 1)
+      uploadFileToS3(file, 0.8, setProgress)
         .then(avatarUrl => patch(`/users/${user._id}`, { avatarUrl }))
-        .then(response => setUserInfo(response.data));
+        .then(response => setUserInfo(response.data))
+        .then(() => setProgress(0));
     }
   }, [user, setUserInfo]);
 
@@ -107,24 +113,28 @@ const ProfileInfo: React.FC<PropTypes> = ({
           ? <Skeleton animation="wave" variant="circle" width={150} height={150} className={classes.avatar} />
           : userInfo?._id === user?._id
             ? (
-              <FileUpload callback={handleUpdateAvatar}>
-                <div className={classes.avatarContainer}>
-                  <Badge
-                    overlap="circle"
-                    anchorOrigin={{
-                      vertical: 'bottom',
-                      horizontal: 'right'
-                    }}
-                    badgeContent={(
+              <div className={classes.avatarContainer}>
+                <Badge
+                  overlap="circle"
+                  anchorOrigin={{
+                    vertical: 'bottom',
+                    horizontal: 'right'
+                  }}
+                  className={classes.avatarContainer}
+                  badgeContent={(
+                    <FileUpload callback={handleUpdateAvatar}>
                       <div className={classes.badge}>
-                        <CameraAltIcon />
+                        <CameraAlt />
                       </div>
-                    )}
-                  >
-                    <Avatar className={classes.avatar} user={userInfo} />
-                  </Badge>
-                </div>
-              </FileUpload>
+                    </FileUpload>
+                  )}
+                >
+                  <Avatar className={classes.avatar} user={userInfo} />
+                  {progress > 0 && (
+                    <CircularProgress variant="static" value={progress} className={classes.progress} />
+                  )}
+                </Badge>
+              </div>
             )
             : <Avatar className={classes.avatar} user={userInfo} />
       }
@@ -134,7 +144,7 @@ const ProfileInfo: React.FC<PropTypes> = ({
           : (
             <Typography variant="h5" className={classes.name}>
               {userInfo?.username}
-              {userInfo?.verified && <VerifiedIcon className={classes.verified} color="primary" />}
+              {userInfo?.verified && <CheckCircleOutline className={classes.verified} color="primary" />}
             </Typography>
           )
       }
-- 
cgit v1.2.3

