63 lines
2.5 KiB
TypeScript
63 lines
2.5 KiB
TypeScript
import { getTmdbImageUrl } from '../api/tmdb'
|
|
import type { BaseItemDto } from '../api/types'
|
|
import type { TmdbDiscoverItem } from '../api/tmdb'
|
|
|
|
/**
|
|
* Convert a TMDB result row (movie / tv / multi) into a synthetic
|
|
* BaseItemDto so it can render through the same PosterCard pipeline as
|
|
* Jellyfin items. When a `libraryMap` (TMDB id -> Jellyfin item) is
|
|
* provided, items already in the user's library are flagged via
|
|
* `_inLibrary` and their `Id` is rewritten to the local Jellyfin id so
|
|
* clicking opens the existing detail page instead of the synthetic one.
|
|
*/
|
|
export function mapTmdbToJf(
|
|
items: TmdbDiscoverItem[],
|
|
libraryMap?: Map<string, { id: string; name: string; type: string }>,
|
|
): BaseItemDto[] {
|
|
return items.map(m => {
|
|
const local = libraryMap?.get(String(m.id))
|
|
const isSeries = m.media_type === 'tv' || !!m.first_air_date
|
|
// Encode kind in the synthetic id so DetailPage can route directly
|
|
// to the right TMDB endpoint without guessing. Library matches keep
|
|
// the Jellyfin id as before.
|
|
const syntheticId = `tmdb-${isSeries ? 'tv' : 'movie'}-${m.id}`
|
|
return {
|
|
Id: local?.id || syntheticId,
|
|
Name: m.title || m.name,
|
|
Type: isSeries ? 'Series' : 'Movie',
|
|
ProductionYear: m.release_date
|
|
? parseInt(m.release_date)
|
|
: m.first_air_date
|
|
? parseInt(m.first_air_date)
|
|
: undefined,
|
|
Overview: m.overview,
|
|
ImageTags: {},
|
|
ProviderIds: { Tmdb: String(m.id) },
|
|
CommunityRating: typeof m.vote_average === 'number' ? m.vote_average : undefined,
|
|
_tmdbPoster: m.poster_path ? getTmdbImageUrl(m.poster_path, 'w342') : undefined,
|
|
_tmdbBackdrop: m.backdrop_path ? getTmdbImageUrl(m.backdrop_path, 'w780') : undefined,
|
|
_inLibrary: !!local,
|
|
_tmdbId: String(m.id),
|
|
} as unknown as BaseItemDto
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Detect whether a route id is a synthetic TMDB id (from the discovery
|
|
* rows) and parse out kind + numeric id when so. Returns null for
|
|
* regular Jellyfin ids.
|
|
*/
|
|
export function parseTmdbRouteId(id: string | undefined | null): { kind: 'movie' | 'tv'; tmdbId: number } | null {
|
|
if (!id) return null
|
|
// New format: tmdb-movie-123 / tmdb-tv-123
|
|
const match = id.match(/^tmdb-(movie|tv)-(\d+)$/)
|
|
if (match) {
|
|
return { kind: match[1] as 'movie' | 'tv', tmdbId: Number(match[2]) }
|
|
}
|
|
// Legacy format: tmdb-123 (kind unknown - default to movie). Persists
|
|
// until any saved data with the old id refreshes.
|
|
const legacy = id.match(/^tmdb-(\d+)$/)
|
|
if (legacy) return { kind: 'movie', tmdbId: Number(legacy[1]) }
|
|
return null
|
|
}
|