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
}