Delaying LiveView.JS commands (avoid quick flash of "Trying to reconnect")

I’d try using JS.dispatch Phoenix.LiveView.JS — Phoenix LiveView v0.20.14 to send a custom event that then uses liveSocket.execJS.

This is pseudo code, I didn’t test it, but I hope that it shows the idea:

<.flash
  id="client-error"
  kind={:error}
  title={gettext("We can't find the internet")}
  phx-disconnected={JS.dispatch("delayed-exec", detail: %{id: "client-error", target: "data-disconnected"})}
  phx-connected={JS.dispatch("clear-delayed-exec", detail: %{id: "client-error"}) |> JS.exec("data-connected")}
  data-disconnected={show(".phx-client-error #client-error")}
  data-connected={hide("#client-error")}
  hidden
>
  <%= gettext("Attempting to reconnect") %>
  <.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
</.flash>

And in your app.js something like:

const timeouts = {};
window.addEventListener("delayed-exec", (e) => {
  clearTimeout(timeouts[e.detail.id]);
  timeouts[e.detail.id] = setTimeout(() => {
    liveSocket.execJS(e.target, e.target.getAttribute(e.detail.target));
  }, e.detail.timeout);
});

window.addEventListener("clear-delayed-exec", (e) => {
  clearTimeout(timeouts[e.detail.id]);
});
4 Likes