import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../shared/theme/app_theme.dart'; import '../../shared/widgets/app_sliver_header.dart'; import '../../shared/widgets/page_background.dart'; import '../../shared/widgets/pill_tab_bar.dart'; import '../favorites/aggregated_favorites_page.dart'; import '../history/history_page.dart'; import 'aggregated_recent_page.dart'; const _kTabHistory = 'history'; const _kTabFavorites = 'favorites'; const _kTabRecent = 'recent'; int _tabIndexFromKey(String? key) => switch (key) { _kTabFavorites => 1, _kTabRecent => 2, _ => 0, }; String _tabKeyFromIndex(int index) => switch (index) { 1 => _kTabFavorites, 2 => _kTabRecent, _ => _kTabHistory, }; class AggregatedViewPage extends ConsumerStatefulWidget { final String? initialTab; final bool isCompactMode; const AggregatedViewPage({ super.key, this.initialTab, this.isCompactMode = false, }); @override ConsumerState createState() => _AggregatedViewPageState(); } class _AggregatedViewPageState extends ConsumerState { late int _index; int _historyRefreshSeed = 0; int _favoritesRefreshSeed = 0; int _recentRefreshSeed = 0; String get _storagePrefix => widget.isCompactMode ? 'watch' : 'aggregated'; @override void initState() { super.initState(); _index = _tabIndexFromKey(widget.initialTab); } @override void didUpdateWidget(covariant AggregatedViewPage oldWidget) { super.didUpdateWidget(oldWidget); if (widget.initialTab != oldWidget.initialTab) { final next = _tabIndexFromKey(widget.initialTab); if (next != _index) { setState(() => _index = next); } } } void _onTabChanged(int next) { if (next == _index) return; setState(() => _index = next); final key = _tabKeyFromIndex(next); context.go('/aggregated?tab=$key'); } Future _refreshActive() async { setState(() { switch (_index) { case 1: _favoritesRefreshSeed++; break; case 2: _recentRefreshSeed++; break; default: _historyRefreshSeed++; } }); await Future.delayed(const Duration(milliseconds: 250)); } @override Widget build(BuildContext context) { final tokens = context.appTokens; final firstTabLabel = widget.isCompactMode ? '继续观看' : '播放记录'; return Scaffold( extendBodyBehindAppBar: true, backgroundColor: Colors.transparent, body: Stack( children: [ const Positioned.fill(child: PageBackground()), RefreshIndicator( onRefresh: _refreshActive, child: NestedScrollView( physics: const AlwaysScrollableScrollPhysics( parent: BouncingScrollPhysics(), ), floatHeaderSlivers: false, headerSliverBuilder: (context, innerBoxIsScrolled) => [ SliverOverlapAbsorber( handle: NestedScrollView.sliverOverlapAbsorberHandleFor( context, ), sliver: AppSliverHeader( toolbarHeight: tokens.titleBarHeight, automaticallyImplyLeading: false, titleWidget: _buildTitleRow(firstTabLabel), ), ), ], body: IndexedStack( index: _index, children: [ KeyedSubtree( key: PageStorageKey( '${_storagePrefix}_history_$_historyRefreshSeed', ), child: const HistoryPage(embedded: true), ), KeyedSubtree( key: PageStorageKey( '${_storagePrefix}_favorites_$_favoritesRefreshSeed', ), child: const AggregatedFavoritesPage(embedded: true), ), KeyedSubtree( key: PageStorageKey( '${_storagePrefix}_recent_$_recentRefreshSeed', ), child: const AggregatedRecentPage(embedded: true), ), ], ), ), ), ], ), ); } Widget _buildTitleRow(String firstTabLabel) { final tabBar = PillTabBar( padding: const EdgeInsets.only(left: 8), tabs: [firstTabLabel, '我的收藏', '最近添加'], selectedIndex: _index, onSelect: _onTabChanged, ); return Align(alignment: Alignment.centerLeft, child: tabBar); } }