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:
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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} />
|
||||
|
||||
Reference in New Issue
Block a user