Files
KVideo/components/home/PopularFeatures.tsx
T
kuekhaoyang 0f39d65b75 fix: default homepage to popular tab
Ensure the homepage always opens on the 热门 tag instead of automatically selecting 为你推荐, even when viewing history exists or cached tags omit the popular tag.

Fixes #182

Fixes #190
2026-07-08 23:00:09 +08:00

171 lines
5.3 KiB
TypeScript

/**
* PopularFeatures - Main component for popular movies section
* Displays Douban movie recommendations with tag filtering and infinite scroll.
* Includes personalized "为你推荐" tag when user has 2+ watched items.
*/
'use client';
import { useState } from 'react';
import { TagManager } from './TagManager';
import { MovieGrid } from './MovieGrid';
import { CategoryQuickSearch } from './CategoryQuickSearch';
import { useTagManager } from './hooks/useTagManager';
import { usePopularMovies } from './hooks/usePopularMovies';
import { usePersonalizedRecommendations } from './hooks/usePersonalizedRecommendations';
interface DoubanMovie {
id: string;
title: string;
cover: string;
rate: string;
url: string;
}
interface PopularFeaturesProps {
onSearch?: (query: string) => void;
}
export function PopularFeatures({ onSearch }: PopularFeaturesProps) {
const {
tags,
selectedTag,
contentType,
newTagInput,
showTagManager,
justAddedTag,
setContentType,
setSelectedTag,
setNewTagInput,
setShowTagManager,
setJustAddedTag,
handleAddTag,
handleDeleteTag,
handleRestoreDefaults,
handleDragEnd,
isLoadingTags,
} = useTagManager();
const {
movies: recommendMovies,
loading: recommendLoading,
hasMore: recommendHasMore,
hasHistory,
prefetchRef: recommendPrefetchRef,
loadMoreRef: recommendLoadMoreRef,
} = usePersonalizedRecommendations(false);
const [isRecommendSelected, setIsRecommendSelected] = useState(false);
const effectiveRecommendSelected = hasHistory && isRecommendSelected;
const {
movies,
loading,
hasMore,
prefetchRef,
loadMoreRef,
} = usePopularMovies(
effectiveRecommendSelected ? '' : selectedTag,
tags,
contentType
);
const handleMovieClick = (movie: DoubanMovie) => {
if (onSearch) {
onSearch(movie.title);
}
};
const handleRecommendSelect = () => {
setIsRecommendSelected(true);
};
const handleRegularTagSelect = (tagId: string) => {
if (tagId === 'custom_高级' || tags.find(t => t.id === tagId)?.label === '高级') {
window.location.href = '/premium';
return;
}
setIsRecommendSelected(false);
setSelectedTag(tagId);
};
return (
<div className="animate-fade-in">
<CategoryQuickSearch onSearch={onSearch} />
{/* Content Type Toggle (Capsule Liquid Glass - Fixed & Centered) */}
{!effectiveRecommendSelected && (
<div className="mb-10 flex justify-center">
<div className="relative w-80 p-1 bg-[var(--glass-bg)] border border-[var(--glass-border)] rounded-full grid grid-cols-2 backdrop-blur-2xl shadow-lg ring-1 ring-white/10 overflow-hidden">
{/* Sliding Indicator */}
<div
className="absolute top-1 bottom-1 w-[calc(50%-4px)] bg-[var(--accent-color)] rounded-full transition-transform duration-400 cubic-bezier(0.4, 0, 0.2, 1) shadow-[0_0_15px_rgba(0,122,255,0.4)]"
style={{
transform: `translateX(${contentType === 'movie' ? '4px' : 'calc(100% + 4px)'})`,
}}
/>
<button
onClick={() => setContentType('movie')}
className={`relative z-10 py-2.5 text-sm font-bold transition-colors duration-300 cursor-pointer flex justify-center items-center ${contentType === 'movie' ? 'text-white' : 'text-[var(--text-color-secondary)] hover:text-[var(--text-color)]'
}`}
>
电影
</button>
<button
onClick={() => setContentType('tv')}
className={`relative z-10 py-2.5 text-sm font-bold transition-colors duration-300 cursor-pointer flex justify-center items-center ${contentType === 'tv' ? 'text-white' : 'text-[var(--text-color-secondary)] hover:text-[var(--text-color)]'
}`}
>
电视剧
</button>
</div>
</div>
)}
<TagManager
tags={tags}
selectedTag={effectiveRecommendSelected ? '' : selectedTag}
showTagManager={showTagManager}
newTagInput={newTagInput}
justAddedTag={justAddedTag}
onTagSelect={handleRegularTagSelect}
onTagDelete={handleDeleteTag}
onToggleManager={() => setShowTagManager(!showTagManager)}
onRestoreDefaults={handleRestoreDefaults}
onNewTagInputChange={setNewTagInput}
onAddTag={handleAddTag}
onDragEnd={handleDragEnd}
onJustAddedTagHandled={() => setJustAddedTag(false)}
isLoadingTags={isLoadingTags}
recommendTag={hasHistory ? {
label: '为你推荐',
isSelected: effectiveRecommendSelected,
onSelect: handleRecommendSelect,
} : undefined}
/>
{effectiveRecommendSelected ? (
<MovieGrid
movies={recommendMovies}
loading={recommendLoading}
hasMore={recommendHasMore}
onMovieClick={handleMovieClick}
prefetchRef={recommendPrefetchRef}
loadMoreRef={recommendLoadMoreRef}
/>
) : (
<MovieGrid
movies={movies}
loading={loading}
hasMore={hasMore}
onMovieClick={handleMovieClick}
prefetchRef={prefetchRef}
loadMoreRef={loadMoreRef}
/>
)}
</div>
);
}