移动云盘在线播放

This commit is contained in:
mtvpls
2026-04-26 17:41:56 +08:00
parent d8d7e57eab
commit c877397682
16 changed files with 984 additions and 104 deletions
+29 -6
View File
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any,react-hooks/exhaustive-deps,@typescript-eslint/no-empty-function */
import { ExternalLink, Heart, Info, Link, PlayCircleIcon, Radio, Sparkles, Trash2 } from 'lucide-react';
import { Cloud, ExternalLink, Heart, Info, Link, PlayCircleIcon, Radio, Sparkles, Trash2 } from 'lucide-react';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import React, {
@@ -21,11 +21,12 @@ import {
saveFavorite,
subscribeToDataUpdates,
} from '@/lib/db.client';
import { isNetdiskSource } from '@/lib/netdisk/source';
import {
processImageUrl,
base58Decode,
tryApplyDoubanImageFallback,
getDoubanImageFallbackUrl,
processImageUrl,
tryApplyDoubanImageFallback,
} from '@/lib/utils';
import { useLongPress } from '@/hooks/useLongPress';
@@ -112,7 +113,25 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(function VideoCard
const router = useRouter();
const actualTitle = title;
const actualPoster = poster;
const processedPoster = useMemo(() => processImageUrl(actualPoster), [actualPoster]);
const netdiskPosterPlaceholder = useMemo(() => {
return `data:image/svg+xml;utf8,${encodeURIComponent(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 600">
<rect width="400" height="600" fill="#f3f4f6"/>
<g fill="none" stroke="#9ca3af" stroke-width="16" stroke-linecap="round" stroke-linejoin="round">
<path d="M118 332c-30.9 0-56-25.1-56-56 0-28.5 21.3-52 48.9-55.4C120.6 184.7 154.8 160 195 160c51.1 0 92.9 39.2 97.1 89.2 27.3 4.2 47.9 27.7 47.9 56.8 0 32-26 58-58 58H118z"/>
</g>
</svg>
`)}`;
}, []);
const processedPoster = useMemo(
() =>
actualPoster
? processImageUrl(actualPoster)
: isNetdiskSource(source)
? netdiskPosterPlaceholder
: '',
[actualPoster, source, netdiskPosterPlaceholder]
);
const [favorited, setFavorited] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [showMobileActions, setShowMobileActions] = useState(false);
@@ -747,6 +766,10 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(function VideoCard
<div className='absolute inset-0 flex items-center justify-center bg-gray-200/80 dark:bg-gray-700/80'>
<Link className='w-8 h-8 text-blue-500' />
</div>
) : (isNetdiskSource(actualSource) && !actualPoster && displayPoster === netdiskPosterPlaceholder) ? (
<div className='absolute inset-0 flex flex-col items-center justify-center bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400'>
<Cloud className='w-10 h-10 opacity-80' />
</div>
) : (
<Image
src={displayPoster}
@@ -1061,7 +1084,7 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(function VideoCard
>
<span
className={`inline-block border rounded px-1 py-0.5 text-[8px] text-white/90 bg-black/60 ${
actualSource === 'xiaoya' ? 'border-blue-500' : actualSource === 'quark-temp' ? 'border-purple-500' : actualSource === 'openlist' || actualSource === 'emby' || actualSource?.startsWith('emby_') ? 'border-yellow-500' : origin === 'live' ? 'border-red-500' : 'border-white/60'
actualSource === 'xiaoya' ? 'border-blue-500' : isNetdiskSource(actualSource) ? 'border-purple-500' : actualSource === 'openlist' || actualSource === 'emby' || actualSource?.startsWith('emby_') ? 'border-yellow-500' : origin === 'live' ? 'border-red-500' : 'border-white/60'
}`}
style={{
WebkitUserSelect: 'none',
@@ -1385,7 +1408,7 @@ const VideoCard = forwardRef<VideoCardHandle, VideoCardProps>(function VideoCard
{config.showSourceName && source_name && !cmsData && (
<span
className={`inline-block border rounded px-1 py-0.5 text-[8px] text-white/90 bg-black/30 backdrop-blur-sm ${
actualSource === 'xiaoya' ? 'border-blue-500' : actualSource === 'quark-temp' ? 'border-purple-500' : actualSource === 'openlist' || actualSource === 'emby' || actualSource?.startsWith('emby_') ? 'border-yellow-500' : 'border-white/60'
actualSource === 'xiaoya' ? 'border-blue-500' : isNetdiskSource(actualSource) ? 'border-purple-500' : actualSource === 'openlist' || actualSource === 'emby' || actualSource?.startsWith('emby_') ? 'border-yellow-500' : 'border-white/60'
}`}
style={{
WebkitUserSelect: 'none',