1
This commit is contained in:
@@ -3,8 +3,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../core/media/cover_cache.dart';
|
||||
import '../../core/log/action_logger.dart';
|
||||
import '../../core/theme/app_theme.dart';
|
||||
import '../../models/video_item.dart';
|
||||
import '../../providers/feed_provider.dart';
|
||||
import '../../providers/search_provider.dart';
|
||||
|
||||
/// 搜索页(《01-开发文档》2.5.8):
|
||||
@@ -24,12 +27,22 @@ class _SearchScreenState extends ConsumerState<SearchScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
ActionLogger.I.log('route_enter', page: '/search');
|
||||
// 打开搜索页挂起首页 Feed:保存当前播放断点 + 停所有槽位。
|
||||
// 用 suspend 而非 stopAll——stopAll 会清掉断点导致返回时从头播,
|
||||
// suspend 会把当前槽位置存到 _resumePosition,rebindCurrent 时经 mpv start 续播
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final strategy = ref.read(activeFeedStrategyProvider);
|
||||
ref.read(feedProvider(strategy).notifier).pool.suspend();
|
||||
});
|
||||
ref.read(searchProvider.notifier).loadHot();
|
||||
_scrollController.addListener(_onScroll);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
ActionLogger.I.log('route_exit', page: '/search');
|
||||
// 首页恢复播放改由 FeedScreen 通过 RouteObserver.didPopNext 感知,这里不再处理
|
||||
_inputController.dispose();
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
@@ -283,7 +296,11 @@ class _SearchScreenState extends ConsumerState<SearchScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
return VideoGridCard(item: state.items[index]);
|
||||
return VideoGridCard(
|
||||
item: state.items[index],
|
||||
allItems: state.items,
|
||||
initialIndex: index,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -293,15 +310,37 @@ class _SearchScreenState extends ConsumerState<SearchScreen> {
|
||||
}
|
||||
|
||||
/// 视频网格卡片:封面 + 标题 + 作者 + 播放量(搜索结果 / 标签视频页共用)
|
||||
class VideoGridCard extends StatelessWidget {
|
||||
const VideoGridCard({super.key, required this.item});
|
||||
/// 点击行为:把当前列表注入到 feedProvider(FeedStrategy.search),跳 /search/feed
|
||||
/// 进入全屏 Feed 播放,支持上下滑切换上/下一个视频
|
||||
class VideoGridCard extends ConsumerWidget {
|
||||
const VideoGridCard({
|
||||
super.key,
|
||||
required this.item,
|
||||
required this.allItems,
|
||||
required this.initialIndex,
|
||||
});
|
||||
|
||||
final VideoItem item;
|
||||
|
||||
/// 当前列表的所有视频(搜索结果/标签结果)
|
||||
final List<VideoItem> allItems;
|
||||
|
||||
/// 当前点击的视频在列表中的下标
|
||||
final int initialIndex;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return GestureDetector(
|
||||
onTap: () => context.push('/search/play', extra: item),
|
||||
// 宿主页(SearchScreen / TagVideosScreen)已在进入时挂起首页 Feed,
|
||||
// 这里只负责把列表注入 search 策略池并跳转;首页池恢复由宿主页 dispose 统一处理
|
||||
onTap: () async {
|
||||
final searchFeedNotifier =
|
||||
ref.read(feedProvider(FeedStrategy.search).notifier);
|
||||
await searchFeedNotifier.injectItems(allItems, initialIndex);
|
||||
|
||||
if (!context.mounted) return;
|
||||
context.push('/search/feed');
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -315,6 +354,7 @@ class VideoGridCard extends StatelessWidget {
|
||||
child: item.coverUrl.isNotEmpty
|
||||
? CachedNetworkImage(
|
||||
imageUrl: item.coverUrl,
|
||||
cacheManager: CoverCacheManager.I,
|
||||
fit: BoxFit.cover,
|
||||
errorWidget: (_, __, ___) => const Icon(
|
||||
Icons.play_circle_outline,
|
||||
|
||||
Reference in New Issue
Block a user