refactor: clean up postage stamp screens (#642)
* refactor: clean up postage stamp screens * fix: add immutable flag
This commit is contained in:
Generated
+7
-7
@@ -9,7 +9,7 @@
|
|||||||
"version": "0.24.1",
|
"version": "0.24.1",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ethersphere/bee-js": "^6.6.0",
|
"@ethersphere/bee-js": "^6.7.0",
|
||||||
"@ethersphere/swarm-cid": "^0.1.0",
|
"@ethersphere/swarm-cid": "^0.1.0",
|
||||||
"@material-ui/core": "4.12.3",
|
"@material-ui/core": "4.12.3",
|
||||||
"@material-ui/icons": "4.11.2",
|
"@material-ui/icons": "4.11.2",
|
||||||
@@ -2440,9 +2440,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ethersphere/bee-js": {
|
"node_modules/@ethersphere/bee-js": {
|
||||||
"version": "6.6.0",
|
"version": "6.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-6.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-6.7.0.tgz",
|
||||||
"integrity": "sha512-f39yEbkCX7mnKSn0x9cV2TAlnMiemiJCiTVLhS6+g7nMbud1r269gzEHopElDaP5VJIsJy1uwD0VN4+HxIp3bg==",
|
"integrity": "sha512-t1bsUj9BmICuRL6XENTVyZZCfkFuCjc6pQxOekuVFLBd0Qpmyf87iRpVizvZN5IKhVqqw9xCzkg8otJKQdAKNA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ethersphere/swarm-cid": "^0.1.0",
|
"@ethersphere/swarm-cid": "^0.1.0",
|
||||||
"@types/readable-stream": "^2.3.13",
|
"@types/readable-stream": "^2.3.13",
|
||||||
@@ -22305,9 +22305,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ethersphere/bee-js": {
|
"@ethersphere/bee-js": {
|
||||||
"version": "6.6.0",
|
"version": "6.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-6.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersphere/bee-js/-/bee-js-6.7.0.tgz",
|
||||||
"integrity": "sha512-f39yEbkCX7mnKSn0x9cV2TAlnMiemiJCiTVLhS6+g7nMbud1r269gzEHopElDaP5VJIsJy1uwD0VN4+HxIp3bg==",
|
"integrity": "sha512-t1bsUj9BmICuRL6XENTVyZZCfkFuCjc6pQxOekuVFLBd0Qpmyf87iRpVizvZN5IKhVqqw9xCzkg8otJKQdAKNA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersphere/swarm-cid": "^0.1.0",
|
"@ethersphere/swarm-cid": "^0.1.0",
|
||||||
"@types/readable-stream": "^2.3.13",
|
"@types/readable-stream": "^2.3.13",
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
"url": "https://github.com/ethersphere/bee-dashboard.git"
|
"url": "https://github.com/ethersphere/bee-dashboard.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ethersphere/bee-js": "^6.6.0",
|
"@ethersphere/bee-js": "^6.7.0",
|
||||||
"@ethersphere/swarm-cid": "^0.1.0",
|
"@ethersphere/swarm-cid": "^0.1.0",
|
||||||
"@material-ui/core": "4.12.3",
|
"@material-ui/core": "4.12.3",
|
||||||
"@material-ui/icons": "4.11.2",
|
"@material-ui/icons": "4.11.2",
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { PostageBatchOptions } from '@ethersphere/bee-js'
|
import { PostageBatchOptions } from '@ethersphere/bee-js'
|
||||||
import { Box, Grid, Typography } from '@material-ui/core'
|
import { Box, Grid, Typography, createStyles, makeStyles } from '@material-ui/core'
|
||||||
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
|
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import { useSnackbar } from 'notistack'
|
import { useSnackbar } from 'notistack'
|
||||||
import { ReactElement, useContext, useState } from 'react'
|
import { ReactElement, useContext, useState } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
import Check from 'remixicon-react/CheckLineIcon'
|
import Check from 'remixicon-react/CheckLineIcon'
|
||||||
import { SwarmButton } from '../../components/SwarmButton'
|
import { SwarmButton } from '../../components/SwarmButton'
|
||||||
import { SwarmSelect } from '../../components/SwarmSelect'
|
import { SwarmSelect } from '../../components/SwarmSelect'
|
||||||
@@ -11,6 +11,7 @@ import { SwarmTextInput } from '../../components/SwarmTextInput'
|
|||||||
import { Context as BeeContext } from '../../providers/Bee'
|
import { Context as BeeContext } from '../../providers/Bee'
|
||||||
import { Context as SettingsContext } from '../../providers/Settings'
|
import { Context as SettingsContext } from '../../providers/Settings'
|
||||||
import { Context as StampsContext } from '../../providers/Stamps'
|
import { Context as StampsContext } from '../../providers/Stamps'
|
||||||
|
import { ROUTES } from '../../routes'
|
||||||
import {
|
import {
|
||||||
calculateStampPrice,
|
calculateStampPrice,
|
||||||
convertAmountToSeconds,
|
convertAmountToSeconds,
|
||||||
@@ -19,14 +20,12 @@ import {
|
|||||||
waitUntilStampExists,
|
waitUntilStampExists,
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
import { getHumanReadableFileSize } from '../../utils/file'
|
import { getHumanReadableFileSize } from '../../utils/file'
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import { ROUTES } from '../../routes'
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onFinished: () => void
|
onFinished: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) =>
|
const useStyles = makeStyles(() =>
|
||||||
createStyles({
|
createStyles({
|
||||||
link: {
|
link: {
|
||||||
color: '#dd7700',
|
color: '#dd7700',
|
||||||
@@ -174,25 +173,22 @@ export function PostageStampAdvancedCreation({ onFinished }: Props): ReactElemen
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box mb={1}>
|
<Box mb={4}>
|
||||||
<Typography variant="h2">Batch name</Typography>
|
<Typography>
|
||||||
|
To upload data to Swarm network, you will need to purchase a postage stamp. If you're not familiar with
|
||||||
|
this, please read{' '}
|
||||||
|
<a
|
||||||
|
href="https://medium.com/ethereum-swarm/how-to-upload-data-to-the-swarm-network-c0766c3ae381"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
this guide
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box mb={2}>
|
<Box mb={2}>
|
||||||
<SwarmTextInput name="label" label="Label" optional onChange={event => setLabelInput(event.target.value)} />
|
<SwarmTextInput name="depth" label="Depth" onChange={event => validateDepthInput(event.target.value)} />
|
||||||
</Box>
|
|
||||||
<Box mb={2}>
|
|
||||||
<SwarmSelect
|
|
||||||
label="Immutable"
|
|
||||||
defaultValue="No"
|
|
||||||
onChange={event => setImmutable(event.target.value === 'Yes')}
|
|
||||||
options={[
|
|
||||||
{ value: 'Yes', label: 'Yes' },
|
|
||||||
{ value: 'No', label: 'No' },
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box mb={2}>
|
|
||||||
<SwarmTextInput name="depth" label="Batch depth" onChange={event => validateDepthInput(event.target.value)} />
|
|
||||||
<Box mt={0.25} sx={{ bgcolor: '#f6f6f6' }} p={2}>
|
<Box mt={0.25} sx={{ bgcolor: '#f6f6f6' }} p={2}>
|
||||||
<Grid container justifyContent="space-between">
|
<Grid container justifyContent="space-between">
|
||||||
<Typography>Corresponding file size</Typography>
|
<Typography>Corresponding file size</Typography>
|
||||||
@@ -209,14 +205,38 @@ export function PostageStampAdvancedCreation({ onFinished }: Props): ReactElemen
|
|||||||
<Typography>{!amountError && amountInput ? getTtl(Number.parseInt(amountInput, 10)) : '-'}</Typography>
|
<Typography>{!amountError && amountInput ? getTtl(Number.parseInt(amountInput, 10)) : '-'}</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
<Box display="flex" justifyContent={'right'} mt={0.5}>
|
|
||||||
<Typography style={{ fontSize: '10px', color: 'rgba(0, 0, 0, 0.26)' }}>
|
|
||||||
Current price of 24000 per block
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
{amountError && <Typography>{amountError}</Typography>}
|
{amountError && <Typography>{amountError}</Typography>}
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box mb={2}>
|
||||||
|
<SwarmTextInput name="label" label="Label" optional onChange={event => setLabelInput(event.target.value)} />
|
||||||
|
</Box>
|
||||||
|
<Box mb={2}>
|
||||||
|
<SwarmSelect
|
||||||
|
label="Immutable"
|
||||||
|
defaultValue="No"
|
||||||
|
onChange={event => setImmutable(event.target.value === 'Yes')}
|
||||||
|
options={[
|
||||||
|
{ value: 'Yes', label: 'Yes' },
|
||||||
|
{ value: 'No', label: 'No' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<Box mt={0.25} sx={{ bgcolor: '#f6f6f6' }} p={2}>
|
||||||
|
<Grid container justifyContent="space-between">
|
||||||
|
{immutable && (
|
||||||
|
<Typography>
|
||||||
|
Once an immutable stamp is maxed out, it disallows further content uploads, thereby safeguarding your
|
||||||
|
previously uploaded content from unintentional overwriting.
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
{!immutable && (
|
||||||
|
<Typography>
|
||||||
|
When a mutable stamp reaches full capacity, it still permits new content uploads. However, this comes
|
||||||
|
with the caveat of overwriting previously uploaded content associated with the same stamp.
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
<Box mb={4} sx={{ bgcolor: '#fcf2e8' }} p={2}>
|
<Box mb={4} sx={{ bgcolor: '#fcf2e8' }} p={2}>
|
||||||
<Grid container justifyContent="space-between">
|
<Grid container justifyContent="space-between">
|
||||||
<Typography>Indicative Price</Typography>
|
<Typography>Indicative Price</Typography>
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import { PostageBatchOptions } from '@ethersphere/bee-js'
|
import { PostageBatchOptions, Utils } from '@ethersphere/bee-js'
|
||||||
import { Utils } from '@ethersphere/bee-js'
|
|
||||||
import { Box, Button, Grid, Slider, Typography } from '@material-ui/core'
|
import { Box, Button, Grid, Slider, Typography } from '@material-ui/core'
|
||||||
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
|
import { Theme, createStyles, makeStyles } from '@material-ui/core/styles'
|
||||||
import { useSnackbar } from 'notistack'
|
import { useSnackbar } from 'notistack'
|
||||||
import { ReactElement, useContext, useState } from 'react'
|
import { ReactElement, useContext, useState } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
import Check from 'remixicon-react/CheckLineIcon'
|
import Check from 'remixicon-react/CheckLineIcon'
|
||||||
import { SwarmButton } from '../../components/SwarmButton'
|
import { SwarmButton } from '../../components/SwarmButton'
|
||||||
import { SwarmTextInput } from '../../components/SwarmTextInput'
|
import { SwarmTextInput } from '../../components/SwarmTextInput'
|
||||||
import { Context as SettingsContext } from '../../providers/Settings'
|
import { Context as SettingsContext } from '../../providers/Settings'
|
||||||
import { Context as StampsContext } from '../../providers/Stamps'
|
import { Context as StampsContext } from '../../providers/Stamps'
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import { ROUTES } from '../../routes'
|
import { ROUTES } from '../../routes'
|
||||||
import { calculateStampPrice, convertAmountToSeconds, secondsToTimeString, waitUntilStampExists } from '../../utils'
|
import { calculateStampPrice, convertAmountToSeconds, secondsToTimeString, waitUntilStampExists } from '../../utils'
|
||||||
|
|
||||||
@@ -43,30 +42,31 @@ const marks = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export function PostageStampStandardCreation({ onFinished }: Props): ReactElement {
|
export function PostageStampStandardCreation({ onFinished }: Props): ReactElement {
|
||||||
const getDepthForCapacity = Utils.getDepthForCapacity
|
|
||||||
const getAmountForTtl = Utils.getAmountForTtl
|
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const { refresh } = useContext(StampsContext)
|
const { refresh } = useContext(StampsContext)
|
||||||
const { beeDebugApi } = useContext(SettingsContext)
|
const { beeDebugApi } = useContext(SettingsContext)
|
||||||
|
|
||||||
const [depthInput, setDepthInput] = useState<number>(getDepthForCapacity(4))
|
const [depthInput, setDepthInput] = useState<number>(Utils.getDepthForCapacity(4))
|
||||||
const [amountInput, setAmountInput] = useState<number>(Number.parseInt(getAmountForTtl(30)))
|
const [amountInput, setAmountInput] = useState<string>(Utils.getAmountForTtl(30))
|
||||||
const [labelInput, setLabelInput] = useState('')
|
const [labelInput, setLabelInput] = useState('')
|
||||||
const [submitting, setSubmitting] = useState(false)
|
const [submitting, setSubmitting] = useState(false)
|
||||||
const [buttonValue, setButtonValue] = useState(4)
|
const [buttonValue, setButtonValue] = useState(4)
|
||||||
|
|
||||||
function sliderValueChange(event: any, newValue: any) {
|
function sliderValueChange(_: unknown, newValue: number | number[]) {
|
||||||
const amountValue = Number.parseInt(getAmountForTtl(newValue))
|
if (typeof newValue !== 'number') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const amountValue = Utils.getAmountForTtl(newValue)
|
||||||
setAmountInput(amountValue)
|
setAmountInput(amountValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { enqueueSnackbar } = useSnackbar()
|
const { enqueueSnackbar } = useSnackbar()
|
||||||
|
|
||||||
function getTtl(amount: number): string {
|
function getTtl(amount: string): string {
|
||||||
const pricePerBlock = 24000
|
const pricePerBlock = 24000
|
||||||
|
|
||||||
return `${secondsToTimeString(
|
return `${secondsToTimeString(
|
||||||
convertAmountToSeconds(amount, pricePerBlock),
|
convertAmountToSeconds(parseInt(amount, 10), pricePerBlock),
|
||||||
)} (with price of ${pricePerBlock.toFixed(0)} per block)`
|
)} (with price of ${pricePerBlock.toFixed(0)} per block)`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ export function PostageStampStandardCreation({ onFinished }: Props): ReactElemen
|
|||||||
const options: PostageBatchOptions = {
|
const options: PostageBatchOptions = {
|
||||||
waitForUsable: false,
|
waitForUsable: false,
|
||||||
label: labelInput || undefined,
|
label: labelInput || undefined,
|
||||||
immutableFlag: false,
|
immutableFlag: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
const batchId = await beeDebugApi.createPostageBatch(amount.toString(), depth, options)
|
const batchId = await beeDebugApi.createPostageBatch(amount.toString(), depth, options)
|
||||||
@@ -107,11 +107,9 @@ export function PostageStampStandardCreation({ onFinished }: Props): ReactElemen
|
|||||||
setSubmitting(false)
|
setSubmitting(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBatchSize(event: any) {
|
function handleBatchSize(gigabytes: number) {
|
||||||
let value = event.target.innerText
|
setButtonValue(gigabytes)
|
||||||
value = Number(value.substring(0, value.length - 3))
|
const capacity = Utils.getDepthForCapacity(gigabytes)
|
||||||
setButtonValue(value)
|
|
||||||
const capacity = getDepthForCapacity(value)
|
|
||||||
setDepthInput(capacity)
|
setDepthInput(capacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +144,7 @@ export function PostageStampStandardCreation({ onFinished }: Props): ReactElemen
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
fullWidth
|
fullWidth
|
||||||
onClick={handleBatchSize}
|
onClick={() => handleBatchSize(4)}
|
||||||
className={buttonValue === 4 ? classes.buttonSelected : ''}
|
className={buttonValue === 4 ? classes.buttonSelected : ''}
|
||||||
>
|
>
|
||||||
4 GB
|
4 GB
|
||||||
@@ -156,7 +154,7 @@ export function PostageStampStandardCreation({ onFinished }: Props): ReactElemen
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
fullWidth
|
fullWidth
|
||||||
onClick={handleBatchSize}
|
onClick={() => handleBatchSize(32)}
|
||||||
className={buttonValue === 32 ? classes.buttonSelected : ''}
|
className={buttonValue === 32 ? classes.buttonSelected : ''}
|
||||||
>
|
>
|
||||||
32 GB
|
32 GB
|
||||||
@@ -166,7 +164,7 @@ export function PostageStampStandardCreation({ onFinished }: Props): ReactElemen
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
fullWidth
|
fullWidth
|
||||||
onClick={handleBatchSize}
|
onClick={() => handleBatchSize(256)}
|
||||||
className={buttonValue === 256 ? classes.buttonSelected : ''}
|
className={buttonValue === 256 ? classes.buttonSelected : ''}
|
||||||
>
|
>
|
||||||
256 GB
|
256 GB
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
export function getStampUsage(utilization: number, depth: number, bucketDepth: number): number {
|
|
||||||
return utilization / Math.pow(2, depth - bucketDepth)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getStampMaximumCapacityBytes(depth: number): number {
|
|
||||||
return 2 ** depth * 4096
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getStampCostInPlur(depth: number, amount: number): number {
|
|
||||||
return 2 ** depth * amount
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getStampCostInBzz(depth: number, amount: number): number {
|
|
||||||
const BZZ_UNIT = 10 ** 16
|
|
||||||
|
|
||||||
return getStampCostInPlur(depth, amount) / BZZ_UNIT
|
|
||||||
}
|
|
||||||
|
|
||||||
// export function getStampTtlSeconds(amount: number, pricePerBlock = 24_000, blockTime = 5): number {
|
|
||||||
// return (amount * blockTime) / pricePerBlock
|
|
||||||
// }
|
|
||||||
|
|
||||||
export function getStampTtlSeconds(amount: number, pricePerBlock = 24_000, blockTime = 5): number {
|
|
||||||
return (amount * blockTime) / pricePerBlock
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user