Skip to content

fix(simkl): resolve metadata through sibling ids for airing anime cours - #2

Merged
Mitsu03 merged 1 commit into
cmp-rewritefrom
fix/simkl-anime-continue-watching
Sep 11, 2026
Merged

Mitsu03 merged 1 commit into
cmp-rewritefrom
fix/simkl-anime-continue-watching

Conversation

@Mitsu03

@Mitsu03 Mitsu03 commented Sep 11, 2026

Copy link
Copy Markdown
Owner

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_watched marker, and artwork that steps to the next candidate when an image fails to load.

PR type

  • Reproducible bug fix
  • UI glitch/bug fix
  • Behavior bug/regression fix
  • Small maintenance only, with no UI or behavior change
  • Docs accuracy fix
  • Translation/localization only
  • Approved larger or directional change

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 carry tt5607616, which every addon serves.

Nothing resolved that id, so MetaDetailsRepository.fetch returned null, resolveHomeNextUpCandidate gave 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

  • No UI change
  • No behavior change
  • UI changed only to fix a documented glitch/bug
  • Behavior changed only to fix a documented bug/regression
  • UI change has explicit maintainer approval
  • Behavior change has explicit maintainer approval

Policy check

  • I have read and understood CONTRIBUTING.md.
  • This PR is small, focused, and limited to one problem.
  • This PR is not cosmetic-only.
  • Any UI change fixes a linked glitch/bug and includes visual proof, or this PR has no UI change.
  • Any behavior change fixes a linked bug/regression or has explicit approval, or this PR has no behavior change.
  • This PR does not bundle unrelated refactors, cleanups, formatting, or drive-by changes.
  • This PR does not add dependencies, architecture changes, migrations, or product-direction changes without explicit approval.
  • I listed the testing performed below.

Scope boundaries

What this PR does:

  • Adds TrackingProgressProvider.alternateContentIds() (defaulting to empty, so Trakt and Nuvio sync are untouched) and implements it for Simkl via alternateContentIdsFor, grouping entries by shared TVDB id and ordering candidates widest-served namespace first (imdb → tmdb → tvdb → kitsu/mal/anilist/anidb), capped at four attempts.
  • Uses it as a second pass only, in WatchProgressRepository.fetchRemoteMetadataGroup and in Next Up resolution. The primary id is always tried first and nothing changes when it resolves.
  • enrichWatchProgressEntry falls back to the episode's position across the addon's main seasons when the exact season+episode lookup misses.
  • Next Up can be seeded from Simkl's last_watched marker for entries that report watched episodes but return no per-episode history. This is robustness, not the cause of the bug above.
  • Continue Watching artwork advances to the next candidate when an image fails to load.

What this PR does not do:

  • No change to id canonicalization, 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.
  • No fabricated watch history. The summary seeds are completed progress rows in the Simkl layer, mirroring Trakt's existing show-progress seeds; the pre-existing invariant test summary counters do not fabricate exact episode markers still passes, deliberately.
  • No fix for content that no addon can resolve under any of its ids. If every sibling id is unknown too, the row still has no metadata.

Testing

  • ./gradlew :composeApp:iosSimulatorArm64Test — full suite green.
  • 15 new tests: 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.
  • Manual, on an iPhone simulator against a real Simkl account with the reported data: before the change the Re:Zero card was absent under the Simkl source. After it, the Continue Watching cache contains contentId tt36501927 with videoId tt5607616:4:17 and episodeThumbnail 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.
  • Same session verified the artwork fallback: the card whose episode still 404s (.../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. alternateContentIds defaults 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

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
@github-actions

Copy link
Copy Markdown

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.

@github-actions github-actions Bot closed this Sep 11, 2026
@Mitsu03
Mitsu03 merged commit 8de75bc into cmp-rewrite Sep 11, 2026
4 of 5 checks passed
@Mitsu03
Mitsu03 deleted the fix/simkl-anime-continue-watching branch September 11, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anime disappears from Continue Watching when the airing cour's Simkl id is not served by any meta addon

1 participant