fix: anime incorrectly marked as completed when anilist doesn't provide an episode count

This commit is contained in:
ThaUnknown 2025-06-16 19:51:46 +02:00
parent a5fa723db1
commit 0db7c3bbd4
No known key found for this signature in database
3 changed files with 17 additions and 12 deletions

View file

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

View file

@ -1,3 +1,5 @@
import { authAggregator } from '../auth'
import type { ScheduleMedia } from './queries' import type { ScheduleMedia } from './queries'
import type { Media } from './types' import type { Media } from './types'
import type { Episode, Episodes } from '../anizip/types' import type { Episode, Episodes } from '../anizip/types'
@ -93,7 +95,7 @@ export function episodes (media: Pick<Media, 'aired' | 'notaired' | 'episodes' |
const upcoming = media.aired?.n?.[media.aired.n.length - 1]?.e ?? 0 const upcoming = media.aired?.n?.[media.aired.n.length - 1]?.e ?? 0
const past = media.notaired?.n?.[media.notaired.n.length - 1]?.e ?? 0 const past = media.notaired?.n?.[media.notaired.n.length - 1]?.e ?? 0
const progress = media.mediaListEntry?.progress ?? 0 const progress = authAggregator.mediaListEntry(media)?.progress ?? 0
return Math.max(upcoming, past, progress) return Math.max(upcoming, past, progress)
} }

View file

@ -106,15 +106,18 @@ export default new class AuthAggregator {
watch (media: Media, progress: number) { watch (media: Media, progress: number) {
// TODO: auto re-watch status // 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 const totalEps = episodes(media) ?? 1 // episodes or movie which is single episode
if (totalEps < progress) return // woah, bad data from resolver?! if (totalEps < progress) return // woah, bad data from resolver?!
const currentProgress = media.mediaListEntry?.progress ?? 0 const currentProgress = media.mediaListEntry?.progress ?? 0
if (currentProgress >= progress) return if (currentProgress >= progress) return
// there's an edge case here that episodes returns 1, because anilist doesn't have episode count for an airing show without an expected end date
// this can set a media to completed when it shouldn't be, so we check if the media is finished or has episodes
const canBeCompleted = media.status === 'FINISHED' || media.episodes != null
const status = const status =
totalEps === progress totalEps === progress && canBeCompleted
? 'COMPLETED' ? 'COMPLETED'
: media.mediaListEntry?.status === 'REPEATING' ? 'REPEATING' : 'CURRENT' : media.mediaListEntry?.status === 'REPEATING' ? 'REPEATING' : 'CURRENT'
@ -124,26 +127,26 @@ export default new class AuthAggregator {
} }
delete (media: Media) { delete (media: Media) {
const syncSettings = get(this.syncSettings) const sync = get(this.syncSettings)
return Promise.allSettled([ return Promise.allSettled([
this.anilist() && syncSettings.al && client.deleteEntry(media), sync.al && this.anilist() && client.deleteEntry(media),
this.kitsu() && syncSettings.kitsu && kitsu.deleteEntry(media), sync.kitsu && this.kitsu() && kitsu.deleteEntry(media),
syncSettings.local && local.deleteEntry(media) sync.local && local.deleteEntry(media)
]) ])
} }
entry (variables: VariablesOf<typeof Entry>) { entry (variables: VariablesOf<typeof Entry>) {
const syncSettings = get(this.syncSettings) const sync = get(this.syncSettings)
variables.lists ??= [] variables.lists ??= []
if (!variables.lists.includes('Watched using Hayase')) { if (!variables.lists.includes('Watched using Hayase')) {
variables.lists.push('Watched using Hayase') variables.lists.push('Watched using Hayase')
} }
return Promise.allSettled([ return Promise.allSettled([
this.anilist() && syncSettings.al && client.entry(variables), sync.al && this.anilist() && client.entry(variables),
this.kitsu() && syncSettings.kitsu && kitsu.entry(variables), sync.kitsu && this.kitsu() && kitsu.entry(variables),
syncSettings.local && local.entry(variables) sync.local && local.entry(variables)
]) ])
} }
}() }()