formatters, device profile, media matching, subtitle utils, syncplay, trakt
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { getTmdbImageUrl } from '../api/tmdb'
|
||||
import type { BaseItemDto } from '../api/types'
|
||||
|
||||
/**
|
||||
* 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: any[],
|
||||
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 any 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
|
||||
}
|
||||
Reference in New Issue
Block a user