import 'package:easy_refresh/easy_refresh.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:go_router/go_router.dart'; import 'package:news_app/constant/size_res.dart'; import 'package:news_app/extension/base.dart'; import 'package:news_app/ui/activity/favorite_video_item_widget.dart'; import 'package:news_app/widget/my_txt.dart'; import '../../constant/color_res.dart'; import '../../model/activity_model.dart'; import '../../provider/user_favorite_provider.dart'; import '../../widget/empty_1_widget.dart'; import '../activity/activity_card_widget.dart'; import '../news/news_child_main_page.dart'; /// @author: bo.zeng /// @email: cnhbwds@gmail.com /// @date: 2025 2025/4/9 16:00 /// @description: class UserFavoritePage extends ConsumerWidget { const UserFavoritePage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return DefaultTabController( length: 3, child: Scaffold( appBar: AppBar( // 移除阴影 scrolledUnderElevation: 0, // 禁用滚动时的阴影变化 backgroundColor: Colors.white, title: myTxt( text: "我的收藏", fontSize: 18.sp, fontWeight: FontWeight.bold, ), centerTitle: true, bottom: TabBar( tabAlignment: TabAlignment.center, isScrollable: false, indicatorColor: color2877FF, dividerHeight: 0, labelColor: color2877FF, // 选中标签颜色 unselectedLabelColor: color7788A0, labelStyle: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold), unselectedLabelStyle: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.bold, ), tabs: [Tab(text: "文章"), Tab(text: "活动"), Tab(text: "视频")], ), ), body: TabBarView( children: [ _UserNewsListPage(), _UserActivityListPage(), _UserVideoListPage(), ], ), ), ); } } final favoriteNewsProvider = NotifierProvider( () { return FavoriteNewsProvider(); }, ); class _UserNewsListPage extends ConsumerStatefulWidget { const _UserNewsListPage(); @override ConsumerState<_UserNewsListPage> createState() => _UserNewsListPageState(); } class _UserNewsListPageState extends ConsumerState<_UserNewsListPage> with AutomaticKeepAliveClientMixin { int pageNum = 0; int totalNews = 0; @override void initState() { super.initState(); ref.read(favoriteNewsProvider.notifier).fetchUserFavorite(pageNum: pageNum); } @override Widget build(BuildContext context) { super.build(context); final news = ref.watch(favoriteNewsProvider); ref.listen(favoriteNewsProvider, (pre, next) { totalNews = next.rows?.length ?? 0; }); return news.rows?.isEmpty == true ? Empty1widget() : EasyRefresh.builder( onRefresh: () async { pageNum = 0; await ref .read(favoriteNewsProvider.notifier) .fetchUserFavorite(pageNum: pageNum); return IndicatorResult.success; }, onLoad: () async { if (totalNews >= news.total.safeValue) { return IndicatorResult.noMore; } else { pageNum++; await ref .read(favoriteNewsProvider.notifier) .fetchUserFavorite(pageNum: pageNum); return IndicatorResult.success; } }, childBuilder: (context, py) { return ListView.separated( physics: py, padding: EdgeInsets.symmetric(horizontal: horizontalPadding), itemBuilder: (BuildContext context, int index) { return buildNewsNewItem(news.rows![index]!, context); }, separatorBuilder: (BuildContext context, int index) { return SizedBox.shrink(); }, itemCount: news.rows?.length ?? 0, ); }, ); } @override bool get wantKeepAlive => true; } final favoriteActivityProvider = NotifierProvider(() { return FavoriteActivityProvider(); }); class _UserActivityListPage extends ConsumerStatefulWidget { @override ConsumerState createState() { return _UserActivityListPageState(); } } class _UserActivityListPageState extends ConsumerState<_UserActivityListPage> with AutomaticKeepAliveClientMixin { int pageNum = 0; int totalActivity = 0; @override void initState() { super.initState(); ref .read(favoriteActivityProvider.notifier) .fetchUserActivity(pageNum: pageNum); } @override Widget build(BuildContext context) { super.build(context); final activities = ref.watch(favoriteActivityProvider); ref.listen(favoriteActivityProvider, (pre, next) { totalActivity = next.rows?.length ?? 0; }); return activities.rows?.isEmpty == true ? Empty1widget() : EasyRefresh.builder( onRefresh: () async { pageNum = 0; await ref .read(favoriteActivityProvider.notifier) .fetchUserActivity(pageNum: pageNum); return IndicatorResult.success; }, onLoad: () async { if (totalActivity >= activities.total.safeValue) { return IndicatorResult.noMore; } else { pageNum++; await ref .read(favoriteActivityProvider.notifier) .fetchUserActivity(pageNum: pageNum); return IndicatorResult.success; } }, childBuilder: (context, py) { return ListView.separated( physics: py, separatorBuilder: (context, index) { return SizedBox(height: 10.h); }, padding: EdgeInsets.symmetric( horizontal: horizontalPadding, vertical: horizontalPadding, ), itemCount: activities.rows?.length ?? 0, itemBuilder: (context, index) { return GestureDetector( onTap: () { context.push( "/activity/detail", extra: activities.rows?[index]?.contentId ?? "", ); }, child: ActivityCardWidget( cellData: activities.rows?[index] ?? ActivityModelRecord(), ), ); }, ); }, ); } @override bool get wantKeepAlive => true; } final favoriteVideoProvider = NotifierProvider(() { return FavoriteVideoProvider(); }); class _UserVideoListPage extends ConsumerStatefulWidget { const _UserVideoListPage(); @override ConsumerState createState() { return _UserVideoListPageState(); } } class _UserVideoListPageState extends ConsumerState<_UserVideoListPage> with AutomaticKeepAliveClientMixin { int pageNum = 0; int totalVideo = 0; @override void initState() { super.initState(); ref.read(favoriteVideoProvider.notifier).fetchUserVideo(pageNum: pageNum); } @override Widget build(BuildContext context) { super.build(context); final videos = ref.watch(favoriteVideoProvider); ref.listen(favoriteVideoProvider, (pre, next) { totalVideo = next.rows?.length ?? 0; }); return videos.rows?.isEmpty == true ? Empty1widget() : EasyRefresh.builder( onRefresh: () async { pageNum = 0; await ref .read(favoriteVideoProvider.notifier) .fetchUserVideo(pageNum: pageNum); return IndicatorResult.success; }, onLoad: () async { if (totalVideo >= videos.total.safeValue) { return IndicatorResult.noMore; } else { pageNum++; await ref .read(favoriteVideoProvider.notifier) .fetchUserVideo(pageNum: pageNum); return IndicatorResult.success; } }, childBuilder: (context, py) { return ListView.separated( physics: py, padding: EdgeInsets.symmetric(horizontal: horizontalPadding), itemBuilder: (context, index) { return FavoriteVideoItemWidget(data: videos.rows![index]); }, separatorBuilder: (context, index) { return SizedBox(height: 10.h); }, itemCount: videos.rows?.length ?? 0, ); }, ); } @override bool get wantKeepAlive => true; }