feat: improve upload flow (#240)

* feat: separate flow for folder and file uploads

* feat: add basic index document detection

* feat(wip): separate preview step

* fix: fix kb and mb units

* feat: add post upload summary, add some styling

* feat: upload flow

* fix: change element order and add conditional rendering

* refactor: remove unused variables for now

* fix: put back stamp creation to stamp page

* refactor: rework postage stamps and grid

* feat: add website and folder icons

* feat: add asset preview to download flow, add file icon

* feat: add basic design to postage stamp selection dialog

* feat: add web icon, shorten stamp in preview

* feat: extract swarm hash in download flow

* fix: extract swarmbutton and solve icon hover and focus color

* fix: always show buy button on stamp page

* refactor: downgrade

* refactor: speed up icon transition

* style: improve download buttons

* style: change [back to upload] icon

* style: add spacing before swarm gateway text

* style: post upload summary spacing

* refactor: drop verticalspacing and use box

* refactor: merge icons to one component

* refactor: use conditions instead of weird assignment

* docs: explain filter(x => x)

* refactor: generalize capacity

* refactor: avoid passing arrow functions

* refactor: get rid of PaperGridContainer and Container

* fix: fix hover color for postage stamps

* feat: add disabled and loading state to buttons

* fix: make drag and drop work for websites

* feat: handle folders and non existing hashes

* fix: provide empty default value to select to avoid console warning

* style: remove body2 font variants

* fix: remove typo

* feat: disable folder upload, add website upload

* fix: disable showPreviews to avoid flickering

* feat(temp): remove folder upload

* fix: remove stuck focus on buttons even after rendering different buttons

* style: merge hover and focus styles, fix safari text wrap issue

* style: remove dropbox outline in safari
This commit is contained in:
Cafe137
2021-11-25 09:54:03 +01:00
committed by GitHub
parent 82cf6d9c01
commit 635621b04a
31 changed files with 1187 additions and 183 deletions
+11 -20
View File
@@ -47,16 +47,13 @@ const useStyles = makeStyles((theme: Theme) =>
)
interface Props {
label?: string
onClose: () => void
}
export default function FormDialog({ label }: Props): ReactElement {
export function CreatePostageStampModal({ onClose }: Props): ReactElement {
const classes = useStyles()
const [open, setOpen] = React.useState(false)
const { refresh } = useContext(Context)
const { beeDebugApi } = useContext(SettingsContext)
const handleClickOpen = () => setOpen(true)
const handleClose = () => setOpen(false)
const { enqueueSnackbar } = useSnackbar()
return (
@@ -75,7 +72,7 @@ export default function FormDialog({ label }: Props): ReactElement {
await beeDebugApi.createPostageBatch(amount.toString(), depth, options)
actions.resetForm()
await refresh()
handleClose()
onClose()
} catch (e) {
enqueueSnackbar(`Error: ${(e as Error).message}`, { variant: 'error' })
actions.setSubmitting(false)
@@ -111,20 +108,9 @@ export default function FormDialog({ label }: Props): ReactElement {
>
{({ submitForm, isValid, isSubmitting, values }) => (
<Form>
<Button variant="contained" onClick={handleClickOpen}>
{label || 'Buy Postage Stamp'}
{isSubmitting && <CircularProgress size={24} className={classes.buttonProgress} />}
</Button>
<Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Purchase new postage stamp</DialogTitle>
<Dialog open={true} onClose={onClose} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">Buy new postage stamp</DialogTitle>
<DialogContent>
<DialogContentText>
Provide the depth, amount and optionally the label of the postage stamp. Please refer to the{' '}
<a href="https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive" target="blank">
official bee docs
</a>{' '}
to understand these values.
</DialogContentText>
<Field
component={TextField}
required
@@ -138,7 +124,7 @@ export default function FormDialog({ label }: Props): ReactElement {
<Field component={TextField} name="label" label="Label" fullWidth className={classes.field} />
</DialogContent>
<DialogActions>
<Button onClick={handleClose} variant="contained">
<Button onClick={onClose} variant="contained">
Cancel
</Button>
<div className={classes.wrapper}>
@@ -153,6 +139,11 @@ export default function FormDialog({ label }: Props): ReactElement {
</Button>
</div>
</DialogActions>
<DialogContent>
<DialogContentText>
Please refer to the official Bee documentation to understand these values.
</DialogContentText>
</DialogContent>
</Dialog>
</Form>
)}
+20
View File
@@ -0,0 +1,20 @@
import { Box, Grid, Typography } from '@material-ui/core'
import { ReactElement } from 'react'
import { Capacity } from '../../components/Capacity'
import { EnrichedPostageBatch } from '../../providers/Stamps'
interface Props {
stamp: EnrichedPostageBatch
shorten?: boolean
}
export function PostageStamp({ stamp, shorten }: Props): ReactElement {
return (
<Box p={2} width="100%">
<Grid container justifyContent="space-between" alignItems="center" direction="row">
<Typography variant="subtitle2">{shorten ? stamp.batchID.slice(0, 8) : stamp.batchID}</Typography>
<Capacity width="100px" usage={stamp.usage} />
</Grid>
</Box>
)
}
@@ -0,0 +1,118 @@
import { Box, createStyles, FormControl, makeStyles, MenuItem, Select, Theme, Typography } from '@material-ui/core'
import Button from '@material-ui/core/Button'
import Dialog from '@material-ui/core/Dialog'
import DialogContent from '@material-ui/core/DialogContent'
import DialogTitle from '@material-ui/core/DialogTitle'
import { Check, Clear } from '@material-ui/icons'
import React, { ReactElement, useState } from 'react'
import ExpandableListItemActions from '../../components/ExpandableListItemActions'
import { EnrichedPostageBatch } from '../../providers/Stamps'
interface Props {
stamps: EnrichedPostageBatch[]
onSelect: (stamp: EnrichedPostageBatch) => void
onClose: () => void
}
const useStyles = makeStyles((theme: Theme) =>
createStyles({
dialog: {
background: theme.palette.background.default,
borderRadius: 0,
width: '100%',
maxWidth: '890px',
},
title: {
color: '#606060',
textAlign: 'center',
},
select: {
background: theme.palette.background.paper,
borderRadius: 0,
border: 0,
},
option: {
height: '52px',
},
hint: {
marginBottom: '16px',
},
}),
)
export function SelectPostageStampModal({ stamps, onSelect, onClose }: Props): ReactElement {
const [selectedStamp, setSelectedStamp] = useState<EnrichedPostageBatch | null>(null)
const classes = useStyles()
function onChange(stampId: string) {
const stamp = stamps.find(x => x.batchID === stampId)
if (stamp) {
setSelectedStamp(stamp)
}
}
function onFinish() {
if (selectedStamp) {
onSelect(selectedStamp)
onClose()
}
}
return (
<Dialog
open={true}
onClose={onClose}
aria-labelledby="form-dialog-title"
fullWidth
PaperProps={{ className: classes.dialog }}
>
<DialogTitle id="form-dialog-title" className={classes.title}>
Select postage stamp
</DialogTitle>
<DialogContent>
<FormControl fullWidth>
<Select
onChange={event => onChange(event.target.value as string)}
fullWidth
variant="outlined"
className={classes.select}
defaultValue=""
>
{stamps.map(x => (
<MenuItem key={x.batchID} value={x.batchID} className={classes.option}>
{x.batchID.slice(0, 8)}
</MenuItem>
))}
</Select>
</FormControl>
</DialogContent>
<Box mb={2}>
<DialogContent>
<ExpandableListItemActions>
<Button disabled={!selectedStamp} onClick={onFinish} variant="contained" startIcon={<Check />}>
Select
</Button>
<Button onClick={onClose} variant="contained" startIcon={<Clear />}>
Cancel
</Button>
</ExpandableListItemActions>
</DialogContent>
</Box>
<DialogContent>
<Typography className={classes.hint}>
Please refer to the{' '}
<a
href="https://docs.ethswarm.org/docs/access-the-swarm/keep-your-data-alive#purchase-a-batch-of-stamps"
target="_blank"
rel="noreferrer"
>
official Bee documentation
</a>{' '}
to understand these values.
</Typography>
</DialogContent>
</Dialog>
)
}
+10 -7
View File
@@ -1,8 +1,9 @@
import type { ReactElement } from 'react'
import { EnrichedPostageBatch } from '../../providers/Stamps'
import ExpandableElement from '../../components/ExpandableElement'
import ExpandableList from '../../components/ExpandableList'
import ExpandableListItem from '../../components/ExpandableListItem'
import ExpandableListItemKey from '../../components/ExpandableListItemKey'
import { EnrichedPostageBatch } from '../../providers/Stamps'
import { PostageStamp } from './PostageStamp'
interface Props {
postageStamps: EnrichedPostageBatch[] | null
@@ -13,11 +14,13 @@ function StampsTable({ postageStamps }: Props): ReactElement | null {
return (
<ExpandableList label="Postage Stamps" defaultOpen>
{postageStamps.map(({ batchID, usageText }) => (
<ExpandableList key={batchID} label={`${batchID.substr(0, 8)}[…]`} level={1} info={`${usageText} used`}>
<ExpandableListItemKey label="Batch ID" value={batchID} />
<ExpandableListItem label="Usage" value={usageText} />
</ExpandableList>
{postageStamps.map(stamp => (
<ExpandableElement
key={stamp.batchID}
expandable={<ExpandableListItemKey label="Batch ID" value={stamp.batchID} />}
>
<PostageStamp stamp={stamp} shorten={true} />
</ExpandableElement>
))}
</ExpandableList>
)
+16 -9
View File
@@ -1,13 +1,13 @@
import { ReactElement, useContext, useEffect } from 'react'
import { CircularProgress, Container } from '@material-ui/core'
import { createStyles, makeStyles } from '@material-ui/core/styles'
import { Container, CircularProgress } from '@material-ui/core'
import StampsTable from './StampsTable'
import CreatePostageStampModal from './CreatePostageStampModal'
import { Context as StampsContext } from '../../providers/Stamps'
import { ReactElement, useContext, useEffect, useState } from 'react'
import { PlusSquare } from 'react-feather'
import { SwarmButton } from '../../components/SwarmButton'
import TroubleshootConnectionCard from '../../components/TroubleshootConnectionCard'
import { Context as BeeContext } from '../../providers/Bee'
import { Context as StampsContext } from '../../providers/Stamps'
import { CreatePostageStampModal } from './CreatePostageStampModal'
import StampsTable from './StampsTable'
const useStyles = makeStyles(() =>
createStyles({
@@ -25,8 +25,11 @@ const useStyles = makeStyles(() =>
}),
)
export default function Accounting(): ReactElement {
export default function Stamp(): ReactElement {
const classes = useStyles()
const [isBuyingStamp, setBuyingStamp] = useState(false)
const { stamps, isLoading, error, start, stop } = useContext(StampsContext)
const { status } = useContext(BeeContext)
@@ -49,7 +52,11 @@ export default function Accounting(): ReactElement {
{!error && (
<>
<div className={classes.actions}>
<CreatePostageStampModal />
{isBuyingStamp ? <CreatePostageStampModal onClose={() => setBuyingStamp(false)} /> : null}
<SwarmButton onClick={() => setBuyingStamp(true)} iconType={PlusSquare}>
Buy New Postage Stamp
</SwarmButton>
<div style={{ height: '5px' }}>{isLoading && <CircularProgress />}</div>
</div>
<StampsTable postageStamps={stamps} />