feat: 最近追番
This commit is contained in:
@ -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©right=-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©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.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'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user