diff --git a/lib/http/user.dart b/lib/http/user.dart index fc9c247c..b047621e 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -89,7 +89,7 @@ class UserHttp { } } - static Future userFavFolderDetailNew( + static Future userFavFolderDetail( {required int mediaId, required int pn, required int ps, @@ -113,31 +113,6 @@ class UserHttp { } } - static Future userFavFolderDetail( - {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) { - FavDetailData data = FavDetailData.fromJson(res.data['data']); - return {'status': true, 'data': data}; - } else { - return {'status': false, 'data': [], 'msg': res.data['message']}; - } - } - // 稍后再看 static Future seeYouLater() async { var res = await Request().get(Api.seeYouLater); diff --git a/lib/pages/fav_detail/controller.dart b/lib/pages/fav_detail/controller.dart index 1863d8e1..aefbc0d1 100644 --- a/lib/pages/fav_detail/controller.dart +++ b/lib/pages/fav_detail/controller.dart @@ -72,7 +72,7 @@ class FavDetailController extends CommonController { } @override - Future customGetData() => UserHttp.userFavFolderDetailNew( + Future customGetData() => UserHttp.userFavFolderDetail( pn: currentPage, ps: 20, mediaId: mediaId!, diff --git a/lib/pages/fav_search/controller.dart b/lib/pages/fav_search/controller.dart index 5fb8efa8..8b875f65 100644 --- a/lib/pages/fav_search/controller.dart +++ b/lib/pages/fav_search/controller.dart @@ -1,26 +1,23 @@ +import 'package:PiliPalaX/http/loading_state.dart'; +import 'package:PiliPalaX/pages/common/common_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/http/user.dart'; -import 'package:PiliPalaX/models/user/fav_detail.dart'; import '../../http/video.dart'; -class FavSearchController extends GetxController { - final ScrollController scrollController = ScrollController(); +class FavSearchController extends CommonController { Rx controller = TextEditingController().obs; final FocusNode searchFocusNode = FocusNode(); RxString searchKeyWord = ''.obs; // 搜索词 String hintText = '请输入已收藏视频名称'; // 默认 - RxBool loadingStatus = false.obs; // 加载状态 RxString loadingText = '加载中...'.obs; // 加载提示 bool hasMore = false; late int searchType; late int mediaId; - int currentPage = 1; // 当前页 int count = 0; // 总数 - RxList favList = [].obs; @override void onInit() { @@ -39,55 +36,60 @@ class FavSearchController extends GetxController { } } + @override + Future onRefresh() { + hasMore = true; + return super.onRefresh(); + } + void onChange(value) { searchKeyWord.value = value; } - // 提交搜索内容 - void submit() { - loadingStatus.value = true; - currentPage = 1; - searchFav(); - } - - // 搜索收藏夹视频 - Future searchFav({type = 'init'}) async { - var res = await await UserHttp.userFavFolderDetail( - pn: currentPage, - ps: 20, - mediaId: mediaId, - keyword: searchKeyWord.value, - type: searchType, - ); - if (res['status']) { - if (currentPage == 1 && type == 'init') { - favList.value = res['data'].medias; - } else if (type == 'onLoad') { - favList.addAll(res['data'].medias); - } - hasMore = res['data'].hasMore; + @override + Future queryData([bool isRefresh = true]) { + if (!hasMore) { + return Future.value(); } - currentPage += 1; - loadingStatus.value = false; + return super.queryData(isRefresh); } - onLoad() { - if (!hasMore) return; - searchFav(type: 'onLoad'); + @override + bool customHandleResponse(Success response) { + 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); + hasMore = response.response.hasMore; + return true; } onCancelFav(int id) async { var result = await VideoHttp.favVideo( 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('取消收藏'); } } + + @override + Future customGetData() => UserHttp.userFavFolderDetail( + pn: currentPage, + ps: 20, + mediaId: mediaId, + keyword: searchKeyWord.value, + type: searchType, + ); + + @override + void onClose() { + searchFocusNode.dispose(); + super.onClose(); + } } diff --git a/lib/pages/fav_search/view.dart b/lib/pages/fav_search/view.dart index f8b4e8ac..2df046d8 100644 --- a/lib/pages/fav_search/view.dart +++ b/lib/pages/fav_search/view.dart @@ -1,7 +1,8 @@ +import 'package:PiliPalaX/common/widgets/http_error.dart'; +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/no_data.dart'; import 'package:PiliPalaX/pages/fav_detail/widget/fav_video_card.dart'; @@ -27,7 +28,7 @@ class _FavSearchPageState extends State { if (_favSearchCtr.scrollController.position.pixels >= _favSearchCtr.scrollController.position.maxScrollExtent - 300) { EasyThrottle.throttle('fav', const Duration(seconds: 1), () { - _favSearchCtr.onLoad(); + _favSearchCtr.onLoadMore(); }); } }, @@ -36,9 +37,7 @@ class _FavSearchPageState extends State { @override void dispose() { - _favSearchCtr.searchFocusNode.dispose(); _favSearchCtr.scrollController.removeListener(() {}); - _favSearchCtr.scrollController.dispose(); super.dispose(); } @@ -50,7 +49,7 @@ class _FavSearchPageState extends State { actions: [ IconButton( tooltip: '搜索', - onPressed: () => _favSearchCtr.submit(), + onPressed: _favSearchCtr.onRefresh, icon: const Icon(Icons.search_outlined, size: 22)), const SizedBox(width: 10) ], @@ -71,47 +70,61 @@ class _FavSearchPageState extends State { onPressed: () => _favSearchCtr.onClear(), ), ), - onSubmitted: (String value) => _favSearchCtr.submit(), + onSubmitted: (String value) => _favSearchCtr.onRefresh(), ), ), ), - body: Obx( - () => _favSearchCtr.loadingStatus.value && _favSearchCtr.favList.isEmpty - ? ListView.builder( - itemCount: 10, - itemBuilder: (context, index) { - return const VideoCardHSkeleton(); - }, - ) - : _favSearchCtr.favList.isNotEmpty - ? ListView.builder( - controller: _favSearchCtr.scrollController, - itemCount: _favSearchCtr.favList.length + 1, - itemBuilder: (context, index) { - if (index == _favSearchCtr.favList.length) { - return Container( - height: MediaQuery.of(context).padding.bottom + 60, - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - ); - } else { - return FavVideoCardH( - videoItem: _favSearchCtr.favList[index], - searchType: searchType, - callFn: () => searchType != 1 - ? _favSearchCtr - .onCancelFav(_favSearchCtr.favList[index].id!) - : {}, - ); - } - }, - ) - : const CustomScrollView( - slivers: [ - NoData(), - ], - ), - ), + body: Obx(() => _buildBody(_favSearchCtr.loadingState.value)), ); } + + Widget _buildBody(LoadingState loadingState) { + return loadingState is Success + ? loadingState.response.isEmpty + ? CustomScrollView( + slivers: [ + HttpError( + errMsg: '没有数据', + fn: _favSearchCtr.onReload, + ), + ], + ) + : ListView.builder( + controller: _favSearchCtr.scrollController, + itemCount: loadingState.response.length + 1, + itemBuilder: (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, + ), + ); + } else { + return FavVideoCardH( + videoItem: loadingState.response[index], + searchType: searchType, + callFn: () => searchType != 1 + ? _favSearchCtr + .onCancelFav(loadingState.response[index].id!) + : {}, + ); + } + }, + ) + : loadingState is Error + ? CustomScrollView( + slivers: [ + HttpError( + errMsg: loadingState.errMsg, + fn: _favSearchCtr.onReload, + ), + ], + ) + : const CustomScrollView( + slivers: [ + NoData(), + ], + ); + } }