From 837e862d752f4f2ec9e7b5b80d4a400400b1f65a Mon Sep 17 00:00:00 2001 From: mtvpls Date: Sat, 17 Jan 2026 20:26:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89tm?= =?UTF-8?q?db=E5=9B=BE=E7=89=87baseurl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/movie-request/page.tsx | 7 +++--- src/components/DetailPanel.tsx | 9 +++---- src/components/UserMenu.tsx | 43 +++++++++++++++++++++++++++++++++- src/lib/tmdb.client.ts | 5 +++- src/lib/tmdb.search.ts | 5 +++- 5 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/app/movie-request/page.tsx b/src/app/movie-request/page.tsx index a213ea2..7781eb5 100644 --- a/src/app/movie-request/page.tsx +++ b/src/app/movie-request/page.tsx @@ -6,6 +6,7 @@ import { createPortal } from 'react-dom'; import { CheckCircle, AlertCircle, Plus } from 'lucide-react'; import PageLayout from '@/components/PageLayout'; +import { getTMDBImageUrl } from '@/lib/tmdb.client'; interface TMDBResult { id: number; @@ -116,7 +117,7 @@ export default function MovieRequestPage() { const submitRequest = async (item: TMDBResult, season?: number) => { setSubmitting(true); try { - let poster = item.poster_path ? `https://image.tmdb.org/t/p/w500${item.poster_path}` : undefined; + let poster = item.poster_path ? getTMDBImageUrl(item.poster_path, 'w500') : undefined; let title = item.title || item.name || ''; if (season && seasons.length > 0) { @@ -124,7 +125,7 @@ export default function MovieRequestPage() { if (seasonData) { title = `${title} ${seasonData.name}`; if (seasonData.poster_path) { - poster = `https://image.tmdb.org/t/p/w500${seasonData.poster_path}`; + poster = getTMDBImageUrl(seasonData.poster_path, 'w500'); } } } @@ -310,7 +311,7 @@ export default function MovieRequestPage() { > {item.poster_path ? ( {item.title diff --git a/src/components/DetailPanel.tsx b/src/components/DetailPanel.tsx index 21d80d0..ff06bb5 100644 --- a/src/components/DetailPanel.tsx +++ b/src/components/DetailPanel.tsx @@ -4,6 +4,7 @@ import { X, Calendar, Star, Clock, Tag, Users, Globe, Film } from 'lucide-react' import Image from 'next/image'; import React, { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; +import { getTMDBImageUrl } from '@/lib/tmdb.client'; interface DetailPanelProps { isOpen: boolean; @@ -372,7 +373,7 @@ const DetailPanel: React.FC = ({ ? detailResult.release_date?.substring(0, 4) : detailResult.first_air_date?.substring(0, 4), poster: detailResult.poster_path - ? `https://image.tmdb.org/t/p/w500${detailResult.poster_path}` + ? getTMDBImageUrl(detailResult.poster_path, 'w500') : poster, rating: detailResult.vote_average ? { @@ -480,7 +481,7 @@ const DetailPanel: React.FC = ({ ...prev, title: episodesData.name || season?.name || prev.title, intro: episodesData.overview || season?.overview || prev.overview, - poster: season?.poster_path ? `https://image.tmdb.org/t/p/w500${season.poster_path}` : prev.poster, + poster: season?.poster_path ? getTMDBImageUrl(season.poster_path, 'w500') : prev.poster, releaseDate: episodesData.air_date || season?.air_date || prev.releaseDate, year: episodesData.air_date?.substring(0, 4) || season?.air_date?.substring(0, 4) || prev.year, episodesCount: episodesData.episodes?.length || season?.episode_count || prev.episodesCount, @@ -732,7 +733,7 @@ const DetailPanel: React.FC = ({ {season.poster_path && (
{season.name} = ({ {episode.still_path && (
{episode.name} { // 折叠面板状态 const [isDoubanSectionOpen, setIsDoubanSectionOpen] = useState(true); + + // TMDB 图片设置 + const [tmdbImageBaseUrl, setTmdbImageBaseUrl] = useState('https://image.tmdb.org'); const [isUsageSectionOpen, setIsUsageSectionOpen] = useState(false); const [isBufferSectionOpen, setIsBufferSectionOpen] = useState(false); const [isDanmakuSectionOpen, setIsDanmakuSectionOpen] = useState(false); @@ -339,6 +342,11 @@ export const UserMenu: React.FC = () => { setDoubanImageProxyUrl(defaultDoubanImageProxyUrl); } + const savedTmdbImageBaseUrl = localStorage.getItem('tmdbImageBaseUrl'); + if (savedTmdbImageBaseUrl !== null) { + setTmdbImageBaseUrl(savedTmdbImageBaseUrl); + } + const savedEnableOptimization = localStorage.getItem('enableOptimization'); if (savedEnableOptimization !== null) { @@ -704,6 +712,13 @@ export const UserMenu: React.FC = () => { } }; + const handleTmdbImageBaseUrlChange = (value: string) => { + setTmdbImageBaseUrl(value); + if (typeof window !== 'undefined') { + localStorage.setItem('tmdbImageBaseUrl', value); + } + }; + const handleBufferStrategyChange = (value: string) => { setBufferStrategy(value); if (typeof window !== 'undefined') { @@ -833,6 +848,7 @@ export const UserMenu: React.FC = () => { setDoubanDataSource(defaultDoubanProxyType); setDoubanImageProxyType(defaultDoubanImageProxyType); setDoubanImageProxyUrl(defaultDoubanImageProxyUrl); + setTmdbImageBaseUrl('https://image.tmdb.org'); setBufferStrategy('medium'); setNextEpisodePreCache(true); setNextEpisodeDanmakuPreload(true); @@ -850,6 +866,7 @@ export const UserMenu: React.FC = () => { localStorage.setItem('doubanDataSource', defaultDoubanProxyType); localStorage.setItem('doubanImageProxyType', defaultDoubanImageProxyType); localStorage.setItem('doubanImageProxyUrl', defaultDoubanImageProxyUrl); + localStorage.setItem('tmdbImageBaseUrl', 'https://image.tmdb.org'); localStorage.setItem('bufferStrategy', 'medium'); localStorage.setItem('nextEpisodePreCache', 'true'); localStorage.setItem('nextEpisodeDanmakuPreload', 'true'); @@ -1167,7 +1184,7 @@ export const UserMenu: React.FC = () => { className='w-full px-3 py-2.5 md:px-4 md:py-3 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-750 transition-colors flex items-center justify-between' >

- 豆瓣设置 + 网络设置

{isDoubanSectionOpen ? ( @@ -1384,6 +1401,30 @@ export const UserMenu: React.FC = () => { />
)} + + {/* 分割线 */} +
+ + {/* TMDB 图片网络请求地址设置 */} +
+
+

+ TMDB 图片网络请求地址 +

+

+ TMDB 图片的 Base URL(默认: https://image.tmdb.org) +

+
+ + handleTmdbImageBaseUrlChange(e.target.value) + } + /> +
)} diff --git a/src/lib/tmdb.client.ts b/src/lib/tmdb.client.ts index f546591..531c43a 100644 --- a/src/lib/tmdb.client.ts +++ b/src/lib/tmdb.client.ts @@ -403,7 +403,10 @@ export function getTMDBImageUrl( size: string = 'w500' ): string { if (!path) return ''; - return `https://image.tmdb.org/t/p/${size}${path}`; + const baseUrl = typeof window !== 'undefined' + ? localStorage.getItem('tmdbImageBaseUrl') || 'https://image.tmdb.org' + : 'https://image.tmdb.org'; + return `${baseUrl}/t/p/${size}${path}`; } /** diff --git a/src/lib/tmdb.search.ts b/src/lib/tmdb.search.ts index 9c1058e..a91a8ed 100644 --- a/src/lib/tmdb.search.ts +++ b/src/lib/tmdb.search.ts @@ -226,5 +226,8 @@ export function getTMDBImageUrl( return path; } - return `https://image.tmdb.org/t/p/${size}${path}`; + const baseUrl = typeof window !== 'undefined' + ? localStorage.getItem('tmdbImageBaseUrl') || 'https://image.tmdb.org' + : 'https://image.tmdb.org'; + return `${baseUrl}/t/p/${size}${path}`; }