import { useState } from 'react' import { CheckCircle2, Info, Rss } from 'lucide-react' import toast from 'react-hot-toast' import type { DiscoverItem } from '../api/discover' import type { ExternalMediaResult } from '../api/ai' import { imageURL } from '../api/client' import { subscriptionsAPI } from '../api/subscriptions' import { DiscoverSubscriptionRules } from './DiscoverDetailModalSections' import { apiErrorMessage, buildDiscoverSubscriptionInput, initialDiscoverSubscriptionForm, } from './discoverDetailModalModel' export function ExternalResults({ items, }: { items: ExternalMediaResult[] }) { const [detail, setDetail] = useState(null) return (

外部数据源

来自 TMDb / 豆瓣 / Bangumi。电影入队最佳资源;剧集/动漫优先整季或全集包,否则按集批量入队。

{items.map((item) => { const keyword = item.subscribe_keyword || item.title const key = `${item.source}:${keyword}` return (
setDetail(item)} onKeyDown={(event) => { if (event.key === 'Enter' || event.key === ' ') setDetail(item) }} className="glass-panel flex cursor-pointer gap-3 !p-3 transition hover:-translate-y-0.5 hover:shadow-lg" >
{item.poster_url ? ( {item.title} ) : null}
{item.source} {item.media_type && {item.media_type}} {item.year ? {item.year} : null} {item.rating ? ★ {item.rating.toFixed(1)} : null}

{item.title}

{item.overview || `订阅关键词:${keyword}`}

{item.in_library ? '本地已入库' : '本地未入库'} {isSeriesItem(item) ? ( 已有 {item.downloaded_episodes || 0}/{item.total_episodes || '未知'} 集 ) : null}
) })}
{detail && ( setDetail(null)} /> )}
) } function ExternalDetailModal({ item, onClose, }: { item: ExternalMediaResult onClose: () => void }) { const missing = item.missing_episodes ?? [] const discoverItem = item as unknown as DiscoverItem const [form, setForm] = useState(() => initialDiscoverSubscriptionForm(discoverItem)) const [formBusy, setFormBusy] = useState(false) const submit = async () => { setFormBusy(true) try { const sub = await subscriptionsAPI.create( buildDiscoverSubscriptionInput(discoverItem, form, item.source || 'tmdb'), ) if (form.run_now) { const run = await subscriptionsAPI.runNow(sub.id) toast.success(run.queued > 0 ? `已订阅并加入 ${run.queued} 个下载` : '已订阅,暂未命中可下载资源') } else { toast.success('已创建订阅') } onClose() } catch (err) { toast.error(apiErrorMessage(err, '订阅失败')) } finally { setFormBusy(false) } } return (
event.stopPropagation()}>
{item.poster_url ? ( {item.title} ) : (
)}
{item.source} {item.media_type ? {item.media_type} : null} {item.year ? {item.year} : null} {item.rating ? ★ {item.rating.toFixed(1)} : null}

{item.title}

{item.overview || '暂无简介。'}

{isSeriesItem(item) && (
缺失情况
{missing.length > 0 ? (
{missing.slice(0, 80).map((episode) => ( 第 {episode} 集 ))} {missing.length > 80 ? 还有 {missing.length - 80} 集… : null}
) : item.in_library && item.total_episodes ? (

已完整入库

) : (

总集数未知,订阅时会跳过本地已有单集,优先补新集。

)}
)} setForm((current) => ({ ...current, ...patch }))} onSubmit={submit} />
) } function StatusBox({ label, value, ok }: { label: string; value: string; ok?: boolean }) { return (
{label}
{value}
) } function isSeriesItem(item: ExternalMediaResult) { return ['tv', 'anime', 'variety'].includes((item.media_type || '').toLowerCase()) }