diff --git a/lib/http/user.dart b/lib/http/user.dart index b047621e..57525c2d 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -114,25 +114,20 @@ class UserHttp { } // 稍后再看 - static Future seeYouLater() async { + static Future seeYouLater() async { var res = await Request().get(Api.seeYouLater); if (res.data['code'] == 0) { if (res.data['data']['count'] == 0) { - return { - 'status': true, - 'data': {'list': [], 'count': 0} - }; + return LoadingState.empty(); } List list = []; for (var i in res.data['data']['list']) { list.add(HotVideoItemModel.fromJson(i)); } - return { - 'status': true, - 'data': {'list': list, 'count': res.data['data']['count']} - }; + return LoadingState.success( + {'list': list, 'count': res.data['data']['count']}); } else { - return {'status': false, 'data': [], 'msg': res.data['message']}; + return LoadingState.error(res.data['message']); } } diff --git a/lib/pages/later/controller.dart b/lib/pages/later/controller.dart index bf3d070e..513c3522 100644 --- a/lib/pages/later/controller.dart +++ b/lib/pages/later/controller.dart @@ -1,26 +1,31 @@ +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/model_hot_video_item.dart'; -class LaterController extends GetxController { - final ScrollController scrollController = ScrollController(); - RxList laterList = [].obs; - int count = 0; - RxBool isLoading = false.obs; +class LaterController extends CommonController { + RxInt count = (-1).obs; - Future queryLaterList() async { - isLoading.value = true; - var res = await UserHttp.seeYouLater(); - if (res['status']) { - count = res['data']['count']; - if (count > 0) { - laterList.value = res['data']['list']; - } + @override + void onInit() { + super.onInit(); + queryData(); + } + + @override + bool customHandleResponse(Success response) { + if (currentPage == 1) { + count.value = response.response['count']; } - isLoading.value = false; - return res; + List currentList = loadingState.value is Success + ? (loadingState.value as Success).response + : []; + loadingState.value = currentPage == 1 + ? LoadingState.success(response.response['list']) + : LoadingState.success(currentList + response.response['list']); + return true; } Future toViewDel(BuildContext context, {int? aid}) async { @@ -44,10 +49,12 @@ class LaterController extends GetxController { var res = await UserHttp.toViewDel(aid: aid); if (res['status']) { if (aid != null) { - laterList.removeWhere((e) => e.aid == aid); + List list = (loadingState.value as Success).response; + list.removeWhere((e) => e.aid == aid); + loadingState.value = LoadingState.success(list); } else { - laterList.clear(); - queryLaterList(); + loadingState.value = LoadingState.loading(); + onRefresh(); } } Get.back(); @@ -81,7 +88,7 @@ class LaterController extends GetxController { onPressed: () async { var res = await UserHttp.toViewClear(); if (res['status']) { - laterList.clear(); + loadingState.value = LoadingState.empty(); } Get.back(); SmartDialog.showToast(res['msg']); @@ -93,4 +100,7 @@ class LaterController extends GetxController { }, ); } + + @override + Future customGetData() => UserHttp.seeYouLater(); } diff --git a/lib/pages/later/view.dart b/lib/pages/later/view.dart index cc0bc739..b451da51 100644 --- a/lib/pages/later/view.dart +++ b/lib/pages/later/view.dart @@ -1,3 +1,4 @@ +import 'package:PiliPalaX/http/loading_state.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/common/skeleton/video_card_h.dart'; @@ -18,13 +19,6 @@ class LaterPage extends StatefulWidget { class _LaterPageState extends State { final LaterController _laterController = Get.put(LaterController()); - Future? _futureBuilderFuture; - - @override - void initState() { - _futureBuilderFuture = _laterController.queryLaterList(); - super.initState(); - } @override Widget build(BuildContext context) { @@ -33,19 +27,14 @@ class _LaterPageState extends State { titleSpacing: 0, centerTitle: false, title: Obx( - () => _laterController.laterList.isNotEmpty - ? Text( - '稍后再看 (${_laterController.laterList.length})', - style: Theme.of(context).textTheme.titleMedium, - ) - : Text( - '稍后再看', - style: Theme.of(context).textTheme.titleMedium, - ), + () => Text( + '稍后再看${_laterController.count.value == -1 ? '' : ' (${_laterController.count.value})'}', + style: Theme.of(context).textTheme.titleMedium, + ), ), actions: [ Obx( - () => _laterController.laterList.isNotEmpty + () => _laterController.count.value != -1 ? TextButton( onPressed: () => _laterController.toViewDel(context), child: const Text('移除已看'), @@ -53,7 +42,7 @@ class _LaterPageState extends State { : const SizedBox(), ), Obx( - () => _laterController.laterList.isNotEmpty + () => _laterController.count.value != -1 ? IconButton( tooltip: '一键清空', onPressed: () => _laterController.toViewClear(context), @@ -73,79 +62,63 @@ class _LaterPageState extends State { controller: _laterController.scrollController, slivers: [ SliverPadding( - padding: - const EdgeInsets.symmetric(horizontal: StyleString.safeSpace), - sliver: FutureBuilder( - future: _futureBuilderFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - Map data = snapshot.data as Map; - if (data['status']) { - return Obx( - () => _laterController.laterList.isNotEmpty && - !_laterController.isLoading.value - ? SliverGrid( - gridDelegate: - SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.safeSpace, - crossAxisSpacing: StyleString.safeSpace, - maxCrossAxisExtent: - Grid.maxRowWidth * 2, - childAspectRatio: - StyleString.aspectRatio * 2.4, - mainAxisExtent: 0), - delegate: SliverChildBuilderDelegate( - (context, index) { - var videoItem = - _laterController.laterList[index]; - return VideoCardH( - videoItem: videoItem, - source: 'later', - longPress: () => - _laterController.toViewDel(context, - aid: videoItem.aid)); - }, - childCount: - _laterController.laterList.length), - ) - : _laterController.isLoading.value - ? const SliverToBoxAdapter( - child: Center(child: Text('加载中')), - ) - : const NoData(), - ); - } else { - return HttpError( - errMsg: data['msg'], - fn: () => setState(() { - _futureBuilderFuture = - _laterController.queryLaterList(); - }), - ); - } - } else { - // 骨架屏 - return SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.safeSpace, - 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: SizedBox( - height: MediaQuery.of(context).padding.bottom + 10, + padding: EdgeInsets.only( + left: StyleString.safeSpace, + right: StyleString.safeSpace, + bottom: MediaQuery.of(context).padding.bottom + 10, ), - ) + sliver: Obx( + () => _buildBody(_laterController.loadingState.value), + ), + ), ], ), ); } + + Widget _buildBody(LoadingState loadingState) { + return loadingState is Success + ? SliverGrid( + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.safeSpace, + crossAxisSpacing: StyleString.safeSpace, + maxCrossAxisExtent: Grid.maxRowWidth * 2, + childAspectRatio: StyleString.aspectRatio * 2.4, + mainAxisExtent: 0, + ), + delegate: SliverChildBuilderDelegate( + (context, index) { + var videoItem = loadingState.response[index]; + return VideoCardH( + videoItem: videoItem, + source: 'later', + longPress: () => _laterController.toViewDel(context, + aid: videoItem.aid)); + }, + childCount: loadingState.response.length, + ), + ) + : loadingState is Empty + ? const NoData() + : loadingState is Error + ? HttpError( + errMsg: loadingState.errMsg, + fn: _laterController.onReload, + ) + : SliverGrid( + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.safeSpace, + crossAxisSpacing: StyleString.safeSpace, + maxCrossAxisExtent: Grid.maxRowWidth * 2, + childAspectRatio: StyleString.aspectRatio * 2.4, + mainAxisExtent: 0, + ), + delegate: SliverChildBuilderDelegate( + (context, index) { + return const VideoCardHSkeleton(); + }, + childCount: 10, + ), + ); + } }