Skip to content

Commit

Permalink
toasts: set max duration for each toast
Browse files Browse the repository at this point in the history
  • Loading branch information
sehyunc committed Sep 5, 2024
1 parent 3674dbb commit c86b017
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 63 deletions.
105 changes: 55 additions & 50 deletions app/components/task-toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Task, useTaskHistoryWebSocket } from "@renegade-fi/react"
import { toast } from "sonner"

import {
WITHDRAW_TOAST_ID,
formatTaskState,
generateCompletionToastMessage,
generateFailedToastMessage,
Expand All @@ -20,101 +19,107 @@ import {
isWithdrawTask,
} from "@/lib/task"

const DURATION_MS = 10000 // 10 seconds

export function TaskToaster() {
const seen = React.useRef<Map<string, Task>>(new Map())
const toastTimers = React.useRef<Map<string, NodeJS.Timeout>>(new Map())
const seenStates = React.useRef<Map<string, string>>(new Map())

const scheduleToastDismissal = React.useCallback((id: string) => {
if (toastTimers.current.has(id)) {
clearTimeout(toastTimers.current.get(id)!)
}
const timer = setTimeout(() => {
toast.dismiss(id)
toastTimers.current.delete(id)
seenStates.current.delete(id)
}, DURATION_MS)
toastTimers.current.set(id, timer)
}, [])

React.useEffect(() => {
const timers = toastTimers.current
return () => {
timers.forEach(clearTimeout)
}
}, [])

useTaskHistoryWebSocket({
onUpdate(task) {
if (seen.current.get(task.id)?.state === task.state) {
return
}
seen.current.set(task.id, task)
const currentState = `${task.id}-${task.state}`
if (seenStates.current.get(task.id) === currentState) return
seenStates.current.set(task.id, currentState)

if (isWithdrawTask(task)) {
processWithdrawTask(task)
processWithdrawTask(task, scheduleToastDismissal)
} else if (
isDepositTask(task) ||
isPlaceOrderTask(task) ||
isCancelOrderTask(task) ||
isRefreshWalletTask(task)
) {
processTask(task)
processTask(task, scheduleToastDismissal)
}
},
})

return null
}

function processTask(incomingTask: Task) {
function processTask(
incomingTask: Task,
scheduleToastDismissal: (id: string) => void,
) {
const state = formatTaskState(incomingTask.state)
const id = incomingTask.id

if (incomingTask.state === "Completed") {
const message = generateCompletionToastMessage(incomingTask)
toast.success(message, {
id: incomingTask.id,
description: state,
})
return
toast.success(message, { id, description: state })
} else if (incomingTask.state === "Failed") {
const message = generateFailedToastMessage(incomingTask)
toast.error(message, {
id: incomingTask.id,
})
toast.error(message, { id })
} else if (incomingTask.state === "Proving") {
const message = generateStartToastMessage(incomingTask)
toast.loading(message, {
id: incomingTask.id,
description: state,
})
toast.loading(message, { id, description: state })
} else if (
incomingTask.state === "Updating Validity Proofs" &&
isDepositTask(incomingTask)
) {
const message = generateCompletionToastMessage(incomingTask)
toast.success(message, {
id: incomingTask.id,
description: "Completed",
})
toast.success(message, { id, description: "Completed" })
} else {
const message = generateStartToastMessage(incomingTask)
toast.loading(message, {
id: incomingTask.id,
description: state,
})
toast.loading(message, { id, description: state })
}

scheduleToastDismissal(id)
}

function processWithdrawTask(incomingTask: Task) {
function processWithdrawTask(
incomingTask: Task,
scheduleToastDismissal: (id: string) => void,
) {
if (isWithdrawTask(incomingTask)) {
const state = formatTaskState(incomingTask.state)
const id = WITHDRAW_TOAST_ID(
incomingTask.task_info.mint,
incomingTask.task_info.amount,
)
const id = incomingTask.id

if (incomingTask.state === "Completed") {
const message = generateCompletionToastMessage(incomingTask)
toast.success(message, {
id,
description: state,
})
return
toast.success(message, { id, description: state })
} else if (incomingTask.state === "Failed") {
const message = generateFailedToastMessage(incomingTask)
toast.error(message, {
id,
})
toast.error(message, { id })
} else if (incomingTask.state === "Updating Validity Proofs") {
const message = generateCompletionToastMessage(incomingTask)
toast.success(message, {
id,
description: "Completed",
})
toast.success(message, { id, description: "Completed" })
} else if (incomingTask.state === "Proving") {
return
} else {
const message = generateStartToastMessage(incomingTask)
toast.loading(message, {
id,
description: state,
})
toast.loading(message, { id, description: state })
}

scheduleToastDismissal(id)
}
}
20 changes: 7 additions & 13 deletions hooks/use-withdraw.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Token, UpdateType, useConfig, usePayFees } from "@renegade-fi/react"
import {
Token,
useConfig,
usePayFees
} from "@renegade-fi/react"
import { withdraw } from "@renegade-fi/react/actions"
import { toast } from "sonner"
import { isAddress } from "viem"
import { useAccount } from "wagmi"

import {
FAILED_WITHDRAWAL_MSG,
WITHDRAW_TOAST_ID,
constructStartToastMessage,
FAILED_WITHDRAWAL_MSG
} from "@/lib/constants/task"
import { safeParseUnits } from "@/lib/format"

Expand All @@ -34,12 +36,6 @@ export function useWithdraw({
toast.error("Withdrawal amount is invalid")
return
}
const message = constructStartToastMessage(UpdateType.Withdraw)
const id = WITHDRAW_TOAST_ID(mint, parsedAmount)

toast.loading(message, {
id,
})

await payFeesAsync()

Expand All @@ -51,9 +47,7 @@ export function useWithdraw({
})
.then(onSuccess)
.catch((e) => {
toast.error(FAILED_WITHDRAWAL_MSG(token, parsedAmount), {
id,
})
toast.error(FAILED_WITHDRAWAL_MSG(token, parsedAmount))
console.error(`Error withdrawing: ${e.response?.data ?? e.message}`)
})
}
Expand Down

0 comments on commit c86b017

Please sign in to comment.