mod: 视频简介与相关视频实现方式微调

This commit is contained in:
orz12
2024-07-11 17:48:15 +08:00
parent 815716c402
commit 17e9f00eca
2 changed files with 252 additions and 255 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -17,6 +18,7 @@ import 'package:PiliPalaX/pages/video/detail/widgets/ai_detail.dart';
import 'package:PiliPalaX/utils/feed_back.dart'; import 'package:PiliPalaX/utils/feed_back.dart';
import 'package:PiliPalaX/utils/storage.dart'; import 'package:PiliPalaX/utils/storage.dart';
import 'package:PiliPalaX/utils/utils.dart'; import 'package:PiliPalaX/utils/utils.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'widgets/action_item.dart'; import 'widgets/action_item.dart';
import 'widgets/action_row_item.dart'; import 'widgets/action_row_item.dart';
@@ -93,7 +95,18 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
snapshot.data['code'] == 62002 snapshot.data['code'] == 62002
? '上一页' ? '上一页'
: null, : null,
fn: () => Get.back(), fn: () {
if (snapshot.data['code'] == -404 ||
snapshot.data['code'] == 62002) {
Get.back();
return;
}
_futureBuilderFuture = videoIntroController.queryVideoIntro();
_futureBuilderFuture!.then((value) {
videoIntroController.videoDetail.refresh();
setState(() {});
});
},
); );
} }
} else { } else {
@@ -245,273 +258,253 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData t = Theme.of(context); final ThemeData t = Theme.of(context);
final Color outline = t.colorScheme.outline; return SliverLayoutBuilder(
bool isHorizontal = context.width > context.height * 1.25; builder: (BuildContext context, SliverConstraints constraints) {
return SliverPadding( bool isHorizontal = constraints.crossAxisExtent >
padding: const EdgeInsets.only( constraints.viewportMainAxisExtent * 1.25;
left: StyleString.safeSpace, right: StyleString.safeSpace, top: 10), return SliverPadding(
sliver: SliverToBoxAdapter( padding: const EdgeInsets.only(
child: !loadingStatus left: StyleString.safeSpace,
? Column( right: StyleString.safeSpace,
crossAxisAlignment: CrossAxisAlignment.start, top: 10),
children: [ sliver: SliverToBoxAdapter(
Row(children: [ child: !loadingStatus
Expanded( ? Column(
child: GestureDetector( crossAxisAlignment: CrossAxisAlignment.start,
onTap: onPushMember,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 1, horizontal: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
NetworkImgLayer(
type: 'avatar',
src: loadingStatus
? owner.face
: widget.videoDetail!.owner!.face,
width: 30,
height: 30,
fadeInDuration: Duration.zero,
fadeOutDuration: Duration.zero,
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
owner.name,
style: TextStyle(
fontSize: 12,
color: t.colorScheme.primary),
// semanticsLabel: "Up主${owner.name}",
),
const SizedBox(height: 0),
Text(
follower,
semanticsLabel: "$follower粉丝",
style: TextStyle(
fontSize: 12,
color: outline,
),
),
]),
const Spacer(),
Obx(() => AnimatedOpacity(
opacity: loadingStatus ||
videoIntroController
.followStatus.isEmpty
? 0
: 1,
duration: const Duration(milliseconds: 50),
child: SizedBox(
height: 32,
child: Obx(
() => videoIntroController
.followStatus.isNotEmpty
? TextButton(
onPressed: () =>
videoIntroController
.actionRelationMod(
context),
style: TextButton.styleFrom(
padding: const EdgeInsets.only(
left: 8, right: 8),
foregroundColor:
followStatus['attribute'] !=
0
? outline
: t.colorScheme
.onPrimary,
backgroundColor:
followStatus['attribute'] !=
0
? t.colorScheme
.onInverseSurface
: t.colorScheme
.primary, // 设置按钮背景色
),
child: Text(
followStatus['attribute'] != 0
? '已关注'
: '关注',
style: TextStyle(
fontSize: t.textTheme
.labelMedium!.fontSize),
),
)
: ElevatedButton(
onPressed: () =>
videoIntroController
.actionRelationMod(
context),
child: const Text('关注'),
),
),
),
)),
],
),
),
)),
if (isHorizontal)
Expanded(
child: actionGrid(context, videoIntroController)),
]),
const SizedBox(height: 8),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => showIntroDetail(),
child: Row(children: [
Expanded(
child: Text(
!loadingStatus
? widget.videoDetail!.title
: videoItem['title'],
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
)),
Icon(
Icons.arrow_forward_ios,
size: 16,
color: t.colorScheme.outline,
),
]),
),
Stack(
children: [ children: [
Row(children: [
Expanded(
child: GestureDetector(
onTap: onPushMember,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 1, horizontal: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
NetworkImgLayer(
type: 'avatar',
src: loadingStatus
? owner.face
: widget.videoDetail!.owner!.face,
width: 30,
height: 30,
fadeInDuration: Duration.zero,
fadeOutDuration: Duration.zero,
),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
owner.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
color: t.colorScheme.primary),
// semanticsLabel: "Up主${owner.name}",
),
const SizedBox(height: 0),
Text(
follower,
semanticsLabel: "$follower粉丝",
style: TextStyle(
fontSize: 12,
color: t.colorScheme.outline,
),
),
],
)),
followButton(context, t),
],
),
),
)),
if (isHorizontal) ...[
const SizedBox(width: 10),
Expanded(
child: actionGrid(context, videoIntroController)),
]
]),
const SizedBox(height: 8),
GestureDetector( GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () => showIntroDetail(), onTap: () => showIntroDetail(),
child: Padding( child: Row(children: [
padding: const EdgeInsets.only(top: 7, bottom: 6), Expanded(
child: Row( child: Text(
children: <Widget>[ !loadingStatus
StatView( ? widget.videoDetail!.title
theme: 'gray', : videoItem['title'],
view: !loadingStatus style: const TextStyle(
? widget.videoDetail!.stat!.view fontSize: 16,
: videoItem['stat'].view, fontWeight: FontWeight.w500,
size: 'medium', ),
), maxLines: 2,
const SizedBox(width: 10), overflow: TextOverflow.ellipsis,
StatDanMu( )),
theme: 'gray', Icon(
danmu: !loadingStatus Icons.arrow_forward_ios,
? widget.videoDetail!.stat!.danmu size: 16,
: videoItem['stat'].danmu, color: t.colorScheme.outline,
size: 'medium', ),
), ]),
const SizedBox(width: 10), ),
Text( Stack(
Utils.dateFormat( children: [
!loadingStatus GestureDetector(
? widget.videoDetail!.pubdate behavior: HitTestBehavior.translucent,
: videoItem['pubdate'], onTap: () => showIntroDetail(),
formatType: 'detail'), child: Padding(
style: TextStyle( padding: const EdgeInsets.only(top: 7, bottom: 6),
fontSize: 12, child: Row(
color: t.colorScheme.outline, children: <Widget>[
), StatView(
), theme: 'gray',
if (MineController.anonymity) ...<Widget>[ view: !loadingStatus
const SizedBox(width: 10), ? widget.videoDetail!.stat!.view
Icon( : videoItem['stat'].view,
CupertinoIcons.checkmark_shield, size: 'medium',
size: 15, ),
color: t.colorScheme.outline, const SizedBox(width: 10),
), StatDanMu(
Text( theme: 'gray',
'无痕', danmu: !loadingStatus
style: TextStyle( ? widget.videoDetail!.stat!.danmu
fontSize: 12, : videoItem['stat'].danmu,
color: t.colorScheme.outline), size: 'medium',
), ),
], const SizedBox(width: 10),
const SizedBox(width: 10), Text(
if (videoIntroController.isShowOnlineTotal) Utils.dateFormat(
Obx( !loadingStatus
() => Text( ? widget.videoDetail!.pubdate
'${videoIntroController.total.value}人在看', : videoItem['pubdate'],
formatType: 'detail'),
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: t.colorScheme.outline, color: t.colorScheme.outline,
), ),
), ),
), if (MineController.anonymity) ...<Widget>[
], const SizedBox(width: 10),
Icon(
MdiIcons.incognito,
size: 15,
color: t.colorScheme.outline,
semanticLabel: '无痕',
),
],
const SizedBox(width: 10),
if (videoIntroController.isShowOnlineTotal)
Obx(
() => Text(
'${videoIntroController.total.value}人在看',
style: TextStyle(
fontSize: 12,
color: t.colorScheme.outline,
),
),
),
],
),
),
), ),
), if (enableAi)
Positioned(
right: 10,
top: 6,
child: Semantics(
label: 'AI总结',
child: GestureDetector(
onTap: () async {
final res = await videoIntroController
.aiConclusion();
if (res['status']) {
showAiBottomSheet();
}
},
child: Image.asset('assets/images/ai.png',
height: 22),
)),
)
],
), ),
if (enableAi) // 点赞收藏转发 布局样式1
Positioned( // SingleChildScrollView(
right: 10, // padding: const EdgeInsets.only(top: 7, bottom: 7),
top: 6, // scrollDirection: Axis.horizontal,
child: Semantics( // child: actionRow(
label: 'AI总结', // context,
child: GestureDetector( // videoIntroController,
onTap: () async { // videoDetailCtr,
final res = // ),
await videoIntroController.aiConclusion(); // ),
if (res['status']) { // 点赞收藏转发 布局样式2
showAiBottomSheet(); if (!isHorizontal)
} actionGrid(context, videoIntroController),
}, // 合集
child: Image.asset('assets/images/ai.png', if (!loadingStatus &&
height: 22), widget.videoDetail!.ugcSeason != null) ...[
)), Obx(
() => SeasonPanel(
heroTag: heroTag,
ugcSeason: widget.videoDetail!.ugcSeason!,
cid: videoIntroController.lastPlayCid.value != 0
? videoIntroController.lastPlayCid.value
: widget.videoDetail!.pages!.first.cid,
changeFuc: videoIntroController.changeSeasonOrbangu,
),
) )
],
if (!loadingStatus &&
widget.videoDetail!.pages != null &&
widget.videoDetail!.pages!.length > 1) ...[
Obx(() => PagesPanel(
heroTag: heroTag,
pages: widget.videoDetail!.pages!,
cid: videoIntroController.lastPlayCid.value,
bvid: videoIntroController.bvid,
changeFuc:
videoIntroController.changeSeasonOrbangu,
))
],
], ],
)
: const SizedBox(
height: 130,
child: Center(
child: CircularProgressIndicator(),
),
), ),
// 点赞收藏转发 布局样式1 ),
// SingleChildScrollView( );
// padding: const EdgeInsets.only(top: 7, bottom: 7), },
// scrollDirection: Axis.horizontal, );
// child: actionRow( }
// context,
// videoIntroController, Obx followButton(BuildContext context, ThemeData t) {
// videoDetailCtr, return Obx(
// ), () => TextButton(
// ), onPressed: () => videoIntroController.actionRelationMod(context),
// 点赞收藏转发 布局样式2 style: TextButton.styleFrom(
if (!isHorizontal) actionGrid(context, videoIntroController), visualDensity: VisualDensity.compact,
// 合集 tapTargetSize: MaterialTapTargetSize.shrinkWrap,
if (!loadingStatus && padding: const EdgeInsets.only(left: 6, right: 6),
widget.videoDetail!.ugcSeason != null) ...[ foregroundColor: (followStatus?['attribute'] ?? 0) != 0
Obx( ? t.colorScheme.outline
() => SeasonPanel( : t.colorScheme.onPrimary,
heroTag: heroTag, backgroundColor: (followStatus?['attribute'] ?? 0) != 0
ugcSeason: widget.videoDetail!.ugcSeason!, ? t.colorScheme.onInverseSurface
cid: videoIntroController.lastPlayCid.value != 0 : t.colorScheme.primary, // 设置按钮背景色
? videoIntroController.lastPlayCid.value ),
: widget.videoDetail!.pages!.first.cid, child: Text(
changeFuc: videoIntroController.changeSeasonOrbangu, ((followStatus?['attribute'] ?? 0) != 0) ? '已关注' : '关注',
), style: TextStyle(fontSize: t.textTheme.labelMedium!.fontSize),
) ),
],
if (!loadingStatus &&
widget.videoDetail!.pages != null &&
widget.videoDetail!.pages!.length > 1) ...[
Obx(() => PagesPanel(
heroTag: heroTag,
pages: widget.videoDetail!.pages!,
cid: videoIntroController.lastPlayCid.value,
bvid: videoIntroController.bvid,
changeFuc: videoIntroController.changeSeasonOrbangu,
))
],
],
)
: const SizedBox(
height: 130,
child: Center(
child: CircularProgressIndicator(),
),
),
), ),
); );
} }
@@ -530,6 +523,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
icon: const Icon(FontAwesomeIcons.thumbsUp), icon: const Icon(FontAwesomeIcons.thumbsUp),
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp), selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
onTap: handleState(videoIntroController.actionLikeVideo), onTap: handleState(videoIntroController.actionLikeVideo),
onLongPress: handleState(videoIntroController.actionOneThree),
selectStatus: videoIntroController.hasLike.value, selectStatus: videoIntroController.hasLike.value,
loadingStatus: loadingStatus, loadingStatus: loadingStatus,
semanticsLabel: '点赞', semanticsLabel: '点赞',

View File

@@ -85,7 +85,10 @@ class _RelatedVideoPanelState extends State<RelatedVideoPanel>
); );
} else { } else {
// 请求错误 // 请求错误
return HttpError(errMsg: '出错了', fn: () {}); return HttpError(errMsg: '出错了', fn: () {
_futureBuilder = _relatedController.queryRelatedVideo();
_futureBuilder.then((value) => setState(() {}));
});
} }
} else { } else {
// 骨架屏 // 骨架屏