Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling activate or reset inside the onPrompt handler does not stop the prompt countdown #346

Open
shennan opened this issue May 23, 2023 · 3 comments
Labels
bug A verified and reproducible bug. triage Has not been reviewed yet and should not be worked on.

Comments

@shennan
Copy link

shennan commented May 23, 2023

Bug information

Calling activate or reset inside the onPrompt handler does not stop the prompt countdown.

Affected Module

  • Version: 5.5.0

Describe the bug

So the use case here is if there are certain conditions in which the prompt should not be shown due to a current state elsewhere in the codebase. In those scenarios I would expect to be able to simply call activate or reset from inside the onPrompt handler, to signify that I don't want the prompt to show and the countdown should not begin.

To Reproduce

Steps to reproduce the behavior:

The code:

// This is the method called when you allow the timeout to go ahead (either by letting the countdown 
// diminish without intervention, or by pressing "exit" button)
const exit = () => console.log('Some exit code')
// This is some condition grabbed from elsewhere in the code base
const someCondition = useSomeCondition()

const timeout = inactivityDuration + promptDuration
const [showTimeoutPrompt, setShowTimeoutPrompt] = useState<boolean>(false)
const [remainingTime, setRemainingTime] = useState<number>(timeout)

const onIdle = () => {

  setShowTimeoutPrompt(false)
  exit()

}

const onActive = () => setShowTimeoutPrompt(false)

const onPrompt = () => {

  if (someCondition === false) {
    // We want to go ahead and show the prompt
    setShowTimeoutPrompt(true)
  } else {
    // We don't want to go ahead with the prompt and instead want to continue doing our thing in the app 
    // because of some external condition that disallows a timeout at the current period of time.
    // If this is run, I would expect this to stop the countdown and restart the idle timer (this does work if
    // used as a handler in a button within the JSX/TSX markup).
    activate()
  }
}

const { reset, activate, getRemainingTime } = useIdleTimer({
  timeout,
  promptBeforeIdle: promptDuration,
  onPrompt: promptDuration ? onPrompt : undefined,
  onIdle,
  onActive,
  debounce: 500,
})

useEffect(() => {

  const interval = setInterval(() => {
    setRemainingTime(secondsFromMillieseconds(getRemainingTime()))
  }, 500)

  return () => clearInterval(interval)

}, [showTimeoutPrompt])

return <>{ /* The usual prompt modal, countdown and buttons etc */ }</>

Expected behavior

If someCondition === true, I would expect that calling activate() would reset idle timer and stop countdown during prompt. Instead, the prompt is not shown (as expected because setShowTimeoutPrompt(true) was not called), but the countdown continues in the background and eventually exit() is called after promptDuration.

Screenshots

N/A

System Information (please complete the following information)

  • OS: macOS 13.1 (22C65)
  • Device: MacBook Pro M1 Pro
  • Browser Vendor: Chrome
  • Browser Version: Version 113.0.5672.126 (Official Build) (arm64)

Additional context

The activate() does work as expected if you throw it into a timeout: setTimeout(() => activate(), 1).

@shennan shennan added bug A verified and reproducible bug. triage Has not been reviewed yet and should not be worked on. labels May 23, 2023
@reify-tanner-stirrat
Copy link

A maybe related behavior: it seems like the timer stops listening to events once the prompt is open, i.e. once onPrompt is called at the promptBeforeIdle mark. I'd expect to be able to do an action and have things reactivate.

@SupremeTechnopriest
Copy link
Owner

This is actually by design. If you want to handle events in the prompt state you need to use onAction.

@SupremeTechnopriest
Copy link
Owner

SupremeTechnopriest commented Jul 27, 2023

const onAction = (event, idleTimer) => {
  if (idleTimer.isPrompted()) idleTimer.activate()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A verified and reproducible bug. triage Has not been reviewed yet and should not be worked on.
Projects
None yet
Development

No branches or pull requests

3 participants