mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: 追番、番剧详情查看
This commit is contained in:
@@ -4,7 +4,6 @@ import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/http/constants.dart';
|
||||
import 'package:pilipala/http/search.dart';
|
||||
import 'package:pilipala/http/user.dart';
|
||||
import 'package:pilipala/http/video.dart';
|
||||
import 'package:pilipala/models/bangumi/info.dart';
|
||||
import 'package:pilipala/models/user/fav_folder.dart';
|
||||
@@ -93,6 +92,7 @@ class BangumiIntroController extends GetxController {
|
||||
var result = await SearchHttp.bangumiInfo(seasonId: seasonId, epId: epId);
|
||||
if (result['status']) {
|
||||
bangumiDetail.value = result['data'];
|
||||
epId = bangumiDetail.value.episodes!.first.id;
|
||||
}
|
||||
if (userLogin) {
|
||||
// 获取点赞状态
|
||||
@@ -101,20 +101,10 @@ class BangumiIntroController extends GetxController {
|
||||
queryHasCoinVideo();
|
||||
// 获取收藏状态
|
||||
queryHasFavVideo();
|
||||
//
|
||||
queryFollowStatus();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 获取up主粉丝数
|
||||
Future queryUserStat() async {
|
||||
var result = await UserHttp.userStat(mid: videoDetail.value.owner!.mid!);
|
||||
if (result['status']) {
|
||||
userStat = result['data'];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取点赞状态
|
||||
Future queryHasLikeVideo() async {
|
||||
var result = await VideoHttp.hasLikeVideo(bvid: bvid);
|
||||
@@ -138,54 +128,10 @@ class BangumiIntroController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
// 一键三连
|
||||
Future actionOneThree() async {
|
||||
if (user.get(UserBoxKey.userMid) == null) {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
return;
|
||||
}
|
||||
if (hasLike.value && hasCoin.value && hasFav.value) {
|
||||
// 已点赞、投币、收藏
|
||||
SmartDialog.showToast('🙏 UP已经收到了~');
|
||||
return false;
|
||||
}
|
||||
SmartDialog.show(
|
||||
useSystem: true,
|
||||
animationType: SmartAnimationType.centerFade_otherSlide,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('提示'),
|
||||
content: const Text('一键三连 给UP送温暖'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => SmartDialog.dismiss(),
|
||||
child: const Text('点错了')),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
var result = await VideoHttp.oneThree(bvid: bvid);
|
||||
if (result['status']) {
|
||||
hasLike.value = result["data"]["like"];
|
||||
hasCoin.value = result["data"]["coin"];
|
||||
hasFav.value = result["data"]["fav"];
|
||||
SmartDialog.showToast('三连成功 🎉');
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
SmartDialog.dismiss();
|
||||
},
|
||||
child: const Text('确认'),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// (取消)点赞
|
||||
Future actionLikeVideo() async {
|
||||
var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value);
|
||||
if (result['status']) {
|
||||
// hasLike.value = result["data"] == 1 ? true : false;
|
||||
if (!hasLike.value) {
|
||||
SmartDialog.showToast('点赞成功 👍');
|
||||
hasLike.value = true;
|
||||
@@ -270,10 +216,7 @@ class BangumiIntroController extends GetxController {
|
||||
delMediaIdsNew.add(i.id);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore: avoid_print
|
||||
print(e);
|
||||
}
|
||||
} catch (_) {}
|
||||
var result = await VideoHttp.favVideo(
|
||||
aid: IdUtils.bv2av(bvid),
|
||||
addIds: addMediaIdsNew.join(','),
|
||||
@@ -297,15 +240,6 @@ class BangumiIntroController extends GetxController {
|
||||
return result;
|
||||
}
|
||||
|
||||
Future queryVideoInFolder() async {
|
||||
var result = await VideoHttp.videoInFolder(
|
||||
mid: user.get(UserBoxKey.userMid), rid: IdUtils.bv2av(bvid));
|
||||
if (result['status']) {
|
||||
favFolderData.value = result['data'];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 选择文件夹
|
||||
onChoose(bool checkValue, int index) {
|
||||
feedBack();
|
||||
@@ -322,15 +256,6 @@ class BangumiIntroController extends GetxController {
|
||||
favFolderData.refresh();
|
||||
}
|
||||
|
||||
// 查询关注状态
|
||||
Future queryFollowStatus() async {
|
||||
var result = await VideoHttp.hasFollow(mid: videoDetail.value.owner!.mid!);
|
||||
if (result['status']) {
|
||||
followStatus.value = result['data'];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 修改分P或番剧分集
|
||||
Future changeSeasonOrbangu(bvid, cid, aid) async {
|
||||
// 重新获取视频资源
|
||||
@@ -348,4 +273,18 @@ class BangumiIntroController extends GetxController {
|
||||
videoReplyCtr.queryReplyList(type: 'init');
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
// 追番
|
||||
Future bangumiAdd() async {
|
||||
var result =
|
||||
await VideoHttp.bangumiAdd(seasonId: bangumiDetail.value.seasonId);
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
|
||||
// 取消追番
|
||||
Future bangumiDel() async {
|
||||
var result =
|
||||
await VideoHttp.bangumiDel(seasonId: bangumiDetail.value.seasonId);
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/common/constants.dart';
|
||||
import 'package:pilipala/common/widgets/badge.dart';
|
||||
import 'package:pilipala/common/widgets/http_error.dart';
|
||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||
import 'package:pilipala/common/widgets/stat/danmu.dart';
|
||||
@@ -18,6 +19,7 @@ import 'package:pilipala/utils/feed_back.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
|
||||
import 'controller.dart';
|
||||
import 'widgets/intro_detail.dart';
|
||||
|
||||
class BangumiIntroPanel extends StatefulWidget {
|
||||
const BangumiIntroPanel({super.key});
|
||||
@@ -90,7 +92,6 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
late BangumiInfoModel? bangumiItem;
|
||||
final BangumiIntroController bangumiIntroController =
|
||||
Get.put(BangumiIntroController(), tag: Get.arguments['heroTag']);
|
||||
bool isExpand = false;
|
||||
|
||||
late VideoDetailController? videoDetailCtr;
|
||||
Box localCache = GStrorage.localCache;
|
||||
@@ -124,13 +125,13 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
// 视频介绍
|
||||
showIntroDetail() {
|
||||
feedBack();
|
||||
// showBottomSheet(
|
||||
// context: context,
|
||||
// enableDrag: true,
|
||||
// builder: (BuildContext context) {
|
||||
// return IntroDetail(videoDetail: widget.videoDetail!);
|
||||
// },
|
||||
// );
|
||||
showBottomSheet(
|
||||
context: context,
|
||||
enableDrag: true,
|
||||
builder: (BuildContext context) {
|
||||
return IntroDetail(bangumiDetail: widget.bangumiDetail!);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -138,7 +139,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
ThemeData t = Theme.of(context);
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: StyleString.safeSpace, right: StyleString.safeSpace, top: 13),
|
||||
left: StyleString.safeSpace, right: StyleString.safeSpace, top: 20),
|
||||
sliver: SliverToBoxAdapter(
|
||||
child: !widget.loadingStatus || bangumiItem != null
|
||||
? Column(
|
||||
@@ -148,12 +149,25 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
width: 105,
|
||||
height: 160,
|
||||
src: !widget.loadingStatus
|
||||
? widget.bangumiDetail!.cover!
|
||||
: bangumiItem!.cover!,
|
||||
Stack(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
width: 105,
|
||||
height: 160,
|
||||
src: !widget.loadingStatus
|
||||
? widget.bangumiDetail!.cover!
|
||||
: bangumiItem!.cover!,
|
||||
),
|
||||
if (bangumiItem != null &&
|
||||
bangumiItem!.rating != null)
|
||||
pBadge(
|
||||
'评分 ${!widget.loadingStatus ? widget.bangumiDetail!.rating!['score']! : bangumiItem!.rating!['score']!}',
|
||||
context,
|
||||
null,
|
||||
6,
|
||||
6,
|
||||
null),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
@@ -196,7 +210,8 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
.withOpacity(0.7);
|
||||
}),
|
||||
),
|
||||
onPressed: () {},
|
||||
onPressed: () =>
|
||||
bangumiIntroController.bangumiAdd(),
|
||||
icon: Icon(
|
||||
Icons.favorite_border_rounded,
|
||||
color: t.colorScheme.primary,
|
||||
@@ -208,7 +223,6 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
// const SizedBox(width: 6),
|
||||
StatView(
|
||||
theme: 'gray',
|
||||
view: !widget.loadingStatus
|
||||
@@ -227,7 +241,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
@@ -252,38 +266,29 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
color: t.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
!widget.loadingStatus
|
||||
? widget.bangumiDetail!.newEp!['desc']
|
||||
: bangumiItem!.newEp!['desc'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: t.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
// const SizedBox(height: 4),
|
||||
Text(
|
||||
'简介:${!widget.loadingStatus ? widget.bangumiDetail!.evaluate! : bangumiItem!.evaluate!}',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
!widget.loadingStatus
|
||||
? widget.bangumiDetail!.newEp!['desc']
|
||||
: bangumiItem!.newEp!['desc'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: t.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 10),
|
||||
const Spacer(),
|
||||
if (bangumiItem != null &&
|
||||
bangumiItem!.rating != null)
|
||||
Text(
|
||||
'评分 ${!widget.loadingStatus ? widget.bangumiDetail!.rating!['score']! : bangumiItem!.rating!['score']!}',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: t.colorScheme.primary,
|
||||
),
|
||||
Text(
|
||||
'简介:${!widget.loadingStatus ? widget.bangumiDetail!.evaluate! : bangumiItem!.evaluate!}',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: t.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
123
lib/pages/bangumi/introduction/widgets/intro_detail.dart
Normal file
123
lib/pages/bangumi/introduction/widgets/intro_detail.dart
Normal file
@@ -0,0 +1,123 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/common/widgets/stat/danmu.dart';
|
||||
import 'package:pilipala/common/widgets/stat/view.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
|
||||
Box localCache = GStrorage.localCache;
|
||||
late double sheetHeight;
|
||||
|
||||
class IntroDetail extends StatelessWidget {
|
||||
final dynamic bangumiDetail;
|
||||
|
||||
const IntroDetail({
|
||||
Key? key,
|
||||
this.bangumiDetail,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
sheetHeight = localCache.get('sheetHeight');
|
||||
TextStyle smallTitle = TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
);
|
||||
return Container(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
padding: const EdgeInsets.only(left: 14, right: 14),
|
||||
height: sheetHeight,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 32,
|
||||
height: 3,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondaryContainer
|
||||
.withOpacity(0.5),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(3))),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
bangumiDetail!.title,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
StatView(
|
||||
theme: 'gray',
|
||||
view: bangumiDetail!.stat!['views'],
|
||||
size: 'medium',
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
StatDanMu(
|
||||
theme: 'gray',
|
||||
danmu: bangumiDetail!.stat!['danmakus'],
|
||||
size: 'medium',
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
bangumiDetail!.areas!.first['name'],
|
||||
style: smallTitle,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
bangumiDetail!.publish!['pub_time_show'],
|
||||
style: smallTitle,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
bangumiDetail!.newEp!['desc'],
|
||||
style: smallTitle,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
'简介:',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'${bangumiDetail!.evaluate!}',
|
||||
style: smallTitle.copyWith(fontSize: 13),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
'声优:',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
bangumiDetail.actors,
|
||||
style: smallTitle.copyWith(fontSize: 13),
|
||||
),
|
||||
SizedBox(height: MediaQuery.of(context).padding.bottom + 20)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user