mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 06:06:18 -08:00
* fix(portals): drop provider placeholder metadata at the mapping layer Stalker and Xtream portals send "N/A", "-" or an unrated "0" score for fields they have nothing for, and the detail templates rendered them as data. Normalize them where provider rows are mapped: createStalkerInfo, the shared VOD view-model adapters and the Xtream detail selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(portals): hide placeholder ratings on catalog cards formatGridRating passed a provider "N/A" through as the badge text and rendered an unrated zero as "0.0". Read the value through the shared readProviderRating so both hide the badge and resolveGridRating reaches the generic rating behind a placeholder rating_imdb. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(xtream): keep placeholder ratings off the sparse VOD fallback page A get_vod_info made only of placeholders is now stripped to sparse and routed to the fallback page, which read the top-level catalog ratings raw: "N/A" survived and a zero became "0.0". Read every candidate through readProviderRating so the next usable rating wins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
60 lines
2.2 KiB
TypeScript
60 lines
2.2 KiB
TypeScript
/**
|
|
* Readers for provider detail metadata (`get_vod_info`, Stalker VOD rows).
|
|
*
|
|
* Portals fill a field they have nothing for with a stand-in instead of
|
|
* leaving it empty — `"N/A"` (in any case) or a lone `"-"` — and a detail
|
|
* template that renders any truthy value then shows the stand-in as if it
|
|
* were data: a `⭐ N/A` chip, an "N/A" director, an "N/A" plot. The detail
|
|
* shell's contract is that missing data simply is not rendered, so these
|
|
* readers turn every stand-in into "absent" where provider rows are MAPPED,
|
|
* and templates keep plain truthiness guards instead of each learning the
|
|
* list.
|
|
*
|
|
* Keep the list to stand-ins providers were actually seen sending: every
|
|
* entry also erases a genuine value that happens to read the same.
|
|
*/
|
|
const PROVIDER_PLACEHOLDERS: ReadonlySet<string> = new Set(['n/a', '-']);
|
|
|
|
/**
|
|
* Trimmed provider text, or `undefined` when it is blank or a placeholder.
|
|
* Finite numbers are read as their text form; anything else is absent.
|
|
*/
|
|
export function readProviderText(value: unknown): string | undefined {
|
|
const text =
|
|
typeof value === 'string'
|
|
? value.trim()
|
|
: typeof value === 'number' && Number.isFinite(value)
|
|
? String(value)
|
|
: '';
|
|
return text && !PROVIDER_PLACEHOLDERS.has(text.toLowerCase())
|
|
? text
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* The first candidate that carries real text. `a ?? b` would stop at a
|
|
* placeholder (or a blank) and never reach the usable fallback behind it.
|
|
*/
|
|
export function firstProviderText(...values: unknown[]): string | undefined {
|
|
for (const value of values) {
|
|
const text = readProviderText(value);
|
|
if (text !== undefined) {
|
|
return text;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* {@link readProviderText} for an IMDb / Kinopoisk score, where zero is a
|
|
* placeholder too: both scales start at 1, so a `"0"` / `"0.0"` is the
|
|
* panel's way of saying "unrated" (TMDB's `vote_average` of 0 is read the
|
|
* same way by the enrichment merge).
|
|
*/
|
|
export function readProviderRating(value: unknown): string | undefined {
|
|
const text = readProviderText(value);
|
|
return text !== undefined && Number(text.replace(',', '.')) === 0
|
|
? undefined
|
|
: text;
|
|
}
|