Files
fizzy/app/javascript/controllers/bubble_controller.js
T
Mike Dalessio 388fe2de73 Introduce a stimulus controller for bubbles
The "closing soon" bubbles were introduced in #406, and the "falling
back" bubbles in #500. However, these bubbles are part of the cached
card and so as time passes, the relative time doesn't change unless
the card is touched.

This PR introduces a stimulus controller for bubbles, which takes care
of:

- making the bubble visible during the reminder period
- calculating the relative number of days until entropy kicks in
- rendering appropriate text around the day count

ref: https://37s.fizzy.37signals.com/collections/693169850/cards/999009091
2025-05-16 10:27:00 -04:00

49 lines
1.3 KiB
JavaScript

import { Controller } from "@hotwired/stimulus"
import { signedDifferenceInDays } from "helpers/date_helpers"
const REFRESH_INTERVAL = 3_600_000 // 1 hour (in milliseconds)
export default class extends Controller {
static targets = [ "closingTop", "consideringTop", "days", "bottom" ]
static values = { "closesAt": String, "reminderBefore": Number }
#timer
connect() {
this.#timer = setInterval(this.update.bind(this), REFRESH_INTERVAL)
this.update()
}
disconnect() {
clearInterval(this.#timer)
}
update() {
const closesInDays = signedDifferenceInDays(new Date(), new Date(this.closesAtValue))
if (closesInDays > this.reminderBeforeValue) {
this.#hide()
return
}
if (this.hasClosingTopTarget) {
this.closingTopTarget.innerHTML = closesInDays < 1 ? "Closes" : "Closes in"
}
if (this.hasConsideringTopTarget) {
this.consideringTopTarget.innerHTML = closesInDays < 1 ? "Falls Back" : "Falls Back in"
}
this.daysTarget.innerHTML = closesInDays < 1 ? "!" : closesInDays
this.bottomTarget.innerHTML = closesInDays < 1 ? "Today" : (closesInDays === 1 ? "day" : "days")
this.#show()
}
#hide() {
this.element.setAttribute("hidden", "")
}
#show() {
this.element.removeAttribute("hidden")
}
}