mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
mod: show fullscreen action item
Closes #367 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -2126,6 +2126,13 @@ List<SettingsModel> get extraSettings => [
|
|||||||
GStorage.slideDismissReplyPage = value;
|
GStorage.slideDismissReplyPage = value;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SettingsModel(
|
||||||
|
settingsType: SettingsType.sw1tch,
|
||||||
|
title: '全屏展示点赞/投币/收藏等操作按钮',
|
||||||
|
leading: Icon(MdiIcons.dotsHorizontalCircleOutline),
|
||||||
|
setKey: SettingBoxKey.showFSActionItem,
|
||||||
|
defaultVal: true,
|
||||||
|
),
|
||||||
SettingsModel(
|
SettingsModel(
|
||||||
settingsType: SettingsType.sw1tch,
|
settingsType: SettingsType.sw1tch,
|
||||||
enableFeedback: true,
|
enableFeedback: true,
|
||||||
|
|||||||
@@ -861,4 +861,24 @@ class VideoIntroController extends GetxController
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 收藏
|
||||||
|
showFavBottomSheet(BuildContext context, {type = 'tap'}) {
|
||||||
|
if (userInfo == null) {
|
||||||
|
SmartDialog.showToast('账号未登录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 快速收藏 &
|
||||||
|
// 点按 收藏至默认文件夹
|
||||||
|
// 长按选择文件夹
|
||||||
|
if (enableQuickFav) {
|
||||||
|
if (type == 'tap') {
|
||||||
|
actionFavVideo(type: 'default');
|
||||||
|
} else {
|
||||||
|
Utils.showFavBottomSheet(context: context, ctr: this);
|
||||||
|
}
|
||||||
|
} else if (type != 'longPress') {
|
||||||
|
Utils.showFavBottomSheet(context: context, ctr: this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -232,26 +232,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收藏
|
|
||||||
showFavBottomSheet({type = 'tap'}) {
|
|
||||||
if (videoIntroController.userInfo == null) {
|
|
||||||
SmartDialog.showToast('账号未登录');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 快速收藏 &
|
|
||||||
// 点按 收藏至默认文件夹
|
|
||||||
// 长按选择文件夹
|
|
||||||
if (videoIntroController.enableQuickFav) {
|
|
||||||
if (type == 'tap') {
|
|
||||||
videoIntroController.actionFavVideo(type: 'default');
|
|
||||||
} else {
|
|
||||||
Utils.showFavBottomSheet(context: context, ctr: videoIntroController);
|
|
||||||
}
|
|
||||||
} else if (type != 'longPress') {
|
|
||||||
Utils.showFavBottomSheet(context: context, ctr: videoIntroController);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 视频介绍
|
// 视频介绍
|
||||||
showIntroDetail() {
|
showIntroDetail() {
|
||||||
if (widget.loadingStatus) {
|
if (widget.loadingStatus) {
|
||||||
@@ -857,7 +837,8 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget actionGrid(BuildContext context, videoIntroController) {
|
Widget actionGrid(
|
||||||
|
BuildContext context, VideoIntroController videoIntroController) {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (BuildContext context, BoxConstraints constraints) {
|
builder: (BuildContext context, BoxConstraints constraints) {
|
||||||
return Container(
|
return Container(
|
||||||
@@ -896,14 +877,15 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
Obx(
|
Obx(
|
||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
handleState(videoIntroController.actionDislikeVideo),
|
handleState(videoIntroController.actionDislikeVideo),
|
||||||
selectStatus: videoIntroController.hasDislike.value,
|
selectStatus: videoIntroController.hasDislike.value,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: widget.loadingStatus,
|
||||||
semanticsLabel: '点踩',
|
semanticsLabel: '点踩',
|
||||||
text: "点踩"),
|
text: "点踩",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// ActionItem(
|
// ActionItem(
|
||||||
// icon: const Icon(FontAwesomeIcons.clock),
|
// icon: const Icon(FontAwesomeIcons.clock),
|
||||||
@@ -931,8 +913,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
key: _favKey,
|
key: _favKey,
|
||||||
icon: const Icon(FontAwesomeIcons.star),
|
icon: const Icon(FontAwesomeIcons.star),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||||
onTap: () => showFavBottomSheet(),
|
onTap: () => videoIntroController.showFavBottomSheet(context),
|
||||||
onLongPress: () => showFavBottomSheet(type: 'longPress'),
|
onLongPress: () => videoIntroController
|
||||||
|
.showFavBottomSheet(context, type: 'longPress'),
|
||||||
selectStatus: videoIntroController.hasFav.value,
|
selectStatus: videoIntroController.hasFav.value,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: widget.loadingStatus,
|
||||||
semanticsLabel: '收藏',
|
semanticsLabel: '收藏',
|
||||||
@@ -943,31 +926,37 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
ActionItem(
|
ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.comment),
|
icon: const Icon(FontAwesomeIcons.comment),
|
||||||
onTap: () => videoDetailCtr.tabCtr
|
onTap: () => videoDetailCtr.tabCtr
|
||||||
.animateTo(videoDetailCtr.tabCtr.index == 1 ? 0 : 1),
|
.animateTo(videoDetailCtr.tabCtr.index == 1 ? 0 : 1),
|
||||||
selectStatus: false,
|
selectStatus: false,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: widget.loadingStatus,
|
||||||
semanticsLabel: '评论',
|
semanticsLabel: '评论',
|
||||||
text: !widget.loadingStatus
|
text: !widget.loadingStatus
|
||||||
? Utils.numFormat(videoDetail.stat!.reply!)
|
? Utils.numFormat(videoDetail.stat!.reply!)
|
||||||
: '评论'),
|
: '评论',
|
||||||
|
),
|
||||||
ActionItem(
|
ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||||
onTap: () => videoIntroController.actionShareVideo(),
|
onTap: () => videoIntroController.actionShareVideo(),
|
||||||
selectStatus: false,
|
selectStatus: false,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: widget.loadingStatus,
|
||||||
semanticsLabel: '分享',
|
semanticsLabel: '分享',
|
||||||
text: !widget.loadingStatus
|
text: !widget.loadingStatus
|
||||||
? Utils.numFormat(videoDetail.stat!.share!)
|
? Utils.numFormat(videoDetail.stat!.share!)
|
||||||
: '分享'),
|
: '分享',
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget actionRow(BuildContext context, videoIntroController, videoDetailCtr) {
|
Widget actionRow(
|
||||||
|
BuildContext context,
|
||||||
|
VideoIntroController videoIntroController,
|
||||||
|
VideoDetailController videoDetailCtr,
|
||||||
|
) {
|
||||||
return Row(children: <Widget>[
|
return Row(children: <Widget>[
|
||||||
Obx(
|
Obx(
|
||||||
() => ActionRowItem(
|
() => ActionRowItem(
|
||||||
@@ -994,8 +983,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
Obx(
|
Obx(
|
||||||
() => ActionRowItem(
|
() => ActionRowItem(
|
||||||
icon: const Icon(FontAwesomeIcons.heart),
|
icon: const Icon(FontAwesomeIcons.heart),
|
||||||
onTap: () => showFavBottomSheet(),
|
onTap: () => videoIntroController.showFavBottomSheet(context),
|
||||||
onLongPress: () => showFavBottomSheet(type: 'longPress'),
|
onLongPress: () => videoIntroController.showFavBottomSheet(context,
|
||||||
|
type: 'longPress'),
|
||||||
selectStatus: videoIntroController.hasFav.value,
|
selectStatus: videoIntroController.hasFav.value,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: widget.loadingStatus,
|
||||||
text: !widget.loadingStatus
|
text: !widget.loadingStatus
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:PiliPlus/utils/feed_back.dart';
|
import 'package:PiliPlus/utils/feed_back.dart';
|
||||||
|
|
||||||
class ActionItem extends StatefulWidget {
|
class ActionItem extends StatefulWidget {
|
||||||
final Icon? icon;
|
final Icon icon;
|
||||||
final Icon? selectIcon;
|
final Icon? selectIcon;
|
||||||
final Function? onTap;
|
final Function? onTap;
|
||||||
final Function? onLongPress;
|
final Function? onLongPress;
|
||||||
@@ -16,10 +16,11 @@ class ActionItem extends StatefulWidget {
|
|||||||
final bool needAnim;
|
final bool needAnim;
|
||||||
final bool hasOneThree;
|
final bool hasOneThree;
|
||||||
final Function? callBack;
|
final Function? callBack;
|
||||||
|
final bool? expand;
|
||||||
|
|
||||||
const ActionItem({
|
const ActionItem({
|
||||||
super.key,
|
super.key,
|
||||||
this.icon,
|
required this.icon,
|
||||||
this.selectIcon,
|
this.selectIcon,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.onLongPress,
|
this.onLongPress,
|
||||||
@@ -30,6 +31,7 @@ class ActionItem extends StatefulWidget {
|
|||||||
this.hasOneThree = false,
|
this.hasOneThree = false,
|
||||||
this.callBack,
|
this.callBack,
|
||||||
required this.semanticsLabel,
|
required this.semanticsLabel,
|
||||||
|
this.expand,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -113,8 +115,10 @@ class ActionItemState extends State<ActionItem> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Expanded(
|
return widget.expand == false ? _buildItem : Expanded(child: _buildItem);
|
||||||
child: Semantics(
|
}
|
||||||
|
|
||||||
|
Widget get _buildItem => Semantics(
|
||||||
label: (widget.text ?? "") +
|
label: (widget.text ?? "") +
|
||||||
(widget.selectStatus ? "已" : "") +
|
(widget.selectStatus ? "已" : "") +
|
||||||
widget.semanticsLabel,
|
widget.semanticsLabel,
|
||||||
@@ -155,42 +159,42 @@ class ActionItemState extends State<ActionItem> with TickerProviderStateMixin {
|
|||||||
Icon(
|
Icon(
|
||||||
widget.selectStatus
|
widget.selectStatus
|
||||||
? widget.selectIcon!.icon!
|
? widget.selectIcon!.icon!
|
||||||
: widget.icon!.icon!,
|
: widget.icon.icon,
|
||||||
size: 18,
|
size: 18,
|
||||||
color: widget.selectStatus
|
color: widget.selectStatus
|
||||||
? Theme.of(context).colorScheme.primary
|
? Theme.of(context).colorScheme.primary
|
||||||
: Theme.of(context).colorScheme.outline,
|
: widget.icon.color ??
|
||||||
|
Theme.of(context).colorScheme.outline,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
AnimatedOpacity(
|
if (widget.text != null)
|
||||||
opacity: widget.loadingStatus! ? 0 : 1,
|
AnimatedOpacity(
|
||||||
duration: const Duration(milliseconds: 200),
|
opacity: widget.loadingStatus! ? 0 : 1,
|
||||||
child: AnimatedSwitcher(
|
duration: const Duration(milliseconds: 200),
|
||||||
duration: const Duration(milliseconds: 300),
|
child: AnimatedSwitcher(
|
||||||
transitionBuilder:
|
duration: const Duration(milliseconds: 300),
|
||||||
(Widget child, Animation<double> animation) {
|
transitionBuilder:
|
||||||
return ScaleTransition(scale: animation, child: child);
|
(Widget child, Animation<double> animation) {
|
||||||
},
|
return ScaleTransition(scale: animation, child: child);
|
||||||
child: Text(
|
},
|
||||||
widget.text ?? '',
|
child: Text(
|
||||||
key: ValueKey<String>(widget.text ?? ''),
|
widget.text!,
|
||||||
style: TextStyle(
|
key: ValueKey<String>(widget.text ?? ''),
|
||||||
color: widget.selectStatus
|
style: TextStyle(
|
||||||
? Theme.of(context).colorScheme.primary
|
color: widget.selectStatus
|
||||||
: Theme.of(context).colorScheme.outline,
|
? Theme.of(context).colorScheme.primary
|
||||||
fontSize:
|
: Theme.of(context).colorScheme.outline,
|
||||||
Theme.of(context).textTheme.labelSmall!.fontSize),
|
fontSize:
|
||||||
semanticsLabel: "",
|
Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||||
|
semanticsLabel: "",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ArcPainter extends CustomPainter {
|
class _ArcPainter extends CustomPainter {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'dart:math';
|
|||||||
import 'package:PiliPlus/common/widgets/self_sized_horizontal_list.dart';
|
import 'package:PiliPlus/common/widgets/self_sized_horizontal_list.dart';
|
||||||
import 'package:PiliPlus/models/common/super_resolution_type.dart';
|
import 'package:PiliPlus/models/common/super_resolution_type.dart';
|
||||||
import 'package:PiliPlus/pages/setting/widgets/switch_item.dart';
|
import 'package:PiliPlus/pages/setting/widgets/switch_item.dart';
|
||||||
|
import 'package:PiliPlus/pages/video/detail/introduction/widgets/action_item.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:PiliPlus/utils/id_utils.dart';
|
import 'package:PiliPlus/utils/id_utils.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
@@ -28,7 +29,6 @@ import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
|
|||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/services/shutdown_timer_service.dart';
|
import 'package:PiliPlus/services/shutdown_timer_service.dart';
|
||||||
import '../../../../models/video/play/CDN.dart';
|
import '../../../../models/video/play/CDN.dart';
|
||||||
import '../../../../models/video_detail_res.dart';
|
|
||||||
import '../../../setting/widgets/select_dialog.dart';
|
import '../../../setting/widgets/select_dialog.dart';
|
||||||
import '../introduction/index.dart';
|
import '../introduction/index.dart';
|
||||||
import 'package:marquee/marquee.dart';
|
import 'package:marquee/marquee.dart';
|
||||||
@@ -61,13 +61,14 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
double buttonSpace = 8;
|
double buttonSpace = 8;
|
||||||
String get heroTag => widget.heroTag;
|
String get heroTag => widget.heroTag;
|
||||||
late VideoIntroController videoIntroController;
|
late VideoIntroController videoIntroController;
|
||||||
late VideoDetailData videoDetail;
|
|
||||||
late bool horizontalScreen;
|
late bool horizontalScreen;
|
||||||
RxString now = ''.obs;
|
RxString now = ''.obs;
|
||||||
Timer? clock;
|
Timer? clock;
|
||||||
late String defaultCDNService;
|
late String defaultCDNService;
|
||||||
bool get isFullScreen => widget.controller.isFullScreen.value;
|
bool get isFullScreen => widget.controller.isFullScreen.value;
|
||||||
Box get setting => GStorage.setting;
|
Box get setting => GStorage.setting;
|
||||||
|
late final _coinKey = GlobalKey<ActionItemState>();
|
||||||
|
late final _favKey = GlobalKey<ActionItemState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -1746,346 +1747,483 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
Widget _buildHeader(bool showFSActionItem) => AppBar(
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final plPlayerController = widget.controller;
|
|
||||||
// final bool isLandscape =
|
|
||||||
// MediaQuery.of(context).orientation == Orientation.landscape;
|
|
||||||
|
|
||||||
bool equivalentFullScreen = !isFullScreen &&
|
|
||||||
!horizontalScreen &&
|
|
||||||
MediaQuery.of(context).orientation == Orientation.landscape;
|
|
||||||
return LayoutBuilder(builder: (context, boxConstraints) {
|
|
||||||
return AppBar(
|
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
primary: false,
|
primary: false,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
title: Row(
|
toolbarHeight: showFSActionItem && isFullScreen ? 112 : null,
|
||||||
|
flexibleSpace: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
const SizedBox(height: 11),
|
||||||
width: 42,
|
Row(
|
||||||
height: 34,
|
children: [
|
||||||
child: IconButton(
|
SizedBox(
|
||||||
tooltip: '返回',
|
width: 42,
|
||||||
icon: const Icon(
|
height: 34,
|
||||||
FontAwesomeIcons.arrowLeft,
|
child: IconButton(
|
||||||
size: 15,
|
tooltip: '返回',
|
||||||
color: Colors.white,
|
icon: const Icon(
|
||||||
),
|
FontAwesomeIcons.arrowLeft,
|
||||||
onPressed: () {
|
size: 15,
|
||||||
if (isFullScreen) {
|
color: Colors.white,
|
||||||
widget.controller.triggerFullScreen(status: false);
|
),
|
||||||
} else if (MediaQuery.of(context).orientation ==
|
onPressed: () {
|
||||||
Orientation.landscape &&
|
if (isFullScreen) {
|
||||||
!horizontalScreen) {
|
widget.controller.triggerFullScreen(status: false);
|
||||||
verticalScreenForTwoSeconds();
|
} else if (MediaQuery.of(context).orientation ==
|
||||||
} else {
|
Orientation.landscape &&
|
||||||
Get.back();
|
!horizontalScreen) {
|
||||||
}
|
verticalScreenForTwoSeconds();
|
||||||
},
|
} else {
|
||||||
),
|
Get.back();
|
||||||
),
|
}
|
||||||
if (!isFullScreen ||
|
},
|
||||||
MediaQuery.of(context).orientation != Orientation.portrait)
|
|
||||||
SizedBox(
|
|
||||||
width: 42,
|
|
||||||
height: 34,
|
|
||||||
child: IconButton(
|
|
||||||
tooltip: '返回主页',
|
|
||||||
icon: const Icon(
|
|
||||||
FontAwesomeIcons.house,
|
|
||||||
size: 15,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
|
||||||
widget.videoDetailCtr.plPlayerController.backToHome = true;
|
|
||||||
Get.until((route) => route.isFirst);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
if (!isFullScreen ||
|
||||||
if ((videoIntroController.videoDetail.value.title != null) &&
|
MediaQuery.of(context).orientation != Orientation.portrait)
|
||||||
(isFullScreen || equivalentFullScreen))
|
SizedBox(
|
||||||
Column(
|
width: 42,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
height: 34,
|
||||||
children: [
|
child: IconButton(
|
||||||
ConstrainedBox(
|
tooltip: '返回主页',
|
||||||
constraints: BoxConstraints(
|
icon: const Icon(
|
||||||
maxWidth: boxConstraints.maxWidth / 2 - 60,
|
FontAwesomeIcons.house,
|
||||||
maxHeight: 25),
|
size: 15,
|
||||||
child: Obx(
|
color: Colors.white,
|
||||||
() => Marquee(
|
),
|
||||||
text: videoIntroController.videoDetail.value.title!,
|
onPressed: () {
|
||||||
style: const TextStyle(
|
widget.videoDetailCtr.plPlayerController.backToHome =
|
||||||
color: Colors.white,
|
true;
|
||||||
fontSize: 16,
|
Get.until((route) => route.isFirst);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if ((videoIntroController.videoDetail.value.title != null) &&
|
||||||
|
(isFullScreen ||
|
||||||
|
(!isFullScreen &&
|
||||||
|
!horizontalScreen &&
|
||||||
|
MediaQuery.of(context).orientation ==
|
||||||
|
Orientation.landscape)))
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
constraints: BoxConstraints(maxHeight: 25),
|
||||||
|
child: Obx(
|
||||||
|
() => Marquee(
|
||||||
|
text:
|
||||||
|
videoIntroController.videoDetail.value.title!,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
scrollAxis: Axis.horizontal,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
blankSpace: 200,
|
||||||
|
velocity: 40,
|
||||||
|
startAfter: const Duration(seconds: 1),
|
||||||
|
showFadingOnlyWhenScrolling: true,
|
||||||
|
fadingEdgeStartFraction: 0,
|
||||||
|
fadingEdgeEndFraction: 0.1,
|
||||||
|
numberOfRounds: 1,
|
||||||
|
startPadding: 0,
|
||||||
|
accelerationDuration: const Duration(seconds: 1),
|
||||||
|
accelerationCurve: Curves.linear,
|
||||||
|
decelerationDuration:
|
||||||
|
const Duration(milliseconds: 500),
|
||||||
|
decelerationCurve: Curves.easeOut,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
scrollAxis: Axis.horizontal,
|
if (videoIntroController.isShowOnlineTotal)
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Obx(
|
||||||
blankSpace: 200,
|
() => Text(
|
||||||
velocity: 40,
|
'${videoIntroController.total.value}人正在看',
|
||||||
startAfter: const Duration(seconds: 1),
|
style: const TextStyle(
|
||||||
showFadingOnlyWhenScrolling: true,
|
color: Colors.white,
|
||||||
fadingEdgeStartFraction: 0,
|
fontSize: 11,
|
||||||
fadingEdgeEndFraction: 0.1,
|
),
|
||||||
numberOfRounds: 1,
|
),
|
||||||
startPadding: 0,
|
),
|
||||||
accelerationDuration: const Duration(seconds: 1),
|
],
|
||||||
accelerationCurve: Curves.linear,
|
),
|
||||||
decelerationDuration: const Duration(milliseconds: 500),
|
)
|
||||||
decelerationCurve: Curves.easeOut,
|
else
|
||||||
|
const Spacer(),
|
||||||
|
if (MediaQuery.of(context).orientation ==
|
||||||
|
Orientation.landscape &&
|
||||||
|
(isFullScreen || !horizontalScreen)) ...[
|
||||||
|
// const Spacer(),
|
||||||
|
// show current datetime
|
||||||
|
Obx(
|
||||||
|
() => Text(
|
||||||
|
now.value,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 13,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (videoIntroController.isShowOnlineTotal)
|
const SizedBox(width: 15),
|
||||||
Obx(
|
|
||||||
() => Text(
|
|
||||||
'${videoIntroController.total.value}人正在看',
|
|
||||||
style: const TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 11,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
// ComBtn(
|
||||||
const Spacer(),
|
// icon: const Icon(
|
||||||
if (MediaQuery.of(context).orientation == Orientation.landscape &&
|
// FontAwesomeIcons.cropSimple,
|
||||||
(isFullScreen || !horizontalScreen)) ...[
|
// size: 15,
|
||||||
// const Spacer(),
|
// color: Colors.white,
|
||||||
// show current datetime
|
// ),
|
||||||
Obx(
|
// fuc: () => _.screenshot(),
|
||||||
() => Text(
|
// ),
|
||||||
now.value,
|
if (widget.videoDetailCtr.enableSponsorBlock == true)
|
||||||
style: const TextStyle(
|
SizedBox(
|
||||||
color: Colors.white,
|
width: 42,
|
||||||
fontSize: 13,
|
height: 34,
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: '提交片段',
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||||
|
),
|
||||||
|
onPressed: () => widget.videoDetailCtr.onBlock(context),
|
||||||
|
icon: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.shield_outlined,
|
||||||
|
size: 19,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.play_arrow_rounded,
|
||||||
|
size: 13,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() => widget.videoDetailCtr.segmentList.isNotEmpty == true
|
||||||
|
? SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: '片段信息',
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||||
|
),
|
||||||
|
onPressed: () =>
|
||||||
|
widget.videoDetailCtr.showSBDetail(context),
|
||||||
|
icon: Icon(
|
||||||
|
MdiIcons.advertisements,
|
||||||
|
size: 19,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: '发弹幕',
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||||
|
),
|
||||||
|
onPressed: widget.videoDetailCtr.showShootDanmakuSheet,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.comment_outlined,
|
||||||
|
size: 19,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
const SizedBox(width: 15),
|
width: 42,
|
||||||
],
|
height: 34,
|
||||||
// ComBtn(
|
child: Obx(
|
||||||
// icon: const Icon(
|
() => IconButton(
|
||||||
// FontAwesomeIcons.cropSimple,
|
tooltip:
|
||||||
// size: 15,
|
"${plPlayerController.isOpenDanmu.value ? '关闭' : '开启'}弹幕",
|
||||||
// color: Colors.white,
|
style: ButtonStyle(
|
||||||
// ),
|
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||||
// fuc: () => _.screenshot(),
|
),
|
||||||
// ),
|
onPressed: () {
|
||||||
if (widget.videoDetailCtr.enableSponsorBlock == true)
|
plPlayerController.isOpenDanmu.value =
|
||||||
SizedBox(
|
!plPlayerController.isOpenDanmu.value;
|
||||||
width: 42,
|
setting.put(SettingBoxKey.enableShowDanmaku,
|
||||||
height: 34,
|
plPlayerController.isOpenDanmu.value);
|
||||||
child: IconButton(
|
// SmartDialog.showToast(
|
||||||
tooltip: '提交片段',
|
// "已${plPlayerController.isOpenDanmu.value ? '开启' : '关闭'}弹幕",
|
||||||
style: ButtonStyle(
|
// displayTime: const Duration(seconds: 1));
|
||||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
},
|
||||||
),
|
icon: Icon(
|
||||||
onPressed: () => widget.videoDetailCtr.onBlock(context),
|
plPlayerController.isOpenDanmu.value
|
||||||
icon: Stack(
|
? Icons.subtitles_outlined
|
||||||
alignment: Alignment.center,
|
: Icons.subtitles_off_outlined,
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.shield_outlined,
|
|
||||||
size: 19,
|
size: 19,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
Icon(
|
),
|
||||||
Icons.play_arrow_rounded,
|
),
|
||||||
size: 13,
|
),
|
||||||
color: Colors.white,
|
if (Platform.isAndroid)
|
||||||
|
SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: '画中画',
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||||
),
|
),
|
||||||
],
|
onPressed: () async {
|
||||||
),
|
bool canUsePiP = widget.floating != null &&
|
||||||
),
|
await widget.floating!.isPipAvailable;
|
||||||
),
|
widget.controller.hiddenControls(false);
|
||||||
Obx(
|
if (canUsePiP) {
|
||||||
() => widget.videoDetailCtr.segmentList.isNotEmpty == true
|
bool enableBackgroundPlay = setting.get(
|
||||||
? SizedBox(
|
SettingBoxKey.enableBackgroundPlay,
|
||||||
width: 42,
|
defaultValue: true);
|
||||||
height: 34,
|
if (!enableBackgroundPlay && context.mounted) {
|
||||||
child: IconButton(
|
// SmartDialog.showToast('建议开启【后台播放】功能\n避免画中画没有暂停按钮');
|
||||||
tooltip: '片段信息',
|
// await Future.delayed(const Duration(seconds: 2), () {
|
||||||
style: ButtonStyle(
|
// });
|
||||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
),
|
SnackBar(
|
||||||
onPressed: () =>
|
content: Column(
|
||||||
widget.videoDetailCtr.showSBDetail(context),
|
|
||||||
icon: Icon(
|
|
||||||
MdiIcons.advertisements,
|
|
||||||
size: 19,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 42,
|
|
||||||
height: 34,
|
|
||||||
child: IconButton(
|
|
||||||
tooltip: '发弹幕',
|
|
||||||
style: ButtonStyle(
|
|
||||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
|
||||||
),
|
|
||||||
onPressed: widget.videoDetailCtr.showShootDanmakuSheet,
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.comment_outlined,
|
|
||||||
size: 19,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 42,
|
|
||||||
height: 34,
|
|
||||||
child: Obx(
|
|
||||||
() => IconButton(
|
|
||||||
tooltip:
|
|
||||||
"${plPlayerController.isOpenDanmu.value ? '关闭' : '开启'}弹幕",
|
|
||||||
style: ButtonStyle(
|
|
||||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
plPlayerController.isOpenDanmu.value =
|
|
||||||
!plPlayerController.isOpenDanmu.value;
|
|
||||||
setting.put(SettingBoxKey.enableShowDanmaku,
|
|
||||||
plPlayerController.isOpenDanmu.value);
|
|
||||||
// SmartDialog.showToast(
|
|
||||||
// "已${plPlayerController.isOpenDanmu.value ? '开启' : '关闭'}弹幕",
|
|
||||||
// displayTime: const Duration(seconds: 1));
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
plPlayerController.isOpenDanmu.value
|
|
||||||
? Icons.subtitles_outlined
|
|
||||||
: Icons.subtitles_off_outlined,
|
|
||||||
size: 19,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (Platform.isAndroid)
|
|
||||||
SizedBox(
|
|
||||||
width: 42,
|
|
||||||
height: 34,
|
|
||||||
child: IconButton(
|
|
||||||
tooltip: '画中画',
|
|
||||||
style: ButtonStyle(
|
|
||||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
bool canUsePiP = widget.floating != null &&
|
|
||||||
await widget.floating!.isPipAvailable;
|
|
||||||
widget.controller.hiddenControls(false);
|
|
||||||
if (canUsePiP) {
|
|
||||||
bool enableBackgroundPlay = setting.get(
|
|
||||||
SettingBoxKey.enableBackgroundPlay,
|
|
||||||
defaultValue: true);
|
|
||||||
if (!enableBackgroundPlay && context.mounted) {
|
|
||||||
// SmartDialog.showToast('建议开启【后台播放】功能\n避免画中画没有暂停按钮');
|
|
||||||
// await Future.delayed(const Duration(seconds: 2), () {
|
|
||||||
// });
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Column(
|
|
||||||
children: [
|
|
||||||
const Row(
|
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
const Row(
|
||||||
Icons.check,
|
children: [
|
||||||
color: Colors.green,
|
Icon(
|
||||||
|
Icons.check,
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
Text('画中画',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15, height: 1.5))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
SizedBox(width: 10),
|
const SizedBox(height: 10),
|
||||||
Text('画中画',
|
const Text(
|
||||||
|
'建议开启【后台音频服务】\n'
|
||||||
|
'避免画中画没有暂停按钮',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15, height: 1.5))
|
fontSize: 12.5, height: 1.5)),
|
||||||
|
Row(children: [
|
||||||
|
TextButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
foregroundColor:
|
||||||
|
WidgetStateProperty.resolveWith(
|
||||||
|
(states) {
|
||||||
|
return Theme.of(context)
|
||||||
|
.snackBarTheme
|
||||||
|
.actionTextColor;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
plPlayerController
|
||||||
|
.setBackgroundPlay(true);
|
||||||
|
SmartDialog.showToast("请重新载入本页面刷新");
|
||||||
|
// Get.back();
|
||||||
|
},
|
||||||
|
child: const Text('启用后台音频服务')),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
TextButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
foregroundColor:
|
||||||
|
WidgetStateProperty.resolveWith(
|
||||||
|
(states) {
|
||||||
|
return Theme.of(context)
|
||||||
|
.snackBarTheme
|
||||||
|
.actionTextColor;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
onPressed: () {},
|
||||||
|
child: const Text('不启用'))
|
||||||
|
])
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
duration: const Duration(seconds: 2),
|
||||||
const Text(
|
showCloseIcon: true,
|
||||||
'建议开启【后台音频服务】\n'
|
),
|
||||||
'避免画中画没有暂停按钮',
|
);
|
||||||
style:
|
await Future.delayed(
|
||||||
TextStyle(fontSize: 12.5, height: 1.5)),
|
const Duration(seconds: 3), () {});
|
||||||
Row(children: [
|
}
|
||||||
TextButton(
|
final Rational aspectRatio = Rational(
|
||||||
style: ButtonStyle(
|
widget
|
||||||
foregroundColor:
|
.videoDetailCtr.data.dash!.video!.first.width!,
|
||||||
WidgetStateProperty.resolveWith(
|
widget
|
||||||
(states) {
|
.videoDetailCtr.data.dash!.video!.first.height!,
|
||||||
return Theme.of(context)
|
);
|
||||||
.snackBarTheme
|
if (!context.mounted) return;
|
||||||
.actionTextColor;
|
await widget.floating!.enable(EnableManual(
|
||||||
}),
|
aspectRatio: aspectRatio,
|
||||||
),
|
));
|
||||||
onPressed: () async {
|
} else {}
|
||||||
plPlayerController
|
},
|
||||||
.setBackgroundPlay(true);
|
icon: const Icon(
|
||||||
SmartDialog.showToast("请重新载入本页面刷新");
|
Icons.picture_in_picture_outlined,
|
||||||
// Get.back();
|
size: 19,
|
||||||
},
|
color: Colors.white,
|
||||||
child: const Text('启用后台音频服务')),
|
),
|
||||||
const SizedBox(width: 10),
|
),
|
||||||
TextButton(
|
),
|
||||||
style: ButtonStyle(
|
SizedBox(
|
||||||
foregroundColor:
|
width: 42,
|
||||||
WidgetStateProperty.resolveWith(
|
height: 34,
|
||||||
(states) {
|
child: IconButton(
|
||||||
return Theme.of(context)
|
tooltip: "更多设置",
|
||||||
.snackBarTheme
|
style: ButtonStyle(
|
||||||
.actionTextColor;
|
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||||
}),
|
),
|
||||||
),
|
onPressed: showSettingSheet,
|
||||||
onPressed: () {},
|
icon: const Icon(
|
||||||
child: const Text('不启用'))
|
Icons.more_vert_outlined,
|
||||||
])
|
size: 19,
|
||||||
],
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
duration: const Duration(seconds: 2),
|
|
||||||
showCloseIcon: true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await Future.delayed(const Duration(seconds: 3), () {});
|
|
||||||
}
|
|
||||||
final Rational aspectRatio = Rational(
|
|
||||||
widget.videoDetailCtr.data.dash!.video!.first.width!,
|
|
||||||
widget.videoDetailCtr.data.dash!.video!.first.height!,
|
|
||||||
);
|
|
||||||
if (!context.mounted) return;
|
|
||||||
await widget.floating!.enable(EnableManual(
|
|
||||||
aspectRatio: aspectRatio,
|
|
||||||
));
|
|
||||||
} else {}
|
|
||||||
},
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.picture_in_picture_outlined,
|
|
||||||
size: 19,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
SizedBox(
|
|
||||||
width: 42,
|
|
||||||
height: 34,
|
|
||||||
child: IconButton(
|
|
||||||
tooltip: "更多设置",
|
|
||||||
style: ButtonStyle(
|
|
||||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
|
||||||
),
|
|
||||||
onPressed: showSettingSheet,
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.more_vert_outlined,
|
|
||||||
size: 19,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
if (showFSActionItem)
|
||||||
|
isFullScreen
|
||||||
|
? Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: Obx(
|
||||||
|
() => ActionItem(
|
||||||
|
expand: false,
|
||||||
|
icon: const Icon(
|
||||||
|
FontAwesomeIcons.thumbsUp,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
selectIcon:
|
||||||
|
const Icon(FontAwesomeIcons.solidThumbsUp),
|
||||||
|
onTap: videoIntroController.actionLikeVideo,
|
||||||
|
onLongPress: videoIntroController.actionOneThree,
|
||||||
|
selectStatus: videoIntroController.hasLike.value,
|
||||||
|
semanticsLabel: '点赞',
|
||||||
|
needAnim: true,
|
||||||
|
hasOneThree: videoIntroController.hasLike.value &&
|
||||||
|
videoIntroController.hasCoin.value &&
|
||||||
|
videoIntroController.hasFav.value,
|
||||||
|
callBack: (start) {
|
||||||
|
if (start) {
|
||||||
|
_coinKey.currentState?.controller?.forward();
|
||||||
|
_favKey.currentState?.controller?.forward();
|
||||||
|
} else {
|
||||||
|
_coinKey.currentState?.controller?.reverse();
|
||||||
|
_favKey.currentState?.controller?.reverse();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: Obx(
|
||||||
|
() => ActionItem(
|
||||||
|
expand: false,
|
||||||
|
icon: const Icon(
|
||||||
|
FontAwesomeIcons.thumbsDown,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
selectIcon:
|
||||||
|
const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||||
|
onTap: videoIntroController.actionDislikeVideo,
|
||||||
|
selectStatus:
|
||||||
|
videoIntroController.hasDislike.value,
|
||||||
|
semanticsLabel: '点踩',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: Obx(
|
||||||
|
() => ActionItem(
|
||||||
|
key: _coinKey,
|
||||||
|
expand: false,
|
||||||
|
icon: const Icon(
|
||||||
|
FontAwesomeIcons.b,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||||
|
onTap: videoIntroController.actionCoinVideo,
|
||||||
|
selectStatus: videoIntroController.hasCoin.value,
|
||||||
|
semanticsLabel: '投币',
|
||||||
|
needAnim: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: Obx(
|
||||||
|
() => ActionItem(
|
||||||
|
key: _favKey,
|
||||||
|
expand: false,
|
||||||
|
icon: const Icon(
|
||||||
|
FontAwesomeIcons.star,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
selectIcon:
|
||||||
|
const Icon(FontAwesomeIcons.solidStar),
|
||||||
|
onTap: () => videoIntroController
|
||||||
|
.showFavBottomSheet(context),
|
||||||
|
onLongPress: () => videoIntroController
|
||||||
|
.showFavBottomSheet(context,
|
||||||
|
type: 'longPress'),
|
||||||
|
selectStatus: videoIntroController.hasFav.value,
|
||||||
|
semanticsLabel: '收藏',
|
||||||
|
needAnim: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 42,
|
||||||
|
height: 34,
|
||||||
|
child: ActionItem(
|
||||||
|
expand: false,
|
||||||
|
icon: const Icon(
|
||||||
|
FontAwesomeIcons.shareFromSquare,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
onTap: videoIntroController.actionShareVideo,
|
||||||
|
selectStatus: false,
|
||||||
|
semanticsLabel: '分享',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
PlPlayerController get plPlayerController => widget.controller;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// final bool isLandscape =
|
||||||
|
// MediaQuery.of(context).orientation == Orientation.landscape;
|
||||||
|
|
||||||
|
return plPlayerController.showFSActionItem
|
||||||
|
? Obx(() => _buildHeader(true))
|
||||||
|
: _buildHeader(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,8 @@ class PlPlayerController {
|
|||||||
/// 弹幕开关
|
/// 弹幕开关
|
||||||
Rx<bool> isOpenDanmu = false.obs;
|
Rx<bool> isOpenDanmu = false.obs;
|
||||||
|
|
||||||
|
late final showFSActionItem = GStorage.showFSActionItem;
|
||||||
|
|
||||||
/// 弹幕权重
|
/// 弹幕权重
|
||||||
int danmakuWeight = 0;
|
int danmakuWeight = 0;
|
||||||
int filterCount = 0;
|
int filterCount = 0;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class AppBarAni extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
parent: controller,
|
parent: controller,
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
)),
|
)),
|
||||||
child: Container(
|
child: DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: position! == 'top'
|
gradient: position! == 'top'
|
||||||
? const LinearGradient(
|
? const LinearGradient(
|
||||||
|
|||||||
@@ -394,6 +394,9 @@ class GStorage {
|
|||||||
static bool slideDismissReplyPage = GStorage.setting
|
static bool slideDismissReplyPage = GStorage.setting
|
||||||
.get(SettingBoxKey.slideDismissReplyPage, defaultValue: Platform.isIOS);
|
.get(SettingBoxKey.slideDismissReplyPage, defaultValue: Platform.isIOS);
|
||||||
|
|
||||||
|
static bool get showFSActionItem =>
|
||||||
|
GStorage.setting.get(SettingBoxKey.showFSActionItem, defaultValue: true);
|
||||||
|
|
||||||
static List<double> get dynamicDetailRatio => List<double>.from(setting
|
static List<double> get dynamicDetailRatio => List<double>.from(setting
|
||||||
.get(SettingBoxKey.dynamicDetailRatio, defaultValue: [60.0, 40.0]));
|
.get(SettingBoxKey.dynamicDetailRatio, defaultValue: [60.0, 40.0]));
|
||||||
|
|
||||||
@@ -649,6 +652,7 @@ class SettingBoxKey {
|
|||||||
collapsibleVideoPage = 'collapsibleVideoPage',
|
collapsibleVideoPage = 'collapsibleVideoPage',
|
||||||
enableHttp2 = 'enableHttp2',
|
enableHttp2 = 'enableHttp2',
|
||||||
slideDismissReplyPage = 'slideDismissReplyPage',
|
slideDismissReplyPage = 'slideDismissReplyPage',
|
||||||
|
showFSActionItem = 'showFSActionItem',
|
||||||
|
|
||||||
// Sponsor Block
|
// Sponsor Block
|
||||||
enableSponsorBlock = 'enableSponsorBlock',
|
enableSponsorBlock = 'enableSponsorBlock',
|
||||||
|
|||||||
Reference in New Issue
Block a user