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 (
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.
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.
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.
⚠️ 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.
Override artwork with custom URL patterns. Select a rating poster provider for pre-filled defaults, or use fully custom patterns.
Pre-fills poster patterns with the selected provider's URL. Choose Custom for fully manual patterns.
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.
{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.
Extra placeholders: {'{season}'}, {'{episode}'}, {'{blur}'} (true/false from blur thumbs setting), {'{thumbnail}'} (original thumbnail URL, encoded), {'{user_agent}'}.