Anime released but no episodes aired yet confuses users. #3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Investigation: "Let's go KAIKIGUMI" showing on homepage before episodes are truly available
src/webview/bridge.ts), Miruro1.12.0Summary
The user noticed that "Let's go KAIKIGUMI" (AniList ID
200230) appears on our app's homepage and asked where Miruro gets its "when will it be released" data, since AniList already reports the show as airing.The answer: Miruro gets all of its release/airing metadata from AniList (with MyAnimeList as a secondary cross-reference). The show is not a mistake — AniList marks it with
status: RELEASINGand astartDateof 2026-07-05, which is today (the investigation ran at2026-07-05 05:20 Manila / 2026-07-04 21:20 UTC). So the first episode's air date is effectively "now."Our app's homepage shows it because our filter is
status: RELEASING(an AniList enum), not a real per-episode air-date/air-time comparison. Any title AniList flips toRELEASING— even on its premiere day, before a specific episode timeslot — will surface on our homepage.Key Findings
1. Miruro's data source is AniList (confirmed via network capture)
Scraping
https://www.miruro.tv/watch/200230/lets-go-kaikigumi?ep=1(seetools/test_miruro_kaikigumi_release_data.js) shows Miruro makes only two meaningful metadata calls, both to its own proxy (/api/secure/pipe) which wraps upstream requests. The request payloads are base64-encoded in thee=query param and decode to:Note the parameter name is literally
anilistId— Miruro keys everything off the AniList ID. The images it loads come straight from AniList's CDN (s4.anilist.co/.../bx200230-YuzdgbXSgi38.png).2. The release date comes from AniList and is TODAY
Miruro's server-rendered
<script type="application/ld+json">(SEO schema) embeds:startDate/datePublished= 2026-07-05 (premiere day).Status: Releasing / Airingand aRELEASE DATE/Schedulesection.anilist.co/anime/200230) and MAL (myanimelist.net/anime/62683) assameAs— these are its identity/metadata anchors.3. Timing context (why it "just appeared")
Miruro's
/healthendpoint returned:2026-07-04 21:20 UTC= 2026-07-05 05:20 in Manila (UTC+8). The premiere date (2026-07-05) has just begun in local time, which is exactly when AniList flips the title toRELEASING. That is why it started showing up "now."4. Why our app shows it — the filtering is coarse
Our homepage (
src/webview/bridge.ts→fetchHomeData()) builds three sections from AniList GraphQL. Two of them filter bystatus: RELEASING:Important nuance about the phrase "we filtered it to see aired episodes only":
nextAiringEpisode.airingAt,airingSchedule, orstartDateto decide "has episode N actually aired yet."RELEASING. AniList setsRELEASINGon/after the premiere day, so a show can appear on the homepage the moment its first episode's day arrives — even if the exact broadcast timeslot hasn't hit, or before a streaming source has the file up.So: the app and Miruro agree with AniList. The "aired" concept we apply is series-level ("currently releasing"), not episode-level ("episode N's timeslot has passed").
Comparison: Series-level vs Episode-level "aired"
status: RELEASING)Media.statusenumnextAiringEpisode.airingAt/airingScheduleFailure / Edge Scenarios
RELEASINGon its premiere calendar day but the first episode's stream isn't up yet on any source → user taps in and finds no playable episode.episodesendpoint may return an empty or partial list on premiere day even though the series isRELEASING.Recommended Actions (NOT implemented — investigation only)
nextAiringEpisode { episode airingAt }(already selected in the search query fields) and, where episode-level accuracy matters, filter/label titles whose first episodeairingAtis still in the future.Files Involved
src/webview/bridge.ts(fetchHomeData, ~L872–932)status: RELEASINGsrc/webview/android-bridge.tstools/test_miruro_kaikigumi_release_data.jsExternal Data Sources Confirmed
graphql.anilist.costatusfilterwww.miruro.tv/api/secure/pipe(proxy)info/{id}+episodes?anilistId={id}anilist.co/s4.anilist.costartDate, cover imagesmyanimelist.netsameAscross-referenceFollow-up Consultation: Total episodes + "lock unaired/unavailable" UI feasibility
The user asked (1) whether this anime has a complete episode count declared, and (2) whether we could show a "lock" message for seasons that are confirmed-but-unavailable or episodes that haven't aired yet (like a movies-module pattern). This is consultation only — no code changes.
A. Does KAIKIGUMI have a complete episode count? — No total, but YES a per-episode schedule
Direct AniList query (
tools/test_kaikigumi_anilist_episodes.js) for id200230returned:status:RELEASINGepisodes:null→ AniList has not declared a fixed total episode count.nextAiringEpisode: episode 2 (so ep 1 has already aired).airingSchedule.nodes: 12 episodes with exact timestamps already scheduled:Takeaway: The
episodestotal is unreliable for ongoing shows (oftennulluntil the season ends), but AniList'sairingSchedule/nextAiringEpisode.airingAtgive us reliable per-episode air timestamps. That is the correct field to drive any "not aired yet" lock — not theepisodescount.B. The lock pattern ALREADY EXISTS — in the Movies & TV (SD10) module
Correction to an earlier draft of this document: the lock/countdown UI the user showed (SILO — "Season 3 / 3", "Episode 10 / 10 🔒 60d") is a real, shipping feature in this app. It lives in the legacy runtime JS modules under
app/src/main/assets/view/modules/, NOT in the TypeScriptsrc/tree (which is a separate/WIP migration). An earlier search only looked atsrc/and wrongly concluded no lock existed.PLAN_FMOVIES_INTEGRATION.md). Its metadata (seasons, episodes, air dates) comes from TMDB, not the FMovies site.app/src/main/assets/view/modules/21-tmdb.js:_getEpAirStatus()— reads TMDB per-episodeair_date, compares to today, computesdaysUntilviaMath.ceil(diffMs / 86400000). If noair_date, it assumes aired (does not block)._formatAirLabel(status)— turnsdaysUntilinto a short label:''(aired),Today,1d,<7 → Nd, elseNw/Nd, orTBAwhendaysUntilis null._setEp()— rendersEpisode X / Yplus<em class="mvplay_ep_air">🔒 <label></em>(the\u{1F512}lock glyph) and adds theunairedCSS class._setSeason()— shows🔒 TBAand anunairedseason class when a confirmed season has no episodes yet (e.g. announced-but-unreleased season).menu_action(episode select) — blocks playback when_getEpAirStatus().aired === false.fetchSeasonEpisodes()— pulls/tv/{id}/season/{n}from TMDB and cachesair_dateper episode.21-movies-source.jsreadsnumber_of_seasons/seasons_datafrom TMDB, and21-tmdb.jshas a full season picker.So there IS a proven pattern to mirror — but it is TMDB-based and lives in the movies module.
C. Applying the same pattern to ANIME (Miruro/AniList)
The anime side is a different source (SD8 Miruro) with its own module
04-miruro.js, and per the project's source-isolation rule, anime logic must stay independent from the movies/TMDB module. So this would be a port of the idea, not code reuse.C1. "Episode not aired yet" lock for anime (feasible):
airingSchedule[].airingAt(confirmed for KAIKIGUMI: 12 episodes with exact timestamps) andnextAiringEpisode.airingAt. This is the anime equivalent of TMDB'sair_date.nextAiringEpisode { episode }in04-miruro.js/04c-anikoto.jsand computessumep = nextAiringEpisode.episode - 1(episodes-so-far). So the app already partially reasons about "how many have aired." Extending this to a per-episode lock is a natural next step.21-tmdb.jsshape inside the anime flow — computedaysUntilfromairingAt(seconds → ms), reuse the same🔒 <label>+unairedpresentation and the play-block guard.airingSchedule(movies, older completed series) must gracefully skip locking (mirror TMDB's "no air_date → assume aired"); timezone display; Miruro sometimes lists an episode slightly before/after its AniListairingAt.C2. "Season confirmed but not available" lock for anime (weaker fit):
number_of_seasons,seasons_data). AniList instead models anime sequels as separateMediaentries (relations), not seasons of one entry — there is no native "Season 2 (empty)" object to lock like TMDB provides.relationsfor aSEQUELwithstatus: NOT_YET_RELEASEDand presenting it as a locked season — more custom work and less reliable than the TMDB path.D. Recommendation summary (for decision — not implemented)
21-tmdb.jslock/countdown/unaired/play-block pattern is the blueprint. Per source-isolation rules, implement an independent anime version in the anime module rather than sharing code with the movies module.airingSchedule[].airingAt/nextAiringEpisode.airingAt(AniList) as the anime air-time source — the analog of TMDBair_date. Ignore theepisodestotal for lock logic — it isnullfor ongoing shows (confirmed for KAIKIGUMI) and misleading.Related References
8b6329e8bdbb27b8471530f1b4e4381144808d3chttps://www.miruro.tv/watch/200230/lets-go-kaikigumi?ep=1tools/test_miruro_kaikigumi_release_data.js,tools/test_kaikigumi_anilist_episodes.jsapp/src/main/assets/view/modules/21-tmdb.js(_getEpAirStatus,_formatAirLabel,_setEp,_setSeason),app/src/main/assets/view/modules/21-movies-source.js(getSeasonEpisodes,seasons_data)app/src/main/assets/view/modules/04-miruro.js(already queriesnextAiringEpisode)app/src/main/assets/view/modules/; the TypeScriptsrc/tree is a separate/WIP migration and does not currently contain the lock feature.