feat: add website and folder upload and download (#260)

* feat: add website and folder upload and download

* feat: download-share-upload navigation

* fix: check for files length in hasIndexDocument

* fix: change router dependency

* refactor: switch to @ethersphere/manfest-js

* fix: hide previews on dropzone, fix spinner align, hide 0 size display

* feat: add upload and download history

* refactor: change drag and drop text

* feat: make history ux better

* refactor: improve code based on review

* build: add missing react-router dependency

* ci: remove beeload

* revert(ci): remove beeload

This reverts commit 4ce6cb0045a2d9aea3047ab395d214d8d368c532.
This commit is contained in:
Cafe137
2021-12-07 16:06:21 +01:00
committed by GitHub
parent dec812be45
commit 3ef1ad9574
26 changed files with 839 additions and 269 deletions
+35 -10
View File
@@ -1,8 +1,9 @@
import { Grid, IconButton, ListItem, Tooltip, Typography } from '@material-ui/core'
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
import { OpenInNewSharp } from '@material-ui/icons'
import { ArrowForward, OpenInNewSharp } from '@material-ui/icons'
import { ReactElement, useState } from 'react'
import CopyToClipboard from 'react-copy-to-clipboard'
import { useHistory } from 'react-router'
const useStyles = makeStyles((theme: Theme) =>
createStyles({
@@ -46,15 +47,35 @@ const useStyles = makeStyles((theme: Theme) =>
interface Props {
label: string
value: string
link?: string
navigationType?: 'NEW_WINDOW' | 'HISTORY_PUSH'
allowClipboard?: boolean
}
export default function ExpandableListItemLink({ label, value }: Props): ReactElement | null {
export default function ExpandableListItemLink({
label,
value,
link,
navigationType = 'NEW_WINDOW',
allowClipboard = true,
}: Props): ReactElement | null {
const classes = useStyles()
const [copied, setCopied] = useState(false)
const history = useHistory()
const tooltipClickHandler = () => setCopied(true)
const tooltipCloseHandler = () => setCopied(false)
const displayValue = value.length > 22 ? value.slice(0, 19) + '...' : value
function onNavigation() {
if (navigationType === 'NEW_WINDOW') {
window.open(link || value)
} else {
history.push(link || value)
}
}
return (
<ListItem className={classes.header}>
<Grid container direction="column" justifyContent="space-between" alignItems="stretch">
@@ -62,15 +83,19 @@ export default function ExpandableListItemLink({ label, value }: Props): ReactEl
{label && <Typography variant="body1">{label}</Typography>}
<Typography variant="body2">
<div>
<span className={classes.copyValue}>
<Tooltip title={copied ? 'Copied' : 'Copy'} placement="top" arrow onClose={tooltipCloseHandler}>
<CopyToClipboard text={value}>
<span onClick={tooltipClickHandler}>{value.slice(0, 19)}...</span>
</CopyToClipboard>
</Tooltip>
</span>
{allowClipboard && (
<span className={classes.copyValue}>
<Tooltip title={copied ? 'Copied' : 'Copy'} placement="top" arrow onClose={tooltipCloseHandler}>
<CopyToClipboard text={value}>
<span onClick={tooltipClickHandler}>{displayValue}</span>
</CopyToClipboard>
</Tooltip>
</span>
)}
{!allowClipboard && <span onClick={onNavigation}>{displayValue}</span>}
<IconButton size="small" className={classes.openLinkIcon}>
<OpenInNewSharp onClick={() => window.open(value)} strokeWidth={1} />
{navigationType === 'NEW_WINDOW' && <OpenInNewSharp onClick={onNavigation} strokeWidth={1} />}
{navigationType === 'HISTORY_PUSH' && <ArrowForward onClick={onNavigation} strokeWidth={1} />}
</IconButton>
</div>
</Typography>
+37
View File
@@ -0,0 +1,37 @@
import { ReactElement, useEffect, useState } from 'react'
import { getPrettyDateString } from '../utils/date'
import { getHistorySafe, HistoryItem, HISTORY_KEYS } from '../utils/local-storage'
import ExpandableList from './ExpandableList'
import ExpandableListItemLink from './ExpandableListItemLink'
interface Props {
title: string
localStorageKey: HISTORY_KEYS
}
export function History({ title, localStorageKey }: Props): ReactElement | null {
const [items, setItems] = useState<HistoryItem[]>([])
useEffect(() => {
setItems(getHistorySafe(localStorageKey))
}, [localStorageKey])
if (!items.length) {
return null
}
return (
<ExpandableList label={title} defaultOpen>
{items.map((x, i) => (
<ExpandableListItemLink
label={getPrettyDateString(new Date(x.createdAt))}
value={x.name}
link={'/files/hash/' + x.hash}
key={i}
navigationType="HISTORY_PUSH"
allowClipboard={false}
/>
))}
</ExpandableList>
)
}
+41
View File
@@ -0,0 +1,41 @@
import { Box, createStyles, Grid, makeStyles, Typography } from '@material-ui/core'
import { ArrowBack } from '@material-ui/icons'
import { ReactElement } from 'react'
import { useHistory } from 'react-router-dom'
interface Props {
children: string
}
const useStyles = makeStyles(() =>
createStyles({
pressable: {
cursor: 'pointer',
},
icon: {
color: '#242424',
},
}),
)
export function HistoryHeader({ children }: Props): ReactElement {
const classes = useStyles()
const history = useHistory()
function goBack() {
history.goBack()
}
return (
<Box mb={4}>
<Grid container direction="row">
<Box mr={2}>
<div className={classes.pressable} onClick={goBack}>
<ArrowBack className={classes.icon} />
</div>
</Box>
<Typography variant="h1">{children}</Typography>
</Grid>
</Box>
)
}
+10
View File
@@ -0,0 +1,10 @@
import { CircularProgress, Grid } from '@material-ui/core'
import { ReactElement } from 'react'
export function Loading(): ReactElement {
return (
<Grid container direction="row" justifyContent="center" alignItems="center">
<CircularProgress />
</Grid>
)
}
+7 -9
View File
@@ -1,16 +1,14 @@
import type { ReactElement } from 'react'
import { Link } from 'react-router-dom'
import { createStyles, Theme, makeStyles } from '@material-ui/core/styles'
import { Divider, Drawer, Grid, Link as MUILink, List } from '@material-ui/core'
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
import { OpenInNewSharp } from '@material-ui/icons'
import { Divider, List, Drawer, Grid, Link as MUILink } from '@material-ui/core'
import { Home, FileText, DollarSign, Settings, Layers, BookOpen } from 'react-feather'
import type { ReactElement } from 'react'
import { BookOpen, DollarSign, FileText, Home, Layers, Settings } from 'react-feather'
import { Link } from 'react-router-dom'
import Logo from '../assets/logo.svg'
import { ROUTES } from '../routes'
import SideBarItem from './SideBarItem'
import SideBarStatus from './SideBarStatus'
import Logo from '../assets/logo.svg'
const navBarItems = [
{
label: 'Info',
@@ -19,7 +17,7 @@ const navBarItems = [
},
{
label: 'Files',
path: ROUTES.FILES,
path: ROUTES.UPLOAD,
icon: FileText,
},
{