How to set a minimum time threshold for showing the spinner?

I want to modify the spinner such that it only appears if the functions takes longer than a specific threshold (e.g., 0.2 secs) to execute.

While the spinner has value in showing users that something is loading and they should wait, it becomes a bit of an annoyance if it appears all the time even for fast functions.

Having the spinner flash for a split second before it disappears is not really great UX.

1 Like

Ah I think I got it. Here is a decorator that can be used for client-side functions. It will work regardless of whether a server function is called or not.

Please let me know if you spot any errors.

from anvil.js import window
import anvil.server
from anvil.server import no_loading_indicator
import functools

def delayed_spinner(func, threshold=0.3):
  """
  A decorator that only shows the built-in Anvil spinner if
  the wrapped function takes longer than `threshold` seconds.
  """
  @functools.wraps(func)
  def wrapper(*args, **kwargs):
    # 1) Create controller for the default spinner
    loading = anvil.server.loading_indicator()
    # 2) Schedule .start() after `threshold` ms
    timer_id = window.setTimeout(lambda: loading.start(),
                                  int(threshold * 1000))
    try:
      # 3) Run the function with the automatic spinner suppressed
      with no_loading_indicator:
        return func(*args, **kwargs)
    finally:
      # 4) Cancel the pending start (if it hasn’t fired yet)
      window.clearTimeout(timer_id)
      #    And stop it if it did fire
      loading.stop()

  return wrapper
7 Likes