feat: add play in new tab

This commit is contained in:
shinya
2025-08-22 19:20:22 +08:00
parent 0e4e72caae
commit 7933c24a10
2 changed files with 46 additions and 25 deletions

View File

@@ -321,30 +321,17 @@ const MobileActionSheet: React.FC<MobileActionSheetProps> = ({
{/* 播放源列表 */}
<div className="max-h-32 overflow-y-auto">
<div className="grid grid-cols-2 gap-2">
{(() => {
// 优先显示的播放源
const prioritySources = ['爱奇艺', '腾讯视频', '优酷', '芒果TV', '哔哩哔哩', 'Netflix', 'Disney+'];
const sortedSources = sources.sort((a, b) => {
const aIndex = prioritySources.indexOf(a);
const bIndex = prioritySources.indexOf(b);
if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;
if (aIndex !== -1) return -1;
if (bIndex !== -1) return 1;
return a.localeCompare(b);
});
return sortedSources.map((source, index) => (
<div
key={index}
className="flex items-center gap-2 py-2 px-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50/30 dark:bg-gray-800/30"
>
<div className="w-1 h-1 bg-gray-400 dark:bg-gray-500 rounded-full flex-shrink-0" />
<span className="text-xs text-gray-600 dark:text-gray-400 truncate">
{source}
</span>
</div>
));
})()}
{sources.map((source, index) => (
<div
key={index}
className="flex items-center gap-2 py-2 px-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50/30 dark:bg-gray-800/30"
>
<div className="w-1 h-1 bg-gray-400 dark:bg-gray-500 rounded-full flex-shrink-0" />
<span className="text-xs text-gray-600 dark:text-gray-400 truncate">
{source}
</span>
</div>
))}
</div>
</div>
</div>

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any,react-hooks/exhaustive-deps,@typescript-eslint/no-empty-function */
import { Heart, Link, PlayCircleIcon, Trash2 } from 'lucide-react';
import { ExternalLink, Heart, Link, PlayCircleIcon, Trash2 } from 'lucide-react';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import React, {
@@ -236,6 +236,31 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(function VideoCard
actualSearchType,
]);
// 新标签页播放处理函数
const handlePlayInNewTab = useCallback(() => {
if (from === 'douban' || (isAggregate && !actualSource && !actualId)) {
const url = `/play?title=${encodeURIComponent(actualTitle.trim())}${actualYear ? `&year=${actualYear}` : ''
}${actualSearchType ? `&stype=${actualSearchType}` : ''}${isAggregate ? '&prefer=true' : ''}${actualQuery ? `&stitle=${encodeURIComponent(actualQuery.trim())}` : ''}`;
window.open(url, '_blank');
} else if (actualSource && actualId) {
const url = `/play?source=${actualSource}&id=${actualId}&title=${encodeURIComponent(
actualTitle
)}${actualYear ? `&year=${actualYear}` : ''}${isAggregate ? '&prefer=true' : ''
}${actualQuery ? `&stitle=${encodeURIComponent(actualQuery.trim())}` : ''
}${actualSearchType ? `&stype=${actualSearchType}` : ''}`;
window.open(url, '_blank');
}
}, [
from,
actualSource,
actualId,
actualTitle,
actualYear,
isAggregate,
actualQuery,
actualSearchType,
]);
// 检查搜索结果的收藏状态
const checkSearchFavoriteStatus = useCallback(async () => {
if (from === 'search' && !isAggregate && actualSource && actualId && searchFavorited === null) {
@@ -327,6 +352,15 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(function VideoCard
onClick: handleClick,
color: 'primary' as const,
});
// 新标签页播放
actions.push({
id: 'play-new-tab',
label: '新标签页播放',
icon: <ExternalLink size={20} />,
onClick: handlePlayInNewTab,
color: 'default' as const,
});
}
// 聚合源信息 - 直接在菜单中展示,不需要单独的操作项