fix(simkl): resolve metadata through sibling ids for airing anime cours - #2
Merged
Merged
Conversation
Simkl models a franchise as one entry per season or cour and gives each its own ids. With anime ids left on the IMDB default, the cour currently airing can carry an IMDB id no installed meta addon has heard of: Re:Zero's 2026 run arrives as tt36501927, which Cinemeta answers nothing for, while the cours beside it carry tt5607616, which every addon serves. Nothing resolved that id, so MetaDetailsRepository.fetch returned null, resolveHomeNextUpCandidate gave up as a transient failure, and the show dropped out of Continue Watching even though Simkl still listed it as being watched. The same rows rendered as empty cards when they did appear. Entries sharing a TVDB id are the same show to every meta addon, so their ids are usable stand-ins. When a row's own id resolves to nothing, the tracker is now asked for the ids it knows the content under and they are tried in turn, widest-served namespace first. Three smaller fixes ride along, each in the same area: - enrichWatchProgressEntry falls back to the episode's position across the addon's seasons. Trackers count anime in one continuous run -- seasonless for Simkl, season 1 for Trakt -- while addons split it into seasons, so the exact season+episode lookup missed and the card lost its still and title. - Next Up can be seeded from Simkl's last_watched marker when an entry reports watched episodes but returns no per-episode history. This is robustness, not the cause of the bug above; it fabricates nothing into watch history, and the existing invariant test covering that still passes. - Continue Watching artwork steps to the next candidate when an image fails to load. Episode stills for recently aired episodes routinely 404 while the backdrop and poster serve fine, which left the card an empty box. Verified against a real Simkl account in the simulator: the Re:Zero card now exists with contentId tt36501927 but videoId tt5607616:4:17, so the metadata demonstrably comes from the sibling id. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BEwXX1nJuKHQvdvGVd7nxG
|
Thanks for the pull request and for the time put into it. The current Nuvio Mobile app is being discontinued in favor of a full Compose Multiplatform rewrite, so changes against the legacy React Native codebase are no longer being reviewed or merged. For that reason, this pull request is being closed as part of the wind-down of the old app. Pull requests for the rewrite are not open yet. Once contribution intake is ready for the new codebase, maintainers will announce it clearly. Thank you again for the contribution and for supporting the project. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves show metadata through the ids of sibling Simkl entries when a row's own content id is not served by any installed meta addon, which is what makes anime like Re:Zero vanish from Continue Watching under the Simkl source. Three smaller fixes in the same path ride along: episode lookup by position for continuous anime numbering, Next Up seeds from Simkl's
last_watchedmarker, and artwork that steps to the next candidate when an image fails to load.PR type
Why
Simkl models a franchise as one entry per season or cour and gives each its own ids. With anime ids on the IMDB default, the cour currently airing can carry an IMDB id no addon has heard of: Re:Zero's 2026 run arrives as
tt36501927, which Cinemeta answers nothing for and TMDB has no TV entry for, while the cours beside it carrytt5607616, which every addon serves.Nothing resolved that id, so
MetaDetailsRepository.fetchreturned null,resolveHomeNextUpCandidategave up as a transient failure, the retries exhausted, and the show dropped out of Continue Watching while Simkl still listed it as being watched. Switching the source to Nuvio made it reappear, because the local rows use the franchise id.All Re:Zero entries share
tvdb: 305089. Entries sharing a TVDB id are the same show to every meta addon, so their ids are usable stand-ins for artwork and episode lists.Issue or approval
Fixes #1
UI / behavior impact
Policy check
CONTRIBUTING.md.Scope boundaries
What this PR does:
TrackingProgressProvider.alternateContentIds()(defaulting to empty, so Trakt and Nuvio sync are untouched) and implements it for Simkl viaalternateContentIdsFor, grouping entries by shared TVDB id and ordering candidates widest-served namespace first (imdb → tmdb → tvdb → kitsu/mal/anilist/anidb), capped at four attempts.WatchProgressRepository.fetchRemoteMetadataGroupand in Next Up resolution. The primary id is always tried first and nothing changes when it resolves.enrichWatchProgressEntryfalls back to the episode's position across the addon's main seasons when the exact season+episode lookup misses.last_watchedmarker for entries that report watched episodes but return no per-episode history. This is robustness, not the cause of the bug above.What this PR does not do:
canonicalContentId, or the anime id preference. Those govern identity across the library and watched badges; changing them to fix a display problem would risk the duplicate-entry class of bug. Metadata is borrowed for display only, and the row keeps its own identity.summary counters do not fabricate exact episode markersstill passes, deliberately.Testing
./gradlew :composeApp:iosSimulatorArm64Test— full suite green.SimklProjectionsTest(22 tests, 0 failures) covers sibling id ordering, unknown content, and unrelated shows never being offered as alternates, plus the summary-marker seeds and the "exact history wins" and "hidden statuses are never seeded" cases.WatchProgressMetadataProjectionTest(7 tests) covers seasonless rows, season-1 overflow across seasons, exact matches winning, later seasons never being guessed, and specials being skipped.contentId tt36501927withvideoId tt5607616:4:17andepisodeThumbnail https://episodes.metahub.space/tt5607616/4/17/w780.jpg— the metadata demonstrably comes from the sibling id, since the seed id resolves to nothing. The card renders in the Upcoming row as "S4 E17 · Airs in 5 Days" with artwork..../tt39551330/1/10/w780.jpg, confirmed 404 while its backdrop and poster return 200) rendered as an empty box before and shows the backdrop after.Screenshots / Video
Before: the Continue Watching row showed "Chainsmoker Cat · S1 E10" as an empty dark card with only the text and the New Episode badge, and Re:Zero was absent from both the Continue Watching and Upcoming rows.
After: the same Chainsmoker Cat card renders its artwork, and Re:Zero appears in Upcoming as "S4 E17 · Episode 17 · Airs in 5 Days" with its episode still.
Both captures were taken on an iPhone 17 Pro simulator against the same account, before and after the change.
Breaking changes
None.
alternateContentIdsdefaults to an empty list, so every provider other than Simkl behaves exactly as before, and the alternate lookup only runs after the primary id has already failed to resolve.Linked issues
Fixes #1
🤖 Generated with Claude Code
https://claude.ai/code/session_01BEwXX1nJuKHQvdvGVd7nxG