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 != "" {
|
if anime.Broadcast.String != "" {
|
||||||
<div class="sidebar-row">
|
<div class="sidebar-row">
|
||||||
<span class="sidebar-label">Broadcast</span>
|
<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>
|
</div>
|
||||||
}
|
}
|
||||||
if len(anime.Streaming) > 0 {
|
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="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<script src="/static/js/discover.js" defer></script>
|
<script src="/static/js/discover.js" defer></script>
|
||||||
<script src="/static/js/anime.js" defer></script>
|
<script src="/static/js/anime.js" defer></script>
|
||||||
|
<script src="/static/js/timezone.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ templ NotificationCard(item WatchingAnimeWithDetails) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="notification-meta">
|
<div class="notification-meta">
|
||||||
if item.Anime.Broadcast.String != "" {
|
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 {
|
if item.Anime.Episodes > 0 {
|
||||||
<span class="notification-progress">
|
<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