feat: 最近追番

This commit is contained in:
guozhigq
2023-08-09 10:35:26 +08:00
parent c4910e7bce
commit d71790b03a
6 changed files with 201 additions and 94 deletions

View File

@ -274,4 +274,8 @@ class Api {
// type=1 // type=1
static const String bangumiList = static const String bangumiList =
'/pgc/season/index/result?st=1&order=3&season_version=-1&spoken_language_type=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&sort=0&season_type=1&pagesize=20&type=1'; '/pgc/season/index/result?st=1&order=3&season_version=-1&spoken_language_type=-1&area=-1&is_finish=-1&copyright=-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';
} }

View File

@ -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'],
};
}
}
} }

View File

@ -45,6 +45,7 @@ class BangumiListItemModel {
this.subTitle, this.subTitle,
this.title, this.title,
this.titleIcon, this.titleIcon,
this.progress,
}); });
String? badge; String? badge;
@ -64,6 +65,8 @@ class BangumiListItemModel {
String? title; String? title;
String? titleIcon; String? titleIcon;
String? progress;
BangumiListItemModel.fromJson(Map<String, dynamic> json) { BangumiListItemModel.fromJson(Map<String, dynamic> json) {
badge = json['badge'] == '' ? null : json['badge']; badge = json['badge'] == '' ? null : json['badge'];
badgeType = json['badge_type']; badgeType = json['badge_type'];
@ -81,5 +84,7 @@ class BangumiListItemModel {
subTitle = json['sub_title']; subTitle = json['sub_title'];
title = json['title']; title = json['title'];
titleIcon = json['title_icon']; titleIcon = json['title_icon'];
progress = json['progress'];
} }
} }

View File

