From 6a05717d6e832b2d8344b40a7da81988ca8caf72 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Fri, 13 Sep 2024 14:48:01 +0800 Subject: [PATCH] refactor: fav detail --- lib/http/user.dart | 24 ++++ lib/pages/fav_detail/controller.dart | 91 +++++++------- lib/pages/fav_detail/view.dart | 173 +++++++++++---------------- 3 files changed, 144 insertions(+), 144 deletions(-) diff --git a/lib/http/user.dart b/lib/http/user.dart index 5aff3e71..fc9c247c 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -89,6 +89,30 @@ class UserHttp { } } + static Future userFavFolderDetailNew( + {required int mediaId, + required int pn, + required int ps, + String keyword = '', + String order = 'mtime', + int type = 0}) async { + var res = await Request().get(Api.userFavFolderDetail, data: { + 'media_id': mediaId, + 'pn': pn, + 'ps': ps, + 'keyword': keyword, + 'order': order, + 'type': type, + 'tid': 0, + 'platform': 'web' + }); + if (res.data['code'] == 0) { + return LoadingState.success(FavDetailData.fromJson(res.data['data'])); + } else { + return LoadingState.error(res.data['message']); + } + } + static Future userFavFolderDetail( {required int mediaId, required int pn, diff --git a/lib/pages/fav_detail/controller.dart b/lib/pages/fav_detail/controller.dart index 9986c9c2..1863d8e1 100644 --- a/lib/pages/fav_detail/controller.dart +++ b/lib/pages/fav_detail/controller.dart @@ -1,20 +1,15 @@ +import 'package:PiliPalaX/http/loading_state.dart'; +import 'package:PiliPalaX/http/user.dart'; +import 'package:PiliPalaX/pages/common/common_controller.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -import 'package:PiliPalaX/http/user.dart'; import 'package:PiliPalaX/http/video.dart'; -import 'package:PiliPalaX/models/user/fav_detail.dart'; import 'package:PiliPalaX/models/user/fav_folder.dart'; -class FavDetailController extends GetxController { +class FavDetailController extends CommonController { FavFolderItemData? item; - Rx favDetailData = FavDetailData().obs; - int? mediaId; late String heroTag; - int currentPage = 1; - bool isLoadingMore = false; - RxMap favInfo = {}.obs; - RxList favList = [].obs; RxString loadingText = '加载中...'.obs; int mediaCount = 0; @@ -26,52 +21,60 @@ class FavDetailController extends GetxController { heroTag = Get.parameters['heroTag']!; } super.onInit(); + + queryData(); } - Future queryUserFavFolderDetail({type = 'init'}) async { - if (type == 'onLoad' && favList.length >= mediaCount) { + @override + Future onRefresh() { + loadingText.value = '加载中...'; + return super.onRefresh(); + } + + @override + Future queryData([bool isRefresh = true]) { + if (loadingText.value == '没有更多了') { + return Future.value(); + } + return super.queryData(isRefresh); + } + + @override + bool customHandleResponse(Success response) { + if (currentPage == 1) { + mediaCount = response.response.info['media_count']; + } + List currentList = loadingState.value is Success + ? (loadingState.value as Success).response + : []; + List dataList = currentPage == 1 + ? response.response.medias + : currentList + response.response.medias; + loadingState.value = LoadingState.success(dataList); + if (dataList.length >= mediaCount) { loadingText.value = '没有更多了'; - return; } - isLoadingMore = true; - var res = await UserHttp.userFavFolderDetail( - pn: currentPage, - ps: 20, - mediaId: mediaId!, - ); - if (res['status']) { - favInfo.value = res['data'].info; - if (currentPage == 1 && type == 'init') { - favList.value = res['data'].medias; - mediaCount = res['data'].info['media_count']; - } else if (type == 'onLoad') { - favList.addAll(res['data'].medias); - } - if (favList.length >= mediaCount) { - loadingText.value = '没有更多了'; - } - } - currentPage += 1; - isLoadingMore = false; - return res; + return true; } onCancelFav(int id) async { var result = await VideoHttp.favVideo( - aid: id, addIds: '', delIds: mediaId.toString()); + aid: id, + addIds: '', + delIds: mediaId.toString(), + ); if (result['status']) { - List dataList = favList; - for (var i in dataList) { - if (i.id == id) { - dataList.remove(i); - break; - } - } + List dataList = (loadingState.value as Success).response; + dataList = dataList.where((item) => item.id != id).toList(); + loadingState.value = LoadingState.success(dataList); SmartDialog.showToast('取消收藏'); } } - onLoad() { - queryUserFavFolderDetail(type: 'onLoad'); - } + @override + Future customGetData() => UserHttp.userFavFolderDetailNew( + pn: currentPage, + ps: 20, + mediaId: mediaId!, + ); } diff --git a/lib/pages/fav_detail/view.dart b/lib/pages/fav_detail/view.dart index 09894d2e..08cef708 100644 --- a/lib/pages/fav_detail/view.dart +++ b/lib/pages/fav_detail/view.dart @@ -1,12 +1,12 @@ import 'dart:async'; +import 'package:PiliPalaX/http/loading_state.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/common/skeleton/video_card_h.dart'; import 'package:PiliPalaX/common/widgets/http_error.dart'; import 'package:PiliPalaX/common/widgets/network_img_layer.dart'; -import 'package:PiliPalaX/common/widgets/no_data.dart'; import 'package:PiliPalaX/pages/fav_detail/index.dart'; import '../../common/constants.dart'; @@ -21,31 +21,29 @@ class FavDetailPage extends StatefulWidget { } class _FavDetailPageState extends State { - late final ScrollController _controller = ScrollController(); final FavDetailController _favDetailController = Get.put(FavDetailController()); late StreamController titleStreamC; // a - Future? _futureBuilderFuture; late String mediaId; @override void initState() { super.initState(); mediaId = Get.parameters['mediaId']!; - _futureBuilderFuture = _favDetailController.queryUserFavFolderDetail(); titleStreamC = StreamController(); - _controller.addListener( + _favDetailController.scrollController.addListener( () { - if (_controller.offset > 160) { + if (_favDetailController.scrollController.offset > 160) { titleStreamC.add(true); - } else if (_controller.offset <= 160) { + } else if (_favDetailController.scrollController.offset <= 160) { titleStreamC.add(false); } - if (_controller.position.pixels >= - _controller.position.maxScrollExtent - 200) { + if (_favDetailController.scrollController.position.pixels >= + _favDetailController.scrollController.position.maxScrollExtent - + 200) { EasyThrottle.throttle('favDetail', const Duration(seconds: 1), () { - _favDetailController.onLoad(); + _favDetailController.onLoadMore(); }); } }, @@ -55,8 +53,7 @@ class _FavDetailPageState extends State { @override void dispose() { titleStreamC.close(); - _controller.removeListener(() {}); - _controller.dispose(); + _favDetailController.scrollController.removeListener(() {}); super.dispose(); } @@ -65,7 +62,7 @@ class _FavDetailPageState extends State { return Scaffold( body: CustomScrollView( physics: const AlwaysScrollableScrollPhysics(), - controller: _controller, + controller: _favDetailController.scrollController, slivers: [ SliverAppBar( expandedHeight: 220 - MediaQuery.of(context).padding.top, @@ -187,95 +184,71 @@ class _FavDetailPageState extends State { ), ), ), - // SliverToBoxAdapter( - // child: Padding( - // padding: const EdgeInsets.only(top: 15, bottom: 8, left: 14), - // child: Obx( - // () => Text( - // '共${_favDetailController.favList.length}条视频', - // style: TextStyle( - // fontSize: - // Theme.of(context).textTheme.labelMedium!.fontSize, - // color: Theme.of(context).colorScheme.outline, - // letterSpacing: 1), - // ), - // ), - // ), - // ), - FutureBuilder( - future: _futureBuilderFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - Map data = snapshot.data; - if (data['status']) { - if (_favDetailController.item!.mediaCount == 0) { - return const NoData(); - } else { - List favList = _favDetailController.favList; - return Obx( - () => favList.isEmpty - ? const SliverToBoxAdapter(child: SizedBox()) - : SliverGrid( - gridDelegate: - SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.safeSpace, - maxCrossAxisExtent: Grid.maxRowWidth * 2, - childAspectRatio: - StyleString.aspectRatio * 2.4, - mainAxisExtent: 0), - delegate: - SliverChildBuilderDelegate((context, index) { - return FavVideoCardH( - videoItem: favList[index], - callFn: () => _favDetailController - .onCancelFav(favList[index].id), - ); - }, childCount: favList.length), - ), - ); - } - } else { - return HttpError( - errMsg: data['msg'], - fn: () => setState(() {}), - ); - } - } else { - // 骨架屏 - return SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.safeSpace, - maxCrossAxisExtent: Grid.maxRowWidth * 2, - childAspectRatio: StyleString.aspectRatio * 2.4, - mainAxisExtent: 0), - delegate: SliverChildBuilderDelegate((context, index) { - return const VideoCardHSkeleton(); - }, childCount: 10), - ); - } - }, - ), - SliverToBoxAdapter( - child: Container( - height: MediaQuery.of(context).padding.bottom + 60, - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: Center( - child: Obx( - () => Text( - _favDetailController.loadingText.value, - style: TextStyle( - color: Theme.of(context).colorScheme.outline, - fontSize: 13), - ), - ), - ), - ), - ) + Obx(() => _buildBody(_favDetailController.loadingState.value)), ], ), ); } + + Widget _buildBody(LoadingState loadingState) { + return loadingState is Success + ? loadingState.response.isEmpty + ? const SliverToBoxAdapter(child: SizedBox()) + : SliverGrid( + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.safeSpace, + maxCrossAxisExtent: Grid.maxRowWidth * 2, + childAspectRatio: StyleString.aspectRatio * 2.4, + mainAxisExtent: 0, + ), + delegate: SliverChildBuilderDelegate( + (context, index) { + if (index == loadingState.response.length) { + return Container( + height: MediaQuery.of(context).padding.bottom + 60, + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom), + child: Center( + child: Obx( + () => Text( + _favDetailController.loadingText.value, + style: TextStyle( + color: Theme.of(context).colorScheme.outline, + fontSize: 13), + ), + ), + ), + ); + } + return FavVideoCardH( + videoItem: loadingState.response[index], + callFn: () => _favDetailController + .onCancelFav(loadingState.response[index].id), + ); + }, + childCount: loadingState.response.length + 1, + ), + ) + : loadingState is Error + ? HttpError( + errMsg: loadingState.errMsg, + fn: _favDetailController.onReload, + ) + : SliverGrid( + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.safeSpace, + maxCrossAxisExtent: Grid.maxRowWidth * 2, + childAspectRatio: StyleString.aspectRatio * 2.4, + mainAxisExtent: 0, + ), + delegate: SliverChildBuilderDelegate( + (context, index) { + return const VideoCardHSkeleton(); + }, + childCount: 10, + ), + ); + } }