issue-166-open-timestamps #220

Merged
eugene merged 25 commits from issue-166-open-timestamps into staging 2024-10-25 11:18:47 +00:00
3 changed files with 103 additions and 9 deletions
Showing only changes of commit 19b815e528 - Show all commits

View File

@ -4,6 +4,7 @@ import {
fromUnixTimestamp, fromUnixTimestamp,
hexToNpub, hexToNpub,
npubToHex, npubToHex,
SigitStatus,
SignStatus SignStatus
} from '../../utils' } from '../../utils'
import { useSigitMeta } from '../../hooks/useSigitMeta' import { useSigitMeta } from '../../hooks/useSigitMeta'
@ -15,6 +16,8 @@ import {
faCalendar, faCalendar,
faCalendarCheck, faCalendarCheck,
faCalendarPlus, faCalendarPlus,
faCheck,
faClock,
faEye, faEye,
faFile, faFile,
faFileCircleExclamation faFileCircleExclamation
@ -22,7 +25,7 @@ import {
import { getExtensionIconLabel } from '../getExtensionIconLabel' import { getExtensionIconLabel } from '../getExtensionIconLabel'
import { useAppSelector } from '../../hooks/store' import { useAppSelector } from '../../hooks/store'
import { DisplaySigner } from '../DisplaySigner' import { DisplaySigner } from '../DisplaySigner'
import { Meta } from '../../types' import { Meta, OpenTimestamp } from '../../types'
import { extractFileExtensions } from '../../utils/file' import { extractFileExtensions } from '../../utils/file'
import { UserAvatar } from '../UserAvatar' import { UserAvatar } from '../UserAvatar'
@ -42,7 +45,9 @@ export const UsersDetails = ({ meta }: UsersDetailsProps) => {
completedAt, completedAt,
parsedSignatureEvents, parsedSignatureEvents,
signedStatus, signedStatus,
isValid isValid,
id,
timestamps
} = useSigitMeta(meta) } = useSigitMeta(meta)
const { usersPubkey } = useAppSelector((state) => state.auth) const { usersPubkey } = useAppSelector((state) => state.auth)
const userCanSign = const userCanSign =
@ -51,6 +56,50 @@ export const UsersDetails = ({ meta }: UsersDetailsProps) => {
const { extensions, isSame } = extractFileExtensions(Object.keys(fileHashes)) const { extensions, isSame } = extractFileExtensions(Object.keys(fileHashes))
const isTimestampVerified = (
timestamps: OpenTimestamp[],
nostrId: string
): boolean => {
const matched = timestamps.find((t) => t.nostrId === nostrId)
return !!(matched && matched.verification)
}
const getOpenTimestampsInfo = (
timestamps: OpenTimestamp[],
nostrId: string
) => {
if (isTimestampVerified(timestamps, nostrId)) {
return <FontAwesomeIcon icon={faCheck} />
eugene marked this conversation as resolved Outdated
Outdated
Review

Can we make add the className={styles.ticket}> to the icon directly here instead of wrapping the SVG in the code below?

Can we make add the `className={styles.ticket}>` to the icon directly here instead of wrapping the SVG in the code below?
} else {
return <FontAwesomeIcon icon={faClock} />
}
}
const getCompletedOpenTimestampsInfo = (timestamp: OpenTimestamp) => {
if (timestamp.verification) {
return <FontAwesomeIcon icon={faCheck} />
} else {
return <FontAwesomeIcon icon={faClock} />
}
}
const getTimestampTooltipTitle = (label: string, isVerified: boolean) => {
return `${label} / Open Timestamp ${isVerified ? 'Verified' : 'Pending'}`
}
const isUserSignatureTimestampVerified = () => {
if (
userCanSign &&
hexToNpub(usersPubkey) in parsedSignatureEvents &&
timestamps &&
timestamps.length > 0
) {
const nostrId = parsedSignatureEvents[hexToNpub(usersPubkey)].id
return isTimestampVerified(timestamps, nostrId)
}
return false
}
return submittedBy ? ( return submittedBy ? (
<div className={styles.container}> <div className={styles.container}>
<div className={styles.section}> <div className={styles.section}>
@ -115,19 +164,36 @@ export const UsersDetails = ({ meta }: UsersDetailsProps) => {
<p>Details</p> <p>Details</p>
<Tooltip <Tooltip
title={'Publication date'} title={getTimestampTooltipTitle(
'Publication date',
!!(timestamps && id && isTimestampVerified(timestamps, id))
)}
placement="top" placement="top"
arrow arrow
disableInteractive disableInteractive
> >
<span className={styles.detailsItem}> <span className={styles.detailsItem}>
<FontAwesomeIcon icon={faCalendarPlus} />{' '} <FontAwesomeIcon icon={faCalendarPlus} />{' '}
{createdAt ? formatTimestamp(createdAt) : <>&mdash;</>} {createdAt ? formatTimestamp(createdAt) : <>&mdash;</>}{' '}
{timestamps && timestamps.length > 0 && id && (
<span className={styles.ticket}>
{getOpenTimestampsInfo(timestamps, id)}
</span>
)}
</span> </span>
</Tooltip> </Tooltip>
<Tooltip <Tooltip
title={'Completion date'} title={getTimestampTooltipTitle(
'Completion date',
!!(
signedStatus === SigitStatus.Complete &&
completedAt &&
timestamps &&
timestamps.length > 0 &&
timestamps[timestamps.length - 1].verification
)
)}
placement="top" placement="top"
arrow arrow
disableInteractive disableInteractive
@ -135,13 +201,26 @@ export const UsersDetails = ({ meta }: UsersDetailsProps) => {
<span className={styles.detailsItem}> <span className={styles.detailsItem}>
<FontAwesomeIcon icon={faCalendarCheck} />{' '} <FontAwesomeIcon icon={faCalendarCheck} />{' '}
{completedAt ? formatTimestamp(completedAt) : <>&mdash;</>} {completedAt ? formatTimestamp(completedAt) : <>&mdash;</>}
{signedStatus === SigitStatus.Complete &&
completedAt &&
timestamps &&
timestamps.length > 0 && (
<span className={styles.ticket}>
{getCompletedOpenTimestampsInfo(
timestamps[timestamps.length - 1]
)}
</span>
)}
</span> </span>
</Tooltip> </Tooltip>
{/* User signed date */} {/* User signed date */}
{userCanSign ? ( {userCanSign ? (
<Tooltip <Tooltip
title={'Your signature date'} title={getTimestampTooltipTitle(
'Your signature date',
isUserSignatureTimestampVerified()
)}
placement="top" placement="top"
arrow arrow
disableInteractive disableInteractive
@ -161,6 +240,16 @@ export const UsersDetails = ({ meta }: UsersDetailsProps) => {
) : ( ) : (
<>&mdash;</> <>&mdash;</>
)} )}
{hexToNpub(usersPubkey) in parsedSignatureEvents &&
timestamps &&
timestamps.length > 0 && (
<span className={styles.ticket}>
{getOpenTimestampsInfo(
timestamps,
parsedSignatureEvents[hexToNpub(usersPubkey)].id
)}
</span>
)}
</span> </span>
</Tooltip> </Tooltip>
) : null} ) : null}

View File

@ -31,8 +31,6 @@
padding: 5px; padding: 5px;
display: flex; display: flex;
align-items: center;
justify-content: start;
> :first-child { > :first-child {
padding: 5px; padding: 5px;
@ -44,3 +42,7 @@
color: white; color: white;
} }
} }
.ticket {
margin-left: auto;
}
eugene marked this conversation as resolved
Review

Tiny styling improvement, 5px padding to match the first icon.

Tiny styling improvement, 5px padding to match the first icon.

View File

@ -294,7 +294,9 @@ export const VerifyPage = () => {
return timestamp return timestamp
}) })
if (upgradedUserTimestamps.length > 0) { console.log('upgraded timestamps: ', upgradedTimestamps)
if (upgradedUserTimestamps.length === 0) {
return return
} }
@ -323,6 +325,7 @@ export const VerifyPage = () => {
updatedMeta.modifiedAt = unixNow() updatedMeta.modifiedAt = unixNow()
const updatedEvent = await updateUsersAppData(updatedMeta) const updatedEvent = await updateUsersAppData(updatedMeta)
console.log('updated event: ', updatedEvent)
if (!updatedEvent) return if (!updatedEvent) return
const userSet = new Set<`npub1${string}`>() const userSet = new Set<`npub1${string}`>()