Merge branch 'feature-bangumi'

This commit is contained in:
guozhigq
2023-08-06 13:52:01 +08:00
8 changed files with 386 additions and 209 deletions

View File

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

View File

@ -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,
),
),
],
),
),

View 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)
],
),
),
)
],
),
);
}
}

View File

@ -111,7 +111,7 @@ class _BangumiPanelState extends State<BangumiPanel> {
return Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 10),
padding: const EdgeInsets.only(top: 10, bottom: 6),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -143,87 +143,161 @@ class _BangumiPanelState extends State<BangumiPanel> {
],
),
),
SingleChildScrollView(
padding: const EdgeInsets.only(top: 7, bottom: 7),
scrollDirection: Axis.horizontal,
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width,
),
child: Row(
children: [
for (int i = 0; i < widget.pages.length; i++) ...[
Container(
width: 150,
margin: const EdgeInsets.only(right: 10),
child: Material(
color: Theme.of(context).colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(6),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => changeFucCall(widget.pages[i], i),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
if (i == currentIndex) ...[
Image.asset(
'assets/images/live.gif',
color:
Theme.of(context).colorScheme.primary,
height: 12,
),
const SizedBox(width: 6)
],
Text(
'${i + 1}',
style: TextStyle(
fontSize: 13,
color: i == currentIndex
? Theme.of(context)
.colorScheme
.primary
: Theme.of(context)
.colorScheme
.onSurface),
SizedBox(
height: 60,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: widget.pages.length,
itemBuilder: ((context, i) {
return Container(
width: 150,
margin: const EdgeInsets.only(right: 10),
child: Material(
color: Theme.of(context).colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(6),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => changeFucCall(widget.pages[i], i),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
if (i == currentIndex) ...[
Image.asset(
'assets/images/live.gif',
color:
Theme.of(context).colorScheme.primary,
height: 12,
),
const SizedBox(width: 2),
if (widget.pages[i].badge != null) ...[
Image.asset(
'assets/images/big-vip.png',
height: 16,
),
],
const SizedBox(width: 6)
],
),
const SizedBox(height: 3),
Text(
widget.pages[i].longTitle!,
maxLines: 1,
style: TextStyle(
fontSize: 13,
color: i == currentIndex
? Theme.of(context).colorScheme.primary
: Theme.of(context)
.colorScheme
.onSurface),
overflow: TextOverflow.ellipsis,
)
],
),
Text(
'${i + 1}',
style: TextStyle(
fontSize: 13,
color: i == currentIndex
? Theme.of(context)
.colorScheme
.primary
: Theme.of(context)
.colorScheme
.onSurface),
),
const SizedBox(width: 2),
if (widget.pages[i].badge != null) ...[
Image.asset(
'assets/images/big-vip.png',
height: 16,
),
],
],
),
const SizedBox(height: 3),
Text(
widget.pages[i].longTitle!,
maxLines: 1,
style: TextStyle(
fontSize: 13,
color: i == currentIndex
? Theme.of(context).colorScheme.primary
: Theme.of(context)
.colorScheme
.onSurface),
overflow: TextOverflow.ellipsis,
)
],
),
),
),
),
]
],
),
),
);
})),
)
// SingleChildScrollView(
// padding: const EdgeInsets.only(top: 7, bottom: 7),
// scrollDirection: Axis.horizontal,
// child: ConstrainedBox(
// constraints: BoxConstraints(
// minWidth: MediaQuery.of(context).size.width,
// ),
// child: Row(
// children: [
// for (int i = 0; i < widget.pages.length; i++) ...[
// Container(
// width: 150,
// margin: const EdgeInsets.only(right: 10),
// child: Material(
// color: Theme.of(context).colorScheme.onInverseSurface,
// borderRadius: BorderRadius.circular(6),
// clipBehavior: Clip.hardEdge,
// child: InkWell(
// onTap: () => changeFucCall(widget.pages[i], i),
// child: Padding(
// padding: const EdgeInsets.symmetric(
// vertical: 8, horizontal: 10),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// children: [
// if (i == currentIndex) ...[
// Image.asset(
// 'assets/images/live.gif',
// color:
// Theme.of(context).colorScheme.primary,
// height: 12,
// ),
// const SizedBox(width: 6)
// ],
// Text(
// '第${i + 1}话',
// style: TextStyle(
// fontSize: 13,
// color: i == currentIndex
// ? Theme.of(context)
// .colorScheme
// .primary
// : Theme.of(context)
// .colorScheme
// .onSurface),
// ),
// const SizedBox(width: 2),
// if (widget.pages[i].badge != null) ...[
// Image.asset(
// 'assets/images/big-vip.png',
// height: 16,
// ),
// ],
// ],
// ),
// const SizedBox(height: 3),
// Text(
// widget.pages[i].longTitle!,
// maxLines: 1,
// style: TextStyle(
// fontSize: 13,
// color: i == currentIndex
// ? Theme.of(context).colorScheme.primary
// : Theme.of(context)
// .colorScheme
// .onSurface),
// overflow: TextOverflow.ellipsis,
// )
// ],
// ),
// ),
// ),
// ),
// ),
// ]
// ],
// ),
// ),
// )
],
);
}

View File

@ -104,23 +104,24 @@ Widget searchMbangumiPanel(BuildContext context, ctr, list) {
SmartDialog.showLoading(msg: '获取中...');
var res = await SearchHttp.bangumiInfo(
seasonId: i.seasonId);
SmartDialog.dismiss();
if (res['status']) {
EpisodeItem episode = res['data'].episodes.first;
String bvid = episode.bvid!;
int cid = episode.cid!;
String pic = episode.cover!;
String heroTag = Utils.makeHeroTag(cid);
Get.toNamed(
'/video?bvid=$bvid&cid=$cid&seasonId=${i.seasonId}',
arguments: {
'pic': pic,
'heroTag': heroTag,
'videoType': SearchType.media_bangumi,
'bangumiItem': res['data'],
},
);
}
SmartDialog.dismiss().then((value) {
if (res['status']) {
EpisodeItem episode = res['data'].episodes.first;
String bvid = episode.bvid!;
int cid = episode.cid!;
String pic = episode.cover!;
String heroTag = Utils.makeHeroTag(cid);
Get.toNamed(
'/video?bvid=$bvid&cid=$cid&seasonId=${i.seasonId}',
arguments: {
'pic': pic,
'heroTag': heroTag,
'videoType': SearchType.media_bangumi,
'bangumiItem': res['data'],
},
);
}
});
},
child: const Text('观看'),
),