mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-06 01:57:45 +08:00
@@ -37,6 +37,7 @@ class BottomControl extends StatelessWidget {
|
||||
children: [
|
||||
PlayOrPauseButton(plPlayerController: plPlayerController),
|
||||
ComBtn(
|
||||
height: 30,
|
||||
icon: const Icon(
|
||||
Icons.refresh,
|
||||
size: 18,
|
||||
@@ -45,92 +46,81 @@ class BottomControl extends StatelessWidget {
|
||||
onTap: onRefresh,
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '弹幕屏蔽',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () {
|
||||
if (liveRoomCtr.isLogin) {
|
||||
Get.toNamed(
|
||||
'/liveDmBlockPage',
|
||||
parameters: {
|
||||
'roomId': liveRoomCtr.roomId.toString(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
}
|
||||
},
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.block,
|
||||
color: Colors.white,
|
||||
),
|
||||
ComBtn(
|
||||
height: 30,
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.block,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: () {
|
||||
if (liveRoomCtr.isLogin) {
|
||||
Get.toNamed(
|
||||
'/liveDmBlockPage',
|
||||
parameters: {
|
||||
'roomId': liveRoomCtr.roomId.toString(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
const SizedBox(width: 3),
|
||||
Obx(
|
||||
() {
|
||||
final enableShowDanmaku =
|
||||
plPlayerController.enableShowDanmaku.value;
|
||||
return SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '弹幕开关',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
if (!plPlayerController.tempPlayerConf) {
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
size: 18,
|
||||
enableShowDanmaku
|
||||
? Icons.subtitles_outlined
|
||||
: Icons.subtitles_off_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
return ComBtn(
|
||||
icon: enableShowDanmaku
|
||||
? const Icon(
|
||||
size: 18,
|
||||
Icons.subtitles_outlined,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
size: 18,
|
||||
Icons.subtitles_off_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
if (!plPlayerController.tempPlayerConf) {
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
Obx(
|
||||
() => Container(
|
||||
height: 30,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 10),
|
||||
alignment: Alignment.center,
|
||||
child: PopupMenuButton<BoxFit>(
|
||||
initialValue: plPlayerController.videoFit.value,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return BoxFit.values.map((BoxFit boxFit) {
|
||||
return PopupMenuItem<BoxFit>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: boxFit,
|
||||
onTap: () => plPlayerController.toggleVideoFit(boxFit),
|
||||
child: Text(
|
||||
boxFit.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
() => PopupMenuButton<BoxFit>(
|
||||
initialValue: plPlayerController.videoFit.value,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
itemBuilder: (context) {
|
||||
return BoxFit.values
|
||||
.map(
|
||||
(BoxFit boxFit) => PopupMenuItem<BoxFit>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: boxFit,
|
||||
onTap: () => plPlayerController.toggleVideoFit(boxFit),
|
||||
child: Text(
|
||||
boxFit.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Text(
|
||||
plPlayerController.videoFit.value.desc,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 13),
|
||||
@@ -138,46 +128,54 @@ class BottomControl extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Obx(
|
||||
() => SizedBox(
|
||||
width: 30,
|
||||
child: PopupMenuButton<int>(
|
||||
padding: EdgeInsets.zero,
|
||||
initialValue: liveRoomCtr.currentQn,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
() => PopupMenuButton<int>(
|
||||
padding: EdgeInsets.zero,
|
||||
initialValue: liveRoomCtr.currentQn,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
itemBuilder: (context) {
|
||||
return liveRoomCtr.acceptQnList
|
||||
.map(
|
||||
(e) => PopupMenuItem<int>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: e.code,
|
||||
onTap: () => liveRoomCtr.changeQn(e.code),
|
||||
child: Text(
|
||||
e.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Text(
|
||||
liveRoomCtr.currentQnDesc.value,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 13),
|
||||
),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return liveRoomCtr.acceptQnList.map((e) {
|
||||
return PopupMenuItem<int>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: e.code,
|
||||
onTap: () => liveRoomCtr.changeQn(e.code),
|
||||
child: Text(
|
||||
e.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
ComBtn(
|
||||
icon: const Icon(
|
||||
Icons.fullscreen,
|
||||
semanticLabel: '全屏切换',
|
||||
size: 20,
|
||||
color: Colors.white,
|
||||
),
|
||||
height: 30,
|
||||
icon: plPlayerController.isFullScreen.value
|
||||
? const Icon(
|
||||
Icons.fullscreen_exit,
|
||||
semanticLabel: '退出全屏',
|
||||
size: 24,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.fullscreen,
|
||||
semanticLabel: '全屏',
|
||||
size: 24,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: () => plPlayerController.triggerFullScreen(
|
||||
status: !plPlayerController.isFullScreen.value,
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/widgets/common_btn.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -27,6 +28,39 @@ class LiveHeaderControl extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isFullScreen = plPlayerController.isFullScreen.value;
|
||||
Widget child;
|
||||
if (title != null) {
|
||||
child = Text(
|
||||
title!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
);
|
||||
if (isFullScreen && upName != null) {
|
||||
child = Column(
|
||||
spacing: 5,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
child,
|
||||
Text(
|
||||
upName!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
child = Expanded(child: child);
|
||||
} else {
|
||||
child = const Spacer();
|
||||
}
|
||||
return AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Colors.white,
|
||||
@@ -37,147 +71,75 @@ class LiveHeaderControl extends StatelessWidget {
|
||||
spacing: 10,
|
||||
children: [
|
||||
if (isFullScreen)
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '返回',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.arrowLeft,
|
||||
size: 15,
|
||||
),
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () =>
|
||||
plPlayerController.triggerFullScreen(status: false),
|
||||
),
|
||||
ComBtn(
|
||||
icon: const Icon(FontAwesomeIcons.arrowLeft, size: 15),
|
||||
onTap: () => plPlayerController.triggerFullScreen(status: false),
|
||||
),
|
||||
if (title != null)
|
||||
Expanded(
|
||||
child: Column(
|
||||
spacing: 5,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
if (isFullScreen && upName != null)
|
||||
Text(
|
||||
upName!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
else
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '发弹幕',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: onSendDanmaku,
|
||||
icon: const Icon(
|
||||
Icons.comment_outlined,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
child,
|
||||
ComBtn(
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.comment_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: onSendDanmaku,
|
||||
),
|
||||
Obx(
|
||||
() {
|
||||
final onlyPlayAudio = plPlayerController.onlyPlayAudio.value;
|
||||
return SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
plPlayerController.onlyPlayAudio.value = !onlyPlayAudio;
|
||||
onPlayAudio();
|
||||
},
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
icon: onlyPlayAudio
|
||||
? const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircle,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircleOutline,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
return ComBtn(
|
||||
onTap: () {
|
||||
plPlayerController.onlyPlayAudio.value = !onlyPlayAudio;
|
||||
onPlayAudio();
|
||||
},
|
||||
icon: onlyPlayAudio
|
||||
? const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircle,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircleOutline,
|
||||
color: Colors.white,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (Platform.isAndroid)
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '画中画',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () async {
|
||||
try {
|
||||
var floating = Floating();
|
||||
if ((await floating.isPipAvailable) == true) {
|
||||
plPlayerController.hiddenControls(false);
|
||||
floating.enable(
|
||||
plPlayerController.isVertical
|
||||
? const EnableManual(
|
||||
aspectRatio: Rational.vertical(),
|
||||
)
|
||||
: const EnableManual(),
|
||||
);
|
||||
}
|
||||
} catch (_) {}
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.picture_in_picture_outlined,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '定时关闭',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => PageUtils.scheduleExit(
|
||||
context,
|
||||
plPlayerController.isFullScreen.value,
|
||||
true,
|
||||
),
|
||||
ComBtn(
|
||||
onTap: () async {
|
||||
try {
|
||||
var floating = Floating();
|
||||
if ((await floating.isPipAvailable) == true) {
|
||||
plPlayerController.hiddenControls(false);
|
||||
floating.enable(
|
||||
plPlayerController.isVertical
|
||||
? const EnableManual(
|
||||
aspectRatio: Rational.vertical(),
|
||||
)
|
||||
: const EnableManual(),
|
||||
);
|
||||
}
|
||||
} catch (_) {}
|
||||
},
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.schedule,
|
||||
Icons.picture_in_picture_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
ComBtn(
|
||||
onTap: () => PageUtils.scheduleExit(
|
||||
context,
|
||||
plPlayerController.isFullScreen.value,
|
||||
true,
|
||||
),
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.schedule,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user