From c5cacacfadf12c9321e932ce2fc3fa669b4c8807 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Fri, 14 Aug 2020 16:16:01 +0300
Subject: feat: handle loading and error states in Image

---
 src/components/Image/Image.tsx | 55 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 2 deletions(-)

(limited to 'src/components/Image/Image.tsx')

diff --git a/src/components/Image/Image.tsx b/src/components/Image/Image.tsx
index de67c6a..7736e8a 100644
--- a/src/components/Image/Image.tsx
+++ b/src/components/Image/Image.tsx
@@ -1,4 +1,7 @@
-import React from 'react';
+import React, { useState, useCallback } from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import CircularProgress from '@material-ui/core/CircularProgress';
+import ErrorIcon from '@material-ui/icons/BrokenImage';
 
 interface PropTypes {
   src?: string;
@@ -6,8 +9,56 @@ interface PropTypes {
   className?: string;
 }
 
+const useStyles = makeStyles(theme => ({
+  container: {
+    width: '100%',
+    height: '100%',
+    display: 'flex',
+    alignItems: 'center',
+    justifyContent: 'center'
+  }
+}));
+
+type Status = 'success' |'loading' | 'error';
+
 const Image: React.FC<PropTypes> = ({ src, alt, className }) => {
-  return <img src={src} alt={alt} className={className} />;
+  const classes = useStyles();
+  const [status, setStatus] = useState<Status>('loading');
+
+  const handleLoad = useCallback((): void => {
+    setStatus('success');
+  }, [setStatus]);
+
+  const handleError = useCallback((): void => {
+    setStatus('error');
+  }, [setStatus]);
+
+  const image = (
+    <img
+      src={src}
+      alt={alt}
+      className={className}
+      style={{ display: status === 'success' ? 'inline' : 'none' }}
+      onLoad={handleLoad}
+      onError={handleError}
+    />
+  );
+
+  return (
+    <>
+      {src && image}
+      {
+        status !== 'success' && (
+          <div className={classes.container}>
+            {
+              (status === 'error' || !src)
+              ? <ErrorIcon fontSize="large" />
+              : <CircularProgress color="primary" />
+            }
+          </div>
+      )}
+    </>
+  );
 };
 
 export default Image;
-- 
cgit v1.2.3

