From 17e9f00ecac5dfa645ed5d40a94f8d9e1944fecb Mon Sep 17 00:00:00 2001 From: orz12 Date: Thu, 11 Jul 2024 17:48:15 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E8=A7=86=E9=A2=91=E7=AE=80=E4=BB=8B?= =?UTF-8?q?=E4=B8=8E=E7=9B=B8=E5=85=B3=E8=A7=86=E9=A2=91=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/video/detail/introduction/view.dart | 502 +++++++++--------- lib/pages/video/detail/related/view.dart | 5 +- 2 files changed, 252 insertions(+), 255 deletions(-) diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 5dc9360e..6b209680 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.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/storage.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_row_item.dart'; @@ -93,7 +95,18 @@ class _VideoIntroPanelState extends State snapshot.data['code'] == 62002 ? '上一页' : 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 { @@ -245,273 +258,253 @@ class _VideoInfoState extends State with TickerProviderStateMixin { @override Widget build(BuildContext context) { final ThemeData t = Theme.of(context); - final Color outline = t.colorScheme.outline; - bool isHorizontal = context.width > context.height * 1.25; - return SliverPadding( - padding: const EdgeInsets.only( - left: StyleString.safeSpace, right: StyleString.safeSpace, top: 10), - sliver: SliverToBoxAdapter( - child: !loadingStatus - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(children: [ - Expanded( - child: GestureDetector( - 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( + return SliverLayoutBuilder( + builder: (BuildContext context, SliverConstraints constraints) { + bool isHorizontal = constraints.crossAxisExtent > + constraints.viewportMainAxisExtent * 1.25; + return SliverPadding( + padding: const EdgeInsets.only( + left: StyleString.safeSpace, + right: StyleString.safeSpace, + top: 10), + sliver: SliverToBoxAdapter( + child: !loadingStatus + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, 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( behavior: HitTestBehavior.translucent, onTap: () => showIntroDetail(), - child: Padding( - padding: const EdgeInsets.only(top: 7, bottom: 6), - child: Row( - children: [ - StatView( - theme: 'gray', - view: !loadingStatus - ? widget.videoDetail!.stat!.view - : videoItem['stat'].view, - size: 'medium', - ), - const SizedBox(width: 10), - StatDanMu( - theme: 'gray', - danmu: !loadingStatus - ? widget.videoDetail!.stat!.danmu - : videoItem['stat'].danmu, - size: 'medium', - ), - const SizedBox(width: 10), - Text( - Utils.dateFormat( - !loadingStatus - ? widget.videoDetail!.pubdate - : videoItem['pubdate'], - formatType: 'detail'), - style: TextStyle( - fontSize: 12, - color: t.colorScheme.outline, - ), - ), - if (MineController.anonymity) ...[ - const SizedBox(width: 10), - Icon( - CupertinoIcons.checkmark_shield, - size: 15, - color: t.colorScheme.outline, - ), - Text( - '无痕', - style: TextStyle( - fontSize: 12, - color: t.colorScheme.outline), - ), - ], - const SizedBox(width: 10), - if (videoIntroController.isShowOnlineTotal) - Obx( - () => Text( - '${videoIntroController.total.value}人在看', + 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: [ + GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => showIntroDetail(), + child: Padding( + padding: const EdgeInsets.only(top: 7, bottom: 6), + child: Row( + children: [ + StatView( + theme: 'gray', + view: !loadingStatus + ? widget.videoDetail!.stat!.view + : videoItem['stat'].view, + size: 'medium', + ), + const SizedBox(width: 10), + StatDanMu( + theme: 'gray', + danmu: !loadingStatus + ? widget.videoDetail!.stat!.danmu + : videoItem['stat'].danmu, + size: 'medium', + ), + const SizedBox(width: 10), + Text( + Utils.dateFormat( + !loadingStatus + ? widget.videoDetail!.pubdate + : videoItem['pubdate'], + formatType: 'detail'), style: TextStyle( fontSize: 12, color: t.colorScheme.outline, ), ), - ), - ], + if (MineController.anonymity) ...[ + 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) - 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), - )), + // 点赞收藏转发 布局样式1 + // SingleChildScrollView( + // padding: const EdgeInsets.only(top: 7, bottom: 7), + // scrollDirection: Axis.horizontal, + // child: actionRow( + // context, + // videoIntroController, + // videoDetailCtr, + // ), + // ), + // 点赞收藏转发 布局样式2 + if (!isHorizontal) + actionGrid(context, videoIntroController), + // 合集 + if (!loadingStatus && + 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, - // videoDetailCtr, - // ), - // ), - // 点赞收藏转发 布局样式2 - if (!isHorizontal) actionGrid(context, videoIntroController), - // 合集 - if (!loadingStatus && - 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(), - ), - ), + ), + ); + }, + ); + } + + Obx followButton(BuildContext context, ThemeData t) { + return Obx( + () => TextButton( + onPressed: () => videoIntroController.actionRelationMod(context), + style: TextButton.styleFrom( + visualDensity: VisualDensity.compact, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + padding: const EdgeInsets.only(left: 6, right: 6), + foregroundColor: (followStatus?['attribute'] ?? 0) != 0 + ? t.colorScheme.outline + : t.colorScheme.onPrimary, + backgroundColor: (followStatus?['attribute'] ?? 0) != 0 + ? t.colorScheme.onInverseSurface + : t.colorScheme.primary, // 设置按钮背景色 + ), + child: Text( + ((followStatus?['attribute'] ?? 0) != 0) ? '已关注' : '关注', + style: TextStyle(fontSize: t.textTheme.labelMedium!.fontSize), + ), ), ); } @@ -530,6 +523,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { icon: const Icon(FontAwesomeIcons.thumbsUp), selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp), onTap: handleState(videoIntroController.actionLikeVideo), + onLongPress: handleState(videoIntroController.actionOneThree), selectStatus: videoIntroController.hasLike.value, loadingStatus: loadingStatus, semanticsLabel: '点赞', diff --git a/lib/pages/video/detail/related/view.dart b/lib/pages/video/detail/related/view.dart index fe56733b..7e2a36ca 100644 --- a/lib/pages/video/detail/related/view.dart +++ b/lib/pages/video/detail/related/view.dart @@ -85,7 +85,10 @@ class _RelatedVideoPanelState extends State ); } else { // 请求错误 - return HttpError(errMsg: '出错了', fn: () {}); + return HttpError(errMsg: '出错了', fn: () { + _futureBuilder = _relatedController.queryRelatedVideo(); + _futureBuilder.then((value) => setState(() {})); + }); } } else { // 骨架屏