Compare commits

..

2 commits

3 changed files with 64 additions and 0 deletions

View file

@ -136,6 +136,7 @@
,(if (config-true? 'feature_search_suggestions)
`(script (@ (type "module") (src ,(get-static-url "search-suggestions.js"))))
"")
(script (@ (type "module") (src ,(get-static-url "countdown.js"))))
(link (@ (rel "icon") (href ,(u (λ (v) (config-true? 'strict_proxy))
(λ (v) (u-proxy-url v))
(head-data^-icon-url head-data))))))

View file

@ -205,6 +205,16 @@
attributes)
;; children
((compose1
; more uncollapsing - sample: bandori/wiki/BanG_Dream!_Wikia
(curry u
(λ (v) (has-class? "mw-collapsible-content" attributes))
(λ (v) (for/list ([element v])
(u (λ (element) (pair? element))
(λ (element)
`(,(car element)
(@ ,@(attribute-maybe-update 'style (λ (a) (regexp-replace #rx"display: *none" a "display:inline")) (bits->attributes element)))
,@(filter element-is-content? (cdr element))))
element))))
; wrap blinking animated images in a slot so they can be animated with CSS
(curry u
(λ (v) (and (has-class? "animated" attributes)

53
static/countdown.js Normal file
View file

@ -0,0 +1,53 @@
// countdown timer for gacha enthusiasts
// sample: bandori/wiki/BanG_Dream!_Wikia
// sample: ensemble-stars/wiki/The_English_Ensemble_Stars_Wiki
import {h, htm, render, useState, useEffect, createContext, useContext, signal, computed, effect} from "./preact.js"
const html = htm.bind(h)
const now = signal(Date.now())
setInterval(() => now.value = Date.now(), 1000)
const units = [
["w", 7*24*60*60*1000],
["d", 24*60*60*1000],
["h", 60*60*1000],
["m", 60*1000],
["s", 1000]
]
function getDisplayTime(datetime, now, or) {
let difference = datetime - now
let foundSignificantField = false
if (difference > 0) {
return units.map(([letter, duration], index) => {
const multiplier = Math.floor(difference / duration)
difference -= multiplier * duration
if (multiplier > 0 || foundSignificantField) {
foundSignificantField = true
return multiplier + letter
}
}).filter(s => s).join(" ")
} else if (or) {
return or
} else {
return `[timer ended on ${new Date(datetime).toLocaleString()}]`
}
}
function Countdown(props) {
return html`<span>${props.display}</span>`
}
document.querySelectorAll(".countdown").forEach(eCountdown => {
// grab information and make variables
const eDate = eCountdown.querySelector(".countdowndate")
const eOr = eCountdown.nextElementSibling
const or = eOr?.textContent
const datetime = new Date(eDate.textContent).getTime()
// the mapped signal
const display = computed(() => getDisplayTime(datetime, now.value, or))
// clear content and render
while (eDate.childNodes[0] !== undefined) eDate.childNodes[0].remove()
render(html`<${Countdown} display=${display} />`, eDate);
})