2024-08-06 12:42:21 +02:00
|
|
|
import { Dispatch, SetStateAction, useEffect } from 'react'
|
|
|
|
import { Meta, ProfileMetadata } from '../../types'
|
|
|
|
import { SignedStatus, useSigitMeta } from '../../hooks/useSigitMeta'
|
|
|
|
import { Event, kinds } from 'nostr-tools'
|
|
|
|
import { Link } from 'react-router-dom'
|
|
|
|
import { MetadataController } from '../../controllers'
|
|
|
|
import { hexToNpub, npubToHex, shorten } from '../../utils'
|
|
|
|
import { appPublicRoutes, appPrivateRoutes } from '../../routes'
|
|
|
|
import { Button, Divider, Tooltip } from '@mui/material'
|
|
|
|
import { DisplaySigner } from '../DisplaySigner'
|
|
|
|
import {
|
|
|
|
faArchive,
|
|
|
|
faCalendar,
|
|
|
|
faCopy,
|
|
|
|
faEye,
|
2024-08-06 13:29:43 +02:00
|
|
|
faFile
|
2024-08-06 12:42:21 +02:00
|
|
|
} from '@fortawesome/free-solid-svg-icons'
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
|
|
import { UserAvatar } from '../UserAvatar'
|
|
|
|
import { UserAvatarGroup } from '../UserAvatarGroup'
|
|
|
|
|
|
|
|
import styles from './style.module.scss'
|
|
|
|
import { TooltipChild } from '../TooltipChild'
|
2024-08-06 13:29:43 +02:00
|
|
|
import { getExtensionIconLabel } from '../getExtensionIconLabel'
|
2024-08-06 12:42:21 +02:00
|
|
|
|
|
|
|
type SigitProps = {
|
|
|
|
meta: Meta
|
|
|
|
profiles: { [key: string]: ProfileMetadata }
|
|
|
|
setProfiles: Dispatch<SetStateAction<{ [key: string]: ProfileMetadata }>>
|
|
|
|
}
|
|
|
|
|
|
|
|
export const DisplaySigit = ({ meta, profiles, setProfiles }: SigitProps) => {
|
|
|
|
const {
|
|
|
|
title,
|
|
|
|
createdAt,
|
|
|
|
submittedBy,
|
|
|
|
signers,
|
2024-08-06 13:29:43 +02:00
|
|
|
signedStatus,
|
|
|
|
fileExtensions
|
2024-08-06 12:42:21 +02:00
|
|
|
} = useSigitMeta(meta)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const hexKeys: string[] = []
|
|
|
|
|
|
|
|
if (submittedBy) {
|
|
|
|
hexKeys.push(npubToHex(submittedBy)!)
|
|
|
|
}
|
|
|
|
hexKeys.push(...signers.map((signer) => npubToHex(signer)!))
|
|
|
|
|
|
|
|
const metadataController = new MetadataController()
|
|
|
|
hexKeys.forEach((key) => {
|
|
|
|
if (!(key in profiles)) {
|
|
|
|
const handleMetadataEvent = (event: Event) => {
|
|
|
|
const metadataContent =
|
|
|
|
metadataController.extractProfileMetadataContent(event)
|
|
|
|
|
|
|
|
if (metadataContent)
|
|
|
|
setProfiles((prev) => ({
|
|
|
|
...prev,
|
|
|
|
[key]: metadataContent
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
|
|
|
metadataController.on(key, (kind: number, event: Event) => {
|
|
|
|
if (kind === kinds.Metadata) {
|
|
|
|
handleMetadataEvent(event)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
metadataController
|
|
|
|
.findMetadata(key)
|
|
|
|
.then((metadataEvent) => {
|
|
|
|
if (metadataEvent) handleMetadataEvent(metadataEvent)
|
|
|
|
})
|
|
|
|
.catch((err) => {
|
|
|
|
console.error(`error occurred in finding metadata for: ${key}`, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}, [submittedBy, signers, profiles, setProfiles])
|
|
|
|
|
|
|
|
return (
|
2024-08-06 13:38:33 +02:00
|
|
|
<div className={styles.itemWrapper}>
|
|
|
|
<Link
|
|
|
|
to={
|
|
|
|
signedStatus === SignedStatus.Complete
|
|
|
|
? appPublicRoutes.verify
|
|
|
|
: appPrivateRoutes.sign
|
|
|
|
}
|
|
|
|
state={{ meta }}
|
|
|
|
className={styles.insetLink}
|
|
|
|
></Link>
|
2024-08-06 12:42:21 +02:00
|
|
|
<p className={`line-clamp-2 ${styles.title}`}>{title}</p>
|
|
|
|
<div className={styles.users}>
|
|
|
|
{submittedBy &&
|
|
|
|
(function () {
|
|
|
|
const profile = profiles[submittedBy]
|
|
|
|
return (
|
|
|
|
<Tooltip
|
|
|
|
title={
|
|
|
|
profile?.display_name ||
|
|
|
|
profile?.name ||
|
|
|
|
shorten(hexToNpub(submittedBy))
|
|
|
|
}
|
|
|
|
placement="top"
|
|
|
|
arrow
|
|
|
|
disableInteractive
|
|
|
|
>
|
|
|
|
<TooltipChild>
|
|
|
|
<UserAvatar pubkey={submittedBy} image={profile?.picture} />
|
|
|
|
</TooltipChild>
|
|
|
|
</Tooltip>
|
|
|
|
)
|
|
|
|
})()}
|
|
|
|
{submittedBy && signers.length ? (
|
|
|
|
<Divider orientation="vertical" flexItem />
|
|
|
|
) : null}
|
|
|
|
<UserAvatarGroup className={styles.signers} max={7}>
|
|
|
|
{signers.map((signer) => {
|
|
|
|
const pubkey = npubToHex(signer)!
|
|
|
|
const profile = profiles[pubkey]
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Tooltip
|
|
|
|
key={signer}
|
|
|
|
title={
|
|
|
|
profile?.display_name || profile?.name || shorten(pubkey)
|
|
|
|
}
|
|
|
|
placement="top"
|
|
|
|
arrow
|
|
|
|
disableInteractive
|
|
|
|
>
|
|
|
|
<TooltipChild>
|
|
|
|
<DisplaySigner
|
|
|
|
meta={meta}
|
|
|
|
profile={profile}
|
|
|
|
pubkey={pubkey}
|
|
|
|
/>
|
|
|
|
</TooltipChild>
|
|
|
|
</Tooltip>
|
|
|
|
)
|
|
|
|
})}
|
|
|
|
</UserAvatarGroup>
|
|
|
|
</div>
|
|
|
|
<div className={`${styles.details} ${styles.date} ${styles.iconLabel}`}>
|
|
|
|
<FontAwesomeIcon icon={faCalendar} />
|
|
|
|
{createdAt}
|
|
|
|
</div>
|
|
|
|
<div className={`${styles.details} ${styles.status}`}>
|
|
|
|
<span className={styles.iconLabel}>
|
|
|
|
<FontAwesomeIcon icon={faEye} /> {signedStatus}
|
|
|
|
</span>
|
2024-08-06 13:29:43 +02:00
|
|
|
{fileExtensions.length > 0 ? (
|
|
|
|
<span className={styles.iconLabel}>
|
|
|
|
{fileExtensions.length > 1 ? (
|
|
|
|
<>
|
|
|
|
<FontAwesomeIcon icon={faFile} /> Multiple File Types
|
|
|
|
</>
|
|
|
|
) : (
|
|
|
|
getExtensionIconLabel(fileExtensions[0])
|
|
|
|
)}
|
|
|
|
</span>
|
|
|
|
) : null}
|
2024-08-06 12:42:21 +02:00
|
|
|
</div>
|
|
|
|
<div className={styles.itemActions}>
|
|
|
|
<Tooltip title="Duplicate" arrow placement="top" disableInteractive>
|
|
|
|
<Button
|
|
|
|
sx={{
|
|
|
|
color: 'var(--primary-main)',
|
|
|
|
minWidth: '34px',
|
|
|
|
padding: '10px'
|
|
|
|
}}
|
|
|
|
variant={'text'}
|
|
|
|
>
|
|
|
|
<FontAwesomeIcon icon={faCopy} />
|
|
|
|
</Button>
|
|
|
|
</Tooltip>
|
|
|
|
<Tooltip title="Archive" arrow placement="top" disableInteractive>
|
|
|
|
<Button
|
|
|
|
sx={{
|
|
|
|
color: 'var(--primary-main)',
|
|
|
|
minWidth: '34px',
|
|
|
|
padding: '10px'
|
|
|
|
}}
|
|
|
|
variant={'text'}
|
|
|
|
>
|
|
|
|
<FontAwesomeIcon icon={faArchive} />
|
|
|
|
</Button>
|
|
|
|
</Tooltip>
|
|
|
|
</div>
|
2024-08-06 13:38:33 +02:00
|
|
|
</div>
|
2024-08-06 12:42:21 +02:00
|
|
|
)
|
|
|
|
}
|