Merge branch 'main' into fix

This commit is contained in:
guozhigq
2024-04-30 15:51:50 +08:00
2 changed files with 197 additions and 217 deletions

View File

@ -135,7 +135,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
late double sheetHeight; late double sheetHeight;
late final dynamic owner; late final dynamic owner;
late final dynamic follower; late final dynamic follower;
late final dynamic followStatus;
late int mid; late int mid;
late String memberHeroTag; late String memberHeroTag;
late bool enableAi; late bool enableAi;
@ -164,7 +163,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
owner = widget.videoDetail!.owner; owner = widget.videoDetail!.owner;
follower = Utils.numFormat(videoIntroController.userStat['follower']); follower = Utils.numFormat(videoIntroController.userStat['follower']);
followStatus = videoIntroController.followStatus;
enableAi = setting.get(SettingBoxKey.enableAi, defaultValue: true); enableAi = setting.get(SettingBoxKey.enableAi, defaultValue: true);
_expandableCtr = ExpandableController(initialExpanded: false); _expandableCtr = ExpandableController(initialExpanded: false);
} }
@ -441,48 +439,39 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
), ),
const Spacer(), const Spacer(),
Obx( Obx(
() => AnimatedOpacity( () {
opacity: final bool isFollowed =
videoIntroController.followStatus.isEmpty ? 0 : 1, videoIntroController.followStatus['attribute'] != 0;
duration: const Duration(milliseconds: 50), return videoIntroController.followStatus.isEmpty
child: SizedBox( ? const SizedBox()
height: 32, : SizedBox(
child: Obx( height: 32,
() => videoIntroController.followStatus.isNotEmpty child: TextButton(
? TextButton( onPressed:
onPressed: videoIntroController.actionRelationMod,
videoIntroController.actionRelationMod, style: TextButton.styleFrom(
style: TextButton.styleFrom( padding: const EdgeInsets.only(
padding: const EdgeInsets.only( left: 8,
left: 8, right: 8), right: 8,
foregroundColor:
followStatus['attribute'] != 0
? outline
: t.colorScheme.onPrimary,
backgroundColor:
followStatus['attribute'] != 0
? t.colorScheme.onInverseSurface
: t.colorScheme
.primary, // 设置按钮背景色
), ),
child: Text( foregroundColor: isFollowed
followStatus['attribute'] != 0 ? outline
? '已关注' : t.colorScheme.onPrimary,
: '关注', backgroundColor: isFollowed
style: TextStyle( ? t.colorScheme.onInverseSurface
fontSize: t : t.colorScheme.primary, // 设置按钮背景色
.textTheme.labelMedium!.fontSize),
),
)
: ElevatedButton(
onPressed:
videoIntroController.actionRelationMod,
child: const Text('关注'),
), ),
), child: Text(
), isFollowed ? '已关注' : '关注',
), style: TextStyle(
), fontSize:
t.textTheme.labelMedium!.fontSize,
),
),
),
);
},
)
], ],
), ),
), ),

View File

