mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 13:46:16 -08:00
fix(portals): read the year with one rule everywhere
The shared detail path fed the chip `meta.year`, which the adapter built with a fixed-prefix fallback: a day-first `31-03-1999` became `31-0`, so that path both displayed the wrong label and lost the facet, since the guard could not parse it back. `parseFacetYear()` moves to shared/interfaces and both callers delegate to it, so the adapters and the Discover chips cannot drift into disagreeing about what a date says. The adapter keeps its date-parse fallback for shapes stating no four-digit run, but no longer invents one by slicing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5534e51c8d
commit
ec55e4910e
4 files changed
+105
-25
No files matched your search
@@ -131,6 +131,23 @@ export function isTmdbYearFacet(year: number): boolean {
|
||||
return Number.isInteger(year) && year >= 1000 && year <= 9999;
|
||||
}
|
||||
|
||||
/**
|
||||
* The year stated by a provider date field, whatever shape it arrives in
|
||||
* — `1976`, `1999-03-31` and `31-03-1999` all resolve to the same year.
|
||||
*
|
||||
* Reads the first four-digit run rather than a fixed prefix: slicing
|
||||
* turns a day-first date into `31-0`, which is both the wrong label and
|
||||
* an unusable filter. Lives here so the Discover chips and the detail
|
||||
* adapters cannot drift into disagreeing about what a date says.
|
||||
*/
|
||||
export function parseFacetYear(
|
||||
releaseDate: string | null | undefined
|
||||
): number | null {
|
||||
const match = releaseDate?.match(/\d{4}/);
|
||||
const year = match ? Number(match[0]) : null;
|
||||
return year !== null && isTmdbYearFacet(year) ? year : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* One cached TMDB lookup. Two kinds of rows share the table, discriminated
|
||||
* by the `lookupKey` prefix:
|
||||
|
||||
@@ -1,4 +1,75 @@
|
||||
import { youtubeEmbedUrl } from './vod-details-adapters';
|
||||
import {
|
||||
normalizeStalkerVod,
|
||||
normalizeXtreamVod,
|
||||
youtubeEmbedUrl,
|
||||
} from './vod-details-adapters';
|
||||
|
||||
describe('normalized release year', () => {
|
||||
const stalker = (releasedate: string) =>
|
||||
normalizeStalkerVod({
|
||||
id: '1',
|
||||
cmd: '',
|
||||
info: {
|
||||
movie_image: '',
|
||||
description: '',
|
||||
name: 'Film',
|
||||
actors: '',
|
||||
director: '',
|
||||
releasedate,
|
||||
genre: '',
|
||||
rating_imdb: '',
|
||||
rating_kinopoisk: '',
|
||||
},
|
||||
}).year;
|
||||
|
||||
it('reads the year out of a day-first provider date', () => {
|
||||
// A fixed prefix renders '31-0' here, which is both the wrong
|
||||
// label and a year the Discover chip cannot filter by
|
||||
expect(stalker('31-03-1999')).toBe('1999');
|
||||
});
|
||||
|
||||
it('keeps reading ordinary date shapes', () => {
|
||||
expect(stalker('1976')).toBe('1976');
|
||||
expect(stalker('1999-03-31')).toBe('1999');
|
||||
expect(
|
||||
normalizeXtreamVod({
|
||||
info: {
|
||||
kinopoisk_url: '',
|
||||
tmdb_id: 0,
|
||||
name: 'Film',
|
||||
o_name: '',
|
||||
cover_big: '',
|
||||
movie_image: '',
|
||||
releasedate: '2018-05-01',
|
||||
episode_run_time: 0,
|
||||
youtube_trailer: '',
|
||||
director: '',
|
||||
actors: '',
|
||||
cast: '',
|
||||
description: '',
|
||||
plot: '',
|
||||
age: '',
|
||||
mpaa_rating: '',
|
||||
rating_count_kinopoisk: 0,
|
||||
country: '',
|
||||
genre: '',
|
||||
backdrop_path: [],
|
||||
duration_secs: 0,
|
||||
duration: '',
|
||||
video: [],
|
||||
audio: [],
|
||||
bitrate: 0,
|
||||
rating: 0,
|
||||
},
|
||||
}).year
|
||||
).toBe('2018');
|
||||
});
|
||||
|
||||
it('states no year for a placeholder or unusable date', () => {
|
||||
expect(stalker('0000-00-00')).toBeUndefined();
|
||||
expect(stalker('')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('youtubeEmbedUrl', () => {
|
||||
it('builds an embed URL from a plain video id (TMDB format)', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { XtreamVodDetails, getXtreamVodInfo } from './xtream-vod-details.interface';
|
||||
import { StalkerVodDetails } from './stalker-vod-details.interface';
|
||||
import { parseFacetYear } from './tmdb.interface';
|
||||
import {
|
||||
NormalizedVodMeta,
|
||||
VodDetailsItem,
|
||||
@@ -170,24 +171,28 @@ export function getVodNumericId(item: VodDetailsItem): number {
|
||||
// ============ Helper Functions ============
|
||||
|
||||
/**
|
||||
* Extracts 4-digit year from various date formats.
|
||||
* Extracts the 4-digit year from the various date formats providers send.
|
||||
*
|
||||
* Delegates to the shared facet parser so the displayed year and the
|
||||
* Discover chip built from it cannot disagree — the old fixed-prefix
|
||||
* fallback turned a day-first `31-03-1999` into `31-0`, which is both
|
||||
* the wrong label and an unusable filter. The date-parse fallback stays
|
||||
* for shapes stating no four-digit run of their own.
|
||||
*/
|
||||
function extractYear(dateString?: string): string | undefined {
|
||||
if (!dateString) return undefined;
|
||||
|
||||
// Try to extract 4-digit year from beginning
|
||||
const yearMatch = dateString.match(/^(\d{4})/);
|
||||
if (yearMatch) {
|
||||
return yearMatch[1];
|
||||
const facetYear = parseFacetYear(dateString);
|
||||
if (facetYear !== null) {
|
||||
return String(facetYear);
|
||||
}
|
||||
|
||||
// Try to parse as date and extract year
|
||||
const date = new Date(dateString);
|
||||
if (!isNaN(date.getTime())) {
|
||||
return date.getFullYear().toString();
|
||||
}
|
||||
|
||||
return dateString.slice(0, 4);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user