diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/routes/hololive/+page.svelte | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/src/routes/hololive/+page.svelte b/src/routes/hololive/+page.svelte index aace56a3..dca0b14a 100644 --- a/src/routes/hololive/+page.svelte +++ b/src/routes/hololive/+page.svelte @@ -65,6 +65,24 @@ 'Content-Type': 'application/json' } }).then(getPinnedStreams); + + const getClosestUpcomingPinnedStreams = (schedule: ParseResult) => { + const now = Date.now(); + let closestUpcomingPinnedStreams = new Map(); + + schedule.lives.forEach((live) => { + const liveTime = new Date(live.time).getTime(); + + if (liveTime > now && pinnedStreams.includes(live.streamer)) { + const existing = closestUpcomingPinnedStreams.get(live.streamer); + + if (!existing || liveTime < new Date(existing.time).getTime()) + closestUpcomingPinnedStreams.set(live.streamer, live); + } + }); + + return closestUpcomingPinnedStreams; + }; </script> <HeadTitle route="hololive Schedule" path="/hololive" /> @@ -81,6 +99,7 @@ <Skeleton grid={true} count={100} width="49%" height="16.25em" /> {:then untypedSchedule} {@const schedule = typeSchedule(parseScheduleHtml(untypedSchedule))} + {@const closestUpcomingPinnedStreams = getClosestUpcomingPinnedStreams(schedule)} {#if schedule.lives.length === 0} <Message message="No upcoming streams." loader="ripple" /> @@ -89,32 +108,36 @@ <div class="container"> {#each schedule.lives .filter((live) => { - const time = new Date(live.time); + try { + $locale().hololive.dateFormatter(new Date(live.time)); - return time.getTime() > Date.now() - 12 * 60 * 60 * 1000 || time.getTime() > Date.now() || live.streaming; + return true; + } catch { + return false; + } }) .sort((a, b) => { - if (pinnedStreams.includes(a.streamer) && a.streaming) { - return -1; - } else if (pinnedStreams.includes(b.streamer) && b.streaming) { - return 1; - } + const now = Date.now(); + const aTime = new Date(a.time).getTime(); + const bTime = new Date(b.time).getTime(); + const aIsLive = a.streaming; + const bIsLive = b.streaming; + const aIsClosestPinned = closestUpcomingPinnedStreams.get(a.streamer) === a; + const bIsClosestPinned = closestUpcomingPinnedStreams.get(b.streamer) === b; - if (a.streaming && !b.streaming) { - return -1; - } else if (!a.streaming && b.streaming) { - return 1; - } + if (aIsLive && pinnedStreams.includes(a.streamer)) return -1; + if (bIsLive && pinnedStreams.includes(b.streamer)) return 1; - const aTime = new Date(a.time).getTime(); + if (aIsLive && !bIsLive) return -1; + if (bIsLive && !aIsLive) return 1; - if (aTime < Date.now() && new Date(b.time).getTime() > Date.now()) { - return 1; - } else if (aTime > Date.now() && new Date(b.time).getTime() < Date.now()) { - return -1; - } + if (aIsClosestPinned && !bIsClosestPinned) return -1; + if (bIsClosestPinned && !aIsClosestPinned) return 1; + + if (aTime > now && !(aTime < now && !aIsLive)) return -1; + if (bTime > now && !(bTime < now && !bIsLive)) return 1; - return aTime - new Date(b.time).getTime(); + return bTime - aTime; }) as live} <div class="stream card"> {#if $identity.id !== -2} |