@ -1,15 +1,32 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/http/bangumi.dart'; import 'package:pilipala/http/bangumi.dart';
import 'package:pilipala/models/bangumi/list.dart'; import 'package:pilipala/models/bangumi/list.dart';
import 'package:pilipala/utils/storage.dart';
class BangumiController extends GetxController { class BangumiController extends GetxController {
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
RxList<BangumiListItemModel> bangumiList = [BangumiListItemModel()].obs; RxList<BangumiListItemModel> bangumiList = [BangumiListItemModel()].obs;
RxList<BangumiListItemModel> bangumiFollowList = [BangumiListItemModel()].obs;
int _currentPage = 1; int _currentPage = 1;
bool isLoadingMore = true; 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 { Future queryBangumiListFeed({type = 'init'}) async {
if (type == 'init') {
_currentPage = 1;
}
var result = await BangumiHttp.bangumiList(page: _currentPage); var result = await BangumiHttp.bangumiList(page: _currentPage);
if (result['status']) { if (result['status']) {
if (type == 'init') { if (type == 'init') {
@ -27,4 +44,13 @@ class BangumiController extends GetxController {
Future onLoad() async { Future onLoad() async {
queryBangumiListFeed(type: 'onLoad'); queryBangumiListFeed(type: 'onLoad');
} }
// 我的订阅
Future queryBangumiFollow() async {
var result = await BangumiHttp.bangumiFollow(mid: 17340771);
if (result['status']) {
bangumiFollowList.value = result['data'].list;
} else {}
return result;
}
} }

View File

@ -3,10 +3,12 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/common/widgets/http_error.dart';
import 'package:pilipala/pages/main/index.dart'; import 'package:pilipala/pages/main/index.dart';
import 'package:pilipala/pages/rcmd/view.dart'; import 'package:pilipala/pages/rcmd/view.dart';
import 'package:pilipala/utils/storage.dart';
import 'controller.dart'; import 'controller.dart';
import 'widgets/bangumu_card_v.dart'; import 'widgets/bangumu_card_v.dart';
@ -22,7 +24,6 @@ class _BangumiPageState extends State<BangumiPage>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
final BangumiController _bangumidController = Get.put(BangumiController()); final BangumiController _bangumidController = Get.put(BangumiController());
late Future? _futureBuilderFuture; late Future? _futureBuilderFuture;
@override @override
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
@ -56,6 +57,7 @@ class _BangumiPageState extends State<BangumiPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context);
return Container( return Container(
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
margin: const EdgeInsets.only( margin: const EdgeInsets.only(
@ -63,37 +65,121 @@ class _BangumiPageState extends State<BangumiPage>
decoration: const BoxDecoration( decoration: const BoxDecoration(
borderRadius: BorderRadius.all(StyleString.imgRadius), borderRadius: BorderRadius.all(StyleString.imgRadius),
), ),
child: RefreshIndicator( child: Expanded(
onRefresh: () async { child: RefreshIndicator(
return Future.delayed(const Duration(seconds: 2)); onRefresh: () async {
}, await _bangumidController.queryBangumiListFeed(type: 'init');
child: CustomScrollView( return _bangumidController.queryBangumiFollow();
controller: _bangumidController.scrollController, },
slivers: [ child: CustomScrollView(
SliverPadding( controller: _bangumidController.scrollController,
padding: EdgeInsets.zero, slivers: [
sliver: FutureBuilder( SliverToBoxAdapter(
future: _futureBuilderFuture, child: Obx(
builder: (context, snapshot) { () => Visibility(
if (snapshot.connectionState == ConnectionState.done) { visible: _bangumidController.userLogin.value,
Map data = snapshot.data as Map; child: Column(
if (data['status']) { children: [
return Obx(() => contentGrid(_bangumidController, Padding(
_bangumidController.bangumiList)); padding: const EdgeInsets.only(
} else { top: 10, bottom: 10, left: 6),
return HttpError( child: Row(
errMsg: data['msg'], mainAxisAlignment: MainAxisAlignment.spaceBetween,
fn: () => {}, children: [
); Text(
} '最近追番',
} else { style: Theme.of(context).textTheme.titleMedium,
return contentGrid(_bangumidController, []); ),
} ],
}, ),
),
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();
}
},
),
),
],
),
),
),
), ),
), SliverToBoxAdapter(
const LoadingMore() 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<BangumiPage>
crossAxisSpacing: StyleString.cardSpace, crossAxisSpacing: StyleString.cardSpace,
// 列数 // 列数
crossAxisCount: 3, crossAxisCount: 3,
mainAxisExtent: Get.size.width / 3 / 0.65 + 45, mainAxisExtent: Get.size.width / 3 / 0.65 + 30,
), ),
delegate: SliverChildBuilderDelegate( delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) { (BuildContext context, int index) {

View File

@ -98,8 +98,9 @@ class BangumiCardV extends StatelessWidget {
), ),
if (bangumiItem.badge != null) if (bangumiItem.badge != null)
pBadge(bangumiItem.badge, context, 6, 6, null, null), pBadge(bangumiItem.badge, context, 6, 6, null, null),
pBadge(bangumiItem.order, context, null, null, 6, 6, if (bangumiItem.order != null)
type: 'gray'), pBadge(bangumiItem.order, context, null, null, 6, 6,
type: 'gray'),
], ],
); );
}), }),
@ -130,71 +131,40 @@ class BangumiContent extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceBetween, // mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(
bangumiItem.title,
textAlign: TextAlign.start,
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
letterSpacing: 0.3,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: LayoutBuilder(builder: child: Text(
(BuildContext context, BoxConstraints constraints) { bangumiItem.title,
return SizedBox( textAlign: TextAlign.start,
width: constraints.maxWidth, style: const TextStyle(
child: Text( fontSize: 13,
bangumiItem.indexShow, fontWeight: FontWeight.w500,
maxLines: 1, letterSpacing: 0.3,
style: TextStyle( ),
fontSize: maxLines: 1,
Theme.of(context).textTheme.labelMedium!.fontSize, overflow: TextOverflow.ellipsis,
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,
// ),
// ),
// ),
], ],
), ),
// Row( if (bangumiItem.indexShow != null)
// children: [ Text(
// StatView( bangumiItem.indexShow,
// theme: 'black', maxLines: 1,
// view: videoItem.stat.view, style: TextStyle(
// ), fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
// const SizedBox(width: 6), color: Theme.of(context).colorScheme.outline,
// StatDanMu( ),
// theme: 'black', ),
// danmu: videoItem.stat.danmaku, if (bangumiItem.progress != null)
// ), Text(
// ], bangumiItem.progress,
// ), maxLines: 1,
style: TextStyle(
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
color: Theme.of(context).colorScheme.outline,
),
),
], ],
), ),
), ),