From d71790b03a3d06d4f53c5109e1bd5970ecc79cb6 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Wed, 9 Aug 2023 10:35:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9C=80=E8=BF=91=E8=BF=BD=E7=95=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 4 + lib/http/bangumi.dart | 16 ++ lib/models/bangumi/list.dart | 5 + lib/pages/bangumi/controller.dart | 26 +++ lib/pages/bangumi/view.dart | 150 ++++++++++++++---- lib/pages/bangumi/widgets/bangumu_card_v.dart | 94 ++++------- 6 files changed, 201 insertions(+), 94 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index d8158b54..0ea3e5f4 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -274,4 +274,8 @@ class Api { // type=1 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'; } diff --git a/lib/http/bangumi.dart b/lib/http/bangumi.dart index 6793dd83..bd20366c 100644 --- a/lib/http/bangumi.dart +++ b/lib/http/bangumi.dart @@ -17,4 +17,20 @@ class BangumiHttp { }; } } + + static Future bangumiFollow({int? mid}) async { + var res = await Request().get(Api.bangumiFollow, data: {'vmid': mid}); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': BangumiListDataModel.fromJson(res.data['data']) + }; + } else { + return { + 'status': false, + 'data': [], + 'msg': res.data['message'], + }; + } + } } diff --git a/lib/models/bangumi/list.dart b/lib/models/bangumi/list.dart index 3971f3c7..c15014d0 100644 --- a/lib/models/bangumi/list.dart +++ b/lib/models/bangumi/list.dart @@ -45,6 +45,7 @@ class BangumiListItemModel { this.subTitle, this.title, this.titleIcon, + this.progress, }); String? badge; @@ -64,6 +65,8 @@ class BangumiListItemModel { String? title; String? titleIcon; + String? progress; + BangumiListItemModel.fromJson(Map json) { badge = json['badge'] == '' ? null : json['badge']; badgeType = json['badge_type']; @@ -81,5 +84,7 @@ class BangumiListItemModel { subTitle = json['sub_title']; title = json['title']; titleIcon = json['title_icon']; + + progress = json['progress']; } } diff --git a/lib/pages/bangumi/controller.dart b/lib/pages/bangumi/controller.dart index 796a541e..dde68075 100644 --- a/lib/pages/bangumi/controller.dart +++ b/lib/pages/bangumi/controller.dart @@ -1,15 +1,32 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:hive/hive.dart'; import 'package:pilipala/http/bangumi.dart'; import 'package:pilipala/models/bangumi/list.dart'; +import 'package:pilipala/utils/storage.dart'; class BangumiController extends GetxController { final ScrollController scrollController = ScrollController(); RxList bangumiList = [BangumiListItemModel()].obs; + RxList bangumiFollowList = [BangumiListItemModel()].obs; int _currentPage = 1; bool isLoadingMore = true; + Box user = GStrorage.user; + RxBool userLogin = false.obs; + late int mid; + + @override + void onInit() { + super.onInit(); + mid = int.parse( + Get.parameters['mid'] ?? user.get(UserBoxKey.userMid).toString()); + userLogin.value = user.get(UserBoxKey.userLogin) != null; + } Future queryBangumiListFeed({type = 'init'}) async { + if (type == 'init') { + _currentPage = 1; + } var result = await BangumiHttp.bangumiList(page: _currentPage); if (result['status']) { if (type == 'init') { @@ -27,4 +44,13 @@ class BangumiController extends GetxController { Future onLoad() async { queryBangumiListFeed(type: 'onLoad'); } + + // 我的订阅 + Future queryBangumiFollow() async { + var result = await BangumiHttp.bangumiFollow(mid: 17340771); + if (result['status']) { + bangumiFollowList.value = result['data'].list; + } else {} + return result; + } } diff --git a/lib/pages/bangumi/view.dart b/lib/pages/bangumi/view.dart index b870906d..158e3b22 100644 --- a/lib/pages/bangumi/view.dart +++ b/lib/pages/bangumi/view.dart @@ -3,10 +3,12 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:get/get.dart'; +import 'package:hive/hive.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/pages/main/index.dart'; import 'package:pilipala/pages/rcmd/view.dart'; +import 'package:pilipala/utils/storage.dart'; import 'controller.dart'; import 'widgets/bangumu_card_v.dart'; @@ -22,7 +24,6 @@ class _BangumiPageState extends State with AutomaticKeepAliveClientMixin { final BangumiController _bangumidController = Get.put(BangumiController()); late Future? _futureBuilderFuture; - @override bool get wantKeepAlive => true; @@ -56,6 +57,7 @@ class _BangumiPageState extends State @override Widget build(BuildContext context) { + super.build(context); return Container( clipBehavior: Clip.hardEdge, margin: const EdgeInsets.only( @@ -63,37 +65,121 @@ class _BangumiPageState extends State decoration: const BoxDecoration( borderRadius: BorderRadius.all(StyleString.imgRadius), ), - child: RefreshIndicator( - onRefresh: () async { - return Future.delayed(const Duration(seconds: 2)); - }, - child: CustomScrollView( - controller: _bangumidController.scrollController, - slivers: [ - SliverPadding( - padding: EdgeInsets.zero, - sliver: FutureBuilder( - future: _futureBuilderFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - Map data = snapshot.data as Map; - if (data['status']) { - return Obx(() => contentGrid(_bangumidController, - _bangumidController.bangumiList)); - } else { - return HttpError( - errMsg: data['msg'], - fn: () => {}, - ); - } - } else { - return contentGrid(_bangumidController, []); - } - }, + child: Expanded( + child: RefreshIndicator( + onRefresh: () async { + await _bangumidController.queryBangumiListFeed(type: 'init'); + return _bangumidController.queryBangumiFollow(); + }, + child: CustomScrollView( + controller: _bangumidController.scrollController, + slivers: [ + SliverToBoxAdapter( + child: Obx( + () => Visibility( + visible: _bangumidController.userLogin.value, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only( + top: 10, bottom: 10, left: 6), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '最近追番', + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ), + ), + SizedBox( + height: 254, + child: FutureBuilder( + future: _bangumidController.queryBangumiFollow(), + builder: (context, snapshot) { + if (snapshot.connectionState == + ConnectionState.done) { + Map data = snapshot.data as Map; + if (data['status']) { + return Obx( + () => ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: _bangumidController + .bangumiFollowList.length, + itemBuilder: (context, index) { + return Container( + width: Get.size.width / 3, + height: 254, + margin: EdgeInsets.only( + right: index < + _bangumidController + .bangumiFollowList + .length - + 1 + ? StyleString.safeSpace + : 0), + child: BangumiCardV( + bangumiItem: _bangumidController + .bangumiFollowList[index], + ), + ); + }, + ), + ); + } else { + return SizedBox(); + } + } else { + return SizedBox(); + } + }, + ), + ), + ], + ), + ), + ), ), - ), - const LoadingMore() - ], + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.only(top: 10, bottom: 10, left: 6), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '推荐', + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ), + ), + ), + SliverPadding( + padding: EdgeInsets.zero, + sliver: FutureBuilder( + future: _futureBuilderFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + Map data = snapshot.data as Map; + if (data['status']) { + return Obx(() => contentGrid(_bangumidController, + _bangumidController.bangumiList)); + } else { + return HttpError( + errMsg: data['msg'], + fn: () => {}, + ); + } + } else { + return contentGrid(_bangumidController, []); + } + }, + ), + ), + const LoadingMore() + ], + ), ), ), ); @@ -108,7 +194,7 @@ class _BangumiPageState extends State crossAxisSpacing: StyleString.cardSpace, // 列数 crossAxisCount: 3, - mainAxisExtent: Get.size.width / 3 / 0.65 + 45, + mainAxisExtent: Get.size.width / 3 / 0.65 + 30, ), delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { diff --git a/lib/pages/bangumi/widgets/bangumu_card_v.dart b/lib/pages/bangumi/widgets/bangumu_card_v.dart index 34a9278f..fdc67c1a 100644 --- a/lib/pages/bangumi/widgets/bangumu_card_v.dart +++ b/lib/pages/bangumi/widgets/bangumu_card_v.dart @@ -98,8 +98,9 @@ class BangumiCardV extends StatelessWidget { ), if (bangumiItem.badge != null) pBadge(bangumiItem.badge, context, 6, 6, null, null), - pBadge(bangumiItem.order, context, null, null, 6, 6, - type: 'gray'), + if (bangumiItem.order != null) + pBadge(bangumiItem.order, context, null, null, 6, 6, + type: 'gray'), ], ); }), @@ -130,71 +131,40 @@ class BangumiContent extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - bangumiItem.title, - textAlign: TextAlign.start, - style: const TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - letterSpacing: 0.3, - ), - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), Row( children: [ Expanded( - child: LayoutBuilder(builder: - (BuildContext context, BoxConstraints constraints) { - return SizedBox( - width: constraints.maxWidth, - child: Text( - bangumiItem.indexShow, - maxLines: 1, - style: TextStyle( - fontSize: - Theme.of(context).textTheme.labelMedium!.fontSize, - color: Theme.of(context).colorScheme.outline, - ), - ), - ); - }), - ), - // SizedBox( - // width: 20, - // height: 20, - // child: IconButton( - // tooltip: '稍后再看', - // style: ButtonStyle( - // padding: MaterialStateProperty.all(EdgeInsets.zero), - // ), - // onPressed: () async { - // var res = - // await UserHttp.toViewLater(bvid: videoItem.bvid); - // SmartDialog.showToast(res['msg']); - // }, - // icon: Icon( - // Icons.more_vert_outlined, - // color: Theme.of(context).colorScheme.outline, - // size: 14, - // ), - // ), - // ), + child: Text( + bangumiItem.title, + textAlign: TextAlign.start, + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + letterSpacing: 0.3, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + )), ], ), - // Row( - // children: [ - // StatView( - // theme: 'black', - // view: videoItem.stat.view, - // ), - // const SizedBox(width: 6), - // StatDanMu( - // theme: 'black', - // danmu: videoItem.stat.danmaku, - // ), - // ], - // ), + if (bangumiItem.indexShow != null) + Text( + bangumiItem.indexShow, + maxLines: 1, + style: TextStyle( + fontSize: Theme.of(context).textTheme.labelMedium!.fontSize, + color: Theme.of(context).colorScheme.outline, + ), + ), + if (bangumiItem.progress != null) + Text( + bangumiItem.progress, + maxLines: 1, + style: TextStyle( + fontSize: Theme.of(context).textTheme.labelMedium!.fontSize, + color: Theme.of(context).colorScheme.outline, + ), + ), ], ), ),