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
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,10 @@ export function differenceInDays(fromDate, toDate) {
|
||||
return Math.round(Math.abs((beginningOfDay(toDate) - beginningOfDay(fromDate)) / (1000 * 60 * 60 * 24)))
|
||||
}
|
||||
|
||||
export function signedDifferenceInDays(fromDate, toDate) {
|
||||
return Math.round((beginningOfDay(toDate) - beginningOfDay(fromDate)) / (1000 * 60 * 60 * 24))
|
||||
}
|
||||
|
||||
export function beginningOfDay(date) {
|
||||
return new Date(date.getFullYear(), date.getMonth(), date.getDate())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user