Преглед на файлове

UX fixes for File upload and Collection selection.

Pushkar Anand преди 4 години
родител
ревизия
fc760ed471

+ 22 - 18
src/components/FullScreenDropZone.tsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useRef } from 'react';
 import styled from 'styled-components';
 
 const DropDiv = styled.div`
@@ -7,21 +7,25 @@ const DropDiv = styled.div`
   flex-direction: column;
 `;
 
-const FullScreenDropZone = ({
-    children,
-    closeModal,
-    showModal,
-}) =>
-(
-    <DropDiv onDragOver={(ev) => {
-        ev.preventDefault();
-        showModal();
-    }} onDragLeave={(ev) => {
-        ev.preventDefault();
-        closeModal();
-    }}>
-        {children}
-    </DropDiv>
-);
+type Props = React.PropsWithChildren<{
+    showModal: () => void;
+    closeModal: () => void;
+}>;
 
-export default FullScreenDropZone;
+export default function FullScreenDropZone({ children, showModal, closeModal }: Props) {
+    const closeTimer = useRef<number>();
+    return (
+        <DropDiv onDragOver={(ev) => {
+            // ev.preventDefault();
+            if (closeTimer.current) {
+                clearTimeout(closeTimer.current);
+            }
+            showModal();
+        }} onDragLeave={(ev) => {
+            // ev.preventDefault();
+            closeTimer.current = setTimeout(closeModal, 300);
+        }}>
+            {children}
+        </DropDiv>
+    );
+};

+ 26 - 3
src/pages/_app.tsx

@@ -82,11 +82,28 @@ const GlobalStyles = createGlobalStyle`
     }
     .modal-90w{
         width:90vw;
-        max-width:880px!important;  
+        max-width:880px!important;
+    }
+    .modal .modal-header, .modal  .modal-footer {
+        border-color: #444 !important;
+    }
+    .modal .modal-header .close {
+        color: #aaa;
+        text-shadow: none;
+    }
+    .modal .card {
+        background-color: #303030;
+        border: none;
+        color: #aaa;
+    }
+    .modal .card > div {
+        border-radius: 30px;
+        overflow: hidden;
+        margin: 0 0 5px 0;
     }
     .modal-content{
         background-color:#303030 !important;
-        color:white;
+        color:#aaa;
     }
 `;
 
@@ -144,6 +161,7 @@ export default function App({ Component, pageProps }) {
         <FullScreenDropZone
             closeModal={closeUploadModal}
             showModal={showUploadModal}
+            uploadModalView={uploadModalView}
         >
             <Head>
                 <title>ente.io | Privacy friendly alternative to Google Photos</title>
@@ -168,7 +186,12 @@ export default function App({ Component, pageProps }) {
                     </Spinner>
                 </Container>
             ) : (
-                    <Component uploadModalView={uploadModalView} showUploadModal={showUploadModal} closeUploadModal={closeUploadModal} setUploadButtonView={setUploadButtonView} />
+                    <Component
+                        uploadModalView={uploadModalView}
+                        showUploadModal={showUploadModal}
+                        closeUploadModal={closeUploadModal}
+                        setUploadButtonView={setUploadButtonView}
+                    />
                 )}
         </FullScreenDropZone>
     );

+ 16 - 6
src/pages/gallery/components/AddCollection.tsx

@@ -5,8 +5,18 @@ import styled from "styled-components";
 import { DropDiv } from "./CollectionDropZone";
 import CreateCollection from "./CreateCollection";
 
-const Image = styled.img`
-  max-height: 190px;
+const ImageContainer = styled.div`
+    min-height: 192px;
+    max-width: 192px;
+    border: 1px solid #555;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 42px;
+`;
+
+const StyledCard = styled(Card)`
+    cursor: pointer;
 `;
 
 export default function AddCollection(props) {
@@ -28,7 +38,7 @@ export default function AddCollection(props) {
                 onDropRejected={closeUploadModal}
                 onDragOver={showUploadModal}
                 noDragEventsBubbling
-                accept="image/*, video/*, application/json,"
+                accept="image/*, video/*"
             >
                 {({
                     getRootProps,
@@ -46,10 +56,10 @@ export default function AddCollection(props) {
                             })}
                         >
                             <input {...getInputProps()} />
-                            <Card style={{ cursor: 'pointer' }}>
-                                <Image alt='logo' src='/plus-sign.png' />
+                            <StyledCard>
+                                <ImageContainer>+</ImageContainer>
                                 <Card.Text style={{ textAlign: "center" }}>Create New Album</Card.Text>
-                            </Card>
+                            </StyledCard>
                         </DropDiv>
                     );
                 }}

+ 6 - 9
src/pages/gallery/components/CollectionSelector.tsx

@@ -1,9 +1,9 @@
 import React, { useEffect, useState } from 'react';
 import { Button, Card, Modal } from 'react-bootstrap';
-import { getData, LS_KEYS } from 'utils/storage/localStorage';
 import CollectionDropZone from './CollectionDropZone';
 import AddCollection from './AddCollection';
 import PreviewCard from './PreviewCard';
