diff --git a/app/secret/page.tsx b/app/secret/page.tsx index dbadeff..92ab1e8 100644 --- a/app/secret/page.tsx +++ b/app/secret/page.tsx @@ -49,6 +49,7 @@ function SecretHomePage() { results={results} availableSources={availableSources} loading={loading} + openDirectLinks={true} /> )} diff --git a/components/home/SearchResults.tsx b/components/home/SearchResults.tsx index f8efeac..311e093 100644 --- a/components/home/SearchResults.tsx +++ b/components/home/SearchResults.tsx @@ -11,9 +11,10 @@ interface SearchResultsProps { results: Video[]; availableSources: SourceBadge[]; loading: boolean; + openDirectLinks?: boolean; } -export function SearchResults({ results, availableSources, loading }: SearchResultsProps) { +export function SearchResults({ results, availableSources, loading, openDirectLinks = false }: SearchResultsProps) { // Source badges hook - filters by video source const { selectedSources, @@ -61,7 +62,7 @@ export function SearchResults({ results, availableSources, loading }: SearchResu )} {/* Display filtered videos (both source and type filters applied) */} - + ); } diff --git a/components/layout/Navbar.tsx b/components/layout/Navbar.tsx index ceffaee..b310c2c 100644 --- a/components/layout/Navbar.tsx +++ b/components/layout/Navbar.tsx @@ -1,6 +1,7 @@ import Link from 'next/link'; import Image from 'next/image'; import { ThemeSwitcher } from '@/components/ThemeSwitcher'; +import { Icons } from '@/components/ui/Icon'; interface NavbarProps { onReset: () => void; @@ -38,6 +39,15 @@ export function Navbar({ onReset }: NavbarProps) {
+ + + void; + onCardClick: (e: React.MouseEvent, cardId: string, videoUrl: string, video: Video) => void; } export const VideoCard = memo(({ @@ -35,7 +35,7 @@ export const VideoCard = memo(({ onCardClick(e, cardId, videoUrl)} + onClick={(e) => onCardClick(e, cardId, videoUrl, video)} role="listitem" aria-label={`${video.vod_name}${video.vod_remarks ? ` - ${video.vod_remarks}` : ''}`} prefetch={false} diff --git a/components/search/VideoGrid.tsx b/components/search/VideoGrid.tsx index 3df511e..794cb90 100644 --- a/components/search/VideoGrid.tsx +++ b/components/search/VideoGrid.tsx @@ -8,9 +8,10 @@ import { Video } from '@/lib/types'; interface VideoGridProps { videos: Video[]; className?: string; + openDirectLinks?: boolean; } -export const VideoGrid = memo(function VideoGrid({ videos, className = '' }: VideoGridProps) { +export const VideoGrid = memo(function VideoGrid({ videos, className = '', openDirectLinks = false }: VideoGridProps) { const [activeCardId, setActiveCardId] = useState(null); const [visibleCount, setVisibleCount] = useState(24); const gridRef = useRef(null); @@ -36,7 +37,25 @@ export const VideoGrid = memo(function VideoGrid({ videos, className = '' }: Vid }, []); // Memoize the click handler to prevent re-renders - const handleCardClick = useCallback((e: React.MouseEvent, videoId: string, videoUrl: string) => { + const handleCardClick = useCallback((e: React.MouseEvent, videoId: string, videoUrl: string, video?: Video) => { + if (openDirectLinks && video?.vod_play_url) { + // For secret page: extract first video URL and open directly + e.preventDefault(); + const playUrls = video.vod_play_url.split('$$$'); + if (playUrls.length > 0) { + const firstPlaylist = playUrls[0]; + const segments = firstPlaylist.split('#'); + if (segments.length > 0) { + const urls = segments[0].split('$'); + if (urls.length > 1) { + window.open(urls[1], '_blank'); + return; + } + } + } + return; + } + // Check if it's a mobile device const isMobile = window.innerWidth < 1024; // lg breakpoint @@ -52,7 +71,7 @@ export const VideoGrid = memo(function VideoGrid({ videos, className = '' }: Vid } } // On desktop, let the Link work normally - }, [activeCardId]); + }, [activeCardId, openDirectLinks]); // Memoize video items to prevent unnecessary re-computations const videoItems = useMemo(() => { diff --git a/components/ui/icons/utility-icons.tsx b/components/ui/icons/utility-icons.tsx index 8b1d751..e1253f9 100644 --- a/components/ui/icons/utility-icons.tsx +++ b/components/ui/icons/utility-icons.tsx @@ -121,4 +121,10 @@ export const UtilityIcons = { ), + + Github: ({ className = "", size = 24 }: IconProps) => ( + + + + ), }; diff --git a/lib/types/index.ts b/lib/types/index.ts index af40e43..9778ff6 100644 --- a/lib/types/index.ts +++ b/lib/types/index.ts @@ -26,6 +26,7 @@ export interface VideoItem { vod_actor?: string; vod_director?: string; vod_content?: string; + vod_play_url?: string; source: string; latency?: number; // Response time in milliseconds }