ui: convert jst to local time
This commit is contained in:
@@ -149,7 +149,7 @@ templ AnimeDetails(anime jikan.Anime, currentStatus string) {
|
||||
if anime.Broadcast.String != "" {
|
||||
<div class="sidebar-row">
|
||||
<span class="sidebar-label">Broadcast</span>
|
||||
<span class="sidebar-value">{ anime.Broadcast.String }</span>
|
||||
<span class="sidebar-value" data-jst-text={ anime.Broadcast.String }>{ anime.Broadcast.String }</span>
|
||||
</div>
|
||||
}
|
||||
if len(anime.Streaming) > 0 {
|
||||
|
||||
@@ -14,6 +14,7 @@ templ Layout(title string) {
|
||||
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||
<script src="/static/js/discover.js" defer></script>
|
||||
<script src="/static/js/anime.js" defer></script>
|
||||
<script src="/static/js/timezone.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
|
||||
@@ -124,7 +124,7 @@ templ NotificationCard(item WatchingAnimeWithDetails) {
|
||||
</div>
|
||||
<div class="notification-meta">
|
||||
if item.Anime.Broadcast.String != "" {
|
||||
<span class="notification-broadcast">{ item.Anime.Broadcast.String }</span>
|
||||
<span class="notification-broadcast" data-jst-text={ item.Anime.Broadcast.String }>{ item.Anime.Broadcast.String }</span>
|
||||
}
|
||||
if item.Anime.Episodes > 0 {
|
||||
<span class="notification-progress">
|
||||
|
||||
113
static/js/timezone.js
Normal file
113
static/js/timezone.js
Normal file
@@ -0,0 +1,113 @@
|
||||
;(function () {
|
||||
const jstOffsetMinutes = 9 * 60
|
||||
|
||||
const parseBroadcast = (text) => {
|
||||
const match = text.match(/^(.*) at (\d{1,2}):(\d{2}) \(JST\)$/i)
|
||||
if (!match) {
|
||||
return null
|
||||
}
|
||||
|
||||
const day = match[1].trim()
|
||||
const hour = Number.parseInt(match[2], 10)
|
||||
const minute = Number.parseInt(match[3], 10)
|
||||
|
||||
if (Number.isNaN(hour) || Number.isNaN(minute)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return { day, hour, minute }
|
||||
}
|
||||
|
||||
const normalizeDay = (day) => {
|
||||
const key = day.trim().toLowerCase().replace(/s$/, '')
|
||||
const days = {
|
||||
mon: 1,
|
||||
monday: 1,
|
||||
tue: 2,
|
||||
tues: 2,
|
||||
tuesday: 2,
|
||||
wed: 3,
|
||||
wednesday: 3,
|
||||
thu: 4,
|
||||
thur: 4,
|
||||
thurs: 4,
|
||||
thursday: 4,
|
||||
fri: 5,
|
||||
friday: 5,
|
||||
sat: 6,
|
||||
saturday: 6,
|
||||
sun: 0,
|
||||
sunday: 0,
|
||||
}
|
||||
|
||||
if (typeof days[key] !== 'number') {
|
||||
return null
|
||||
}
|
||||
|
||||
return days[key]
|
||||
}
|
||||
|
||||
const convertToLocal = (parsed, localOffsetMinutes) => {
|
||||
const sourceMinutes = parsed.hour * 60 + parsed.minute
|
||||
const diff = jstOffsetMinutes - localOffsetMinutes
|
||||
const localTotal = sourceMinutes - diff
|
||||
|
||||
const dayShift = Math.floor(localTotal / 1440)
|
||||
const normalizedMinutes = ((localTotal % 1440) + 1440) % 1440
|
||||
const localHour = Math.floor(normalizedMinutes / 60)
|
||||
const localMinute = normalizedMinutes % 60
|
||||
|
||||
const sourceDayIndex = normalizeDay(parsed.day)
|
||||
if (sourceDayIndex === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const localDayIndex = ((sourceDayIndex + dayShift) % 7 + 7) % 7
|
||||
const localDay = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][localDayIndex]
|
||||
|
||||
const time = `${localHour.toString().padStart(2, '0')}:${localMinute.toString().padStart(2, '0')}`
|
||||
return `${localDay} at ${time} (Local)`
|
||||
}
|
||||
|
||||
const updateNode = (node, localOffsetMinutes) => {
|
||||
const source = node.getAttribute('data-jst-text')
|
||||
if (!source) {
|
||||
return
|
||||
}
|
||||
|
||||
const parsed = parseBroadcast(source)
|
||||
if (!parsed) {
|
||||
return
|
||||
}
|
||||
|
||||
const converted = convertToLocal(parsed, localOffsetMinutes)
|
||||
if (!converted) {
|
||||
return
|
||||
}
|
||||
|
||||
node.textContent = converted
|
||||
}
|
||||
|
||||
const hideJstSuffix = () => {
|
||||
document.querySelectorAll('.notification-broadcast, [data-jst-text]').forEach((node) => {
|
||||
if (!(node instanceof HTMLElement)) {
|
||||
return
|
||||
}
|
||||
|
||||
const text = node.textContent || ''
|
||||
if (text.includes('(JST)')) {
|
||||
node.textContent = text.replace(/\s*\(JST\)/gi, ' (Local)')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const updateAll = () => {
|
||||
const localOffsetMinutes = -new Date().getTimezoneOffset()
|
||||
const nodes = document.querySelectorAll('[data-jst-text]')
|
||||
nodes.forEach((node) => updateNode(node, localOffsetMinutes))
|
||||
hideJstSuffix()
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', updateAll)
|
||||
document.body.addEventListener('htmx:afterSwap', updateAll)
|
||||
})()
|
||||
Reference in New Issue
Block a user