@ -23,6 +23,7 @@ import 'package:pilipala/plugin/pl_player/index.dart';
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart'; import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
import 'package:pilipala/services/service_locator.dart'; import 'package:pilipala/services/service_locator.dart';
import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/storage.dart';
import 'package:status_bar_control/status_bar_control.dart';
import '../../../plugin/pl_player/models/bottom_control_type.dart'; import '../../../plugin/pl_player/models/bottom_control_type.dart';
import '../../../services/shutdown_timer_service.dart'; import '../../../services/shutdown_timer_service.dart';
@ -63,10 +64,12 @@ class _VideoDetailPageState extends State<VideoDetailPage>
bool isShowing = true; bool isShowing = true;
// 生命周期监听 // 生命周期监听
late final AppLifecycleListener _lifecycleListener; late final AppLifecycleListener _lifecycleListener;
late double statusHeight;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
getStatusHeight();
heroTag = Get.arguments['heroTag']; heroTag = Get.arguments['heroTag'];
vdCtr = Get.put(VideoDetailController(), tag: heroTag); vdCtr = Get.put(VideoDetailController(), tag: heroTag);
vdCtr.sheetHeight.value = localCache.get('sheetHeight'); vdCtr.sheetHeight.value = localCache.get('sheetHeight');
@ -207,6 +210,10 @@ class _VideoDetailPageState extends State<VideoDetailPage>
}); });
} }
getStatusHeight() async {
statusHeight = await StatusBarControl.getHeight;
}
@override @override
void dispose() { void dispose() {
shutdownTimerService.handleWaitingFinished(); shutdownTimerService.handleWaitingFinished();
@ -310,6 +317,143 @@ class _VideoDetailPageState extends State<VideoDetailPage>
} }
} }
/// 手动播放
Widget handlePlayPanel() {
return Stack(
children: [
GestureDetector(
onTap: handlePlay,
child: Image.network(
vdCtr.videoItem['pic'],
width: Get.width,
height: videoHeight,
fit: BoxFit.cover, // 适应方式根据需要调整
),
),
buildCustomAppBar(),
Positioned(
right: 12,
bottom: 10,
child: GestureDetector(
onTap: handlePlay,
child: Image.asset(
'assets/images/play.png',
width: 60,
height: 60,
),
),
),
],
);
}
/// tabbar
Widget tabbarBuild() {
return Container(
width: double.infinity,
height: 45,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
),
),
child: Material(
child: Row(
children: [
Expanded(
child: Obx(
() => TabBar(
padding: EdgeInsets.zero,
controller: vdCtr.tabCtr,
labelStyle: const TextStyle(fontSize: 13),
labelPadding: const EdgeInsets.symmetric(horizontal: 10.0),
dividerColor: Colors.transparent,
tabs:
vdCtr.tabs.map((String name) => Tab(text: name)).toList(),
),
),
),
Flexible(
flex: 1,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Obx(() => AnimatedOpacity(
opacity: playerStatus.value != PlayerStatus.playing
? 1
: 0,
duration: const Duration(milliseconds: 100),
child: const Icon(
Icons.drag_handle_rounded,
size: 20,
color: Colors.grey,
),
)),
const SizedBox(width: 8),
SizedBox(
height: 32,
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () => vdCtr.showShootDanmakuSheet(),
child:
const Text('发弹幕', style: TextStyle(fontSize: 12)),
),
),
SizedBox(
width: 38,
height: 38,
child: Obx(
() => !vdCtr.isShowCover.value
? IconButton(
onPressed: () {
plPlayerController?.isOpenDanmu.value =
!(plPlayerController?.isOpenDanmu.value ??
false);
},
icon: !(plPlayerController?.isOpenDanmu.value ??
false)
? SvgPicture.asset(
'assets/images/video/danmu_close.svg',
// ignore: deprecated_member_use
color: Theme.of(context)
.colorScheme
.outline,
)
: SvgPicture.asset(
'assets/images/video/danmu_open.svg',
// ignore: deprecated_member_use
color: Theme.of(context)
.colorScheme
.primary,
),
)
: IconButton(
icon: SvgPicture.asset(
'assets/images/video/danmu_close.svg',
// ignore: deprecated_member_use
color: Theme.of(context).colorScheme.outline,
),
onPressed: () {},
),
),
),
const SizedBox(width: 18),
],
),
),
),
],
),
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final sizeContext = MediaQuery.sizeOf(context); final sizeContext = MediaQuery.sizeOf(context);
@ -367,168 +511,13 @@ class _VideoDetailPageState extends State<VideoDetailPage>
}, },
); );
/// tabbar
Widget tabbarBuild = Container(
width: double.infinity,
height: 45,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
),
),
child: Material(
child: Row(
children: [
Flexible(
flex: 1,
child: Obx(
() => TabBar(
padding: EdgeInsets.zero,
controller: vdCtr.tabCtr,
labelStyle: const TextStyle(fontSize: 13),
labelPadding:
const EdgeInsets.symmetric(horizontal: 10.0), // 设置每个标签的宽度
dividerColor: Colors.transparent,
tabs: vdCtr.tabs
.map(
(String name) => Tab(text: name),
)
.toList(),
),
),
),
Flexible(
flex: 1,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Obx(() => AnimatedOpacity(
opacity: playerStatus.value != PlayerStatus.playing
? 1
: 0,
duration: const Duration(milliseconds: 100),
child: const Icon(
Icons.drag_handle_rounded,
size: 20,
color: Colors.grey,
),
)),
const SizedBox(width: 8),
SizedBox(
height: 32,
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () => vdCtr.showShootDanmakuSheet(),
child:
const Text('发弹幕', style: TextStyle(fontSize: 12)),
),
),
SizedBox(
width: 38,
height: 38,
child: Obx(
() => !vdCtr.isShowCover.value
? IconButton(
onPressed: () {
plPlayerController?.isOpenDanmu.value =
!(plPlayerController
?.isOpenDanmu.value ??
false);
},
icon:
!(plPlayerController?.isOpenDanmu.value ??
false)
? SvgPicture.asset(
'assets/images/video/danmu_close.svg',
// ignore: deprecated_member_use
color: Theme.of(context)
.colorScheme
.outline,
)
: SvgPicture.asset(
'assets/images/video/danmu_open.svg',
// ignore: deprecated_member_use
color: Theme.of(context)
.colorScheme
.primary,
),
)
: IconButton(
icon: SvgPicture.asset(
'assets/images/video/danmu_close.svg',
// ignore: deprecated_member_use
color:
Theme.of(context).colorScheme.outline,
),
onPressed: () {},
),
),
),
const SizedBox(width: 18),
],
),
)),
],
),
),
);
/// 手动播放
Widget handlePlayPanel() {
return Stack(
children: [
GestureDetector(
onTap: () {
handlePlay();
},
child: Obx(
() => AnimatedOpacity(
duration: const Duration(milliseconds: 100), // 渐变动画的持续时间
opacity: 1, // 设置不透明度
child: NetworkImgLayer(
type: 'emote',
src: vdCtr.cover.value,
width: Get.width,
height: videoHeight.value,
),
),
),
),
Positioned(
top: 0,
left: 0,
right: 0,
child: buildCustomAppBar(),
),
Positioned(
right: 12,
bottom: 10,
child: IconButton(
tooltip: '播放',
onPressed: () => handlePlay(),
icon: Image.asset(
'assets/images/play.png',
width: 60,
height: 60,
)),
),
],
);
}
Widget childWhenDisabled = SafeArea( Widget childWhenDisabled = SafeArea(
top: MediaQuery.of(context).orientation == Orientation.portrait && top: MediaQuery.of(context).orientation == Orientation.portrait &&
plPlayerController?.isFullScreen.value == true, plPlayerController?.isFullScreen.value == true,
bottom: MediaQuery.of(context).orientation == Orientation.portrait && bottom: MediaQuery.of(context).orientation == Orientation.portrait &&
plPlayerController?.isFullScreen.value == true, plPlayerController?.isFullScreen.value == true,
left: false, //plPlayerController?.isFullScreen.value != true, left: false,
right: false, //plPlayerController?.isFullScreen.value != true, right: false,
child: Stack( child: Stack(
children: [ children: [
Scaffold( Scaffold(
@ -546,12 +535,22 @@ class _VideoDetailPageState extends State<VideoDetailPage>
controller: _extendNestCtr, controller: _extendNestCtr,
headerSliverBuilder: headerSliverBuilder:
(BuildContext context2, bool innerBoxIsScrolled) { (BuildContext context2, bool innerBoxIsScrolled) {
final Orientation orientation =
MediaQuery.of(context).orientation;
final bool isFullScreen =
plPlayerController?.isFullScreen.value == true;
final double expandedHeight =
orientation == Orientation.landscape || isFullScreen
? (MediaQuery.sizeOf(context).height -
(orientation == Orientation.landscape
? 0
: MediaQuery.of(context).padding.top))
: videoHeight.value;
return <Widget>[ return <Widget>[
Obx( Obx(
() { () {
if (MediaQuery.of(context).orientation == if (orientation == Orientation.landscape ||
Orientation.landscape || isFullScreen) {
plPlayerController?.isFullScreen.value == true) {
enterFullScreen(); enterFullScreen();
} else { } else {
exitFullScreen(); exitFullScreen();
@ -563,15 +562,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
elevation: 0, elevation: 0,
scrolledUnderElevation: 0, scrolledUnderElevation: 0,
forceElevated: innerBoxIsScrolled, forceElevated: innerBoxIsScrolled,
expandedHeight: MediaQuery.of(context).orientation == expandedHeight: expandedHeight,
Orientation.landscape ||
plPlayerController?.isFullScreen.value == true
? (MediaQuery.sizeOf(context).height -
(MediaQuery.of(context).orientation ==
Orientation.landscape
? 0
: MediaQuery.of(context).padding.top))
: videoHeight.value,
backgroundColor: Colors.black, backgroundColor: Colors.black,
flexibleSpace: FlexibleSpaceBar( flexibleSpace: FlexibleSpaceBar(
background: PopScope( background: PopScope(
@ -591,13 +582,13 @@ class _VideoDetailPageState extends State<VideoDetailPage>
child: LayoutBuilder( child: LayoutBuilder(
builder: (BuildContext context, builder: (BuildContext context,
BoxConstraints boxConstraints) { BoxConstraints boxConstraints) {
// final double maxWidth =
// boxConstraints.maxWidth;
// final double maxHeight =
// boxConstraints.maxHeight;
return Stack( return Stack(
children: <Widget>[ children: <Widget>[
if (isShowing) videoPlayerPanel, if (isShowing)
Padding(
padding: EdgeInsets.only(top: 0),
child: videoPlayerPanel,
),
/// 关闭自动播放时 手动播放 /// 关闭自动播放时 手动播放
Obx( Obx(
@ -639,7 +630,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
color: Theme.of(context).colorScheme.background, color: Theme.of(context).colorScheme.background,
child: Column( child: Column(
children: [ children: [
tabbarBuild, tabbarBuild(),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
controller: vdCtr.tabCtr, controller: vdCtr.tabCtr,