Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-06-13 10:17:35 +08:00
parent b02e4253f1
commit 3fae4ef632
8 changed files with 177 additions and 195 deletions

View File

@@ -632,19 +632,22 @@ class LiveRoomController extends GetxController {
PublishRoute(
barrierColor: Colors.transparent,
pageBuilder: (context, animation, secondaryAnimation) {
return LiveSendDmPanel(
fromEmote: fromEmote,
liveRoomController: this,
items: savedDanmaku,
autofocus: !fromEmote,
onSave: (msg) {
if (msg.isEmpty) {
savedDanmaku?.clear();
savedDanmaku = null;
} else {
savedDanmaku = msg.toList();
}
},
return Theme(
data: ThemeUtils.darkTheme,
child: LiveSendDmPanel(
fromEmote: fromEmote,
liveRoomController: this,
items: savedDanmaku,
autofocus: !fromEmote,
onSave: (msg) {
if (msg.isEmpty) {
savedDanmaku?.clear();
savedDanmaku = null;
} else {
savedDanmaku = msg.toList();
}
},
),
);
},
transitionDuration: fromEmote

View File

@@ -48,6 +48,7 @@ import 'package:PiliPlus/utils/share_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/theme_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image_ce/cached_network_image.dart';
import 'package:canvas_danmaku/danmaku_screen.dart';
@@ -57,6 +58,8 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:screen_brightness_platform_interface/screen_brightness_platform_interface.dart';
const baseWhite = Color(0xFFEEEEEE);
class LiveRoomPage extends StatefulWidget {
const LiveRoomPage({super.key});
@@ -233,7 +236,10 @@ class _LiveRoomPageState extends State<LiveRoomPage>
child: child,
);
}
return child;
return Theme(
data: ThemeUtils.darkTheme,
child: child,
);
}
Widget videoPlayerPanel(
@@ -541,7 +547,6 @@ class _LiveRoomPageState extends State<LiveRoomPage>
}
PreferredSizeWidget _buildAppBar(bool isFullScreen) {
final color = Theme.of(context).colorScheme.onSurfaceVariant;
return AppBar(
primary: !plPlayerController.removeSafeArea,
toolbarHeight: isFullScreen ? 0 : null,
@@ -563,7 +568,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
Get.toNamed('/member?mid=${roomInfoH5.roomInfo?.uid}'),
child: Row(
spacing: 10,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
NetworkImgLayer(
width: 34,
@@ -623,47 +628,35 @@ class _LiveRoomPageState extends State<LiveRoomPage>
return <PopupMenuEntry>[
PopupMenuItem(
onTap: () => Utils.copyText(liveUrl),
child: Row(
child: const Row(
spacing: 10,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
Icon(
Icons.copy,
size: 19,
color: color,
),
const Text('复制链接'),
Icon(Icons.copy, size: 19),
Text('复制链接'),
],
),
),
if (PlatformUtils.isMobile)
PopupMenuItem(
onTap: () => ShareUtils.shareText(liveUrl),
child: Row(
child: const Row(
spacing: 10,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
Icon(
Icons.share,
size: 19,
color: color,
),
const Text('分享直播间'),
Icon(Icons.share, size: 19),
Text('分享直播间'),
],
),
),
PopupMenuItem(
onTap: () => PageUtils.inAppWebview(liveUrl, off: true),
child: Row(
child: const Row(
spacing: 10,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
Icon(
Icons.open_in_browser,
size: 19,
color: color,
),
const Text('浏览器打开'),
Icon(Icons.open_in_browser, size: 19),
Text('浏览器打开'),
],
),
),
@@ -690,16 +683,12 @@ class _LiveRoomPageState extends State<LiveRoomPage>
SmartDialog.showToast(e.toString());
}
},
child: Row(
child: const Row(
spacing: 10,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
Icon(
Icons.forward_to_inbox,
size: 19,
color: color,
),
const Text('分享至消息'),
Icon(Icons.forward_to_inbox, size: 19),
Text('分享至消息'),
],
),
),
@@ -800,25 +789,20 @@ class _LiveRoomPageState extends State<LiveRoomPage>
Widget get _buildInputWidget {
final child = Container(
padding: EdgeInsets.only(
top: 5,
left: 10,
right: 10,
bottom: padding.bottom,
),
padding: .only(top: 5, left: 10, right: 10, bottom: padding.bottom),
height: 70 + padding.bottom,
decoration: const BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
borderRadius: .vertical(top: .circular(20)),
border: Border(top: BorderSide(color: Color(0x1AFFFFFF))),
color: Color(0x1AFFFFFF),
),
child: GestureDetector(
onTap: _liveRoomController.onSendDanmaku,
behavior: HitTestBehavior.opaque,
behavior: .opaque,
child: Padding(
padding: const EdgeInsets.only(top: 5, bottom: 10),
padding: const .only(top: 5, bottom: 10),
child: Align(
alignment: Alignment.topCenter,
alignment: .topCenter,
child: Row(
spacing: 6,
children: [
@@ -830,9 +814,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
width: 34,
height: 34,
child: IconButton(
style: IconButton.styleFrom(
padding: EdgeInsets.zero,
),
style: IconButton.styleFrom(padding: .zero),
onPressed: () {
final newVal = !enableShowLiveDanmaku;
plPlayerController.enableShowDanmaku.value = newVal;
@@ -847,12 +829,12 @@ class _LiveRoomPageState extends State<LiveRoomPage>
? const Icon(
size: 22,
CustomIcons.dm_on,
color: Color(0xFFEEEEEE),
color: baseWhite,
)
: const Icon(
size: 22,
CustomIcons.dm_off,
color: Color(0xFFEEEEEE),
color: baseWhite,
),
),
);
@@ -861,7 +843,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
const Expanded(
child: Text(
'发送弹幕',
style: TextStyle(color: Color(0xFFEEEEEE)),
style: TextStyle(color: baseWhite),
),
),
Builder(
@@ -882,7 +864,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
dimension: 34,
child: Icon(
size: 22,
color: Color(0xFFEEEEEE),
color: baseWhite,
Icons.thumb_up_off_alt,
),
),
@@ -930,7 +912,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
onPressed: () => _liveRoomController.onSendDanmaku(true),
icon: const Icon(
size: 22,
color: Color(0xFFEEEEEE),
color: baseWhite,
Icons.emoji_emotions_outlined,
),
),

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/plugin/pl_player/widgets/common_btn.dart';
import 'package:PiliPlus/plugin/pl_player/widgets/play_pause_btn.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -36,6 +37,8 @@ class _BottomControlState extends State<BottomControl> with HeaderMixin {
late final LiveRoomController liveRoomCtr = widget.liveRoomCtr;
@override
late final PlPlayerController plPlayerController = widget.plPlayerController;
@override
ThemeData get theme => ThemeUtils.darkTheme;
@override
Widget build(BuildContext context) {

View File

@@ -307,7 +307,6 @@ class _LiveHeaderControlState extends State<LiveHeaderControl>
showModalBottomSheet(
context: context,
useSafeArea: true,
clipBehavior: .hardEdge,
isScrollControlled: true,
constraints: BoxConstraints(
maxWidth: math.min(640, context.mediaQueryShortestSide),
@@ -331,11 +330,7 @@ class _LiveHeaderControlState extends State<LiveHeaderControl>
final currStyle = TextStyle(fontSize: 14, color: secondary);
return Theme(
data: theme.copyWith(dividerColor: Colors.transparent),
child: ListView(
controller: scrollController,
padding: .only(
bottom: MediaQuery.viewPaddingOf(context).bottom + 100,
),
child: Column(
children: [
InkWell(
onTap: Get.back,
@@ -354,90 +349,100 @@ class _LiveHeaderControlState extends State<LiveHeaderControl>
),
),
),
...controller.stream.indexed.map((stream) {
final isCurrStream = stream.$1 == controller.streamIndex;
final streamColor = isCurrStream
? secondary
: onSurfaceVariant;
return _ExpansionTile(
initiallyExpanded: isCurrStream,
iconColor: streamColor,
collapsedIconColor: streamColor,
title: Text(
stream.$2.protocolName ?? stream.$1.toString(),
style: isCurrStream
? currStyle
: const TextStyle(fontSize: 14),
Expanded(
child: ListView(
controller: scrollController,
padding: .only(
bottom: MediaQuery.viewPaddingOf(context).bottom + 100,
),
children: stream.$2.format.indexed.map((format) {
final isCurrFormat =
isCurrStream && format.$1 == controller.formatIndex;
final formatColor = isCurrFormat
children: controller.stream.indexed.map((stream) {
final isCurrStream =
stream.$1 == controller.streamIndex;
final streamColor = isCurrStream
? secondary
: onSurfaceVariant;
return _ExpansionTile(
initiallyExpanded: isCurrFormat,
iconColor: formatColor,
collapsedIconColor: formatColor,
initiallyExpanded: isCurrStream,
iconColor: streamColor,
collapsedIconColor: streamColor,
title: Text(
format.$2.formatName ?? format.$1.toString(),
style: isCurrFormat
stream.$2.protocolName ?? stream.$1.toString(),
style: isCurrStream
? currStyle
: const TextStyle(fontSize: 14),
),
children: format.$2.codec.indexed.map((codec) {
final e = codec.$2;
final isCurrCodec =
isCurrFormat &&
codec.$1 == controller.codecIndex;
final codecColor = isCurrCodec
children: stream.$2.format.indexed.map((format) {
final isCurrFormat =
isCurrStream &&
format.$1 == controller.formatIndex;
final formatColor = isCurrFormat
? secondary
: onSurfaceVariant;
return _ExpansionTile(
initiallyExpanded: isCurrCodec,
iconColor: codecColor,
collapsedIconColor: codecColor,
initiallyExpanded: isCurrFormat,
iconColor: formatColor,
collapsedIconColor: formatColor,
title: Text(
'${e.codecName ?? codec.$1.toString()} (${LiveQuality.fromCode(e.currentQn)?.desc ?? e.currentQn})',
style: isCurrCodec
format.$2.formatName ?? format.$1.toString(),
style: isCurrFormat
? currStyle
: const TextStyle(fontSize: 14),
),
children: e.urlInfo.indexed.map((url) {
final isCurrUrl =
(isCurrCodec &&
url.$1 == controller.liveUrlIndex);
return ListTile(
dense: true,
children: format.$2.codec.indexed.map((codec) {
final e = codec.$2;
final isCurrCodec =
isCurrFormat &&
codec.$1 == controller.codecIndex;
final codecColor = isCurrCodec
? secondary
: onSurfaceVariant;
return _ExpansionTile(
initiallyExpanded: isCurrCodec,
iconColor: codecColor,
collapsedIconColor: codecColor,
title: Text(
'${url.$2.host}${e.baseUrl}...',
style: isCurrUrl
? const TextStyle(fontSize: 14)
: TextStyle(
fontSize: 14,
color: onSurfaceVariant,
),
'${e.codecName ?? codec.$1.toString()} (${LiveQuality.fromCode(e.currentQn)?.desc ?? e.currentQn})',
style: isCurrCodec
? currStyle
: const TextStyle(fontSize: 14),
),
selected: isCurrUrl,
onTap: isCurrUrl
? null
: () {
Get.back();
controller.initLiveUrl(
streamIndex: stream.$1,
formatIndex: format.$1,
codecIndex: codec.$1,
liveUrlIndex: url.$1,
);
},
children: e.urlInfo.indexed.map((url) {
final isCurrUrl =
(isCurrCodec &&
url.$1 == controller.liveUrlIndex);
return ListTile(
dense: true,
title: Text(
'${url.$2.host}${e.baseUrl}...',
style: isCurrUrl
? const TextStyle(fontSize: 14)
: TextStyle(
fontSize: 14,
color: onSurfaceVariant,
),
),
selected: isCurrUrl,
onTap: isCurrUrl
? null
: () {
Get.back();
controller.initLiveUrl(
streamIndex: stream.$1,
formatIndex: format.$1,
codecIndex: codec.$1,
liveUrlIndex: url.$1,
);
},
);
}).toList(),
);
}).toList(),
);
}).toList(),
);
}).toList(),
);
}),
),
),
],
),
);

View File

@@ -644,7 +644,7 @@ class VideoDetailController extends GetxController
await Get.key.currentState!.push(
PublishRoute(
pageBuilder: (buildContext, animation, secondaryAnimation) {
return SendDanmakuPanel(
final child = SendDanmakuPanel(
cid: cid.value,
bvid: bvid,
progress: plPlayerController.position.inMilliseconds,
@@ -654,10 +654,13 @@ class VideoDetailController extends GetxController
savedDanmaku = null;
plPlayerController.danmakuController?.addDanmaku(danmakuModel);
},
darkVideoPage: plPlayerController.darkVideoPage,
dmConfig: dmConfig,
onSaveDmConfig: (dmConfig) => this.dmConfig = dmConfig,
);
if (plPlayerController.darkVideoPage) {
return Theme(data: ThemeUtils.darkTheme, child: child);
}
return child;
},
),
);
@@ -1022,22 +1025,16 @@ class VideoDetailController extends GetxController
);
}
if (plPlayerController.isFullScreen.value || showVideoSheet) {
final child = PostPanel(
enableSlide: false,
videoDetailController: this,
plPlayerController: plPlayerController,
);
PageUtils.showVideoBottomSheet(
context,
child: plPlayerController.darkVideoPage
? Theme(
data: ThemeUtils.darkTheme,
child: PostPanel(
enableSlide: false,
videoDetailController: this,
plPlayerController: plPlayerController,
),
)
: PostPanel(
enableSlide: false,
videoDetailController: this,
plPlayerController: plPlayerController,
),
? Theme(data: ThemeUtils.darkTheme, child: child)
: child,
);
} else {
childKey.currentState?.showBottomSheet(
@@ -1349,26 +1346,18 @@ class VideoDetailController extends GetxController
).videoDetail.value.title;
} catch (_) {}
if (plPlayerController.isFullScreen.value || showVideoSheet) {
final child = NoteListPage(
oid: aid,
enableSlide: false,
heroTag: heroTag,
isStein: graphVersion != null,
title: title,
);
PageUtils.showVideoBottomSheet(
context,
child: plPlayerController.darkVideoPage
? Theme(
data: ThemeUtils.darkTheme,
child: NoteListPage(
oid: aid,
enableSlide: false,
heroTag: heroTag,
isStein: graphVersion != null,
title: title,
),
)
: NoteListPage(
oid: aid,
enableSlide: false,
heroTag: heroTag,
isStein: graphVersion != null,
title: title,
),
? Theme(data: ThemeUtils.darkTheme, child: child)
: child,
);
} else {
childKey.currentState?.showBottomSheet(

View File

@@ -10,7 +10,6 @@ import 'package:PiliPlus/pages/danmaku/danmaku_model.dart';
import 'package:PiliPlus/pages/setting/slide_color_picker.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/theme_utils.dart';
import 'package:canvas_danmaku/models/danmaku_content_item.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show LengthLimitingTextInputFormatter;
@@ -24,7 +23,6 @@ class SendDanmakuPanel extends CommonTextPubPage {
final dynamic progress;
final ValueChanged<DanmakuContentItem<DanmakuExtra>> onSuccess;
final bool darkVideoPage;
// config
final ({int? mode, int? fontSize, Color? color})? dmConfig;
@@ -38,7 +36,6 @@ class SendDanmakuPanel extends CommonTextPubPage {
this.bvid,
this.progress,
required this.onSuccess,
required this.darkVideoPage,
this.dmConfig,
this.onSaveDmConfig,
});
@@ -138,14 +135,14 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
themeData = widget.darkVideoPage ? ThemeUtils.darkTheme : Theme.of(context);
themeData = Theme.of(context);
}
late ThemeData themeData;
@override
Widget build(BuildContext context) {
Widget child = ViewSafeArea(
return ViewSafeArea(
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
@@ -164,7 +161,6 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
),
),
);
return widget.darkVideoPage ? Theme(data: themeData, child: child) : child;
}
@override

View File

@@ -1983,14 +1983,12 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
},
);
if (isFullScreen || videoDetailController.showVideoSheet) {
final child = listSheetContent(enableSlide: false);
PageUtils.showVideoBottomSheet(
context,
child: videoDetailController.plPlayerController.darkVideoPage
? Theme(
data: themeData,
child: listSheetContent(enableSlide: false),
)
: listSheetContent(enableSlide: false),
? Theme(data: themeData, child: child)
: child,
);
} else {
videoDetailController.childKey.currentState?.showBottomSheet(
@@ -2062,22 +2060,16 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
void showViewPoints() {
if (isFullScreen || videoDetailController.showVideoSheet) {
final child = ViewPointsPage(
enableSlide: false,
videoDetailController: videoDetailController,
plPlayerController: plPlayerController,
);
PageUtils.showVideoBottomSheet(
context,
child: videoDetailController.plPlayerController.darkVideoPage
? Theme(
data: themeData,
child: ViewPointsPage(
enableSlide: false,
videoDetailController: videoDetailController,
plPlayerController: plPlayerController,
),
)
: ViewPointsPage(
enableSlide: false,
videoDetailController: videoDetailController,
plPlayerController: plPlayerController,
),
? Theme(data: themeData, child: child)
: child,
);
} else {
videoDetailController.childKey.currentState?.showBottomSheet(

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/plugin/pl_player/utils/danmaku_options.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -12,6 +13,13 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
bool get isFullScreen => plPlayerController.isFullScreen.value;
ThemeData? get theme {
if (plPlayerController.darkVideoPage) {
return ThemeUtils.darkTheme;
}
return null;
}
Future<void>? showBottomSheet(
StatefulWidgetBuilder builder, {
ValueGetter<EdgeInsets>? padding,
@@ -21,12 +29,16 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
maxWidth: 512,
padding: padding,
child: StatefulBuilder(
builder: (context, setState) => plPlayerController.darkVideoPage
? Theme(
data: Theme.of(this.context),
child: builder(this.context, setState),
)
: builder(context, setState),
builder: (context, setState) {
final theme = this.theme;
if (theme != null) {
return Theme(
data: theme,
child: builder(this.context, setState),
);
}
return builder(context, setState);
},
),
);
}