feat: 最近追番
This commit is contained in:
@ -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';
|
||||
}
|
||||
|
@ -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'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<String, dynamic> 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'];
|
||||
}
|
||||
}
|
||||
|
@ -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<BangumiListItemModel> bangumiList = [BangumiListItemModel()].obs;
|
||||
RxList<BangumiListItemModel> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<BangumiPage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
final BangumiController _bangumidController = Get.put(BangumiController());
|
||||
late Future? _futureBuilderFuture;
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
@ -56,6 +57,7 @@ class _BangumiPageState extends State<BangumiPage>
|
||||
|
||||
@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<BangumiPage>
|
||||
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<BangumiPage>
|
||||
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) {
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
Reference in New Issue
Block a user