mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-17 23:56:13 +08:00
opt action item
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
@@ -44,25 +43,17 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
AutomaticKeepAliveClientMixin,
|
AutomaticKeepAliveClientMixin,
|
||||||
SingleTickerProviderStateMixin,
|
SingleTickerProviderStateMixin,
|
||||||
TripleAnimMixin {
|
TripleAnimMixin {
|
||||||
late PgcIntroController pgcIntroController;
|
@override
|
||||||
|
late PgcIntroController introController;
|
||||||
late VideoDetailController videoDetailCtr;
|
late VideoDetailController videoDetailCtr;
|
||||||
|
|
||||||
bool isProcessing = false;
|
|
||||||
Future<void> handleState(FutureOr Function() action) async {
|
|
||||||
if (!isProcessing) {
|
|
||||||
isProcessing = true;
|
|
||||||
await action();
|
|
||||||
isProcessing = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
pgcIntroController = Get.put(PgcIntroController(), tag: widget.heroTag);
|
introController = Get.put(PgcIntroController(), tag: widget.heroTag);
|
||||||
videoDetailCtr = Get.find<VideoDetailController>(tag: widget.heroTag);
|
videoDetailCtr = Get.find<VideoDetailController>(tag: widget.heroTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +61,7 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
final ThemeData theme = Theme.of(context);
|
final ThemeData theme = Theme.of(context);
|
||||||
final item = pgcIntroController.pgcItem;
|
final item = introController.pgcItem;
|
||||||
final isLandscape = context.isLandscape;
|
final isLandscape = context.isLandscape;
|
||||||
Widget sliver = SliverToBoxAdapter(
|
Widget sliver = SliverToBoxAdapter(
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -86,22 +77,21 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
// 点赞收藏转发 布局样式2
|
// 点赞收藏转发 布局样式2
|
||||||
if (pgcIntroController.isPgc)
|
if (introController.isPgc) actionGrid(theme, item, introController),
|
||||||
actionGrid(theme, item, pgcIntroController),
|
|
||||||
// 番剧分集
|
// 番剧分集
|
||||||
if (item.episodes?.isNotEmpty == true)
|
if (item.episodes?.isNotEmpty == true)
|
||||||
PgcPanel(
|
PgcPanel(
|
||||||
heroTag: widget.heroTag,
|
heroTag: widget.heroTag,
|
||||||
pages: item.episodes!,
|
pages: item.episodes!,
|
||||||
cid: videoDetailCtr.cid.value,
|
cid: videoDetailCtr.cid.value,
|
||||||
onChangeEpisode: pgcIntroController.onChangeEpisode,
|
onChangeEpisode: introController.onChangeEpisode,
|
||||||
showEpisodes: widget.showEpisodes,
|
showEpisodes: widget.showEpisodes,
|
||||||
newEp: item.newEp,
|
newEp: item.newEp,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (!pgcIntroController.isPgc) {
|
if (!introController.isPgc) {
|
||||||
sliver = SliverMainAxisGroup(
|
sliver = SliverMainAxisGroup(
|
||||||
slivers: [
|
slivers: [
|
||||||
sliver,
|
sliver,
|
||||||
@@ -181,18 +171,18 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
bottom: 6,
|
bottom: 6,
|
||||||
left: null,
|
left: null,
|
||||||
),
|
),
|
||||||
if (!pgcIntroController.isPgc)
|
if (!introController.isPgc)
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 6,
|
right: 6,
|
||||||
bottom: 6,
|
bottom: 6,
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
final isFav = pgcIntroController.isFav.value;
|
final isFav = introController.isFav.value;
|
||||||
return iconButton(
|
return iconButton(
|
||||||
context: context,
|
context: context,
|
||||||
size: 28,
|
size: 28,
|
||||||
iconSize: 26,
|
iconSize: 26,
|
||||||
tooltip: '${isFav ? '取消' : ''}收藏',
|
tooltip: '${isFav ? '取消' : ''}收藏',
|
||||||
onPressed: () => pgcIntroController.onFavPugv(isFav),
|
onPressed: () => introController.onFavPugv(isFav),
|
||||||
icon: isFav ? Icons.star_rounded : Icons.star_border_rounded,
|
icon: isFav ? Icons.star_rounded : Icons.star_border_rounded,
|
||||||
bgColor: isFav ? null : theme.colorScheme.onInverseSurface,
|
bgColor: isFav ? null : theme.colorScheme.onInverseSurface,
|
||||||
iconColor: isFav ? null : theme.colorScheme.onSurfaceVariant,
|
iconColor: isFav ? null : theme.colorScheme.onSurfaceVariant,
|
||||||
@@ -204,11 +194,11 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInfoPanel(bool isLandscape, ThemeData theme, PgcInfoModel item) {
|
Widget _buildInfoPanel(bool isLandscape, ThemeData theme, PgcInfoModel item) {
|
||||||
if (pgcIntroController.isPgc) {
|
if (introController.isPgc) {
|
||||||
Widget subBtn() => Obx(
|
Widget subBtn() => Obx(
|
||||||
() {
|
() {
|
||||||
final isFollowed = pgcIntroController.isFollowed.value;
|
final isFollowed = introController.isFollowed.value;
|
||||||
final followStatus = pgcIntroController.followStatus.value;
|
final followStatus = introController.followStatus.value;
|
||||||
return FilledButton.tonal(
|
return FilledButton.tonal(
|
||||||
style: FilledButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
@@ -228,26 +218,26 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
if (isFollowed) {
|
if (isFollowed) {
|
||||||
showPgcFollowDialog(
|
showPgcFollowDialog(
|
||||||
context: context,
|
context: context,
|
||||||
type: pgcIntroController.pgcType,
|
type: introController.pgcType,
|
||||||
followStatus: followStatus,
|
followStatus: followStatus,
|
||||||
onUpdateStatus: (followStatus) {
|
onUpdateStatus: (followStatus) {
|
||||||
if (followStatus == -1) {
|
if (followStatus == -1) {
|
||||||
pgcIntroController.pgcDel();
|
introController.pgcDel();
|
||||||
} else {
|
} else {
|
||||||
pgcIntroController.pgcUpdate(
|
introController.pgcUpdate(
|
||||||
followStatus,
|
followStatus,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pgcIntroController.pgcAdd();
|
introController.pgcAdd();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
isFollowed
|
isFollowed
|
||||||
? '已${pgcIntroController.pgcType}'
|
? '已${introController.pgcType}'
|
||||||
: pgcIntroController.pgcType,
|
: introController.pgcType,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -309,7 +299,7 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => widget.showIntroDetail(
|
onTap: () => widget.showIntroDetail(
|
||||||
item,
|
item,
|
||||||
pgcIntroController.videoTags.value,
|
introController.videoTags.value,
|
||||||
),
|
),
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
@@ -413,7 +403,7 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
Widget actionGrid(
|
Widget actionGrid(
|
||||||
ThemeData theme,
|
ThemeData theme,
|
||||||
PgcInfoModel item,
|
PgcInfoModel item,
|
||||||
PgcIntroController pgcIntroController,
|
PgcIntroController introController,
|
||||||
) {
|
) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 48,
|
height: 48,
|
||||||
@@ -423,9 +413,8 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
||||||
onTap: () => handleState(pgcIntroController.actionLikeVideo),
|
onTap: () => handleAction(introController.actionLikeVideo),
|
||||||
onLongPress: () => handleState(pgcIntroController.actionTriple),
|
selectStatus: introController.hasLike.value,
|
||||||
selectStatus: pgcIntroController.hasLike.value,
|
|
||||||
semanticsLabel: '点赞',
|
semanticsLabel: '点赞',
|
||||||
text: NumUtil.numFormat(item.stat!.like),
|
text: NumUtil.numFormat(item.stat!.like),
|
||||||
controller: animController,
|
controller: animController,
|
||||||
@@ -438,8 +427,8 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.b),
|
icon: const Icon(FontAwesomeIcons.b),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||||
onTap: () => handleState(pgcIntroController.actionCoinVideo),
|
onTap: introController.actionCoinVideo,
|
||||||
selectStatus: pgcIntroController.hasCoin,
|
selectStatus: introController.hasCoin,
|
||||||
semanticsLabel: '投币',
|
semanticsLabel: '投币',
|
||||||
text: NumUtil.numFormat(item.stat!.coin),
|
text: NumUtil.numFormat(item.stat!.coin),
|
||||||
controller: animController,
|
controller: animController,
|
||||||
@@ -450,12 +439,12 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.star),
|
icon: const Icon(FontAwesomeIcons.star),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||||
onTap: () => pgcIntroController.showFavBottomSheet(context),
|
onTap: () => introController.showFavBottomSheet(context),
|
||||||
onLongPress: () => pgcIntroController.showFavBottomSheet(
|
onLongPress: () => introController.showFavBottomSheet(
|
||||||
context,
|
context,
|
||||||
isLongPress: true,
|
isLongPress: true,
|
||||||
),
|
),
|
||||||
selectStatus: pgcIntroController.hasFav.value,
|
selectStatus: introController.hasFav.value,
|
||||||
semanticsLabel: '收藏',
|
semanticsLabel: '收藏',
|
||||||
text: NumUtil.numFormat(item.stat!.favorite),
|
text: NumUtil.numFormat(item.stat!.favorite),
|
||||||
controller: animController,
|
controller: animController,
|
||||||
@@ -466,15 +455,15 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.clock),
|
icon: const Icon(FontAwesomeIcons.clock),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidClock),
|
selectIcon: const Icon(FontAwesomeIcons.solidClock),
|
||||||
onTap: () => handleState(pgcIntroController.viewLater),
|
onTap: () => handleAction(introController.viewLater),
|
||||||
selectStatus: pgcIntroController.hasLater.value,
|
selectStatus: introController.hasLater.value,
|
||||||
semanticsLabel: '再看',
|
semanticsLabel: '再看',
|
||||||
text: '再看',
|
text: '再看',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ActionItem(
|
ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||||
onTap: () => pgcIntroController.actionShareVideo(context),
|
onTap: () => introController.actionShareVideo(context),
|
||||||
selectStatus: false,
|
selectStatus: false,
|
||||||
semanticsLabel: '转发',
|
semanticsLabel: '转发',
|
||||||
text: NumUtil.numFormat(item.stat!.share),
|
text: NumUtil.numFormat(item.stat!.share),
|
||||||
@@ -483,16 +472,4 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
bool get hasTriple =>
|
|
||||||
pgcIntroController.hasLike.value &&
|
|
||||||
pgcIntroController.hasCoin &&
|
|
||||||
pgcIntroController.hasFav.value;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onLike() => handleState(pgcIntroController.actionLikeVideo);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTriple() => handleState(pgcIntroController.actionTriple);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||||
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
|
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
|
||||||
@@ -57,16 +55,15 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
AutomaticKeepAliveClientMixin,
|
AutomaticKeepAliveClientMixin,
|
||||||
SingleTickerProviderStateMixin,
|
SingleTickerProviderStateMixin,
|
||||||
TripleAnimMixin {
|
TripleAnimMixin {
|
||||||
late UgcIntroController ugcIntroController;
|
@override
|
||||||
|
late UgcIntroController introController;
|
||||||
late final VideoDetailController videoDetailCtr =
|
late final VideoDetailController videoDetailCtr =
|
||||||
Get.find<VideoDetailController>(tag: widget.heroTag);
|
Get.find<VideoDetailController>(tag: widget.heroTag);
|
||||||
|
|
||||||
bool isProcessing = false;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
ugcIntroController = Get.put(UgcIntroController(), tag: widget.heroTag);
|
introController = Get.put(UgcIntroController(), tag: widget.heroTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -95,8 +92,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
),
|
),
|
||||||
sliver: Obx(
|
sliver: Obx(
|
||||||
() {
|
() {
|
||||||
VideoDetailData videoDetail =
|
VideoDetailData videoDetail = introController.videoDetail.value;
|
||||||
ugcIntroController.videoDetail.value;
|
|
||||||
bool isLoading = videoDetail.bvid == null;
|
bool isLoading = videoDetail.bvid == null;
|
||||||
int? mid = videoDetail.owner?.mid;
|
int? mid = videoDetail.owner?.mid;
|
||||||
return SliverToBoxAdapter(
|
return SliverToBoxAdapter(
|
||||||
@@ -107,7 +103,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
feedBack();
|
feedBack();
|
||||||
ugcIntroController.expandableCtr.toggle();
|
introController.expandableCtr.toggle();
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@@ -127,7 +123,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
if (mid != null) {
|
if (mid != null) {
|
||||||
feedBack();
|
feedBack();
|
||||||
if (!isPortrait &&
|
if (!isPortrait &&
|
||||||
ugcIntroController
|
introController
|
||||||
.horizontalMemberPage) {
|
.horizontalMemberPage) {
|
||||||
widget.onShowMemberPage(mid);
|
widget.onShowMemberPage(mid);
|
||||||
} else {
|
} else {
|
||||||
@@ -146,7 +142,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
physics: ReloadScrollPhysics(
|
physics: ReloadScrollPhysics(
|
||||||
controller: ugcIntroController,
|
controller: introController,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
spacing: 25,
|
spacing: 25,
|
||||||
@@ -170,7 +166,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
context,
|
context,
|
||||||
isLoading,
|
isLoading,
|
||||||
videoDetail,
|
videoDetail,
|
||||||
ugcIntroController,
|
introController,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -182,7 +178,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
_buildVideoTitle(theme, videoDetail)
|
_buildVideoTitle(theme, videoDetail)
|
||||||
else
|
else
|
||||||
ExpandablePanel(
|
ExpandablePanel(
|
||||||
controller: ugcIntroController.expandableCtr,
|
controller: introController.expandableCtr,
|
||||||
collapsed: GestureDetector(
|
collapsed: GestureDetector(
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
Feedback.forLongPress(context);
|
Feedback.forLongPress(context);
|
||||||
@@ -208,11 +204,11 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
_buildInfo(theme, videoDetail),
|
_buildInfo(theme, videoDetail),
|
||||||
if (ugcIntroController.enableAi) _aiBtn,
|
if (introController.enableAi) _aiBtn,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (videoDetail.argueInfo?.argueMsg?.isNotEmpty == true &&
|
if (videoDetail.argueInfo?.argueMsg?.isNotEmpty == true &&
|
||||||
ugcIntroController.showArgueMsg) ...[
|
introController.showArgueMsg) ...[
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
@@ -238,7 +234,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
ExpandablePanel(
|
ExpandablePanel(
|
||||||
controller: ugcIntroController.expandableCtr,
|
controller: introController.expandableCtr,
|
||||||
collapsed: const SizedBox.shrink(),
|
collapsed: const SizedBox.shrink(),
|
||||||
expanded: Column(
|
expanded: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@@ -270,8 +266,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
Obx(() {
|
Obx(() {
|
||||||
final videoTags =
|
final videoTags = introController.videoTags.value;
|
||||||
ugcIntroController.videoTags.value;
|
|
||||||
if (videoTags.isNullOrEmpty) {
|
if (videoTags.isNullOrEmpty) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
@@ -282,13 +277,13 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
theme: expandTheme,
|
theme: expandTheme,
|
||||||
),
|
),
|
||||||
Obx(
|
Obx(
|
||||||
() => ugcIntroController.status.value
|
() => introController.status.value
|
||||||
? const SizedBox.shrink()
|
? const SizedBox.shrink()
|
||||||
: Center(
|
: Center(
|
||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
icon: const Icon(Icons.refresh),
|
icon: const Icon(Icons.refresh),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ugcIntroController
|
introController
|
||||||
..status.value = true
|
..status.value = true
|
||||||
..queryVideoIntro();
|
..queryVideoIntro();
|
||||||
if (videoDetailCtr.videoUrl.isNullOrEmpty &&
|
if (videoDetailCtr.videoUrl.isNullOrEmpty &&
|
||||||
@@ -307,7 +302,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
context,
|
context,
|
||||||
isLoading,
|
isLoading,
|
||||||
videoDetail,
|
videoDetail,
|
||||||
ugcIntroController,
|
introController,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
// 合集
|
// 合集
|
||||||
@@ -320,7 +315,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
SeasonPanel(
|
SeasonPanel(
|
||||||
heroTag: widget.heroTag,
|
heroTag: widget.heroTag,
|
||||||
showEpisodes: widget.showEpisodes,
|
showEpisodes: widget.showEpisodes,
|
||||||
ugcIntroController: ugcIntroController,
|
ugcIntroController: introController,
|
||||||
),
|
),
|
||||||
if (!isLoading &&
|
if (!isLoading &&
|
||||||
videoDetail.pages != null &&
|
videoDetail.pages != null &&
|
||||||
@@ -331,8 +326,8 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
.horizontalSeasonPanel)) ...[
|
.horizontalSeasonPanel)) ...[
|
||||||
PagesPanel(
|
PagesPanel(
|
||||||
heroTag: widget.heroTag,
|
heroTag: widget.heroTag,
|
||||||
ugcIntroController: ugcIntroController,
|
ugcIntroController: introController,
|
||||||
bvid: ugcIntroController.bvid,
|
bvid: introController.bvid,
|
||||||
showEpisodes: widget.showEpisodes,
|
showEpisodes: widget.showEpisodes,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -474,20 +469,12 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
return child();
|
return child();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> handleState(FutureOr Function() action) async {
|
|
||||||
if (!isProcessing) {
|
|
||||||
isProcessing = true;
|
|
||||||
await action();
|
|
||||||
isProcessing = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget followButton(BuildContext context, ThemeData t) {
|
Widget followButton(BuildContext context, ThemeData t) {
|
||||||
return Obx(
|
return Obx(
|
||||||
() {
|
() {
|
||||||
int attr = ugcIntroController.followStatus['attribute'] ?? 0;
|
int attr = introController.followStatus['attribute'] ?? 0;
|
||||||
return TextButton(
|
return TextButton(
|
||||||
onPressed: () => ugcIntroController.actionRelationMod(context),
|
onPressed: () => introController.actionRelationMod(context),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
visualDensity: const VisualDensity(vertical: -2.8),
|
visualDensity: const VisualDensity(vertical: -2.8),
|
||||||
@@ -518,7 +505,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
BuildContext context,
|
BuildContext context,
|
||||||
bool isLoading,
|
bool isLoading,
|
||||||
VideoDetailData videoDetail,
|
VideoDetailData videoDetail,
|
||||||
UgcIntroController ugcIntroController,
|
UgcIntroController introController,
|
||||||
) {
|
) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 48,
|
height: 48,
|
||||||
@@ -528,9 +515,8 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
||||||
onTap: () => handleState(ugcIntroController.actionLikeVideo),
|
onTap: () => handleAction(introController.actionLikeVideo),
|
||||||
onLongPress: () => handleState(ugcIntroController.actionTriple),
|
selectStatus: introController.hasLike.value,
|
||||||
selectStatus: ugcIntroController.hasLike.value,
|
|
||||||
semanticsLabel: '点赞',
|
semanticsLabel: '点赞',
|
||||||
text: !isLoading
|
text: !isLoading
|
||||||
? NumUtil.numFormat(videoDetail.stat!.like)
|
? NumUtil.numFormat(videoDetail.stat!.like)
|
||||||
@@ -545,8 +531,8 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||||
onTap: () => handleState(ugcIntroController.actionDislikeVideo),
|
onTap: () => handleAction(introController.actionDislikeVideo),
|
||||||
selectStatus: ugcIntroController.hasDislike.value,
|
selectStatus: introController.hasDislike.value,
|
||||||
semanticsLabel: '点踩',
|
semanticsLabel: '点踩',
|
||||||
text: "点踩",
|
text: "点踩",
|
||||||
),
|
),
|
||||||
@@ -555,8 +541,8 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.b),
|
icon: const Icon(FontAwesomeIcons.b),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||||
onTap: () => handleState(ugcIntroController.actionCoinVideo),
|
onTap: introController.actionCoinVideo,
|
||||||
selectStatus: ugcIntroController.hasCoin,
|
selectStatus: introController.hasCoin,
|
||||||
semanticsLabel: '投币',
|
semanticsLabel: '投币',
|
||||||
text: !isLoading
|
text: !isLoading
|
||||||
? NumUtil.numFormat(videoDetail.stat!.coin)
|
? NumUtil.numFormat(videoDetail.stat!.coin)
|
||||||
@@ -569,12 +555,12 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.star),
|
icon: const Icon(FontAwesomeIcons.star),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||||
onTap: () => ugcIntroController.showFavBottomSheet(context),
|
onTap: () => introController.showFavBottomSheet(context),
|
||||||
onLongPress: () => ugcIntroController.showFavBottomSheet(
|
onLongPress: () => introController.showFavBottomSheet(
|
||||||
context,
|
context,
|
||||||
isLongPress: true,
|
isLongPress: true,
|
||||||
),
|
),
|
||||||
selectStatus: ugcIntroController.hasFav.value,
|
selectStatus: introController.hasFav.value,
|
||||||
semanticsLabel: '收藏',
|
semanticsLabel: '收藏',
|
||||||
text: !isLoading
|
text: !isLoading
|
||||||
? NumUtil.numFormat(videoDetail.stat!.favorite)
|
? NumUtil.numFormat(videoDetail.stat!.favorite)
|
||||||
@@ -587,15 +573,15 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.clock),
|
icon: const Icon(FontAwesomeIcons.clock),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidClock),
|
selectIcon: const Icon(FontAwesomeIcons.solidClock),
|
||||||
onTap: () => handleState(ugcIntroController.viewLater),
|
onTap: () => handleAction(introController.viewLater),
|
||||||
selectStatus: ugcIntroController.hasLater.value,
|
selectStatus: introController.hasLater.value,
|
||||||
semanticsLabel: '再看',
|
semanticsLabel: '再看',
|
||||||
text: '再看',
|
text: '再看',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ActionItem(
|
ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||||
onTap: () => ugcIntroController.actionShareVideo(context),
|
onTap: () => introController.actionShareVideo(context),
|
||||||
selectStatus: false,
|
selectStatus: false,
|
||||||
semanticsLabel: '分享',
|
semanticsLabel: '分享',
|
||||||
text: !isLoading
|
text: !isLoading
|
||||||
@@ -706,7 +692,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
if (item.mid == ownerMid &&
|
if (item.mid == ownerMid &&
|
||||||
!isPortrait &&
|
!isPortrait &&
|
||||||
ugcIntroController.horizontalMemberPage) {
|
introController.horizontalMemberPage) {
|
||||||
widget.onShowMemberPage(ownerMid);
|
widget.onShowMemberPage(ownerMid);
|
||||||
} else {
|
} else {
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
@@ -750,9 +736,8 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
right: -6,
|
right: -6,
|
||||||
child: Obx(
|
child: Obx(
|
||||||
() =>
|
() =>
|
||||||
ugcIntroController.staffRelations['status'] == true &&
|
introController.staffRelations['status'] == true &&
|
||||||
ugcIntroController.staffRelations['${item.mid}'] ==
|
introController.staffRelations['${item.mid}'] == null
|
||||||
null
|
|
||||||
? Material(
|
? Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
shape: const CircleBorder(),
|
shape: const CircleBorder(),
|
||||||
@@ -763,8 +748,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
mid: item.mid,
|
mid: item.mid,
|
||||||
isFollow: false,
|
isFollow: false,
|
||||||
callback: (val) {
|
callback: (val) {
|
||||||
ugcIntroController
|
introController.staffRelations['${item.mid}'] =
|
||||||
.staffRelations['${item.mid}'] =
|
|
||||||
true;
|
true;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -825,7 +809,7 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: Obx(
|
child: Obx(
|
||||||
() {
|
() {
|
||||||
final userStat = ugcIntroController.userStat.value;
|
final userStat = introController.userStat.value;
|
||||||
final isVip = (userStat.card?.vip?.status ?? 0) > 0;
|
final isVip = (userStat.card?.vip?.status ?? 0) > 0;
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@@ -895,10 +879,10 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
color: theme.colorScheme.outline,
|
color: theme.colorScheme.outline,
|
||||||
semanticLabel: '无痕',
|
semanticLabel: '无痕',
|
||||||
),
|
),
|
||||||
if (ugcIntroController.isShowOnlineTotal)
|
if (introController.isShowOnlineTotal)
|
||||||
Obx(
|
Obx(
|
||||||
() => Text(
|
() => Text(
|
||||||
'${ugcIntroController.total.value}人在看',
|
'${introController.total.value}人在看',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: theme.colorScheme.outline,
|
color: theme.colorScheme.outline,
|
||||||
@@ -917,15 +901,15 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
label: 'AI总结',
|
label: 'AI总结',
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (ugcIntroController.aiConclusionResult == null) {
|
if (introController.aiConclusionResult == null) {
|
||||||
await ugcIntroController.aiConclusion();
|
await introController.aiConclusion();
|
||||||
}
|
}
|
||||||
if (ugcIntroController.aiConclusionResult == null) {
|
if (introController.aiConclusionResult == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ugcIntroController.aiConclusionResult!.summary?.isNotEmpty ==
|
if (introController.aiConclusionResult!.summary?.isNotEmpty ==
|
||||||
true ||
|
true ||
|
||||||
ugcIntroController.aiConclusionResult!.outline?.isNotEmpty ==
|
introController.aiConclusionResult!.outline?.isNotEmpty ==
|
||||||
true) {
|
true) {
|
||||||
widget.showAiBottomSheet();
|
widget.showAiBottomSheet();
|
||||||
} else {
|
} else {
|
||||||
@@ -968,16 +952,4 @@ class _UgcIntroPanelState extends State<UgcIntroPanel>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
@override
|
|
||||||
bool get hasTriple =>
|
|
||||||
ugcIntroController.hasLike.value &&
|
|
||||||
ugcIntroController.hasCoin &&
|
|
||||||
ugcIntroController.hasFav.value;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onLike() => handleState(ugcIntroController.actionLikeVideo);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTriple() => handleState(ugcIntroController.actionTriple);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:async' show Timer;
|
import 'dart:async' show Timer, FutureOr;
|
||||||
import 'dart:math' show pi;
|
import 'dart:math' show pi;
|
||||||
|
|
||||||
|
import 'package:PiliPlus/pages/common/common_intro_controller.dart';
|
||||||
import 'package:PiliPlus/utils/feed_back.dart';
|
import 'package:PiliPlus/utils/feed_back.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart' show HapticFeedback;
|
import 'package:flutter/services.dart' show HapticFeedback;
|
||||||
@@ -8,15 +9,26 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|||||||
|
|
||||||
mixin TripleAnimMixin<T extends StatefulWidget>
|
mixin TripleAnimMixin<T extends StatefulWidget>
|
||||||
on SingleTickerProviderStateMixin<T> {
|
on SingleTickerProviderStateMixin<T> {
|
||||||
|
CommonIntroController get introController;
|
||||||
late AnimationController animController;
|
late AnimationController animController;
|
||||||
late Animation<double> animation;
|
late Animation<double> animation;
|
||||||
|
|
||||||
late int _lastTime;
|
late int _lastTime;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
bool get hasTriple;
|
bool get _hasTriple =>
|
||||||
void onTriple();
|
introController.hasLike.value &&
|
||||||
void onLike();
|
introController.hasCoin &&
|
||||||
|
introController.hasFav.value;
|
||||||
|
|
||||||
|
bool isProcessing = false;
|
||||||
|
Future<void> handleAction(FutureOr Function() action) async {
|
||||||
|
if (!isProcessing) {
|
||||||
|
isProcessing = true;
|
||||||
|
await action();
|
||||||
|
isProcessing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -38,13 +50,13 @@ mixin TripleAnimMixin<T extends StatefulWidget>
|
|||||||
void onStartTriple() {
|
void onStartTriple() {
|
||||||
_lastTime = DateTime.now().millisecondsSinceEpoch;
|
_lastTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
_timer ??= Timer(const Duration(milliseconds: 200), () {
|
_timer ??= Timer(const Duration(milliseconds: 200), () {
|
||||||
if (hasTriple) {
|
|
||||||
HapticFeedback.lightImpact();
|
HapticFeedback.lightImpact();
|
||||||
|
if (_hasTriple) {
|
||||||
SmartDialog.showToast('已经完成三连');
|
SmartDialog.showToast('已经完成三连');
|
||||||
} else {
|
} else {
|
||||||
animController.forward().whenComplete(() {
|
animController.forward().whenComplete(() {
|
||||||
animController.reset();
|
animController.reset();
|
||||||
onTriple();
|
handleAction(introController.actionTriple);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
cancelTimer();
|
cancelTimer();
|
||||||
@@ -54,14 +66,14 @@ mixin TripleAnimMixin<T extends StatefulWidget>
|
|||||||
void onCancelTriple(bool isCancel) {
|
void onCancelTriple(bool isCancel) {
|
||||||
int duration = DateTime.now().millisecondsSinceEpoch - _lastTime;
|
int duration = DateTime.now().millisecondsSinceEpoch - _lastTime;
|
||||||
if (duration >= 200 && duration < 1500) {
|
if (duration >= 200 && duration < 1500) {
|
||||||
if (!hasTriple) {
|
if (!_hasTriple) {
|
||||||
animController.reverse();
|
animController.reverse();
|
||||||
}
|
}
|
||||||
} else if (duration < 200) {
|
} else if (duration < 200) {
|
||||||
cancelTimer();
|
cancelTimer();
|
||||||
if (!isCancel) {
|
if (!isCancel) {
|
||||||
feedBack();
|
feedBack();
|
||||||
onLike();
|
handleAction(introController.actionLikeVideo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ class HeaderControlState extends State<HeaderControl>
|
|||||||
String get heroTag => widget.heroTag;
|
String get heroTag => widget.heroTag;
|
||||||
late final UgcIntroController ugcIntroController;
|
late final UgcIntroController ugcIntroController;
|
||||||
late final PgcIntroController pgcIntroController;
|
late final PgcIntroController pgcIntroController;
|
||||||
|
@override
|
||||||
late final CommonIntroController introController = videoDetailCtr.isUgc
|
late final CommonIntroController introController = videoDetailCtr.isUgc
|
||||||
? ugcIntroController
|
? ugcIntroController
|
||||||
: pgcIntroController;
|
: pgcIntroController;
|
||||||
@@ -2235,7 +2236,8 @@ class HeaderControlState extends State<HeaderControl>
|
|||||||
selectIcon: const Icon(
|
selectIcon: const Icon(
|
||||||
FontAwesomeIcons.solidThumbsUp,
|
FontAwesomeIcons.solidThumbsUp,
|
||||||
),
|
),
|
||||||
onTap: introController.actionLikeVideo,
|
onTap: () =>
|
||||||
|
handleAction(introController.actionLikeVideo),
|
||||||
selectStatus: introController.hasLike.value,
|
selectStatus: introController.hasLike.value,
|
||||||
semanticsLabel: '点赞',
|
semanticsLabel: '点赞',
|
||||||
controller: animController,
|
controller: animController,
|
||||||
@@ -2267,7 +2269,9 @@ class HeaderControlState extends State<HeaderControl>
|
|||||||
selectIcon: const Icon(
|
selectIcon: const Icon(
|
||||||
FontAwesomeIcons.solidThumbsDown,
|
FontAwesomeIcons.solidThumbsDown,
|
||||||
),
|
),
|
||||||
onTap: ugcIntroController.actionDislikeVideo,
|
onTap: () => handleAction(
|
||||||
|
ugcIntroController.actionDislikeVideo,
|
||||||
|
),
|
||||||
selectStatus: ugcIntroController.hasDislike.value,
|
selectStatus: ugcIntroController.hasDislike.value,
|
||||||
semanticsLabel: '点踩',
|
semanticsLabel: '点踩',
|
||||||
),
|
),
|
||||||
@@ -2342,18 +2346,6 @@ class HeaderControlState extends State<HeaderControl>
|
|||||||
? Obx(() => _buildHeader(true))
|
? Obx(() => _buildHeader(true))
|
||||||
: _buildHeader(false);
|
: _buildHeader(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
bool get hasTriple =>
|
|
||||||
introController.hasLike.value &&
|
|
||||||
introController.hasCoin &&
|
|
||||||
introController.hasFav.value;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onLike() => introController.actionLikeVideo();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onTriple() => introController.actionTriple();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSliderTrackShape extends RoundedRectSliderTrackShape {
|
class MSliderTrackShape extends RoundedRectSliderTrackShape {
|
||||||
|
|||||||
Reference in New Issue
Block a user