feat: autocomplete

This commit is contained in:
ThaUnknown 2025-04-14 00:40:59 +02:00
parent a6fa96f61e
commit b74a53c4c5
No known key found for this signature in database
2 changed files with 41 additions and 2 deletions

View file

@ -33,6 +33,7 @@
import { episodes } from '$lib/modules/anizip'
import { page } from '$app/stores'
import { isPlaying } from '$lib/modules/idle'
import { authAggregator } from '$lib/modules/auth'
export let mediaInfo: MediaInfo
export let files: TorrentFile[]
@ -216,6 +217,22 @@
}
}
let completed = false
function checkCompletion () {
if (!completed && $settings.playerAutocomplete) {
checkCompletionByTime(currentTime, safeduration)
}
}
let externalPlayerReady = false
function checkCompletionByTime (currentTime: number, safeduration: number) {
const fromend = Math.max(180, safeduration / 10)
if (safeduration && currentTime && (video.readyState || externalPlayerReady) && safeduration - fromend < currentTime) {
authAggregator.watch(mediaInfo.media, mediaInfo.episode)
completed = true
externalPlayerReady = false
}
}
// other
$: if (ended && $settings.playerAutoplay) next?.()
@ -551,6 +568,7 @@
on:dblclick={fullscreen}
on:loadeddata={checkAudio}
on:timeupdate={checkSkippableChapters}
on:timeupdate={checkCompletion}
/>
<div class='absolute w-full h-full flex items-center justify-center top-0 pointer-events-none'>
{#if seeking}

View file

@ -2,7 +2,7 @@ import { readable } from 'simple-store-svelte'
import { persisted } from 'svelte-persisted-store'
import { get } from 'svelte/store'
import { client } from '../anilist'
import { client, episodes, type Media } from '../anilist'
import local from './local'
@ -31,7 +31,7 @@ export default new class AuthAggregator {
}
id () {
if (this.anilist()) return client.viewer.value?.viewer?.id
if (this.anilist()) return client.viewer.value!.viewer?.id
return -1
}
@ -75,6 +75,27 @@ export default new class AuthAggregator {
return client.sequelIDs
}
watch (media: Media, progress: number) {
// TODO: auto re-watch status
// if (media.status !== 'FINISHED' && media.status !== 'RELEASING') return // this turned out to be a bad idea, anilist sometimes delays status changes by up to a day... yikes
const totalEps = episodes(media) ?? 1 // episodes or movie which is single episode
if (totalEps < progress) return // woah, bad data from resolver?!
const currentProgress = media.mediaListEntry?.progress ?? 0
if (currentProgress <= progress) return
const status =
totalEps === progress
? 'COMPLETED'
: media.mediaListEntry?.status === 'REPEATING' ? 'REPEATING' : 'CURRENT'
const repeat = media.mediaListEntry?.repeat ?? 0 + (totalEps === progress ? 1 : 0)
const lists = (media.mediaListEntry?.customLists as Array<{enabled: boolean, name: string}> | undefined)?.filter(list => list.enabled).map(list => list.name) ?? []
this.entry({ id: media.id, progress, repeat, status, lists })
}
entry (variables: VariablesOf<typeof Entry>) {
const syncSettings = get(this.syncSettings)
variables.lists ??= []