UX fixes for File upload and Collection selection.
This commit is contained in:
parent
cf1cb28320
commit
fc760ed471
7 changed files with 109 additions and 75 deletions
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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?.();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue