Anime released but no episodes aired yet confuses users. #3

Open
opened 2026-07-04 22:03:44 +00:00 by k-nacion · 0 comments
Owner

image

Investigation: "Let's go KAIKIGUMI" showing on homepage before episodes are truly available

  • Date: 2026-07-05
  • Reporter: User
  • Versions involved: Current SPA homepage (src/webview/bridge.ts), Miruro 1.12.0
  • Status: Confirmed (behavior explained — no bug in miruro; app-side filtering caveat identified)
  • Severity: Low (expected upstream behavior; app filtering is coarse)
  • Type: Data-source investigation (READ ONLY — no code changes)

Summary

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: RELEASING and a startDate of 2026-07-05, which is today (the investigation ran at 2026-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 to RELEASING — 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 (see tools/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 the e= query param and decode to:

// #42 — anime info
{"path":"info/200230","method":"GET","query":{},"body":null,"version":"0.2.0"}

// #43 / #47 / #48 — episode list
{"path":"episodes","method":"GET","query":{"anilistId":"200230"},"body":null,"version":"0.2.0"}

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:

{
  "@type": "TVSeries",
  "startDate": "2026-07-05",
  "datePublished": "2026-07-05",
  "name": "Let's go KAIKIGUMI",
  "sameAs": [
    "https://anilist.co/anime/200230",
    "https://myanimelist.net/anime/62683",
    ...
  ]
}
  • startDate / datePublished = 2026-07-05 (premiere day).
  • The visible page DOM shows Status: Releasing / Airing and a RELEASE DATE / Schedule section.
  • Miruro cross-links to AniList (anilist.co/anime/200230) and MAL (myanimelist.net/anime/62683) as sameAs — these are its identity/metadata anchors.

3. Timing context (why it "just appeared")

Miruro's /health endpoint returned:

{"status":"ok","timestamp":"2026-07-04T21:20:03.904Z","version":"1.12.0"}

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 to RELEASING. 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 by status: RELEASING:

# "Trending Now"
media(sort: TRENDING_DESC, isAdult: false, type: ANIME, status: RELEASING) { ... }

# "Recently Updated"
media(sort: UPDATED_AT_DESC, isAdult: false, type: ANIME, status: RELEASING) { ... }

Important nuance about the phrase "we filtered it to see aired episodes only":

  • We do NOT compare a specific episode's air date/time. There is no logic using nextAiringEpisode.airingAt, airingSchedule, or startDate to decide "has episode N actually aired yet."
  • We simply ask AniList for titles whose series status is RELEASING. AniList sets RELEASING on/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"

Aspect What our app does (status: RELEASING) True episode-level "aired"
Data field AniList Media.status enum AniList nextAiringEpisode.airingAt / airingSchedule
Granularity Whole series ("is it currently airing?") Specific episode timeslot
KAIKIGUMI result Shows on premiere day (2026-07-05) Would only show ep 1 after its exact airing timestamp
False positives Premiere-day / between-episode titles appear Fewer; matches actual broadcast

Failure / Edge Scenarios

  • A title flips to RELEASING on 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.
  • Timezone skew: AniList premiere day vs the user's local day vs the broadcaster's timezone can make a title appear up to ~24h "early" relative to a specific region's expectations.
  • Miruro's episodes endpoint may return an empty or partial list on premiere day even though the series is RELEASING.

  • Immediate: None required. This is expected upstream behavior; nothing is broken in Miruro or AniList.
  • Short-term (if we want stricter "aired" semantics): Consider querying nextAiringEpisode { episode airingAt } (already selected in the search query fields) and, where episode-level accuracy matters, filter/label titles whose first episode airingAt is still in the future.
  • Long-term: Decide product intent — "currently-airing series" (current behavior, coarse) vs "episodes that have actually aired" (episode-level). Document the chosen definition so homepage sections are unambiguous.

Files Involved

File Role
src/webview/bridge.ts (fetchHomeData, ~L872–932) Builds homepage sections using AniList status: RELEASING
src/webview/android-bridge.ts Near-identical Android homepage/AniList query logic
tools/test_miruro_kaikigumi_release_data.js Puppeteer scrape used for this investigation

External Data Sources Confirmed

Source Used by Purpose
graphql.anilist.co Our app Homepage titles + status filter
www.miruro.tv/api/secure/pipe (proxy) Miruro Wraps info/{id} + episodes?anilistId={id}
anilist.co / s4.anilist.co Miruro Metadata identity, startDate, cover images
myanimelist.net Miruro Secondary sameAs cross-reference

Follow-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 id 200230 returned:

  • status: RELEASING
  • episodes: 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:
Ep Airs at (UTC)
1 2026-07-04 19:30 (already aired)
2 2026-07-11 19:30
3 2026-07-18 19:30
… weekly …
12 2026-09-19 19:30

Takeaway: The episodes total is unreliable for ongoing shows (often null until the season ends), but AniList's airingSchedule / nextAiringEpisode.airingAt give us reliable per-episode air timestamps. That is the correct field to drive any "not aired yet" lock — not the episodes count.

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 TypeScript src/ tree (which is a separate/WIP migration). An earlier search only looked at src/ and wrongly concluded no lock existed.

  • SD10 = FMovies / Movies & TV source (see PLAN_FMOVIES_INTEGRATION.md). Its metadata (seasons, episodes, air dates) comes from TMDB, not the FMovies site.
  • The lock UI is implemented in app/src/main/assets/view/modules/21-tmdb.js:
    • _getEpAirStatus() — reads TMDB per-episode air_date, compares to today, computes daysUntil via Math.ceil(diffMs / 86400000). If no air_date, it assumes aired (does not block).
    • _formatAirLabel(status) — turns daysUntil into a short label: '' (aired), Today, 1d, <7 → Nd, else Nw/Nd, or TBA when daysUntil is null.
    • _setEp() — renders Episode X / Y plus <em class="mvplay_ep_air">🔒 <label></em> (the \u{1F512} lock glyph) and adds the unaired CSS class.
    • _setSeason() — shows 🔒 TBA and an unaired season 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 caches air_date per episode.
  • Season awareness exists here too: 21-movies-source.js reads number_of_seasons / seasons_data from TMDB, and 21-tmdb.js has 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):

  • Data is available. AniList already exposes per-episode air times via airingSchedule[].airingAt (confirmed for KAIKIGUMI: 12 episodes with exact timestamps) and nextAiringEpisode.airingAt. This is the anime equivalent of TMDB's air_date.
  • Existing hooks. The anime pipeline already queries nextAiringEpisode { episode } in 04-miruro.js / 04c-anikoto.js and computes sumep = 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.
  • Mapping to the movies pattern: replicate the 21-tmdb.js shape inside the anime flow — compute daysUntil from airingAt (seconds → ms), reuse the same 🔒 <label> + unaired presentation and the play-block guard.
  • Caveat / mismatch: the anime episode list comes from Miruro (source), while air times come from AniList (metadata) — so they must be merged by episode number, exactly like the movies module merges TMDB season data onto the FMovies stream source.
  • Edge cases: shows with no 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 AniList airingAt.

C2. "Season confirmed but not available" lock for anime (weaker fit):

  • The movies module gets clean season structure from TMDB (number_of_seasons, seasons_data). AniList instead models anime sequels as separate Media entries (relations), not seasons of one entry — there is no native "Season 2 (empty)" object to lock like TMDB provides.
  • Doing the anime equivalent would mean querying AniList relations for a SEQUEL with status: NOT_YET_RELEASED and presenting it as a locked season — more custom work and less reliable than the TMDB path.
  • Recommendation: do C1 (per-episode lock) first; treat C2 as a separate, larger effort.

D. Recommendation summary (for decision — not implemented)

  1. Reuse the concept, not the code. The 21-tmdb.js lock/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.
  2. Use airingSchedule[].airingAt / nextAiringEpisode.airingAt (AniList) as the anime air-time source — the analog of TMDB air_date. Ignore the episodes total for lock logic — it is null for ongoing shows (confirmed for KAIKIGUMI) and misleading.
  3. Merge by episode number: episode existence = Miruro (source); episode air time = AniList (metadata) — same shape as the movies module merging TMDB onto FMovies.
  4. Gracefully skip locking when no airing schedule exists (movies-format anime, completed classics), mirroring TMDB's "no air_date → assume aired."
  5. Defer C2 (season locks) for anime — AniList relations make it harder and less reliable than the TMDB season model.

  • Latest commit at time of investigation: 8b6329e8bdbb27b8471530f1b4e4381144808d3c
  • Target URL: https://www.miruro.tv/watch/200230/lets-go-kaikigumi?ep=1
  • Consultation scripts: tools/test_miruro_kaikigumi_release_data.js, tools/test_kaikigumi_anilist_episodes.js
  • Existing lock/countdown reference implementation (movies/TMDB): app/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)
  • Anime module where an equivalent lock would live: app/src/main/assets/view/modules/04-miruro.js (already queries nextAiringEpisode)
  • Note: the active runtime app uses the legacy JS modules under app/src/main/assets/view/modules/; the TypeScript src/ tree is a separate/WIP migration and does not currently contain the lock feature.
![image](/attachments/a9f9c5ec-7a1a-4664-98c8-e86015328d09) # Investigation: "Let's go KAIKIGUMI" showing on homepage before episodes are truly available - **Date:** 2026-07-05 - **Reporter:** User - **Versions involved:** Current SPA homepage (`src/webview/bridge.ts`), Miruro `1.12.0` - **Status:** Confirmed (behavior explained — no bug in miruro; app-side filtering caveat identified) - **Severity:** Low (expected upstream behavior; app filtering is coarse) - **Type:** Data-source investigation (READ ONLY — no code changes) --- ## Summary 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: RELEASING` and a `startDate` of **2026-07-05**, which is *today* (the investigation ran at `2026-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 to `RELEASING` — 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` (see `tools/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 the `e=` query param and decode to: ```json // #42 — anime info {"path":"info/200230","method":"GET","query":{},"body":null,"version":"0.2.0"} // #43 / #47 / #48 — episode list {"path":"episodes","method":"GET","query":{"anilistId":"200230"},"body":null,"version":"0.2.0"} ``` 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: ```json { "@type": "TVSeries", "startDate": "2026-07-05", "datePublished": "2026-07-05", "name": "Let's go KAIKIGUMI", "sameAs": [ "https://anilist.co/anime/200230", "https://myanimelist.net/anime/62683", ... ] } ``` - `startDate` / `datePublished` = **2026-07-05** (premiere day). - The visible page DOM shows **`Status: Releasing / Airing`** and a **`RELEASE DATE`** / **`Schedule`** section. - Miruro cross-links to AniList (`anilist.co/anime/200230`) and MAL (`myanimelist.net/anime/62683`) as `sameAs` — these are its identity/metadata anchors. ### 3. Timing context (why it "just appeared") Miruro's `/health` endpoint returned: ```json {"status":"ok","timestamp":"2026-07-04T21:20:03.904Z","version":"1.12.0"} ``` `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 to `RELEASING`. 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 by **`status: RELEASING`**: ```graphql # "Trending Now" media(sort: TRENDING_DESC, isAdult: false, type: ANIME, status: RELEASING) { ... } # "Recently Updated" media(sort: UPDATED_AT_DESC, isAdult: false, type: ANIME, status: RELEASING) { ... } ``` Important nuance about the phrase *"we filtered it to see aired episodes only"*: - We do **NOT** compare a specific episode's air date/time. There is **no** logic using `nextAiringEpisode.airingAt`, `airingSchedule`, or `startDate` to decide "has episode N actually aired yet." - We simply ask AniList for titles whose **series status** is `RELEASING`. AniList sets `RELEASING` on/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" | Aspect | What our app does (`status: RELEASING`) | True episode-level "aired" | |---|---|---| | Data field | AniList `Media.status` enum | AniList `nextAiringEpisode.airingAt` / `airingSchedule` | | Granularity | Whole series ("is it currently airing?") | Specific episode timeslot | | KAIKIGUMI result | Shows on premiere day (2026-07-05) | Would only show ep 1 after its exact airing timestamp | | False positives | Premiere-day / between-episode titles appear | Fewer; matches actual broadcast | --- ## Failure / Edge Scenarios - A title flips to `RELEASING` on 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. - Timezone skew: AniList premiere day vs the user's local day vs the broadcaster's timezone can make a title appear up to ~24h "early" relative to a specific region's expectations. - Miruro's `episodes` endpoint may return an empty or partial list on premiere day even though the series is `RELEASING`. --- ## Recommended Actions (NOT implemented — investigation only) - **Immediate:** None required. This is expected upstream behavior; nothing is broken in Miruro or AniList. - **Short-term (if we want stricter "aired" semantics):** Consider querying `nextAiringEpisode { episode airingAt }` (already selected in the search query fields) and, where episode-level accuracy matters, filter/label titles whose first episode `airingAt` is still in the future. - **Long-term:** Decide product intent — "currently-airing series" (current behavior, coarse) vs "episodes that have actually aired" (episode-level). Document the chosen definition so homepage sections are unambiguous. --- ## Files Involved | File | Role | |---|---| | `src/webview/bridge.ts` (`fetchHomeData`, ~L872–932) | Builds homepage sections using AniList `status: RELEASING` | | `src/webview/android-bridge.ts` | Near-identical Android homepage/AniList query logic | | `tools/test_miruro_kaikigumi_release_data.js` | Puppeteer scrape used for this investigation | ## External Data Sources Confirmed | Source | Used by | Purpose | |---|---|---| | `graphql.anilist.co` | Our app | Homepage titles + `status` filter | | `www.miruro.tv/api/secure/pipe` (proxy) | Miruro | Wraps `info/{id}` + `episodes?anilistId={id}` | | `anilist.co` / `s4.anilist.co` | Miruro | Metadata identity, `startDate`, cover images | | `myanimelist.net` | Miruro | Secondary `sameAs` cross-reference | ## Follow-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 id `200230` returned: - `status`: `RELEASING` - `episodes`: **`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: | Ep | Airs at (UTC) | |----|----------------| | 1 | 2026-07-04 19:30 (already aired) | | 2 | 2026-07-11 19:30 | | 3 | 2026-07-18 19:30 | | … | weekly … | | 12 | 2026-09-19 19:30 | **Takeaway:** The `episodes` total is unreliable for ongoing shows (often `null` until the season ends), but AniList's **`airingSchedule` / `nextAiringEpisode.airingAt` give us reliable per-episode air timestamps**. That is the correct field to drive any "not aired yet" lock — not the `episodes` count. ### 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 TypeScript `src/` tree (which is a separate/WIP migration). An earlier search only looked at `src/` and wrongly concluded no lock existed. - **SD10 = FMovies / Movies & TV** source (see `PLAN_FMOVIES_INTEGRATION.md`). Its metadata (seasons, episodes, air dates) comes from **TMDB**, not the FMovies site. - The lock UI is implemented in **`app/src/main/assets/view/modules/21-tmdb.js`**: - `_getEpAirStatus()` — reads TMDB per-episode `air_date`, compares to today, computes `daysUntil` via `Math.ceil(diffMs / 86400000)`. If no `air_date`, it assumes aired (does not block). - `_formatAirLabel(status)` — turns `daysUntil` into a short label: `''` (aired), `Today`, `1d`, `<7 → Nd`, else `Nw`/`Nd`, or `TBA` when `daysUntil` is null. - `_setEp()` — renders `Episode X / Y` plus `<em class="mvplay_ep_air">🔒 <label></em>` (the `\u{1F512}` lock glyph) and adds the `unaired` CSS class. - `_setSeason()` — shows `🔒 TBA` and an `unaired` season 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 caches `air_date` per episode. - Season awareness exists here too: `21-movies-source.js` reads `number_of_seasons` / `seasons_data` from TMDB, and `21-tmdb.js` has 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):** - **Data is available.** AniList already exposes per-episode air times via `airingSchedule[].airingAt` (confirmed for KAIKIGUMI: 12 episodes with exact timestamps) and `nextAiringEpisode.airingAt`. This is the anime equivalent of TMDB's `air_date`. - **Existing hooks.** The anime pipeline already queries `nextAiringEpisode { episode }` in `04-miruro.js` / `04c-anikoto.js` and computes `sumep = 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. - **Mapping to the movies pattern:** replicate the `21-tmdb.js` shape inside the anime flow — compute `daysUntil` from `airingAt` (seconds → ms), reuse the same `🔒 <label>` + `unaired` presentation and the play-block guard. - **Caveat / mismatch:** the anime **episode list comes from Miruro (source)**, while **air times come from AniList (metadata)** — so they must be merged by episode number, exactly like the movies module merges TMDB season data onto the FMovies stream source. - **Edge cases:** shows with no `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 AniList `airingAt`. **C2. "Season confirmed but not available" lock for anime (weaker fit):** - The movies module gets clean season structure from TMDB (`number_of_seasons`, `seasons_data`). AniList instead models anime sequels as **separate `Media` entries (relations)**, not seasons of one entry — there is no native "Season 2 (empty)" object to lock like TMDB provides. - Doing the anime equivalent would mean querying AniList `relations` for a `SEQUEL` with `status: NOT_YET_RELEASED` and presenting it as a locked season — more custom work and less reliable than the TMDB path. - Recommendation: do C1 (per-episode lock) first; treat C2 as a separate, larger effort. ### D. Recommendation summary (for decision — not implemented) 1. **Reuse the concept, not the code.** The `21-tmdb.js` lock/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. 2. **Use `airingSchedule[].airingAt` / `nextAiringEpisode.airingAt`** (AniList) as the anime air-time source — the analog of TMDB `air_date`. **Ignore the `episodes` total** for lock logic — it is `null` for ongoing shows (confirmed for KAIKIGUMI) and misleading. 3. **Merge by episode number:** episode existence = Miruro (source); episode air time = AniList (metadata) — same shape as the movies module merging TMDB onto FMovies. 4. **Gracefully skip locking** when no airing schedule exists (movies-format anime, completed classics), mirroring TMDB's "no air_date → assume aired." 5. **Defer C2** (season locks) for anime — AniList relations make it harder and less reliable than the TMDB season model. --- ## Related References - Latest commit at time of investigation: `8b6329e8bdbb27b8471530f1b4e4381144808d3c` - Target URL: `https://www.miruro.tv/watch/200230/lets-go-kaikigumi?ep=1` - Consultation scripts: `tools/test_miruro_kaikigumi_release_data.js`, `tools/test_kaikigumi_anilist_episodes.js` - Existing lock/countdown reference implementation (movies/TMDB): `app/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`) - Anime module where an equivalent lock would live: `app/src/main/assets/view/modules/04-miruro.js` (already queries `nextAiringEpisode`) - **Note:** the active runtime app uses the legacy JS modules under `app/src/main/assets/view/modules/`; the TypeScript `src/` tree is a separate/WIP migration and does not currently contain the lock feature.
973 KiB
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Anime-TV-Fork/AnimeTV#3
No description provided.