+import constants from 'utils/strings/constants';
 
 function CollectionSelector(props) {
     const {
@@ -23,8 +23,8 @@ function CollectionSelector(props) {
             collectionLatestFile={item}
         >
             <Card>
-                <PreviewCard data={item.file} updateUrl={() => { }} onClick={() => { }} />
-                <Card.Text style={{ textAlign: 'center' }}>{item.collection.name}</Card.Text>
+                <PreviewCard data={item.file} updateUrl={() => { }}/>
+                <Card.Text className="text-center">{item.collection.name}</Card.Text>
             </Card>
 
         </CollectionDropZone>
@@ -38,10 +38,10 @@ function CollectionSelector(props) {
         >
             <Modal.Header closeButton>
                 <Modal.Title >
-                    Select/Click on Collection to upload
-                    </Modal.Title>
+                    {constants.SELECT_COLLECTION}
+                </Modal.Title>
             </Modal.Header>
-            <Modal.Body style={{ display: "flex", justifyContent: "space-around", flexWrap: "wrap" }}>
+            <Modal.Body style={{ display: "flex", justifyContent: "flex-start", flexWrap: "wrap" }}>
                 <AddCollection
                     {...rest}
                     showUploadModal={showUploadModal}
@@ -49,9 +49,6 @@ function CollectionSelector(props) {
                 />
                 {CollectionIcons}
             </Modal.Body>
-            <Modal.Footer>
-                <Button onClick={closeUploadModal}>Close</Button>
-            </Modal.Footer>
         </Modal>
     );
 }

+ 2 - 2
src/pages/gallery/components/PreviewCard.tsx

@@ -7,7 +7,7 @@ import PlayCircleOutline from 'components/PlayCircleOutline';
 interface IProps {
     data: file,
     updateUrl: (url: string) => void,
-    onClick: () => void,
+    onClick?: () => void,
 }
 
 const Cont = styled.div<{ disabled: boolean }>`
@@ -58,7 +58,7 @@ export default function PreviewCard(props: IProps) {
 
     const handleClick = () => {
         if (data?.msrc || imgSrc) {
-            onClick();
+            onClick?.();
         }
     }
 

+ 34 - 36
src/pages/gallery/index.tsx

@@ -39,58 +39,55 @@ interface TimeStampListItem {
 }
 
 const Container = styled.div`
-  display: block;
-  flex: 1;
-  width: 100%;
-  flex-wrap: wrap;
-  margin: 0 auto;
+    display: block;
+    flex: 1;
+    width: 100%;
+    flex-wrap: wrap;
+    margin: 0 auto;
 
-  .pswp-thumbnail {
-    display: inline-block;
-    cursor: pointer;
-  }
+    .pswp-thumbnail {
+        display: inline-block;
+        cursor: pointer;
+    }
 `;
 
 const ListItem = styled.div`
-  display: flex;
-  justify-content: center;
+    display: flex;
+    justify-content: center;
 `;
 
 const DeadCenter = styled.div`
-  flex: 1;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  color: #fff;
-  text-align: center;
-  flex-direction: column;
+    flex: 1;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #fff;
+    text-align: center;
+    flex-direction: column;
 `;
 
 const ListContainer = styled.div`
-  display: flex;
-  max-width: 100%;
-  color: #fff;
+    display: flex;
+    max-width: 100%;
+    color: #fff;
 
-  @media (min-width: 1000px) {
-    width: 1000px;
-  }
+    @media (min-width: 1000px) {
+        width: 1000px;
+    }
 
-  @media (min-width: 450px) and (max-width: 1000px) {
-    width: 600px;
-  }
+    @media (min-width: 450px) and (max-width: 1000px) {
+        width: 600px;
+    }
 
-  @media (max-width: 450px) {
-    width: 100%;
-  }
+    @media (max-width: 450px) {
+        width: 100%;
+    }
 `;
 
 const DateContainer = styled.div`
-  padding: 0 4px;
+    padding: 0 4px;
 `;
 
-const PAGE_SIZE = 12;
-const COLUMNS = 3;
-
 export default function Gallery(props) {
     const router = useRouter();
     const [loading, setLoading] = useState(false);
@@ -297,8 +294,9 @@ export default function Gallery(props) {
                 closeUploadModal={props.closeUploadModal}
                 showUploadModal={props.showUploadModal}
                 collectionLatestFile={collectionLatestFile}
-                refetchData={() => setReload(Math.random())} />
-
+                refetchData={() => setReload(Math.random())}
+                
+            />
             {filteredData.length ? (
                 <Container>
                     <AutoSizer>

+ 3 - 1
src/utils/strings/englishConstants.tsx

@@ -41,7 +41,9 @@ const englishConstants = {
     PASSPHRASE_CONFIRM: 'Please repeat it once more',
     PASSPHRASE_MATCH_ERROR: `Passphrase didn't match`,
     CONSOLE_WARNING_STOP: 'STOP!',
-    CONSOLE_WARNING_DESC: `This is a browser feature intended for developers. If someone told you to copy-paste something here to enable a feature or "hack" someone's account, it is a scam and will give them access to your account.`
+    CONSOLE_WARNING_DESC: `This is a browser feature intended for developers. If someone told you to copy-paste something here to enable a feature or "hack" someone's account, it is a scam and will give them access to your account.`,
+    SELECT_COLLECTION: `Select/Click on Collection to upload`,
+    CLOSE: 'Close'
 };
 
 export default englishConstants;