Merge branch 'opt-bangumi'
This commit is contained in:
@ -430,7 +430,7 @@ class EpisodeGridItem extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrentIndex
|
||||
? colorScheme.primaryContainer.withOpacity(0.6)
|
||||
: colorScheme.secondaryContainer.withOpacity(0.4),
|
||||
: colorScheme.onInverseSurface.withOpacity(0.6),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: isCurrentIndex
|
||||
|
||||
@ -301,10 +301,6 @@ 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';
|
||||
|
||||
// 黑名单
|
||||
static const String blackLst = '/x/relation/blacks';
|
||||
|
||||
@ -604,4 +600,10 @@ class Api {
|
||||
|
||||
/// 图片上传
|
||||
static const String uploadImage = '/x/dynamic/feed/draw/upload_bfs';
|
||||
|
||||
/// 更新追番状态
|
||||
static const String updateBangumiStatus = '/pgc/web/follow/status/update';
|
||||
|
||||
/// 番剧点赞投币收藏状态
|
||||
static const String bangumiActionStatus = '/pgc/season/episode/community';
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import 'dart:convert';
|
||||
import '../models/bangumi/list.dart';
|
||||
import 'index.dart';
|
||||
import 'package:html/parser.dart' as html_parser;
|
||||
import 'package:html/dom.dart' as html_dom;
|
||||
|
||||
class BangumiHttp {
|
||||
static Future bangumiList({int? page}) async {
|
||||
@ -18,8 +21,19 @@ class BangumiHttp {
|
||||
}
|
||||
}
|
||||
|
||||
static Future bangumiFollow({int? mid}) async {
|
||||
var res = await Request().get(Api.bangumiFollow, data: {'vmid': mid});
|
||||
static Future getRecentBangumi({
|
||||
int? mid,
|
||||
int type = 1,
|
||||
int pn = 1,
|
||||
int ps = 20,
|
||||
}) async {
|
||||
var res = await Request().get(Api.getRecentBangumiApi, data: {
|
||||
'vmid': mid,
|
||||
'type': type,
|
||||
'follow_status': 0,
|
||||
'pn': pn,
|
||||
'ps': ps,
|
||||
});
|
||||
if (res.data['code'] == 0) {
|
||||
return {
|
||||
'status': true,
|
||||
@ -33,4 +47,62 @@ class BangumiHttp {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 获取追番状态
|
||||
static Future bangumiStatus({required int seasonId}) async {
|
||||
var res = await Request()
|
||||
.get('https://www.bilibili.com/bangumi/play/ss$seasonId');
|
||||
html_dom.Document document = html_parser.parse(res.data);
|
||||
// 查找 id 为 __NEXT_DATA__ 的 script 元素
|
||||
html_dom.Element? scriptElement =
|
||||
document.querySelector('script#\\__NEXT_DATA__');
|
||||
if (scriptElement != null) {
|
||||
// 提取 script 元素的内容
|
||||
String scriptContent = scriptElement.text;
|
||||
final dynamic scriptContentJson = jsonDecode(scriptContent);
|
||||
Map followState = scriptContentJson['props']['pageProps']['followState'];
|
||||
return {
|
||||
'status': true,
|
||||
'data': {
|
||||
'isFollowed': followState['isFollowed'],
|
||||
'followStatus': followState['followStatus']
|
||||
}
|
||||
};
|
||||
} else {
|
||||
print('Script element with id "__NEXT_DATA__" not found.');
|
||||
}
|
||||
}
|
||||
|
||||
// 更新追番状态
|
||||
static Future updateBangumiStatus({
|
||||
required int seasonId,
|
||||
required int status,
|
||||
}) async {
|
||||
var res = await Request().post(Api.updateBangumiStatus, data: {
|
||||
'season_id': seasonId,
|
||||
'status': status,
|
||||
});
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'data': [],
|
||||
'msg': res.data['message'],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 获取番剧点赞投币收藏状态
|
||||
static Future bangumiActionStatus({required int epId}) async {
|
||||
var res = await Request().get(
|
||||
Api.bangumiActionStatus,
|
||||
data: {'ep_id': epId},
|
||||
);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {'status': false, 'data': [], 'msg': res.data['message']};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,7 @@ class BangumiListItemModel {
|
||||
this.title,
|
||||
this.titleIcon,
|
||||
this.progress,
|
||||
this.progressIndex,
|
||||
});
|
||||
|
||||
String? badge;
|
||||
@ -66,8 +67,8 @@ class BangumiListItemModel {
|
||||
String? subTitle;
|
||||
String? title;
|
||||
String? titleIcon;
|
||||
|
||||
String? progress;
|
||||
int? progressIndex;
|
||||
|
||||
BangumiListItemModel.fromJson(Map<String, dynamic> json) {
|
||||
badge = json['badge'] == '' ? null : json['badge'];
|
||||
@ -87,7 +88,9 @@ class BangumiListItemModel {
|
||||
subTitle = json['sub_title'];
|
||||
title = json['title'];
|
||||
titleIcon = json['title_icon'];
|
||||
|
||||
progress = json['progress'];
|
||||
progressIndex = int.parse(
|
||||
RegExp(r'第(\d+)话').firstMatch(json['progress'] ?? '第1话')?.group(1) ??
|
||||
'0');
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ class BangumiController extends GetxController {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
RxList<BangumiListItemModel> bangumiList = <BangumiListItemModel>[].obs;
|
||||
RxList<BangumiListItemModel> bangumiFollowList = <BangumiListItemModel>[].obs;
|
||||
RxInt total = 0.obs;
|
||||
int _currentPage = 1;
|
||||
bool isLoadingMore = true;
|
||||
Box userInfoCache = GStrorage.userInfo;
|
||||
@ -54,9 +55,10 @@ class BangumiController extends GetxController {
|
||||
if (userInfo == null) {
|
||||
return;
|
||||
}
|
||||
var result = await BangumiHttp.bangumiFollow(mid: userInfo.mid);
|
||||
var result = await BangumiHttp.getRecentBangumi(mid: userInfo.mid);
|
||||
if (result['status']) {
|
||||
bangumiFollowList.value = result['data'].list;
|
||||
total.value = result['data'].total;
|
||||
} else {}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/http/bangumi.dart';
|
||||
import 'package:pilipala/http/constants.dart';
|
||||
import 'package:pilipala/http/search.dart';
|
||||
import 'package:pilipala/http/video.dart';
|
||||
@ -52,28 +53,34 @@ class BangumiIntroController extends GetxController {
|
||||
Rx<FavFolderData> favFolderData = FavFolderData().obs;
|
||||
List addMediaIdsNew = [];
|
||||
List delMediaIdsNew = [];
|
||||
// 关注状态 默认未关注
|
||||
RxMap followStatus = {}.obs;
|
||||
// 追番状态 1想看 2在看 3已看
|
||||
RxBool isFollowed = false.obs;
|
||||
RxInt followStatus = 1.obs;
|
||||
int _tempThemeValue = -1;
|
||||
var userInfo;
|
||||
PersistentBottomSheetController? bottomSheetController;
|
||||
List<Map<String, dynamic>> followStatusList = [
|
||||
{'title': '标记为 「想看」', 'status': 1},
|
||||
{'title': '标记为 「在看」', 'status': 2},
|
||||
{'title': '标记为 「已看」', 'status': 3},
|
||||
{'title': '取消追番', 'status': -1},
|
||||
];
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
userInfo = userInfoCache.get('userInfoCache');
|
||||
userLogin = userInfo != null;
|
||||
if (userLogin && seasonId != null) {
|
||||
bangumiStatus();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取番剧简介&选集
|
||||
Future queryBangumiIntro() async {
|
||||
if (userLogin) {
|
||||
// 获取点赞状态
|
||||
queryHasLikeVideo();
|
||||
// 获取投币状态
|
||||
queryHasCoinVideo();
|
||||
// 获取收藏状态
|
||||
queryHasFavVideo();
|
||||
// 获取点赞投币收藏状态
|
||||
bangumiActionStatus();
|
||||
}
|
||||
var result = await SearchHttp.bangumiInfo(seasonId: seasonId, epId: epId);
|
||||
if (result['status']) {
|
||||
@ -83,26 +90,15 @@ class BangumiIntroController extends GetxController {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 获取点赞状态
|
||||
Future queryHasLikeVideo() async {
|
||||
var result = await VideoHttp.hasLikeVideo(bvid: bvid);
|
||||
// data num 被点赞标志 0:未点赞 1:已点赞
|
||||
hasLike.value = result["data"] == 1 ? true : false;
|
||||
}
|
||||
|
||||
// 获取投币状态
|
||||
Future queryHasCoinVideo() async {
|
||||
var result = await VideoHttp.hasCoinVideo(bvid: bvid);
|
||||
hasCoin.value = result["data"]['multiply'] == 0 ? false : true;
|
||||
}
|
||||
|
||||
// 获取收藏状态
|
||||
Future queryHasFavVideo() async {
|
||||
var result = await VideoHttp.hasFavVideo(aid: IdUtils.bv2av(bvid));
|
||||
// 获取番剧点赞投币收藏状态
|
||||
Future bangumiActionStatus() async {
|
||||
var result = await BangumiHttp.bangumiActionStatus(epId: epId!);
|
||||
if (result['status']) {
|
||||
hasFav.value = result["data"]['favoured'];
|
||||
hasLike.value = result['data']['like'] == 1;
|
||||
hasCoin.value = result['data']['coin_number'] != 0;
|
||||
hasFav.value = result['data']['favorite'] == 1;
|
||||
} else {
|
||||
hasFav.value = false;
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +106,7 @@ class BangumiIntroController extends GetxController {
|
||||
Future actionLikeVideo() async {
|
||||
var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value);
|
||||
if (result['status']) {
|
||||
SmartDialog.showToast(!hasLike.value ? '点赞成功 👍' : '取消赞');
|
||||
SmartDialog.showToast(!hasLike.value ? '点赞成功' : '取消赞');
|
||||
hasLike.value = !hasLike.value;
|
||||
bangumiDetail.value.stat!['likes'] =
|
||||
bangumiDetail.value.stat!['likes'] + (!hasLike.value ? 1 : -1);
|
||||
@ -147,7 +143,7 @@ class BangumiIntroController extends GetxController {
|
||||
var res = await VideoHttp.coinVideo(
|
||||
bvid: bvid, multiply: _tempThemeValue);
|
||||
if (res['status']) {
|
||||
SmartDialog.showToast('投币成功 👏');
|
||||
SmartDialog.showToast('投币成功');
|
||||
hasCoin.value = true;
|
||||
bangumiDetail.value.stat!['coins'] =
|
||||
bangumiDetail.value.stat!['coins'] +
|
||||
@ -185,9 +181,11 @@ class BangumiIntroController extends GetxController {
|
||||
addMediaIdsNew = [];
|
||||
delMediaIdsNew = [];
|
||||
// 重新获取收藏状态
|
||||
queryHasFavVideo();
|
||||
SmartDialog.showToast('✅ 操作成功');
|
||||
bangumiActionStatus();
|
||||
SmartDialog.showToast('操作成功');
|
||||
Get.back();
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,15 +237,22 @@ class BangumiIntroController extends GetxController {
|
||||
|
||||
// 追番
|
||||
Future bangumiAdd() async {
|
||||
var result =
|
||||
await VideoHttp.bangumiAdd(seasonId: bangumiDetail.value.seasonId);
|
||||
var result = await VideoHttp.bangumiAdd(
|
||||
seasonId: seasonId ?? bangumiDetail.value.seasonId);
|
||||
if (result['status']) {
|
||||
followStatus.value = 2;
|
||||
isFollowed.value = true;
|
||||
}
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
|
||||
// 取消追番
|
||||
Future bangumiDel() async {
|
||||
var result =
|
||||
await VideoHttp.bangumiDel(seasonId: bangumiDetail.value.seasonId);
|
||||
var result = await VideoHttp.bangumiDel(
|
||||
seasonId: seasonId ?? bangumiDetail.value.seasonId);
|
||||
if (result['status']) {
|
||||
isFollowed.value = false;
|
||||
}
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
|
||||
@ -315,4 +320,35 @@ class BangumiIntroController extends GetxController {
|
||||
hiddenEpisodeBottomSheet() {
|
||||
bottomSheetController?.close();
|
||||
}
|
||||
|
||||
// 获取追番状态
|
||||
Future bangumiStatus() async {
|
||||
var result = await BangumiHttp.bangumiStatus(seasonId: seasonId!);
|
||||
if (result['status']) {
|
||||
followStatus.value = result['data']['followStatus'];
|
||||
isFollowed.value = result['data']['isFollowed'];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 更新追番状态
|
||||
Future updateBangumiStatus(int status) async {
|
||||
Get.back();
|
||||
if (status == -1) {
|
||||
bangumiDel();
|
||||
} else {
|
||||
var result = await BangumiHttp.bangumiStatus(seasonId: seasonId!);
|
||||
if (result['status']) {
|
||||
followStatus.value = status;
|
||||
final title = followStatusList.firstWhere(
|
||||
(e) => e['status'] == status,
|
||||
orElse: () => {'title': '未知状态'},
|
||||
)['title'];
|
||||
SmartDialog.showToast('追番状态$title');
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,104 +239,65 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () => showIntroDetail(),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: SizedBox(
|
||||
height: 115 / 0.75,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.bangumiDetail!.title!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
SizedBox(
|
||||
width: 34,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(
|
||||
EdgeInsets.zero),
|
||||
backgroundColor:
|
||||
MaterialStateProperty.resolveWith(
|
||||
(Set<MaterialState> states) {
|
||||
return t.colorScheme.primaryContainer
|
||||
.withOpacity(0.7);
|
||||
}),
|
||||
),
|
||||
onPressed: () =>
|
||||
bangumiIntroController.bangumiAdd(),
|
||||
icon: Icon(
|
||||
Icons.favorite_border_rounded,
|
||||
color: t.colorScheme.primary,
|
||||
size: 22,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(6, 4, 6, 6),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.bangumiDetail!.title!,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
StatView(
|
||||
view: widget.bangumiDetail!.stat!['views'],
|
||||
size: 'medium',
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
StatDanMu(
|
||||
danmu: widget.bangumiDetail!.stat!['danmakus'],
|
||||
size: 'medium',
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
(widget.bangumiDetail!.areas!.isNotEmpty
|
||||
? widget.bangumiDetail!.areas!.first['name']
|
||||
: ''),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: t.colorScheme.outline,
|
||||
const SizedBox(width: 20),
|
||||
Obx(
|
||||
() => BangumiStatusWidget(
|
||||
ctr: bangumiIntroController,
|
||||
isFollowed:
|
||||
bangumiIntroController.isFollowed.value,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
widget.bangumiDetail!.publish!['pub_time_show'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: t.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
widget.bangumiDetail!.newEp!['desc'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: t.colorScheme.outline,
|
||||
],
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'简介:${widget.bangumiDetail!.evaluate!}',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: t.colorScheme.outline,
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
StatView(
|
||||
view: widget.bangumiDetail!.stat!['views'],
|
||||
size: 'medium',
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
StatDanMu(
|
||||
danmu: widget.bangumiDetail!.stat!['danmakus'],
|
||||
size: 'medium',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'简介:${widget.bangumiDetail!.evaluate!}',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: t.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -426,3 +387,97 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 追番状态
|
||||
class BangumiStatusWidget extends StatelessWidget {
|
||||
final BangumiIntroController ctr;
|
||||
final bool isFollowed;
|
||||
|
||||
const BangumiStatusWidget({
|
||||
Key? key,
|
||||
required this.ctr,
|
||||
required this.isFollowed,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
void updateFollowStatus() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
useRootNavigator: true,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return morePanel(context, ctr);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return Obx(
|
||||
() => SizedBox(
|
||||
width: 34,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||
backgroundColor:
|
||||
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
return ctr.isFollowed.value
|
||||
? colorScheme.primaryContainer.withOpacity(0.7)
|
||||
: colorScheme.outlineVariant.withOpacity(0.7);
|
||||
}),
|
||||
),
|
||||
onPressed:
|
||||
isFollowed ? () => updateFollowStatus() : () => ctr.bangumiAdd(),
|
||||
icon: Icon(
|
||||
ctr.isFollowed.value
|
||||
? Icons.favorite
|
||||
: Icons.favorite_border_rounded,
|
||||
color: ctr.isFollowed.value
|
||||
? colorScheme.primary
|
||||
: colorScheme.outline,
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget morePanel(BuildContext context, BangumiIntroController ctr) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => Get.back(),
|
||||
child: Container(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 32,
|
||||
height: 3,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(3))),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
...ctr.followStatusList
|
||||
.map(
|
||||
(e) => ListTile(
|
||||
onTap: () => ctr.updateBangumiStatus(e['status']),
|
||||
selected: ctr.followStatus == e['status'],
|
||||
title: Text(e['title']),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,9 +76,14 @@ class _BangumiPageState extends State<BangumiPage>
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'最近追番',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
Obx(
|
||||
() => 0 != _bangumidController.total.value
|
||||
? Text(
|
||||
'我的追番(${_bangumidController.total.value})',
|
||||
style:
|
||||
Theme.of(context).textTheme.titleMedium,
|
||||
)
|
||||
: const SizedBox(),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
|
||||
@ -175,59 +175,60 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
return Container(
|
||||
width: 150,
|
||||
margin: const EdgeInsets.only(right: 10),
|
||||
child: Material(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
onTap: () => changeFucCall(page, i),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
if (isSelected) ...<Widget>[
|
||||
Image.asset('assets/images/live.png',
|
||||
color: primary, height: 12),
|
||||
const SizedBox(width: 6)
|
||||
],
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
onTap: () => changeFucCall(page, i),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 10,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
if (isSelected) ...<Widget>[
|
||||
Image.asset('assets/images/live.png',
|
||||
color: primary, height: 12),
|
||||
const SizedBox(width: 6)
|
||||
],
|
||||
Text(
|
||||
'第${i + 1}话',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isSelected ? primary : onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
if (page.badge != null) ...[
|
||||
const Spacer(),
|
||||
Text(
|
||||
'第${i + 1}话',
|
||||
page.badge!,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isSelected ? primary : onSurface,
|
||||
fontSize: 12,
|
||||
color: primary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
if (page.badge != null) ...[
|
||||
const Spacer(),
|
||||
Text(
|
||||
page.badge!,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: primary,
|
||||
),
|
||||
),
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
page.longTitle!,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isSelected ? primary : onSurface,
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
page.longTitle!,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isSelected ? primary : onSurface,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
],
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -25,6 +25,7 @@ class BangumiCardV extends StatelessWidget {
|
||||
RoutePush.bangumiPush(
|
||||
bangumiItem.seasonId,
|
||||
null,
|
||||
progressIndex: bangumiItem.progressIndex,
|
||||
heroTag: heroTag,
|
||||
);
|
||||
},
|
||||
|
||||
@ -8,7 +8,7 @@ import 'package:pilipala/utils/utils.dart';
|
||||
class RoutePush {
|
||||
// 番剧跳转
|
||||
static Future<void> bangumiPush(int? seasonId, int? epId,
|
||||
{String? heroTag}) async {
|
||||
{String? heroTag, int? progressIndex}) async {
|
||||
SmartDialog.showLoading<dynamic>(msg: '获取中...');
|
||||
try {
|
||||
var result = await SearchHttp.bangumiInfo(seasonId: seasonId, epId: epId);
|
||||
@ -19,7 +19,10 @@ class RoutePush {
|
||||
return;
|
||||
}
|
||||
final BangumiInfoModel bangumiDetail = result['data'];
|
||||
final EpisodeItem episode = bangumiDetail.episodes!.first;
|
||||
EpisodeItem episode = bangumiDetail.episodes!.first;
|
||||
if (progressIndex != null && progressIndex >= 1) {
|
||||
episode = bangumiDetail.episodes![progressIndex - 1];
|
||||
}
|
||||
final int epId = episode.id!;
|
||||
final int cid = episode.cid!;
|
||||
final String bvid = episode.bvid!;
|
||||
@ -31,7 +34,7 @@ class RoutePush {
|
||||
};
|
||||
arguments['heroTag'] = heroTag ?? Utils.makeHeroTag(cid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid&epId=$epId',
|
||||
'/video?bvid=$bvid&cid=$cid&epId=$epId&seasonId=$seasonId',
|
||||
arguments: arguments,
|
||||
);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user