feat(renotifications): can re-notify users on the signing page
This commit is contained in:
parent
9cefdad3fc
commit
89f6cd1dbe
@ -46,9 +46,7 @@ import {
|
|||||||
shorten,
|
shorten,
|
||||||
signEventForMetaFile,
|
signEventForMetaFile,
|
||||||
updateUsersAppData,
|
updateUsersAppData,
|
||||||
uploadToFileStorage,
|
uploadToFileStorage
|
||||||
isPromiseFulfilled,
|
|
||||||
isPromiseRejected
|
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
import { Container } from '../../components/Container'
|
import { Container } from '../../components/Container'
|
||||||
import styles from './style.module.scss'
|
import styles from './style.module.scss'
|
||||||
@ -86,6 +84,7 @@ import {
|
|||||||
faUpload
|
faUpload
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { SigitFile } from '../../utils/file.ts'
|
import { SigitFile } from '../../utils/file.ts'
|
||||||
|
import { checkNotifications } from '../../utils/notifications.ts'
|
||||||
|
|
||||||
export const CreatePage = () => {
|
export const CreatePage = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@ -787,14 +786,7 @@ export const CreatePage = () => {
|
|||||||
|
|
||||||
setLoadingSpinnerDesc('Sending notifications to counterparties')
|
setLoadingSpinnerDesc('Sending notifications to counterparties')
|
||||||
const notifications = await Promise.allSettled(sendNotifications(meta))
|
const notifications = await Promise.allSettled(sendNotifications(meta))
|
||||||
if (notifications.every(isPromiseFulfilled)) {
|
checkNotifications(notifications)
|
||||||
toast.success('Notifications sent successfully')
|
|
||||||
} else {
|
|
||||||
logRejectedNotifications(notifications)
|
|
||||||
toast.error(
|
|
||||||
'Some notifications failed to publish. Please rebroadcast them again.'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
navigate(appPrivateRoutes.sign, { state: { meta: meta } })
|
navigate(appPrivateRoutes.sign, { state: { meta: meta } })
|
||||||
} else {
|
} else {
|
||||||
const zip = new JSZip()
|
const zip = new JSZip()
|
||||||
@ -850,15 +842,6 @@ export const CreatePage = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const logRejectedNotifications = (
|
|
||||||
notifications: PromiseSettledResult<string[]>[]
|
|
||||||
) => {
|
|
||||||
notifications
|
|
||||||
.filter(isPromiseRejected)
|
|
||||||
.map((res: PromiseRejectedResult) => (res.reason as Error).message)
|
|
||||||
.forEach((message: string) => console.log(message))
|
|
||||||
}
|
|
||||||
|
|
||||||
const onDrawFieldsChange = (sigitFiles: SigitFile[]) => {
|
const onDrawFieldsChange = (sigitFiles: SigitFile[]) => {
|
||||||
setDrawnFiles(sigitFiles)
|
setDrawnFiles(sigitFiles)
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ import {
|
|||||||
SigitFile
|
SigitFile
|
||||||
} from '../../utils/file.ts'
|
} from '../../utils/file.ts'
|
||||||
import { ARRAY_BUFFER, DEFLATE } from '../../utils/const.ts'
|
import { ARRAY_BUFFER, DEFLATE } from '../../utils/const.ts'
|
||||||
|
import { checkNotifications } from '../../utils/notifications.ts'
|
||||||
enum SignedStatus {
|
enum SignedStatus {
|
||||||
Fully_Signed,
|
Fully_Signed,
|
||||||
User_Is_Next_Signer,
|
User_Is_Next_Signer,
|
||||||
@ -663,59 +664,22 @@ export const SignPage = () => {
|
|||||||
|
|
||||||
// Handle the online flow: update users app data and send notifications
|
// Handle the online flow: update users app data and send notifications
|
||||||
const handleOnlineFlow = async (meta: Meta) => {
|
const handleOnlineFlow = async (meta: Meta) => {
|
||||||
setLoadingSpinnerDesc('Updating users app data')
|
try {
|
||||||
const updatedEvent = await updateUsersAppData(meta)
|
setLoadingSpinnerDesc('Updating users app data')
|
||||||
if (!updatedEvent) {
|
const updatedEvent = await updateUsersAppData(meta)
|
||||||
|
if (!updatedEvent) {
|
||||||
|
throw new Error('There was an error updating user app data.')
|
||||||
|
}
|
||||||
|
setLoadingSpinnerDesc('Sending notifications')
|
||||||
|
|
||||||
|
const notifications = await notifyUsers(meta)
|
||||||
|
checkNotifications(notifications)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
toast.error('There was an error finalising signatures.')
|
||||||
|
} finally {
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const userSet = new Set<`npub1${string}`>()
|
|
||||||
if (submittedBy && submittedBy !== usersPubkey) {
|
|
||||||
userSet.add(hexToNpub(submittedBy))
|
|
||||||
}
|
|
||||||
|
|
||||||
const usersNpub = hexToNpub(usersPubkey!)
|
|
||||||
const isLastSigner = checkIsLastSigner(signers)
|
|
||||||
if (isLastSigner) {
|
|
||||||
signers.forEach((signer) => {
|
|
||||||
if (signer !== usersNpub) {
|
|
||||||
userSet.add(signer)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
viewers.forEach((viewer) => {
|
|
||||||
userSet.add(viewer)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const currentSignerIndex = signers.indexOf(usersNpub)
|
|
||||||
const prevSigners = signers.slice(0, currentSignerIndex)
|
|
||||||
|
|
||||||
prevSigners.forEach((signer) => {
|
|
||||||
userSet.add(signer)
|
|
||||||
})
|
|
||||||
|
|
||||||
const nextSigner = signers[currentSignerIndex + 1]
|
|
||||||
userSet.add(nextSigner)
|
|
||||||
}
|
|
||||||
|
|
||||||
setLoadingSpinnerDesc('Sending notifications')
|
|
||||||
const users = Array.from(userSet)
|
|
||||||
console.log('users: ', users)
|
|
||||||
const publishedRelays = await Promise.all(
|
|
||||||
users.map(async (user) => sendNotification(npubToHex(user)!, meta))
|
|
||||||
)
|
|
||||||
console.log('published relays: ', publishedRelays)
|
|
||||||
// await Promise.all(promises)
|
|
||||||
// .then(() => {
|
|
||||||
// toast.success('Notifications sent successfully')
|
|
||||||
// setMeta(meta)
|
|
||||||
// })
|
|
||||||
// .catch(() => {
|
|
||||||
// toast.error('Failed to publish notifications')
|
|
||||||
// })
|
|
||||||
|
|
||||||
setIsLoading(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the current user is the last signer
|
// Check if the current user is the last signer
|
||||||
@ -873,6 +837,64 @@ export const SignPage = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getUsersToNotify = (): `npub1${string}`[] => {
|
||||||
|
const userSet = new Set<`npub1${string}`>()
|
||||||
|
if (submittedBy && submittedBy !== usersPubkey) {
|
||||||
|
userSet.add(hexToNpub(submittedBy))
|
||||||
|
}
|
||||||
|
|
||||||
|
const usersNpub = hexToNpub(usersPubkey!)
|
||||||
|
const isLastSigner = checkIsLastSigner(signers)
|
||||||
|
if (isLastSigner) {
|
||||||
|
signers.forEach((signer) => {
|
||||||
|
if (signer !== usersNpub) {
|
||||||
|
userSet.add(signer)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
viewers.forEach((viewer) => userSet.add(viewer))
|
||||||
|
} else {
|
||||||
|
const currentSignerIndex = signers.indexOf(usersNpub)
|
||||||
|
const prevSigners = signers.slice(0, currentSignerIndex)
|
||||||
|
|
||||||
|
prevSigners.forEach((signer) => {
|
||||||
|
userSet.add(signer)
|
||||||
|
})
|
||||||
|
|
||||||
|
const nextSigner = signers[currentSignerIndex + 1]
|
||||||
|
userSet.add(nextSigner)
|
||||||
|
}
|
||||||
|
return Array.from(userSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
const notifyUsers = async (meta: Meta) => {
|
||||||
|
try {
|
||||||
|
const usersToNotify = getUsersToNotify()
|
||||||
|
return await Promise.allSettled(
|
||||||
|
usersToNotify.map(async (user) =>
|
||||||
|
sendNotification(npubToHex(user)!, meta)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error('There was a problem sending notifications to users', {
|
||||||
|
cause: error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRenotifyUsers = async () => {
|
||||||
|
try {
|
||||||
|
setIsLoading(true)
|
||||||
|
const notifications = await notifyUsers(meta!)
|
||||||
|
checkNotifications(notifications)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
toast.error('There was an error re-notifying users')
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (authUrl) {
|
if (authUrl) {
|
||||||
return (
|
return (
|
||||||
<iframe
|
<iframe
|
||||||
@ -969,6 +991,12 @@ export const SignPage = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
||||||
|
<Button onClick={handleRenotifyUsers} variant="contained">
|
||||||
|
Re-notify Next Signer
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
|
26
src/utils/notifications.ts
Normal file
26
src/utils/notifications.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { isPromiseFulfilled, isPromiseRejected } from './utils.ts'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
|
const checkNotifications = (
|
||||||
|
notifications: PromiseSettledResult<string[]>[]
|
||||||
|
) => {
|
||||||
|
if (notifications.every(isPromiseFulfilled)) {
|
||||||
|
toast.success('Notifications sent successfully')
|
||||||
|
} else {
|
||||||
|
logRejectedNotifications(notifications)
|
||||||
|
toast.error(
|
||||||
|
'Some notifications failed to publish. Please rebroadcast them again.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logRejectedNotifications = (
|
||||||
|
notifications: PromiseSettledResult<string[]>[]
|
||||||
|
) => {
|
||||||
|
notifications
|
||||||
|
.filter(isPromiseRejected)
|
||||||
|
.map((res: PromiseRejectedResult) => (res.reason as Error).message)
|
||||||
|
.forEach((message: string) => console.log(message))
|
||||||
|
}
|
||||||
|
|
||||||
|
export { checkNotifications }
|
Loading…
Reference in New Issue
Block a user