cb5adfe031
* fix: swap error caused by invalid id and batchcount * fix: enhance creation messages for admin drive and user drives * fix: identity and wallet creation * fix: asset preview types * fix: fm search unicode text * fix: feed identity and stamp usage * fix: ui display changes * fix: stamp buy and dilute * fix: vite polyfill warning for stream * fix: standard mode postage stamp purchase reserves incorrect size and duration * fix: add syncing message for Bee node and update page state handling * refactor: stamp depth and amount validation --------- Co-authored-by: Balint Ujvari <balint.ujvari@solarpunk.buzz> Co-authored-by: Bálint Ujvári <58116288+bosi95@users.noreply.github.com> Co-authored-by: rolandlor <33499567+rolandlor@users.noreply.github.com>
118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
import { Collapse, Grid, IconButton, ListItemButton, Tooltip, Typography } from '@mui/material'
|
|
import { ReactElement, useState } from 'react'
|
|
import Eye from 'remixicon-react/EyeLineIcon'
|
|
import Minus from 'remixicon-react/SubtractLineIcon'
|
|
import { makeStyles } from 'tss-react/mui'
|
|
|
|
import { useClipboardCopy } from '../hooks/useClipboardCopy'
|
|
|
|
const useStyles = makeStyles()(theme => ({
|
|
header: {
|
|
backgroundColor: theme.palette.background.paper,
|
|
marginBottom: theme.spacing(0.25),
|
|
borderLeft: `${theme.spacing(0.25)} solid rgba(0,0,0,0)`,
|
|
wordBreak: 'break-word',
|
|
'&:hover': {
|
|
backgroundColor: theme.palette.background.paper,
|
|
},
|
|
'&:focus-within': {
|
|
backgroundColor: theme.palette.background.paper,
|
|
},
|
|
},
|
|
headerOpen: {
|
|
borderLeft: `${theme.spacing(0.25)} solid ${theme.palette.primary.main}`,
|
|
},
|
|
copyValue: {
|
|
cursor: 'pointer',
|
|
padding: theme.spacing(1),
|
|
borderRadius: 0,
|
|
'&:hover': {
|
|
backgroundColor: '#fcf2e8',
|
|
color: theme.palette.primary.main,
|
|
},
|
|
},
|
|
content: {
|
|
marginTop: theme.spacing(2),
|
|
marginBottom: theme.spacing(2),
|
|
},
|
|
keyMargin: {
|
|
marginRight: theme.spacing(1),
|
|
},
|
|
}))
|
|
|
|
interface Props {
|
|
label: string
|
|
value: string
|
|
expanded?: boolean
|
|
}
|
|
|
|
const lengthWithoutPrefix = (s: string) => s.replace(/^0x/i, '').length
|
|
|
|
function isPrefixedHexString(s: unknown): boolean {
|
|
return typeof s === 'string' && /^0x[0-9a-f]+$/i.test(s)
|
|
}
|
|
|
|
const split = (s: string): string[] => {
|
|
const nonPrefixLength = lengthWithoutPrefix(s)
|
|
|
|
if (nonPrefixLength % 6 === 0) return s.match(/(0x|.{6})/gi) || []
|
|
|
|
return s.match(/(0x|.{1,8})/gi) || []
|
|
}
|
|
|
|
export default function ExpandableListItemKey({ label, value, expanded }: Props): ReactElement | null {
|
|
const { classes } = useStyles()
|
|
|
|
const [open, setOpen] = useState(expanded || false)
|
|
const { copied, handleCopy, tooltipCloseHandler } = useClipboardCopy(value)
|
|
const toggleOpen = () => setOpen(!open)
|
|
|
|
const splitValues = split(value)
|
|
const hasPrefix = isPrefixedHexString(value)
|
|
const spanText = `${hasPrefix ? `${splitValues[0]} ${splitValues[1]}` : splitValues[0]}[…]${
|
|
splitValues[splitValues.length - 1]
|
|
}`
|
|
|
|
return (
|
|
<ListItemButton className={`${classes.header} ${open ? classes.headerOpen : ''}`}>
|
|
<Grid container direction="column" justifyContent="space-between" alignItems="stretch" style={{ width: '100%' }}>
|
|
<Grid container direction="row" justifyContent="space-between" alignItems="center">
|
|
{label && (
|
|
<Typography variant="body1" component="span">
|
|
{label}
|
|
</Typography>
|
|
)}
|
|
<Typography variant="body2" component="span">
|
|
{!open && (
|
|
<span className={classes.copyValue}>
|
|
<Tooltip title={copied ? 'Copied' : 'Copy'} placement="top" arrow onClose={tooltipCloseHandler}>
|
|
<span onClick={handleCopy}>{value ? spanText : ''}</span>
|
|
</Tooltip>
|
|
</span>
|
|
)}
|
|
<IconButton size="small" className={classes.copyValue} onClick={toggleOpen}>
|
|
{open ? <Minus strokeWidth={1} /> : <Eye strokeWidth={1} />}
|
|
</IconButton>
|
|
</Typography>
|
|
</Grid>
|
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
|
<div className={classes.content}>
|
|
<Tooltip title={copied ? 'Copied' : 'Copy'} placement="top" arrow onClose={tooltipCloseHandler}>
|
|
{/* This has to be wrapped in two spans otherwise either the tooltip or the highlighting does not work*/}
|
|
<span onClick={handleCopy}>
|
|
<span className={classes.copyValue}>
|
|
{splitValues.map((s, i) => (
|
|
<Typography variant="body2" key={i} className={classes.keyMargin} component="span">
|
|
{s}
|
|
</Typography>
|
|
))}
|
|
</span>
|
|
</span>
|
|
</Tooltip>
|
|
</div>
|
|
</Collapse>
|
|
</Grid>
|
|
</ListItemButton>
|
|
)
|
|
}
|