diff --git a/app/api/adult/types/route.ts b/app/api/adult/types/route.ts index 67fdcf7..06ccc90 100644 --- a/app/api/adult/types/route.ts +++ b/app/api/adult/types/route.ts @@ -76,17 +76,17 @@ export async function GET() { return label.replace(/[视频片区专]/g, ''); }; - // Helper to check if two labels match fuzzily (>= 2 chars overlap) + // Helper to check if two labels match fuzzily (>= 4 chars overlap) const isFuzzyMatch = (label1: string, label2: string) => { const clean1 = cleanLabel(label1); const clean2 = cleanLabel(label2); // If either is too short after cleaning, require exact match - if (clean1.length < 2 || clean2.length < 2) { + if (clean1.length < 4 || clean2.length < 4) { return clean1 === clean2; } - // Check for 2+ char overlap + // Check for 4+ char overlap let overlapCount = 0; const set1 = new Set(clean1.split('')); for (const char of clean2) { @@ -94,7 +94,7 @@ export async function GET() { overlapCount++; } } - return overlapCount >= 2; + return overlapCount >= 4; }; // Process results @@ -104,6 +104,9 @@ export async function GET() { categories.forEach((cat: Category) => { const typeName = cat.type_name.trim(); + // Skip empty type names + if (!typeName) return; + const value = `${sourceId}:${cat.type_id}`; // Try to find a fuzzy match in existing categories @@ -131,6 +134,9 @@ export async function GET() { // Convert merged categories to tags mergedCategories.forEach((cat) => { + // Skip categories with no values (shouldn't happen with current logic but good for safety) + if (cat.values.length === 0) return; + // Create a unique ID based on the label (using base64 to be safe) const id = Buffer.from(cat.label).toString('base64'); diff --git a/components/adult/AdultContent.tsx b/components/adult/AdultContent.tsx index 4314fb0..4ac5e94 100644 --- a/components/adult/AdultContent.tsx +++ b/components/adult/AdultContent.tsx @@ -1,6 +1,5 @@ 'use client'; -import { useState, useEffect } from 'react'; import { TagManager } from '@/components/home/TagManager'; import { AdultContentGrid } from './AdultContentGrid'; import { useAdultTagManager } from '@/lib/hooks/useAdultTagManager'; @@ -25,7 +24,6 @@ export function AdultContent({ onSearch }: AdultContentProps) { handleDeleteTag, handleRestoreDefaults, handleDragEnd, - loading: tagsLoading, } = useAdultTagManager(); // Get the category value from selected tag @@ -33,38 +31,18 @@ export function AdultContent({ onSearch }: AdultContentProps) { const { videos, - loading: contentLoading, + loading, hasMore, prefetchRef, loadMoreRef, } = useAdultContent(categoryValue); - const [mounted, setMounted] = useState(false); - - useEffect(() => { - setMounted(true); - }, []); - const handleVideoClick = (video: any) => { if (onSearch) { onSearch(video.vod_name); } }; - if (!mounted || tagsLoading) { - return ( -
-
-
-
- {[...Array(10)].map((_, i) => ( -
- ))} -
-
- ); - } - return (
setJustAddedTag(false)} /> + ; + } + return ( -
-
+ <> +
{videos.map((video) => ( -
onVideoClick?.(video)} + onClick={(e) => { + // Allow default behavior for modifier keys (new tab, etc.) + if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return; + + e.preventDefault(); + onVideoClick?.(video); + }} style={{ contain: 'layout style paint', contentVisibility: 'auto' }} > -
+
{video.vod_pic ? ( {video.vod_name} @@ -80,62 +91,51 @@ export function AdultContentGrid({ )}
-
+ ))}
- {/* Prefetch Trigger */} + {/* Prefetch Trigger - Earlier */} {hasMore && !loading &&
} {/* Loading Indicator */} - {loading && ( -
-
-
-

加载中...

-
-
- )} + {loading && } {/* Intersection Observer Target */} {hasMore && !loading &&
} {/* No More Content */} - {!loading && !hasMore && videos.length > 0 && ( -
-

没有更多内容了

-
- )} + {!hasMore && videos.length > 0 && } + + ); +} - {/* Empty State */} - {!loading && videos.length === 0 && ( -
-
- - - - - - - - - - -
-

暂无内容

-
- )} +function AdultGridLoading() { + return ( +
+
+
+

加载中...

+
+
+ ); +} + +function AdultGridNoMore() { + return ( +
+

没有更多内容了

+
+ ); +} + +function AdultGridEmpty() { + // Using require to avoid top-level import issues if any, matching MovieGrid pattern + const { Icons } = require('@/components/ui/Icon'); + return ( +
+ +

暂无内容

); } diff --git a/components/home/MovieCard.tsx b/components/home/MovieCard.tsx index f53cb8b..b8acbf7 100644 --- a/components/home/MovieCard.tsx +++ b/components/home/MovieCard.tsx @@ -27,6 +27,9 @@ export const MovieCard = memo(function MovieCard({ movie, onMovieClick }: MovieC { + // Allow default behavior for modifier keys (new tab, etc.) + if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return; + e.preventDefault(); onMovieClick(movie); }}