Files
requestarr/src/components/TvDetails/Season/index.tsx
THOMAS B 22b2824441 feat: add tvdb indexer (#899)
* feat(tvdb): get tv seasons/episodes with tvdb

* fix: fix rate limiter index tvdb indexer

* fix(usersettings): remove unused column tvdbtoken

* refactor(tvdb): replace tvdb api by skyhook

* fix: error during get episodes

* fix: error if tmdb poster is null

* refactor: clean tvdb indexer code

* fix: wrong language with tmdb indexer

* style: replace avalaible to available

* style: tvdb.login to tvdb.test

* fix(test): fix  discover test

* fix(test): wrong url tv-details

* test(tvdb): add tvdb tests

* style(tvdb): rename pokemon to correct tv show

* refactor(indexer): remove unused getSeasonIdentifier method

* refactor(settings): replace tvdb object to boolean type

* refactor(tmdb): reduce still path condition

* test(tvdb): change 'use' to 'tvdb' condition check

* fix(tmdb): fix build

fix build after rebase

* fix(build): revert package.json

* fix(tvdb): ensure that seasons contain data

* refactor(swagger): fix /tvdb/test response

* fix(scanner): add tvdb indexer for scanner

* refactor(tvdb): remove skyhook api

* refactor(tvdb): use tvdb api

* fix(tvdb): rename tvdb to medatada

* refactor(medata): add tvdb settings

* refactor(metadata): rewrite metadata settings

* refactor(metadata): refactor metadata routes

* refactor(metadata): remove french comments

* refactor(metadata): refactor tvdb api calls

* style(prettier): run prettier

* fix(scanner): fix jellyfin scanner with tvdb provider

* fix(scanner): fix plex scanner tvdb provider

* style(provider): change provider name in info section

* style(provider): full provider name in select

* style(provider): remove french comment

* fix(tests): fix all cypress tests

* refactor(tvdb): fix apikey

* refactor(tmdb): apply prettier

* refactor(tvdb): remove logger info

* feat(metadata): replace fetch with axios for API calls

* feat(provider): replace indexer by provider

* fix(tests): fix cypress test

* chore: add project-wide apikey for tvdb

* chore: add correct application-wide key

* fix(test): fix test with default provider tmdb anime

* style(cypress): fix anime name variable

* chore(i18n): remove french translation + apply i18n:extract

* style(wording): standardize naming to "Metadata Provider" in UI text

* docs(comments): translate from French to English

* refactor(tvdb): remove unnecessary try/catch block

* feat(i18n): add missing translations

* fix(scanner): correct metadata provider ID from Tmdb to Tvdb

* style(settings): clarify navigation label from "Metadata" to "Metadata Providers"

* style(logs): update error log label from "Metadata" to "MetadataProvider"

* refactor(tvdb): replace indexer by metadata providers

* refactor(settings): remove metadata providers logo

* fix(config): restore missing config/db/.gitkeep file

---------

Co-authored-by: TOomaAh <ubuntu@PC>
Co-authored-by: fallenbagel <98979876+Fallenbagel@users.noreply.github.com>
2025-09-02 22:40:47 +02:00

78 lines
2.5 KiB
TypeScript

import AirDateBadge from '@app/components/AirDateBadge';
import CachedImage from '@app/components/Common/CachedImage';
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import defineMessages from '@app/utils/defineMessages';
import type { SeasonWithEpisodes } from '@server/models/Tv';
import { useIntl } from 'react-intl';
import useSWR from 'swr';
const messages = defineMessages('components.TvDetails.Season', {
somethingwentwrong: 'Something went wrong while retrieving season data.',
noepisodes: 'Episode list unavailable.',
});
type SeasonProps = {
seasonNumber: number;
tvId: number;
};
const Season = ({ seasonNumber, tvId }: SeasonProps) => {
const intl = useIntl();
const { data, error } = useSWR<SeasonWithEpisodes>(
`/api/v1/tv/${tvId}/season/${seasonNumber}`
);
if (!data && !error) {
return <LoadingSpinner />;
}
if (!data) {
return <div>{intl.formatMessage(messages.somethingwentwrong)}</div>;
}
return (
<div className="flex flex-col justify-center divide-y divide-gray-700">
{data.episodes.length === 0 ? (
<p>{intl.formatMessage(messages.noepisodes)}</p>
) : (
data.episodes
.slice()
.reverse()
.map((episode) => {
return (
<div
className="flex flex-col space-y-4 py-4 xl:flex-row xl:space-y-4 xl:space-x-4"
key={`season-${seasonNumber}-episode-${episode.episodeNumber}`}
>
<div className="flex-1">
<div className="flex flex-col space-y-2 xl:flex-row xl:items-center xl:space-y-0 xl:space-x-2">
<h3 className="text-lg">
{episode.episodeNumber} - {episode.name}
</h3>
{episode.airDate && (
<AirDateBadge airDate={episode.airDate} />
)}
</div>
{episode.overview && <p>{episode.overview}</p>}
</div>
{episode.stillPath && (
<div className="relative aspect-video xl:h-32">
<CachedImage
type="tmdb"
className="rounded-lg object-contain"
src={episode.stillPath}
alt=""
fill
/>
</div>
)}
</div>
);
})
)}
</div>
);
};
export default Season;