mirror of
https://github.com/ThaUnknown/miru.git
synced 2026-03-11 22:15:35 +00:00
feat: re-introduce watch progress
This commit is contained in:
parent
d8c2a25a34
commit
00dae69e9b
4 changed files with 64 additions and 1 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 ?? '')}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
33
src/lib/modules/watchProgress.ts
Normal file
33
src/lib/modules/watchProgress.ts
Normal 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
|
||||
})
|
||||
}
|
||||
Loading…
Reference in a new issue