As you can see above, the code becomes more complex and difficult to read.

Modeling it with a statechart

I finally modeled it using a statechart and implemented it using XState. I used delayed transitions and found it so useful for this case. See how the final statechart code looks:

The statechart has two main states:

active : the Screensaver is shown, and switches between visible and hidden state until the user interacts with the app. When the user interacts with the app, the next state is inactive.

: the Screensaver is shown, and switches between visible and hidden state until the user interacts with the app. When the user interacts with the app, the next state is inactive. inactive: the Screensaver is hidden, and there is a timer for making it appear again.

I use a self-transition in the inactive state to reset the timer each time the user interacts with the app.

Note that the active state has two sub-states (is a compound state), visible and hidden, which are used to meet the latest client requirements.

In the example, I reduced the delays to be able to test it faster. Here the working code: