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, faFile } 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' import { getExtensionIconLabel } from '../getExtensionIconLabel' 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, signedStatus, fileExtensions } = 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 ( <Link className={styles.itemWrapper} to={ signedStatus === SignedStatus.Complete ? appPublicRoutes.verify : appPrivateRoutes.sign } state={{ meta }} > <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> {fileExtensions.length > 0 ? ( <span className={styles.iconLabel}> {fileExtensions.length > 1 ? ( <> <FontAwesomeIcon icon={faFile} /> Multiple File Types </> ) : ( getExtensionIconLabel(fileExtensions[0]) )} </span> ) : null} </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> </Link> ) }