diff --git a/app/javascript/solid_queue_web/application.js b/app/javascript/solid_queue_web/application.js index ad1349d..7e08a27 100644 --- a/app/javascript/solid_queue_web/application.js +++ b/app/javascript/solid_queue_web/application.js @@ -1,6 +1,8 @@ import "@hotwired/turbo" import { Application } from "@hotwired/stimulus" import SearchController from "solid_queue_web/search_controller" +import RefreshController from "solid_queue_web/refresh_controller" const application = Application.start() application.register("search", SearchController) +application.register("refresh", RefreshController) diff --git a/app/javascript/solid_queue_web/refresh_controller.js b/app/javascript/solid_queue_web/refresh_controller.js new file mode 100644 index 0000000..f0eedf6 --- /dev/null +++ b/app/javascript/solid_queue_web/refresh_controller.js @@ -0,0 +1,51 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static values = { interval: { type: Number, default: 5000 } } + + initialize() { + this._onVisibilityChange = this._onVisibilityChange.bind(this) + } + + connect() { + document.addEventListener("visibilitychange", this._onVisibilityChange) + this._schedule() + } + + disconnect() { + clearTimeout(this._timer) + document.removeEventListener("visibilitychange", this._onVisibilityChange) + } + + _schedule() { + this._timer = setTimeout(() => this._reload(), this.intervalValue) + } + + async _reload() { + clearTimeout(this._timer) + if (!document.hidden) { + try { + const response = await fetch(window.location.href, { + headers: { "Turbo-Frame": this.element.id, Accept: "text/html" } + }) + if (response.ok) { + const html = await response.text() + const doc = new DOMParser().parseFromString(html, "text/html") + const frame = doc.querySelector(`turbo-frame#${this.element.id}`) + if (frame && this.element.isConnected) this.element.innerHTML = frame.innerHTML + } + } catch { + // network error — skip this tick + } + } + if (this.element.isConnected) this._schedule() + } + + _onVisibilityChange() { + if (document.hidden) { + clearTimeout(this._timer) + } else { + this._reload() + } + } +} \ No newline at end of file diff --git a/app/views/solid_queue_web/dashboard/index.html.erb b/app/views/solid_queue_web/dashboard/index.html.erb index 56d5a38..96d3934 100644 --- a/app/views/solid_queue_web/dashboard/index.html.erb +++ b/app/views/solid_queue_web/dashboard/index.html.erb @@ -1,3 +1,4 @@ +<%= turbo_frame_tag "dashboard", target: "_top", data: { controller: "refresh", refresh_interval_value: 5000 } do %>