Skip to content

Commit

Permalink
fix(desk-tool): add useCondionalToast hook as workaround for missing …
Browse files Browse the repository at this point in the history
…@sanity/ui feature

This adds a utility hook that provides a "declarative toast"-feature currently missing from @sanity/ui
  • Loading branch information
bjoerge committed Sep 26, 2022
1 parent 93a38c1 commit 57ad2ae
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
DocumentMutationEvent,
DocumentRebaseEvent,
} from '../../../../../datastores/document/buffered-doc/types'
import {useConditionalToast} from './useConditionalToast'

interface FormViewProps {
granted: boolean
Expand Down Expand Up @@ -103,19 +104,15 @@ export function FormView(props: FormViewProps) {
// return () => sub.unsubscribe()
// }, [])

const toast = useToast()
const isLocked = editState?.transactionSyncLock?.enabled
useEffect(() => {
toast.push({
id: `sync-lock-${documentId}`,
status: 'warning',
// note1: there's a `duration || 0` in Sanity UI's pushToast(), so make it non-falsey
// note2: cannot use `Infinity` as duration, since it exceeds setTimeout's maximum delay value
duration: isLocked ? 3_600_000 : 0.01,
title: `Syncing document…`,
description: `Please hold tight while the document is synced. This usually happens right after the document has been published, and it shouldn't take more than a few seconds`,
})
}, [documentId, isLocked, toast])

useConditionalToast({
id: `sync-lock-${documentId}`,
status: 'warning',
enabled: isLocked,
title: `Syncing document…`,
description: `Please hold tight while the document is synced. This usually happens right after the document has been published, and it shouldn't take more than a few seconds`,
})

useEffect(() => {
const sub = documentStore.pair
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {useEffect, useRef} from 'react'
import {ToastParams, useToast} from '@sanity/ui'

function usePrevious<T>(value: T) {
const ref = useRef<T>()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}

// https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value
const LONG_ENOUGH_BUT_NOT_TOO_LONG = 1000 * 60 * 60 * 24 * 24

/**
* Workaround to support conditional toast (e.g. a toast that is visible as long as a condition holds true)
* @param params
*/
export function useConditionalToast(params: ToastParams & {id: string; enabled?: boolean}) {
const toast = useToast()

const wasEnabled = usePrevious(params.enabled)
// note1: there's a `duration || 0` in Sanity UI's pushToast(), so make it non-falsey
// note2: cannot use `Infinity` as duration, since it exceeds setTimeout's maximum delay value
useEffect(() => {
if (!wasEnabled && params.enabled) {
toast.push({...params, duration: LONG_ENOUGH_BUT_NOT_TOO_LONG})
}
if (wasEnabled && !params.enabled) {
toast.push({
...params,
// Note: @sanity/ui fallbacks to the default duration of 4s in case of falsey values
duration: 0.01,
})
}
}, [params, toast, wasEnabled])
}

0 comments on commit 57ad2ae

Please sign in to comment.