mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-18 16:16:14 +08:00
refa: pgc intro
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -3,13 +3,10 @@ import 'dart:convert';
|
||||
|
||||
import 'package:PiliPlus/http/constants.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
import 'package:PiliPlus/http/user.dart';
|
||||
import 'package:PiliPlus/http/video.dart';
|
||||
import 'package:PiliPlus/models/bangumi/info.dart';
|
||||
import 'package:PiliPlus/models/user/fav_folder.dart';
|
||||
import 'package:PiliPlus/pages/common/common_data_controller.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_repost/view.dart';
|
||||
import 'package:PiliPlus/pages/video/controller.dart';
|
||||
import 'package:PiliPlus/pages/video/introduction/ugc/controller.dart';
|
||||
@@ -28,8 +25,7 @@ import 'package:get/get.dart';
|
||||
import 'package:html/dom.dart' as dom;
|
||||
import 'package:html/parser.dart' as html_parser;
|
||||
|
||||
class BangumiIntroController
|
||||
extends CommonDataController<BangumiInfoModel, BangumiInfoModel> {
|
||||
class BangumiIntroController extends GetxController {
|
||||
// 视频bvid
|
||||
String bvid = Get.parameters['bvid'] ?? '';
|
||||
var seasonId = Get.parameters['seasonId'] != null
|
||||
@@ -44,15 +40,7 @@ class BangumiIntroController
|
||||
? '追番'
|
||||
: '追剧';
|
||||
|
||||
// 是否预渲染 骨架屏
|
||||
bool preRender = false;
|
||||
|
||||
// 视频详情 上个页面传入
|
||||
Map? videoItem = {};
|
||||
BangumiInfoModel? bangumiItem;
|
||||
|
||||
// up主粉丝数
|
||||
Map userStat = {'follower': '-'};
|
||||
BangumiInfoModel bangumiItem = Get.arguments['bangumiItem'];
|
||||
|
||||
// 是否点赞
|
||||
RxBool hasLike = false.obs;
|
||||
@@ -62,11 +50,14 @@ class BangumiIntroController
|
||||
bool get hasCoin => _coinNum.value != 0;
|
||||
// 是否收藏
|
||||
RxBool hasFav = false.obs;
|
||||
|
||||
dynamic videoTags;
|
||||
bool isLogin = false;
|
||||
Rx<FavFolderData> favFolderData = FavFolderData().obs;
|
||||
|
||||
List? favIds;
|
||||
dynamic userInfo;
|
||||
Rx<FavFolderData> favFolderData = FavFolderData().obs;
|
||||
|
||||
bool isLogin = Accounts.main.isLogin;
|
||||
int mid = Accounts.main.mid;
|
||||
|
||||
late final enableQuickFav =
|
||||
GStorage.setting.get(SettingBoxKey.enableQuickFav, defaultValue: false);
|
||||
@@ -74,30 +65,15 @@ class BangumiIntroController
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
if (Get.arguments.isNotEmpty as bool) {
|
||||
if (Get.arguments.containsKey('bangumiItem') as bool) {
|
||||
preRender = true;
|
||||
bangumiItem = Get.arguments['bangumiItem'];
|
||||
}
|
||||
}
|
||||
userInfo = GStorage.userInfo.get('userInfoCache');
|
||||
isLogin = userInfo != null;
|
||||
|
||||
if (isLogin && epId != null) {
|
||||
queryBangumiLikeCoinFav();
|
||||
}
|
||||
|
||||
queryData();
|
||||
|
||||
if (isLogin && seasonId != null) {
|
||||
if (isLogin) {
|
||||
if (seasonId != null) {
|
||||
queryIsFollowed();
|
||||
}
|
||||
if (epId != null) {
|
||||
queryBangumiLikeCoinFav();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> queryData([bool isRefresh = true]) async {
|
||||
await queryVideoTags();
|
||||
return super.queryData(isRefresh);
|
||||
}
|
||||
queryVideoTags();
|
||||
}
|
||||
|
||||
Future<void> queryVideoTags() async {
|
||||
@@ -107,18 +83,6 @@ class BangumiIntroController
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool customHandleResponse(
|
||||
bool isRefresh, Success<BangumiInfoModel> response) {
|
||||
epId ??= response.response.episodes?.firstOrNull?.id;
|
||||
loadingState.value = response;
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState<BangumiInfoModel>> customGetData() =>
|
||||
SearchHttp.bangumiInfoNew(seasonId: seasonId, epId: epId);
|
||||
|
||||
// 获取点赞/投币/收藏状态
|
||||
Future<void> queryBangumiLikeCoinFav() async {
|
||||
var result = await VideoHttp.bangumiLikeCoinFav(epId: epId);
|
||||
@@ -136,9 +100,8 @@ class BangumiIntroController
|
||||
var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value);
|
||||
if (result['status']) {
|
||||
SmartDialog.showToast(!hasLike.value ? result['data']['toast'] : '取消赞');
|
||||
BangumiInfoModel bangumiDetail = (loadingState.value as Success).response;
|
||||
bangumiDetail.stat!['likes'] =
|
||||
bangumiDetail.stat!['likes'] + (!hasLike.value ? 1 : -1);
|
||||
bangumiItem.stat!['likes'] =
|
||||
bangumiItem.stat!['likes'] + (!hasLike.value ? 1 : -1);
|
||||
hasLike.value = !hasLike.value;
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
@@ -153,11 +116,10 @@ class BangumiIntroController
|
||||
);
|
||||
if (res['status']) {
|
||||
SmartDialog.showToast('投币成功');
|
||||
BangumiInfoModel bangumiDetail = (loadingState.value as Success).response;
|
||||
bangumiDetail.stat!['coins'] = bangumiDetail.stat!['coins'] + coin;
|
||||
bangumiItem.stat!['coins'] = bangumiItem.stat!['coins'] + coin;
|
||||
if (selectLike && hasLike.value.not) {
|
||||
hasLike.value = true;
|
||||
bangumiDetail.stat!['likes'] = bangumiDetail.stat!['likes'] + 1;
|
||||
bangumiItem.stat!['likes'] = bangumiItem.stat!['likes'] + 1;
|
||||
}
|
||||
_coinNum.value += coin;
|
||||
GlobalData().afterCoin(coin);
|
||||
@@ -168,7 +130,7 @@ class BangumiIntroController
|
||||
|
||||
// 投币
|
||||
Future<void> actionCoinVideo() async {
|
||||
if (userInfo == null) {
|
||||
if (!isLogin) {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
return;
|
||||
}
|
||||
@@ -306,7 +268,7 @@ class BangumiIntroController
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
EpisodeItem? item = bangumiItem?.episodes
|
||||
EpisodeItem? item = bangumiItem.episodes
|
||||
?.firstWhereOrNull((item) => item.epId == epId);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
@@ -331,9 +293,9 @@ class BangumiIntroController
|
||||
'5' || '7' => 4099,
|
||||
_ => -1,
|
||||
},
|
||||
pic: bangumiItem?.cover,
|
||||
pic: bangumiItem.cover,
|
||||
title:
|
||||
'${bangumiItem?.title}${item != null ? '\n${item.showTitle}' : ''}',
|
||||
'${bangumiItem.title}${item != null ? '\n${item.showTitle}' : ''}',
|
||||
uname: '',
|
||||
),
|
||||
);
|
||||
@@ -348,9 +310,9 @@ class BangumiIntroController
|
||||
onTap: () {
|
||||
Get.back();
|
||||
try {
|
||||
EpisodeItem item = bangumiItem!.episodes!
|
||||
EpisodeItem item = bangumiItem.episodes!
|
||||
.firstWhere((item) => item.epId == epId);
|
||||
final title = '${bangumiItem!.title!} ${item.showTitle}';
|
||||
final title = '${bangumiItem.title!} ${item.showTitle}';
|
||||
PageUtils.pmShare(
|
||||
context,
|
||||
content: {
|
||||
@@ -360,7 +322,7 @@ class BangumiIntroController
|
||||
"headline": title,
|
||||
"source": 16,
|
||||
"thumb": item.cover,
|
||||
"source_desc": switch (bangumiItem!.type) {
|
||||
"source_desc": switch (bangumiItem.type) {
|
||||
1 => '番剧',
|
||||
2 => '电影',
|
||||
3 => '纪录片',
|
||||
@@ -439,8 +401,7 @@ class BangumiIntroController
|
||||
|
||||
// 追番
|
||||
Future<void> bangumiAdd() async {
|
||||
var result = await VideoHttp.bangumiAdd(
|
||||
seasonId: (loadingState.value as Success).response.seasonId);
|
||||
var result = await VideoHttp.bangumiAdd(seasonId: bangumiItem.seasonId);
|
||||
if (result['status']) {
|
||||
isFollowed.value = true;
|
||||
followStatus.value = 2;
|
||||
@@ -450,8 +411,7 @@ class BangumiIntroController
|
||||
|
||||
// 取消追番
|
||||
Future<void> bangumiDel() async {
|
||||
var result = await VideoHttp.bangumiDel(
|
||||
seasonId: (loadingState.value as Success).response.seasonId);
|
||||
var result = await VideoHttp.bangumiDel(seasonId: bangumiItem.seasonId);
|
||||
if (result['status']) {
|
||||
isFollowed.value = false;
|
||||
}
|
||||
@@ -460,7 +420,7 @@ class BangumiIntroController
|
||||
|
||||
Future<void> bangumiUpdate(status) async {
|
||||
var result = await VideoHttp.bangumiUpdate(
|
||||
seasonId: [(loadingState.value as Success).response.seasonId],
|
||||
seasonId: [bangumiItem.seasonId],
|
||||
status: status,
|
||||
);
|
||||
if (result['status']) {
|
||||
@@ -472,7 +432,7 @@ class BangumiIntroController
|
||||
Future queryVideoInFolder() async {
|
||||
favIds = null;
|
||||
var result = await VideoHttp.videoInFolder(
|
||||
mid: userInfo.mid,
|
||||
mid: mid,
|
||||
rid: epId, // bangumi
|
||||
type: 24, // bangumi
|
||||
);
|
||||
@@ -487,10 +447,7 @@ class BangumiIntroController
|
||||
}
|
||||
|
||||
bool prevPlay() {
|
||||
late List episodes;
|
||||
if ((loadingState.value as Success).response.episodes != null) {
|
||||
episodes = (loadingState.value as Success).response.episodes!;
|
||||
}
|
||||
List episodes = bangumiItem.episodes!;
|
||||
VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
|
||||
int currentIndex =
|
||||
@@ -516,21 +473,11 @@ class BangumiIntroController
|
||||
/// 列表循环或者顺序播放时,自动播放下一个;自动连播时,播放相关视频
|
||||
bool nextPlay() {
|
||||
try {
|
||||
late List episodes;
|
||||
List episodes = bangumiItem.episodes!;
|
||||
VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
|
||||
PlayRepeat playRepeat = videoDetailCtr.plPlayerController.playRepeat;
|
||||
|
||||
if ((loadingState.value as Success<BangumiInfoModel>).response.episodes !=
|
||||
null) {
|
||||
episodes = (loadingState.value as Success<BangumiInfoModel>)
|
||||
.response
|
||||
.episodes!;
|
||||
} else {
|
||||
if (playRepeat == PlayRepeat.autoPlayRelated) {
|
||||
return playRelated();
|
||||
}
|
||||
}
|
||||
int currentIndex =
|
||||
episodes.indexWhere((e) => e.cid == videoDetailCtr.cid.value);
|
||||
int nextIndex = currentIndex + 1;
|
||||
@@ -539,7 +486,7 @@ class BangumiIntroController
|
||||
if (playRepeat == PlayRepeat.listCycle) {
|
||||
nextIndex = 0;
|
||||
} else if (playRepeat == PlayRepeat.autoPlayRelated) {
|
||||
return playRelated();
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -556,15 +503,10 @@ class BangumiIntroController
|
||||
}
|
||||
}
|
||||
|
||||
bool playRelated() {
|
||||
SmartDialog.showToast('番剧暂无相关视频');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 一键三连
|
||||
Future<void> actionOneThree() async {
|
||||
feedBack();
|
||||
if (userInfo == null) {
|
||||
if (!isLogin) {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
return;
|
||||
}
|
||||
@@ -610,7 +552,7 @@ class BangumiIntroController
|
||||
|
||||
// 收藏
|
||||
void showFavBottomSheet(BuildContext context, {type = 'tap'}) {
|
||||
if (userInfo == null) {
|
||||
if (!isLogin) {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/bangumi/info.dart';
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
import 'package:PiliPlus/pages/video/controller.dart';
|
||||
@@ -15,7 +13,6 @@ import 'package:PiliPlus/pages/video/introduction/pgc/widgets/bangumi_panel.dart
|
||||
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/action_item.dart';
|
||||
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/action_row_item.dart';
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:PiliPlus/utils/feed_back.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -44,95 +41,10 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
late BangumiIntroController bangumiIntroController;
|
||||
late VideoDetailController videoDetailCtr;
|
||||
late int cid;
|
||||
StreamSubscription? _listener;
|
||||
|
||||
// 添加页面缓存
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
late final _coinKey = GlobalKey<ActionItemState>();
|
||||
late final _favKey = GlobalKey<ActionItemState>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
cid = widget.cid!;
|
||||
bangumiIntroController =
|
||||
Get.put(BangumiIntroController(), tag: widget.heroTag);
|
||||
videoDetailCtr = Get.find<VideoDetailController>(tag: widget.heroTag);
|
||||
_listener = videoDetailCtr.cid.listen((int p0) {
|
||||
cid = p0;
|
||||
if (!mounted) return;
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Obx(() => _buildBody(bangumiIntroController.loadingState.value));
|
||||
}
|
||||
|
||||
Widget _buildBody(LoadingState loadingState) {
|
||||
return switch (loadingState) {
|
||||
Loading() => BangumiInfo(
|
||||
heroTag: widget.heroTag,
|
||||
isLoading: true,
|
||||
bangumiDetail: null,
|
||||
cid: cid,
|
||||
showEpisodes: widget.showEpisodes,
|
||||
showIntroDetail: () {},
|
||||
),
|
||||
Success(:var response) => BangumiInfo(
|
||||
heroTag: widget.heroTag,
|
||||
isLoading: false,
|
||||
bangumiDetail: response,
|
||||
cid: cid,
|
||||
showEpisodes: widget.showEpisodes,
|
||||
showIntroDetail: () => widget.showIntroDetail(
|
||||
response,
|
||||
bangumiIntroController.videoTags,
|
||||
),
|
||||
),
|
||||
Error(:var errMsg) => HttpError(
|
||||
errMsg: errMsg,
|
||||
onReload: bangumiIntroController.onReload,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class BangumiInfo extends StatefulWidget {
|
||||
const BangumiInfo({
|
||||
super.key,
|
||||
this.isLoading = false,
|
||||
this.bangumiDetail,
|
||||
this.cid,
|
||||
required this.showEpisodes,
|
||||
required this.showIntroDetail,
|
||||
required this.heroTag,
|
||||
});
|
||||
|
||||
final bool isLoading;
|
||||
final BangumiInfoModel? bangumiDetail;
|
||||
final int? cid;
|
||||
final Function showEpisodes;
|
||||
final Function showIntroDetail;
|
||||
final String heroTag;
|
||||
|
||||
@override
|
||||
State<BangumiInfo> createState() => _BangumiInfoState();
|
||||
}
|
||||
|
||||
class _BangumiInfoState extends State<BangumiInfo> {
|
||||
late final BangumiIntroController bangumiIntroController;
|
||||
late final VideoDetailController videoDetailCtr;
|
||||
late final BangumiInfoModel? bangumiItem;
|
||||
int? cid;
|
||||
bool isProcessing = false;
|
||||
Future<void> handleState(Future Function() action) async {
|
||||
if (isProcessing.not) {
|
||||
@@ -142,10 +54,8 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
late final _coinKey = GlobalKey<ActionItemState>();
|
||||
late final _favKey = GlobalKey<ActionItemState>();
|
||||
|
||||
StreamSubscription? _listener;
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -153,32 +63,14 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
bangumiIntroController =
|
||||
Get.put(BangumiIntroController(), tag: widget.heroTag);
|
||||
videoDetailCtr = Get.find<VideoDetailController>(tag: widget.heroTag);
|
||||
bangumiItem = bangumiIntroController.bangumiItem;
|
||||
cid = widget.cid!;
|
||||
debugPrint('cid: $cid');
|
||||
_listener = videoDetailCtr.cid.listen((p0) {
|
||||
cid = p0;
|
||||
if (!mounted) return;
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// 视频介绍
|
||||
void showIntroDetail() {
|
||||
feedBack();
|
||||
widget.showIntroDetail();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final ThemeData theme = Theme.of(context);
|
||||
bool isLandscape =
|
||||
final bangumiItem = bangumiIntroController.bangumiItem;
|
||||
final isLandscape =
|
||||
MediaQuery.of(context).orientation == Orientation.landscape;
|
||||
return SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
@@ -188,8 +80,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
bottom: StyleString.safeSpace + MediaQuery.paddingOf(context).bottom,
|
||||
),
|
||||
sliver: SliverToBoxAdapter(
|
||||
child: !widget.isLoading || bangumiItem != null
|
||||
? Column(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
@@ -204,33 +95,25 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
context.imageView(
|
||||
imgList: [
|
||||
SourceModel(
|
||||
url: !widget.isLoading
|
||||
? widget.bangumiDetail!.cover!
|
||||
: bangumiItem!.cover!,
|
||||
url: bangumiItem.cover!,
|
||||
)
|
||||
],
|
||||
onDismissed: videoDetailCtr.onDismissed,
|
||||
);
|
||||
},
|
||||
child: Hero(
|
||||
tag: !widget.isLoading
|
||||
? widget.bangumiDetail!.cover!
|
||||
: bangumiItem!.cover!,
|
||||
tag: bangumiItem.cover!,
|
||||
child: NetworkImgLayer(
|
||||
width: isLandscape ? 115 / 0.75 : 115,
|
||||
height: isLandscape ? 115 : 115 / 0.75,
|
||||
src: !widget.isLoading
|
||||
? widget.bangumiDetail!.cover!
|
||||
: bangumiItem!.cover!,
|
||||
src: bangumiItem.cover!,
|
||||
semanticsLabel: '封面',
|
||||
),
|
||||
),
|
||||
),
|
||||
if (bangumiItem != null &&
|
||||
bangumiItem!.rating != null)
|
||||
if (bangumiItem.rating != null)
|
||||
PBadge(
|
||||
text:
|
||||
'评分 ${!widget.isLoading ? widget.bangumiDetail!.rating!['score']! : bangumiItem!.rating!['score']!}',
|
||||
text: '评分 ${bangumiItem.rating!['score']!}',
|
||||
top: null,
|
||||
right: 6,
|
||||
bottom: 6,
|
||||
@@ -241,7 +124,8 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: showIntroDetail,
|
||||
onTap: () => widget.showIntroDetail(
|
||||
bangumiItem, bangumiIntroController.videoTags),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: SizedBox(
|
||||
height: isLandscape ? 115 : 115 / 0.75,
|
||||
@@ -254,9 +138,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
!widget.isLoading
|
||||
? widget.bangumiDetail!.title!
|
||||
: bangumiItem!.title!,
|
||||
bangumiItem.title!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
@@ -276,15 +158,12 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
),
|
||||
visualDensity: VisualDensity.compact,
|
||||
foregroundColor:
|
||||
bangumiIntroController
|
||||
.isFollowed.value
|
||||
bangumiIntroController.isFollowed.value
|
||||
? theme.colorScheme.outline
|
||||
: null,
|
||||
backgroundColor:
|
||||
bangumiIntroController
|
||||
.isFollowed.value
|
||||
? theme.colorScheme
|
||||
.onInverseSurface
|
||||
bangumiIntroController.isFollowed.value
|
||||
? theme.colorScheme.onInverseSurface
|
||||
: null,
|
||||
),
|
||||
onPressed: bangumiIntroController
|
||||
@@ -296,13 +175,11 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
.isFollowed.value) {
|
||||
showPgcFollowDialog(
|
||||
context: context,
|
||||
type: bangumiIntroController
|
||||
.type,
|
||||
type: bangumiIntroController.type,
|
||||
followStatus:
|
||||
bangumiIntroController
|
||||
.followStatus.value,
|
||||
onUpdateStatus:
|
||||
(followStatus) {
|
||||
onUpdateStatus: (followStatus) {
|
||||
if (followStatus == -1) {
|
||||
bangumiIntroController
|
||||
.bangumiDel();
|
||||
@@ -314,13 +191,11 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
},
|
||||
);
|
||||
} else {
|
||||
bangumiIntroController
|
||||
.bangumiAdd();
|
||||
bangumiIntroController.bangumiAdd();
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
bangumiIntroController
|
||||
.isFollowed.value
|
||||
bangumiIntroController.isFollowed.value
|
||||
? '已${bangumiIntroController.type}'
|
||||
: '${bangumiIntroController.type}',
|
||||
),
|
||||
@@ -333,51 +208,32 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
StatView(
|
||||
context: context,
|
||||
theme: 'gray',
|
||||
value: Utils.numFormat(!widget.isLoading
|
||||
? widget.bangumiDetail!.stat!['views']
|
||||
: bangumiItem!.stat!['views']),
|
||||
value:
|
||||
Utils.numFormat(bangumiItem.stat!['views']),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
StatDanMu(
|
||||
context: context,
|
||||
theme: 'gray',
|
||||
value: Utils.numFormat(!widget.isLoading
|
||||
? widget
|
||||
.bangumiDetail!.stat!['danmakus']
|
||||
: bangumiItem!.stat!['danmakus']),
|
||||
value: Utils.numFormat(
|
||||
bangumiItem.stat!['danmakus']),
|
||||
),
|
||||
if (isLandscape) ...[
|
||||
const SizedBox(width: 6),
|
||||
AreasAndPubTime(
|
||||
widget: widget,
|
||||
bangumiItem: bangumiItem,
|
||||
theme: theme,
|
||||
),
|
||||
areasAndPubTime(theme, bangumiItem),
|
||||
const SizedBox(width: 6),
|
||||
NewEpDesc(
|
||||
widget: widget,
|
||||
bangumiItem: bangumiItem,
|
||||
theme: theme,
|
||||
),
|
||||
newEpDesc(theme, bangumiItem),
|
||||
]
|
||||
],
|
||||
),
|
||||
SizedBox(height: isLandscape ? 2 : 6),
|
||||
if (!isLandscape)
|
||||
AreasAndPubTime(
|
||||
widget: widget,
|
||||
bangumiItem: bangumiItem,
|
||||
theme: theme,
|
||||
),
|
||||
if (!isLandscape)
|
||||
NewEpDesc(
|
||||
widget: widget,
|
||||
bangumiItem: bangumiItem,
|
||||
theme: theme,
|
||||
),
|
||||
if (!isLandscape) ...[
|
||||
areasAndPubTime(theme, bangumiItem),
|
||||
newEpDesc(theme, bangumiItem),
|
||||
],
|
||||
const Spacer(),
|
||||
Text(
|
||||
'简介:${!widget.isLoading ? widget.bangumiDetail!.evaluate! : bangumiItem!.evaluate!}',
|
||||
'简介:${bangumiItem.evaluate!}',
|
||||
maxLines: isLandscape ? 2 : 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
@@ -394,40 +250,26 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
// 点赞收藏转发 布局样式2
|
||||
actionGrid(theme, bangumiIntroController),
|
||||
actionGrid(theme, bangumiItem, bangumiIntroController),
|
||||
// 番剧分p
|
||||
if ((!widget.isLoading &&
|
||||
widget.bangumiDetail!.episodes!.isNotEmpty) ||
|
||||
bangumiItem != null &&
|
||||
bangumiItem!.episodes!.isNotEmpty) ...[
|
||||
if (bangumiItem.episodes!.isNotEmpty) ...[
|
||||
BangumiPanel(
|
||||
heroTag: widget.heroTag,
|
||||
pages: bangumiItem != null
|
||||
? bangumiItem!.episodes!
|
||||
: widget.bangumiDetail!.episodes!,
|
||||
cid: cid ??
|
||||
(bangumiItem != null
|
||||
? bangumiItem!.episodes!.first.cid
|
||||
: widget.bangumiDetail!.episodes!.first.cid),
|
||||
pages: bangumiItem.episodes!,
|
||||
cid: videoDetailCtr.cid.value,
|
||||
changeFuc: bangumiIntroController.changeSeasonOrbangu,
|
||||
showEpisodes: widget.showEpisodes,
|
||||
newEp: bangumiItem?.newEp,
|
||||
newEp: bangumiItem.newEp,
|
||||
)
|
||||
],
|
||||
],
|
||||
)
|
||||
: const SizedBox(
|
||||
height: 100,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget actionGrid(
|
||||
ThemeData theme, BangumiIntroController bangumiIntroController) {
|
||||
Widget actionGrid(ThemeData theme, BangumiInfoModel bangumiItem,
|
||||
BangumiIntroController bangumiIntroController) {
|
||||
return Material(
|
||||
color: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
@@ -445,13 +287,9 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
handleState(bangumiIntroController.actionLikeVideo),
|
||||
onLongPress: bangumiIntroController.actionOneThree,
|
||||
selectStatus: bangumiIntroController.hasLike.value,
|
||||
loadingStatus: false,
|
||||
isLoading: false,
|
||||
semanticsLabel: '点赞',
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(widget.bangumiDetail!.stat!['likes']!)
|
||||
: Utils.numFormat(
|
||||
bangumiItem!.stat!['likes']!,
|
||||
),
|
||||
text: Utils.numFormat(bangumiItem.stat!['likes']!),
|
||||
needAnim: true,
|
||||
hasTriple: bangumiIntroController.hasLike.value &&
|
||||
bangumiIntroController.hasCoin &&
|
||||
@@ -476,13 +314,9 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
onTap: () =>
|
||||
handleState(bangumiIntroController.actionCoinVideo),
|
||||
selectStatus: bangumiIntroController.hasCoin,
|
||||
loadingStatus: false,
|
||||
isLoading: false,
|
||||
semanticsLabel: '投币',
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(widget.bangumiDetail!.stat!['coins']!)
|
||||
: Utils.numFormat(
|
||||
bangumiItem!.stat!['coins']!,
|
||||
),
|
||||
text: Utils.numFormat(bangumiItem.stat!['coins']!),
|
||||
needAnim: true,
|
||||
),
|
||||
),
|
||||
@@ -496,14 +330,9 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
onLongPress: () => bangumiIntroController
|
||||
.showFavBottomSheet(context, type: 'longPress'),
|
||||
selectStatus: bangumiIntroController.hasFav.value,
|
||||
loadingStatus: false,
|
||||
isLoading: false,
|
||||
semanticsLabel: '收藏',
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(
|
||||
widget.bangumiDetail!.stat!['favorite']!)
|
||||
: Utils.numFormat(
|
||||
bangumiItem!.stat!['favorite']!,
|
||||
),
|
||||
text: Utils.numFormat(bangumiItem.stat!['favorite']!),
|
||||
needAnim: true,
|
||||
),
|
||||
),
|
||||
@@ -512,21 +341,18 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
selectIcon: const Icon(FontAwesomeIcons.reply),
|
||||
onTap: () => videoDetailCtr.tabCtr.animateTo(1),
|
||||
selectStatus: false,
|
||||
loadingStatus: false,
|
||||
isLoading: false,
|
||||
semanticsLabel: '评论',
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(widget.bangumiDetail!.stat!['reply']!)
|
||||
: Utils.numFormat(bangumiItem!.stat!['reply']!),
|
||||
text: Utils.numFormat(bangumiItem.stat!['reply']!),
|
||||
),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||
onTap: () => bangumiIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
loadingStatus: false,
|
||||
isLoading: false,
|
||||
semanticsLabel: '转发',
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(widget.bangumiDetail!.stat!['share']!)
|
||||
: Utils.numFormat(bangumiItem!.stat!['share']!)),
|
||||
text: Utils.numFormat(bangumiItem.stat!['share']!),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -535,20 +361,19 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
}
|
||||
|
||||
Widget actionRow(
|
||||
BuildContext context,
|
||||
BangumiInfoModel bangumiItem,
|
||||
BangumiIntroController bangumiIntroController,
|
||||
VideoDetailController videoDetailCtr,
|
||||
) {
|
||||
return Row(children: [
|
||||
return Row(
|
||||
children: [
|
||||
Obx(
|
||||
() => ActionRowItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||
onTap: () => handleState(bangumiIntroController.actionLikeVideo),
|
||||
selectStatus: bangumiIntroController.hasLike.value,
|
||||
loadingStatus: widget.isLoading,
|
||||
text: !widget.isLoading
|
||||
? widget.bangumiDetail!.stat!['likes']!.toString()
|
||||
: '-',
|
||||
isLoading: false,
|
||||
text: bangumiItem.stat!['likes']!.toString(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -557,10 +382,8 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
onTap: () => handleState(bangumiIntroController.actionCoinVideo),
|
||||
selectStatus: bangumiIntroController.hasCoin,
|
||||
loadingStatus: widget.isLoading,
|
||||
text: !widget.isLoading
|
||||
? widget.bangumiDetail!.stat!['coins']!.toString()
|
||||
: '-',
|
||||
isLoading: false,
|
||||
text: bangumiItem.stat!['coins']!.toString(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -568,13 +391,11 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
() => ActionRowItem(
|
||||
icon: const Icon(FontAwesomeIcons.heart),
|
||||
onTap: () => bangumiIntroController.showFavBottomSheet(context),
|
||||
onLongPress: () => bangumiIntroController.showFavBottomSheet(context,
|
||||
type: 'longPress'),
|
||||
onLongPress: () => bangumiIntroController
|
||||
.showFavBottomSheet(context, type: 'longPress'),
|
||||
selectStatus: bangumiIntroController.hasFav.value,
|
||||
loadingStatus: widget.isLoading,
|
||||
text: !widget.isLoading
|
||||
? widget.bangumiDetail!.stat!['favorite']!.toString()
|
||||
: '-',
|
||||
isLoading: false,
|
||||
text: bangumiItem.stat!['favorite']!.toString(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -584,45 +405,27 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
videoDetailCtr.tabCtr.animateTo(1);
|
||||
},
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.isLoading,
|
||||
text: !widget.isLoading
|
||||
? widget.bangumiDetail!.stat!['reply']!.toString()
|
||||
: '-',
|
||||
isLoading: false,
|
||||
text: bangumiItem.stat!['reply']!.toString(),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionRowItem(
|
||||
icon: const Icon(FontAwesomeIcons.share),
|
||||
onTap: () => bangumiIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.isLoading,
|
||||
text: '转发'),
|
||||
]);
|
||||
isLoading: false,
|
||||
text: '转发',
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AreasAndPubTime extends StatelessWidget {
|
||||
const AreasAndPubTime({
|
||||
super.key,
|
||||
required this.widget,
|
||||
required this.bangumiItem,
|
||||
required this.theme,
|
||||
});
|
||||
|
||||
final BangumiInfo widget;
|
||||
final BangumiInfoModel? bangumiItem;
|
||||
final ThemeData theme;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget areasAndPubTime(ThemeData theme, BangumiInfoModel bangumiItem) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
!widget.isLoading
|
||||
? (widget.bangumiDetail!.areas!.isNotEmpty
|
||||
? widget.bangumiDetail!.areas!.first['name']
|
||||
: '')
|
||||
: (bangumiItem!.areas!.isNotEmpty
|
||||
? bangumiItem!.areas!.first['name']
|
||||
(bangumiItem.areas!.isNotEmpty
|
||||
? bangumiItem.areas!.first['name']
|
||||
: ''),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
@@ -631,9 +434,7 @@ class AreasAndPubTime extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
!widget.isLoading
|
||||
? widget.bangumiDetail!.publish!['pub_time_show']
|
||||
: bangumiItem!.publish!['pub_time_show'],
|
||||
bangumiItem.publish!['pub_time_show'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
@@ -642,26 +443,10 @@ class AreasAndPubTime extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NewEpDesc extends StatelessWidget {
|
||||
const NewEpDesc({
|
||||
super.key,
|
||||
required this.widget,
|
||||
required this.bangumiItem,
|
||||
required this.theme,
|
||||
});
|
||||
|
||||
final BangumiInfo widget;
|
||||
final BangumiInfoModel? bangumiItem;
|
||||
final ThemeData theme;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget newEpDesc(ThemeData theme, BangumiInfoModel bangumiItem) {
|
||||
return Text(
|
||||
!widget.isLoading
|
||||
? widget.bangumiDetail!.newEp!['desc']
|
||||
: bangumiItem!.newEp!['desc'],
|
||||
bangumiItem.newEp!['desc'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
|
||||
@@ -71,7 +71,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
return Obx(
|
||||
() => videoIntroController.videoDetail.value.title == null
|
||||
? VideoInfo(
|
||||
loadingStatus: true,
|
||||
isLoading: true,
|
||||
videoIntroController: videoIntroController,
|
||||
heroTag: widget.heroTag,
|
||||
showAiBottomSheet: widget.showAiBottomSheet,
|
||||
@@ -80,7 +80,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
)
|
||||
: VideoInfo(
|
||||
key: ValueKey(widget.heroTag),
|
||||
loadingStatus: false,
|
||||
isLoading: false,
|
||||
videoIntroController: videoIntroController,
|
||||
heroTag: widget.heroTag,
|
||||
showAiBottomSheet: widget.showAiBottomSheet,
|
||||
@@ -92,7 +92,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
}
|
||||
|
||||
class VideoInfo extends StatefulWidget {
|
||||
final bool loadingStatus;
|
||||
final bool isLoading;
|
||||
final String heroTag;
|
||||
final Function showAiBottomSheet;
|
||||
final Function showEpisodes;
|
||||
@@ -101,7 +101,7 @@ class VideoInfo extends StatefulWidget {
|
||||
|
||||
const VideoInfo({
|
||||
super.key,
|
||||
this.loadingStatus = false,
|
||||
this.isLoading = false,
|
||||
required this.heroTag,
|
||||
required this.showAiBottomSheet,
|
||||
required this.showEpisodes,
|
||||
@@ -236,7 +236,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
|
||||
// 视频介绍
|
||||
void showIntroDetail() {
|
||||
if (widget.loadingStatus) {
|
||||
if (widget.isLoading) {
|
||||
return;
|
||||
}
|
||||
feedBack();
|
||||
@@ -246,9 +246,8 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
// 用户主页
|
||||
void onPushMember() {
|
||||
feedBack();
|
||||
int? mid = !widget.loadingStatus
|
||||
? videoDetail.owner?.mid
|
||||
: videoItem['owner']?.mid;
|
||||
int? mid =
|
||||
!widget.isLoading ? videoDetail.owner?.mid : videoItem['owner']?.mid;
|
||||
if (mid != null) {
|
||||
if (context.orientation == Orientation.landscape &&
|
||||
_horizontalMemberPage) {
|
||||
@@ -369,7 +368,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
childBuilder: (index) => GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
int? ownerMid = !widget.loadingStatus
|
||||
int? ownerMid = !widget.isLoading
|
||||
? videoDetail.owner?.mid
|
||||
: videoItem['owner']?.mid;
|
||||
if (videoItem['staff'][index].mid ==
|
||||
@@ -557,7 +556,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
StatView(
|
||||
context: context,
|
||||
theme: 'gray',
|
||||
value: Utils.numFormat(!widget.loadingStatus
|
||||
value: Utils.numFormat(!widget.isLoading
|
||||
? videoDetail.stat?.view ?? '-'
|
||||
: videoItem['stat']?.view ?? '-'),
|
||||
textColor: theme.colorScheme.outline,
|
||||
@@ -566,7 +565,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
StatDanMu(
|
||||
context: context,
|
||||
theme: 'gray',
|
||||
value: Utils.numFormat(!widget.loadingStatus
|
||||
value: Utils.numFormat(!widget.isLoading
|
||||
? videoDetail.stat?.danmaku ?? '-'
|
||||
: videoItem['stat']?.danmu ?? '-'),
|
||||
textColor: theme.colorScheme.outline,
|
||||
@@ -574,7 +573,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
Utils.dateFormat(
|
||||
!widget.loadingStatus
|
||||
!widget.isLoading
|
||||
? videoDetail.pubdate
|
||||
: videoItem['pubdate'],
|
||||
formatType: 'detail'),
|
||||
@@ -769,7 +768,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
actionGrid(context, videoIntroController),
|
||||
],
|
||||
// 合集
|
||||
if (!widget.loadingStatus &&
|
||||
if (!widget.isLoading &&
|
||||
videoDetail.ugcSeason != null &&
|
||||
(context.orientation != Orientation.landscape ||
|
||||
(context.orientation == Orientation.landscape &&
|
||||
@@ -784,7 +783,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
videoIntroController: videoIntroController,
|
||||
),
|
||||
),
|
||||
if (!widget.loadingStatus &&
|
||||
if (!widget.isLoading &&
|
||||
videoDetail.pages != null &&
|
||||
videoDetail.pages!.length > 1 &&
|
||||
(context.orientation != Orientation.landscape ||
|
||||
@@ -857,9 +856,9 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
onLongPress: () =>
|
||||
handleState(videoIntroController.actionOneThree),
|
||||
selectStatus: videoIntroController.hasLike.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
isLoading: widget.isLoading,
|
||||
semanticsLabel: '点赞',
|
||||
text: !widget.loadingStatus
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(videoDetail.stat!.like!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
@@ -884,7 +883,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||
onTap: () => handleState(videoIntroController.actionDislikeVideo),
|
||||
selectStatus: videoIntroController.hasDislike.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
isLoading: widget.isLoading,
|
||||
semanticsLabel: '点踩',
|
||||
text: "点踩",
|
||||
),
|
||||
@@ -896,9 +895,9 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||
onTap: () => handleState(videoIntroController.actionCoinVideo),
|
||||
selectStatus: videoIntroController.hasCoin,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
isLoading: widget.isLoading,
|
||||
semanticsLabel: '投币',
|
||||
text: !widget.loadingStatus
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(videoDetail.stat!.coin!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
@@ -913,9 +912,9 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
onLongPress: () => videoIntroController
|
||||
.showFavBottomSheet(context, type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
isLoading: widget.isLoading,
|
||||
semanticsLabel: '收藏',
|
||||
text: !widget.loadingStatus
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(videoDetail.stat!.favorite!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
@@ -927,7 +926,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidClock),
|
||||
onTap: () => handleState(videoIntroController.viewLater),
|
||||
selectStatus: videoIntroController.hasLater.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
isLoading: widget.isLoading,
|
||||
semanticsLabel: '再看',
|
||||
text: '再看',
|
||||
),
|
||||
@@ -936,9 +935,9 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||
onTap: () => videoIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
isLoading: widget.isLoading,
|
||||
semanticsLabel: '分享',
|
||||
text: !widget.loadingStatus
|
||||
text: !widget.isLoading
|
||||
? Utils.numFormat(videoDetail.stat!.share!)
|
||||
: '分享',
|
||||
),
|
||||
@@ -958,9 +957,8 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||
onTap: () => handleState(videoIntroController.actionLikeVideo),
|
||||
selectStatus: videoIntroController.hasLike.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
text:
|
||||
!widget.loadingStatus ? videoDetail.stat!.like!.toString() : '-',
|
||||
isLoading: widget.isLoading,
|
||||
text: !widget.isLoading ? videoDetail.stat!.like!.toString() : '-',
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -969,9 +967,8 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
onTap: () => handleState(videoIntroController.actionCoinVideo),
|
||||
selectStatus: videoIntroController.hasCoin,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
text:
|
||||
!widget.loadingStatus ? videoDetail.stat!.coin!.toString() : '-',
|
||||
isLoading: widget.isLoading,
|
||||
text: !widget.isLoading ? videoDetail.stat!.coin!.toString() : '-',
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -982,10 +979,9 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
onLongPress: () => videoIntroController.showFavBottomSheet(context,
|
||||
type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
text: !widget.loadingStatus
|
||||
? videoDetail.stat!.favorite!.toString()
|
||||
: '-',
|
||||
isLoading: widget.isLoading,
|
||||
text:
|
||||
!widget.isLoading ? videoDetail.stat!.favorite!.toString() : '-',
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -995,15 +991,15 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
videoDetailCtr.tabCtr.animateTo(1);
|
||||
},
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
text: !widget.loadingStatus ? videoDetail.stat!.reply!.toString() : '-',
|
||||
isLoading: widget.isLoading,
|
||||
text: !widget.isLoading ? videoDetail.stat!.reply!.toString() : '-',
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionRowItem(
|
||||
icon: const Icon(FontAwesomeIcons.share),
|
||||
onTap: () => videoIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
isLoading: widget.isLoading,
|
||||
text: '转发',
|
||||
),
|
||||
]);
|
||||
|
||||
@@ -12,7 +12,7 @@ class ActionItem extends StatefulWidget {
|
||||
final Icon? selectIcon;
|
||||
final Function? onTap;
|
||||
final Function? onLongPress;
|
||||
final bool? loadingStatus;
|
||||
final bool? isLoading;
|
||||
final String? text;
|
||||
final bool selectStatus;
|
||||
final String semanticsLabel;
|
||||
@@ -27,7 +27,7 @@ class ActionItem extends StatefulWidget {
|
||||
this.selectIcon,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.loadingStatus,
|
||||
this.isLoading,
|
||||
this.text,
|
||||
this.selectStatus = false,
|
||||
this.needAnim = false,
|
||||
@@ -183,7 +183,7 @@ class ActionItemState extends State<ActionItem>
|
||||
),
|
||||
if (widget.text != null)
|
||||
AnimatedOpacity(
|
||||
opacity: widget.loadingStatus! ? 0 : 1,
|
||||
opacity: widget.isLoading! ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
|
||||
@@ -5,7 +5,7 @@ class ActionRowItem extends StatelessWidget {
|
||||
final Icon? icon;
|
||||
final Icon? selectIcon;
|
||||
final Function? onTap;
|
||||
final bool? loadingStatus;
|
||||
final bool? isLoading;
|
||||
final String? text;
|
||||
final bool selectStatus;
|
||||
final Function? onLongPress;
|
||||
@@ -15,7 +15,7 @@ class ActionRowItem extends StatelessWidget {
|
||||
this.icon,
|
||||
this.selectIcon,
|
||||
this.onTap,
|
||||
this.loadingStatus,
|
||||
this.isLoading,
|
||||
this.text,
|
||||
this.selectStatus = false,
|
||||
this.onLongPress,
|
||||
@@ -53,7 +53,7 @@ class ActionRowItem extends StatelessWidget {
|
||||
const SizedBox(width: 6),
|
||||
],
|
||||
AnimatedOpacity(
|
||||
opacity: loadingStatus! ? 0 : 1,
|
||||
opacity: isLoading! ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
|
||||
@@ -4,9 +4,9 @@ import 'package:flutter/material.dart';
|
||||
class MenuRow extends StatelessWidget {
|
||||
const MenuRow({
|
||||
super.key,
|
||||
this.loadingStatus,
|
||||
this.isLoading,
|
||||
});
|
||||
final bool? loadingStatus;
|
||||
final bool? isLoading;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -20,28 +20,28 @@ class MenuRow extends StatelessWidget {
|
||||
child: Row(children: [
|
||||
ActionRowLineItem(
|
||||
onTap: () => {},
|
||||
loadingStatus: loadingStatus,
|
||||
isLoading: isLoading,
|
||||
text: '推荐',
|
||||
selectStatus: false,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionRowLineItem(
|
||||
onTap: () => {},
|
||||
loadingStatus: loadingStatus,
|
||||
isLoading: isLoading,
|
||||
text: '弹幕',
|
||||
selectStatus: false,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionRowLineItem(
|
||||
onTap: () => {},
|
||||
loadingStatus: loadingStatus,
|
||||
isLoading: isLoading,
|
||||
text: '评论列表',
|
||||
selectStatus: false,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionRowLineItem(
|
||||
onTap: () => {},
|
||||
loadingStatus: loadingStatus,
|
||||
isLoading: isLoading,
|
||||
text: '播放列表',
|
||||
selectStatus: false,
|
||||
),
|
||||
@@ -51,7 +51,7 @@ class MenuRow extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget actionRowLineItem(
|
||||
ThemeData theme, Function? onTap, bool? loadingStatus, String? text,
|
||||
ThemeData theme, Function? onTap, bool? isLoading, String? text,
|
||||
{bool selectStatus = false}) {
|
||||
return Material(
|
||||
color: selectStatus
|
||||
@@ -78,7 +78,7 @@ class MenuRow extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
AnimatedOpacity(
|
||||
opacity: loadingStatus! ? 0 : 1,
|
||||
opacity: isLoading! ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Text(
|
||||
text!,
|
||||
@@ -103,13 +103,13 @@ class ActionRowLineItem extends StatelessWidget {
|
||||
required this.selectStatus,
|
||||
this.onTap,
|
||||
this.text,
|
||||
this.loadingStatus = false,
|
||||
this.isLoading = false,
|
||||
this.iconData,
|
||||
this.icon,
|
||||
});
|
||||
final bool selectStatus;
|
||||
final Function? onTap;
|
||||
final bool? loadingStatus;
|
||||
final bool? isLoading;
|
||||
final String? text;
|
||||
final IconData? iconData;
|
||||
final Widget? icon;
|
||||
@@ -152,7 +152,7 @@ class ActionRowLineItem extends StatelessWidget {
|
||||
else if (icon != null)
|
||||
icon!,
|
||||
AnimatedOpacity(
|
||||
opacity: loadingStatus! ? 0 : 1,
|
||||
opacity: isLoading! ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Text(
|
||||
text!,
|
||||
|
||||
@@ -10,7 +10,6 @@ import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/main.dart';
|
||||
import 'package:PiliPlus/models/bangumi/info.dart' as bangumi;
|
||||
import 'package:PiliPlus/models/bangumi/info.dart';
|
||||
import 'package:PiliPlus/models/common/episode_panel_type.dart';
|
||||
import 'package:PiliPlus/models/common/reply/reply_type.dart';
|
||||
import 'package:PiliPlus/models/common/search_type.dart';
|
||||
@@ -103,8 +102,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
videoDetailController.plPlayerController.horizontalPreview;
|
||||
|
||||
StreamSubscription? _listenerDetail;
|
||||
StreamSubscription? _listenerLoadingState;
|
||||
StreamSubscription? _listenerCid;
|
||||
StreamSubscription? _listenerFS;
|
||||
|
||||
Box get setting => GStorage.setting;
|
||||
@@ -137,23 +134,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
});
|
||||
if (videoDetailController.videoType == SearchType.media_bangumi) {
|
||||
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
|
||||
_listenerLoadingState =
|
||||
bangumiIntroController.loadingState.listen((value) {
|
||||
if (!context.mounted) return;
|
||||
if (value is Success<BangumiInfoModel>) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(
|
||||
value.response, videoDetailController.cid.value, heroTag);
|
||||
}
|
||||
});
|
||||
_listenerCid = videoDetailController.cid.listen((p0) {
|
||||
if (!context.mounted) return;
|
||||
if (bangumiIntroController.loadingState.value is Success) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(
|
||||
(bangumiIntroController.loadingState.value as Success).response,
|
||||
p0,
|
||||
heroTag);
|
||||
}
|
||||
});
|
||||
}
|
||||
autoExitFullscreen =
|
||||
setting.get(SettingBoxKey.enableAutoExit, defaultValue: true);
|
||||
@@ -337,8 +317,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
@override
|
||||
void dispose() {
|
||||
_listenerDetail?.cancel();
|
||||
_listenerLoadingState?.cancel();
|
||||
_listenerCid?.cancel();
|
||||
_listenerFS?.cancel();
|
||||
|
||||
videoDetailController.skipTimer?.cancel();
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'dart:math';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/super_resolution_type.dart';
|
||||
import 'package:PiliPlus/models/video_detail_res.dart';
|
||||
import 'package:PiliPlus/pages/video/controller.dart';
|
||||
@@ -266,7 +265,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
bool isSeason = videoIntroController?.videoDetail.value.ugcSeason != null;
|
||||
bool isPage = videoIntroController?.videoDetail.value.pages != null &&
|
||||
videoIntroController!.videoDetail.value.pages!.length > 1;
|
||||
bool isBangumi = bangumiIntroController?.loadingState.value is Success;
|
||||
bool isBangumi = bangumiIntroController != null;
|
||||
bool anySeason = isSeason || isPage || isBangumi;
|
||||
double widgetWidth =
|
||||
isFullScreen && context.orientation == Orientation.landscape ? 42 : 35;
|
||||
@@ -508,9 +507,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
videoIntroController!.videoDetail.value.pages!;
|
||||
episodes = pages;
|
||||
} else if (isBangumi) {
|
||||
episodes = (bangumiIntroController!.loadingState.value as Success)
|
||||
.response
|
||||
.episodes!;
|
||||
episodes = bangumiIntroController!.bangumiItem.episodes!;
|
||||
}
|
||||
widget.showEpisodes?.call(
|
||||
index,
|
||||
|
||||
Reference in New Issue
Block a user