feat: re-introduce watch progress

This commit is contained in:
ThaUnknown 2025-06-15 23:00:36 +02:00
parent d8c2a25a34
commit 00dae69e9b
No known key found for this signature in database
4 changed files with 64 additions and 1 deletions

View file

@ -1,6 +1,6 @@
{
"name": "ui",
"version": "6.3.60",
"version": "6.3.61",
"license": "BUSL-1.1",
"private": true,
"packageManager": "pnpm@9.14.4",

View file

@ -22,6 +22,7 @@
import { episodes as _episodes, dedupeAiring, episodeByAirDate, notes, type Media } from '$lib/modules/anilist'
import { authAggregator, list, progress } from '$lib/modules/auth'
import { click, dragScroll } from '$lib/modules/navigate'
import { liveAnimeProgress } from '$lib/modules/watchProgress'
import { cn, isMobile, since } from '$lib/utils'
export let eps: EpisodesResponse | null
@ -74,6 +75,8 @@
export let following = authAggregator.following(media.id)
$: followerEntries = $following?.data?.Page?.mediaList?.filter(e => e?.user?.id !== authAggregator.id()) ?? []
$: watchProgress = liveAnimeProgress(media.id)
</script>
<Pagination count={episodeCount} {perPage} bind:currentPage let:pages let:hasNext let:hasPrev let:range let:setPage siblingCount={1}>
@ -108,6 +111,10 @@
</div>
{#if watched || completed}
<div class='mb-2 h-0.5 overflow-hidden w-full bg-blue-600 shrink-0' />
{:else if $watchProgress?.episode === episode}
<div class='w-full bg-neutral-800 mb-2'>
<div class='h-0.5 overflow-hidden bg-blue-600 shrink-0' style:width={$watchProgress.progress + '%'} />
</div>
{/if}
<div class='text-[9.6px] text-muted-foreground overflow-hidden'>
{notes(summary ?? '')}

View file

@ -61,6 +61,7 @@
import { settings, SUPPORTS } from '$lib/modules/settings'
import { server } from '$lib/modules/torrent'
import { w2globby } from '$lib/modules/w2g/lobby'
import { getAnimeProgress, setAnimeProgress } from '$lib/modules/watchProgress'
import { toTS, fastPrettyBits } from '$lib/utils'
export let mediaInfo: MediaInfo
@ -695,6 +696,27 @@
$: $w2globby?.playerStateChanged({ paused, time: Math.floor(currentTime) })
$: $w2globby?.on('player', updateState)
function loadAnimeProgress () {
if (!mediaInfo.media.id || !mediaInfo.episode) return
const animeProgress = getAnimeProgress(mediaInfo.media.id)
if (!animeProgress || animeProgress.episode !== mediaInfo.episode) return
currentTime = Math.max(animeProgress.currentTime - 5, 0)
}
function saveAnimeProgress () {
if (!mediaInfo.media.id || !mediaInfo.episode) return
if (buffering || paused || video.readyState < 4) return
setAnimeProgress(mediaInfo.media.id, { episode: mediaInfo.episode, currentTime: video.currentTime, safeduration })
}
const saveProgressLoop = setInterval(saveAnimeProgress, 10000)
onDestroy(() => {
clearInterval(saveProgressLoop)
})
</script>
<svelte:document bind:fullscreenElement bind:visibilityState use:holdToFF={'key'} />
@ -721,6 +743,7 @@
on:click={() => isMiniplayer ? goto('/app/player') : playPause()}
on:dblclick={fullscreen}
on:loadeddata={checkAudio}
on:loadedmetadata={loadAnimeProgress}
on:timeupdate={checkSkippableChapters}
on:timeupdate={checkCompletion}
on:loadedmetadata={autoPlay}

View file

@ -0,0 +1,33 @@
import { derived, get } from 'svelte/store'
import { persisted } from 'svelte-persisted-store'
export interface WatchProgress {
episode: number
currentTime: number
safeduration: number
}
const animeProgressStore = persisted<Record<number, WatchProgress>>('watchProgress', {})
export function liveAnimeProgress (mediaId: number) {
return derived(animeProgressStore, (data) => {
if (!mediaId) return
const entry = data[mediaId]
if (!entry) return
return {
progress: Math.ceil(entry.currentTime / entry.safeduration * 100),
episode: entry.episode
}
})
}
export function getAnimeProgress (mediaId: number) {
return get(animeProgressStore)[mediaId]
}
export function setAnimeProgress (mediaId: number, progress: WatchProgress) {
animeProgressStore.update(data => {
data[mediaId] = progress
return data
})
}