From c9fe3c6485b5fbdfed36aba8402002c32a4278bb Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Fri, 10 Jan 2025 10:17:54 +0800 Subject: [PATCH] mod: bangumi: load more followlist Signed-off-by: bggRGjQaUbCoE --- lib/http/api.dart | 5 +- lib/http/bangumi.dart | 15 ++++-- lib/pages/bangumi/controller.dart | 76 +++++++++++++++++++++++++------ lib/pages/bangumi/view.dart | 30 +++++++++--- 4 files changed, 97 insertions(+), 29 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 8d99b5f5..b0ddb682 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -390,9 +390,8 @@ class Api { static const String bangumiList = '/pgc/season/index/result?st=1&order=3&season_version=-1&spoken_language_type=-1&area=-1&is_finish=-1©right=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&sort=0&season_type=1&pagesize=20&type=1'; - // 我的订阅 - static const String bangumiFollow = - '/x/space/bangumi/follow/list?type=1&follow_status=0&pn=1&ps=15&ts=1691544359969'; + // 我的追番/追剧 ?type=1&pn=1&ps=15 + static const String bangumiFollow = '/x/space/bangumi/follow/list'; // 黑名单 static const String blackLst = '/x/relation/blacks'; diff --git a/lib/http/bangumi.dart b/lib/http/bangumi.dart index e37b95a9..bf1caf56 100644 --- a/lib/http/bangumi.dart +++ b/lib/http/bangumi.dart @@ -16,13 +16,20 @@ class BangumiHttp { } } - static Future bangumiFollow({int? mid}) async { - var res = - await Request().get(Api.bangumiFollow, queryParameters: {'vmid': mid}); + static Future bangumiFollow({ + dynamic mid, + required int type, + required int pn, + }) async { + var res = await Request().get(Api.bangumiFollow, queryParameters: { + 'vmid': mid, + 'type': type, + 'pn': pn, + }); if (res.data['code'] == 0) { BangumiListDataModel data = BangumiListDataModel.fromJson(res.data['data']); - return LoadingState.success(data.list); + return LoadingState.success(data); } else { return LoadingState.error(res.data['message']); } diff --git a/lib/pages/bangumi/controller.dart b/lib/pages/bangumi/controller.dart index cda130be..baac445d 100644 --- a/lib/pages/bangumi/controller.dart +++ b/lib/pages/bangumi/controller.dart @@ -1,5 +1,8 @@ import 'package:PiliPlus/http/loading_state.dart'; +import 'package:PiliPlus/models/bangumi/list.dart'; import 'package:PiliPlus/pages/common/common_controller.dart'; +import 'package:PiliPlus/utils/extension.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPlus/http/bangumi.dart'; import 'package:PiliPlus/utils/storage.dart'; @@ -7,33 +10,76 @@ import 'package:PiliPlus/utils/storage.dart'; class BangumiController extends CommonController { bool isLoadingMore = true; RxBool isLogin = false.obs; - late int mid; + int? mid; dynamic userInfo; - Rx followState = LoadingState.loading().obs; - @override void onInit() { super.onInit(); userInfo = GStorage.userInfo.get('userInfoCache'); - if (userInfo != null) { - mid = userInfo.mid; - } + mid = userInfo?.mid; isLogin.value = userInfo != null; queryData(); queryBangumiFollow(); - } - - // 我的订阅 - Future queryBangumiFollow() async { - userInfo = userInfo ?? GStorage.userInfo.get('userInfoCache'); - if (userInfo != null) { - followState.value = await BangumiHttp.bangumiFollow(mid: userInfo.mid); + if (isLogin.value) { + followController = ScrollController(); } } @override - Future customGetData() => - BangumiHttp.bangumiList(page: currentPage); + Future onRefresh() { + if (isLogin.value) { + followPage = 1; + followEnd = false; + } + return super.onRefresh(); + } + + late int followPage = 1; + late RxInt followCount = (-1).obs; + late bool followLoading = false; + late bool followEnd = false; + late Rx followState = LoadingState.loading().obs; + ScrollController? followController; + + // 我的订阅 + Future queryBangumiFollow([bool isRefresh = true]) async { + if (isLogin.value.not || followLoading || (isRefresh.not && followEnd)) { + return; + } + followLoading = true; + dynamic res = await BangumiHttp.bangumiFollow( + mid: mid, + type: 1, + pn: followPage, + ); + if (res is Success) { + BangumiListDataModel data = res.response; + followPage++; + followEnd = data.hasNext == 0 || data.list.isNullOrEmpty; + followCount.value = data.total ?? -1; + if (isRefresh.not && followState.value is Success) { + data.list?.insertAll(0, (followState.value as Success).response); + } + followState.value = LoadingState.success(data.list); + if (isRefresh) { + followController?.animToTop(); + } + } else { + followState.value = res; + } + followLoading = false; + } + + @override + Future customGetData() => BangumiHttp.bangumiList( + page: currentPage, + ); + + @override + void onClose() { + followController?.dispose(); + super.onClose(); + } } diff --git a/lib/pages/bangumi/view.dart b/lib/pages/bangumi/view.dart index 0361718d..f5e76239 100644 --- a/lib/pages/bangumi/view.dart +++ b/lib/pages/bangumi/view.dart @@ -1,11 +1,11 @@ import 'dart:async'; +import 'package:PiliPlus/common/widgets/loading_widget.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:get/get.dart'; -import 'package:nil/nil.dart'; import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/http_error.dart'; import 'package:PiliPlus/pages/home/index.dart'; @@ -82,14 +82,19 @@ class _BangumiPageState extends State child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - '最近追番', - style: Theme.of(context).textTheme.titleMedium, + Obx( + () => Text( + '最近追番${_bangumiController.followCount.value == -1 ? '' : ' ${_bangumiController.followCount.value}'}', + style: Theme.of(context).textTheme.titleMedium, + ), ), IconButton( tooltip: '刷新', onPressed: () { - _bangumiController.queryBangumiFollow(); + _bangumiController + ..followPage = 1 + ..followEnd = false + ..queryBangumiFollow(); }, icon: const Icon( Icons.refresh, @@ -177,9 +182,13 @@ class _BangumiPageState extends State Widget _buildFollowList(Success loadingState) { return ListView.builder( + controller: _bangumiController.followController, scrollDirection: Axis.horizontal, itemCount: loadingState.response.length, itemBuilder: (context, index) { + if (index == loadingState.response.length - 1) { + _bangumiController.queryBangumiFollow(false); + } return Container( width: Grid.maxRowWidth / 2, margin: EdgeInsets.only( @@ -198,11 +207,18 @@ class _BangumiPageState extends State Widget _buildFollowBody(LoadingState loadingState) { return switch (loadingState) { - Loading() => nil, + Loading() => loadingWidget, Success() => (loadingState.response as List?)?.isNotEmpty == true ? _buildFollowList(loadingState) : const Center(child: Text('还没有追番')), - Error() => Center(child: Text(loadingState.errMsg)), + Error() => Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + alignment: Alignment.center, + child: Text( + loadingState.errMsg, + textAlign: TextAlign.center, + ), + ), LoadingState() => throw UnimplementedError(), }; }