import { Label } from '@/components/ui/label'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Switch } from '@/components/ui/switch'; import { useConfig } from '@/contexts/ConfigContext'; import { AlertCircle, RotateCcw } from 'lucide-react'; const movieArtProviders = [ { value: 'tmdb', label: 'The Movie Database (TMDB)' }, { value: 'tvdb', label: 'TheTVDB' }, { value: 'fanart', label: 'Fanart.tv' }, { value: 'imdb', label: 'Internet Movie Database (IMDB/Cinemeta)' }, ]; const seriesArtProviders = [ { value: 'tmdb', label: 'The Movie Database (TMDB)' }, { value: 'tvdb', label: 'TheTVDB' }, { value: 'fanart', label: 'Fanart.tv' }, { value: 'imdb', label: 'Internet Movie Database (IMDB/Cinemeta)' }, ]; const animeArtProviders = [ { value: 'mal', label: 'MyAnimeList' }, { value: 'anilist', label: 'AniList' }, { value: 'kitsu', label: 'Kitsu' }, { value: 'tvdb', label: 'TheTVDB' }, { value: 'tmdb', label: 'The Movie Database (TMDB)' }, { value: 'fanart', label: 'Fanart.tv' }, { value: 'imdb', label: 'Internet Movie Database (IMDB/Cinemeta)' }, ]; const animeBackgroundArtProviders = [ { value: 'mal', label: 'MyAnimeList' }, { value: 'anilist', label: 'AniList' }, { value: 'kitsu', label: 'Kitsu' }, { value: 'tvdb', label: 'TheTVDB' }, { value: 'tmdb', label: 'The Movie Database (TMDB)' }, { value: 'fanart', label: 'Fanart.tv' }, { value: 'imdb', label: 'Internet Movie Database (IMDB/Cinemeta) (Recommended)' }, ]; const animeLogoArtProviders = [ { value: 'imdb', label: 'Internet Movie Database (IMDB/Cinemeta) (Recommended)' }, { value: 'tvdb', label: 'TheTVDB' }, { value: 'tmdb', label: 'The Movie Database (TMDB)' }, { value: 'fanart', label: 'Fanart.tv' }, ]; export function ArtProviderSettings() { const { config, setConfig, hasBuiltInTvdb } = useConfig(); const hasTvdbKey = !!config.apiKeys?.tvdb?.trim() || hasBuiltInTvdb; const handleArtProviderChange = ( contentType: 'movie' | 'series' | 'anime', artType: 'poster' | 'background' | 'logo', value: string ) => { setConfig(prev => ({ ...prev, artProviders: { ...prev.artProviders, [contentType]: { ...(typeof prev.artProviders?.[contentType] === 'object' ? prev.artProviders[contentType] : { poster: 'meta', background: 'meta', logo: 'meta' }), [artType]: value } } })); }; const handleEnglishArtOnlyChange = (value: boolean) => { setConfig(prev => ({ ...prev, artProviders: { ...prev.artProviders, englishArtOnly: value } })); }; const isFanartSelected = () => { const artProviders = config.artProviders; if (!artProviders) return false; return Object.values(artProviders).some(contentType => contentType && typeof contentType === 'object' && Object.values(contentType).includes('fanart') ); }; const hasFanartKey = config.apiKeys.fanart && config.apiKeys.fanart.trim() !== ''; const getArtProviders = (contentType: 'movie' | 'series' | 'anime', artType: 'poster' | 'background' | 'logo') => { switch (contentType) { case 'movie': return movieArtProviders; case 'series': return seriesArtProviders; case 'anime': if (artType === 'background') { return animeBackgroundArtProviders; } else if (artType === 'logo') { return animeLogoArtProviders; } else { return animeArtProviders; } default: return []; } }; const getCurrentValue = (contentType: 'movie' | 'series' | 'anime', artType: 'poster' | 'background' | 'logo') => { const contentTypeConfig = config.artProviders?.[contentType]; if (typeof contentTypeConfig === 'string') { // Legacy format - return the single value for all art types return contentTypeConfig; } if (contentTypeConfig && typeof contentTypeConfig === 'object') { return contentTypeConfig[artType] || 'meta'; } return 'meta'; }; return (

Art Providers

Choose your preferred sources for different types of artwork. You can select different providers for posters, backgrounds, and logos.

{/* Search Notice */}

Note: Art provider settings apply to catalogs and detail pages, but not to search results. Search uses the selected search engine's poster sources for faster performance. Art URL Overrides (configured below) take priority over art provider settings.

{/* English Art Only Toggle */}

Force all artwork to be in English language, regardless of your language setting.

Skip region-mismatched posters in your display language and fall back to English or the title's original language instead.

setConfig(prev => ({ ...prev, artProviders: { ...prev.artProviders, originalLangFallback: value } }))} />
{isFanartSelected() && !hasFanartKey && (

Fanart.tv API Key Required: You've selected Fanart.tv as an art provider. Please add your Fanart.tv API key in the Integrations tab to use this service.

)}
{/* Movies Art Providers */}

Movies

Poster Provider Source for movie posters. Background Provider Source for movie backgrounds. Logo Provider Source for movie logos.
{/* Series Art Providers */}

Series

Poster Provider Source for series posters. Background Provider Source for series backgrounds. Logo Provider Source for series logos.
{/* Anime Art Providers */}

Anime

{/* Warning when IMDb settings are affecting anime art providers */} {(config.mal?.useImdbIdForCatalogAndSearch || config.providers?.forceAnimeForDetectedImdb) && (

⚠️ Important: Anime Art Providers Limited

{config.mal?.useImdbIdForCatalogAndSearch && config.providers?.forceAnimeForDetectedImdb ? 'Both "Use IMDb ID for Catalog/Search" and "Anime Detection Override" are enabled. Most anime will use the Movie/Series art providers instead of these Anime art providers.' : config.mal?.useImdbIdForCatalogAndSearch ? '"Use IMDb ID for Catalog/Search" is enabled in MAL settings. Anime in catalogs/search will use the Movie/Series art providers instead of these Anime art providers.' : '"Anime Detection Override" is enabled in Providers settings. Detected anime with IMDb IDs will use the Movie/Series art providers instead of these Anime art providers.'}

)}

These settings apply only to anime using MAL, AniList, Kitsu, or AniDB as metadata ID. Anime using IMDB IDs will use the Movie or Series art providers instead depending on the type.

Poster Provider Source for anime posters. Background Provider Source for anime backgrounds. Logo Provider Source for anime logos.
{/* Art URL Overrides */}

Art URL Overrides

Override artwork with custom URL patterns. Select a rating poster provider for pre-filled defaults, or use fully custom patterns.

{/* Provider Selection */}

Pre-fills poster patterns with the selected provider's URL. Choose Custom for fully manual patterns.

{/* Proxy Toggle */}

Route poster, logo, and backdrop requests through this addon. Enables fallback to the original art when a rating provider or custom URL is missing or down, but adds a small delay.

setConfig(prev => ({ ...prev, usePosterProxy: checked }))} />
{/* Pattern Fields */}

{config.posterRatingProvider === 'rpdb' || config.posterRatingProvider === 'top' ? 'Pre-filled with the default pattern for your selected provider. You can customize it if needed.' : 'Override art with custom URL patterns. If a placeholder references an unavailable value, normal art is used instead.'}

ID placeholders: {'{id}'}, {'{imdb_id}'}, {'{tmdb_id}'}, {'{tvdb_id}'}, {'{mal_id}'}, {'{kitsu_id}'}, {'{anilist_id}'}, {'{anidb_id}'}, {'{type}'}. API keys/Extra: {'{rpdb_key}'}, {'{top_key}'}, {'{tmdb_key}'}, {'{mdblist_key}'}, {'{fanart_key}'}, {'{user_agent}'}. Language: {'{language}'} (e.g. fr-FR), {'{language_short}'} (e.g. fr). RPDB/TOP patterns automatically fall back to alternative IDs when the primary one is unavailable.

{(config.posterRatingProvider === 'rpdb' || config.posterRatingProvider === 'top') && ( )}
setConfig(prev => ({ ...prev, customPosterUrlPattern: e.target.value }))} />
setConfig(prev => ({ ...prev, customBackgroundUrlPattern: e.target.value }))} />
setConfig(prev => ({ ...prev, customLogoUrlPattern: e.target.value }))} />
{(config.posterRatingProvider === 'top') && ( )}
setConfig(prev => ({ ...prev, customThumbnailUrlPattern: e.target.value }))} />

Extra placeholders: {'{season}'}, {'{episode}'}, {'{blur}'} (true/false from blur thumbs setting), {'{thumbnail}'} (original thumbnail URL, encoded), {'{user_agent}'}.

); }