feat: dark video page

Closes #420

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-03-10 23:30:40 +08:00
parent fafe6c1e91
commit 33375aeb7d
11 changed files with 271 additions and 228 deletions

View File

@@ -118,6 +118,8 @@ class MyApp extends StatelessWidget {
Box get setting => GStorage.setting;
static ThemeData? darkThemeData;
@override
Widget build(BuildContext context) {
// 主题色
@@ -183,12 +185,12 @@ class MyApp extends StatelessWidget {
return GetMaterialApp(
// showSemanticsDebugger: true,
title: 'PiliPlus',
theme: _getThemeData(
theme: Utils.getThemeData(
colorScheme: lightColorScheme,
isDynamic: lightDynamic != null && isDynamicColor,
variant: variant,
),
darkTheme: _getThemeData(
darkTheme: Utils.getThemeData(
colorScheme: darkColorScheme,
isDynamic: darkDynamic != null && isDynamicColor,
isDark: true,
@@ -224,71 +226,6 @@ class MyApp extends StatelessWidget {
}),
);
}
ThemeData _getThemeData({
required ColorScheme colorScheme,
required bool isDynamic,
bool isDark = false,
required FlexSchemeVariant variant,
}) {
ThemeData themeData = ThemeData(
colorScheme: colorScheme,
useMaterial3: true,
appBarTheme: AppBarTheme(
elevation: 0,
titleSpacing: 0,
centerTitle: false,
scrolledUnderElevation: 0,
backgroundColor: isDynamic ? null : colorScheme.surface,
titleTextStyle: TextStyle(fontSize: 16, color: colorScheme.onSurface),
),
navigationBarTheme: NavigationBarThemeData(
surfaceTintColor: isDynamic ? colorScheme.onSurfaceVariant : null,
),
snackBarTheme: SnackBarThemeData(
actionTextColor: colorScheme.primary,
backgroundColor: colorScheme.secondaryContainer,
closeIconColor: colorScheme.secondary,
contentTextStyle: TextStyle(color: colorScheme.secondary),
elevation: 20,
),
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder(
allowEnterRouteSnapshotting: false,
),
},
),
popupMenuTheme: PopupMenuThemeData(
surfaceTintColor: isDynamic ? colorScheme.onSurfaceVariant : null,
),
cardTheme: CardTheme(
elevation: 1,
surfaceTintColor: isDynamic
? colorScheme.onSurfaceVariant
: isDark
? colorScheme.onSurfaceVariant
: null,
shadowColor: Colors.transparent,
),
// dialogTheme: DialogTheme(
// surfaceTintColor: isDark ? colorScheme.onSurfaceVariant : null,
// ),
progressIndicatorTheme: ProgressIndicatorThemeData(
refreshBackgroundColor: colorScheme.onSecondary,
),
dialogTheme: DialogTheme(
titleTextStyle: TextStyle(
fontSize: 18,
color: colorScheme.onSurface,
),
),
);
if (isDark && GStorage.isPureBlackTheme) {
themeData = Utils.darkenTheme(themeData);
}
return themeData;
}
}
class _CustomHttpOverrides extends HttpOverrides {

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/refresh_indicator.dart'
import 'package:PiliPlus/http/interceptor.dart';
import 'package:PiliPlus/http/reply.dart';
import 'package:PiliPlus/http/video.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/models/common/audio_normalization.dart';
import 'package:PiliPlus/models/common/dynamic_badge_mode.dart';
import 'package:PiliPlus/models/common/dynamics_type.dart';
@@ -206,6 +207,18 @@ List<SettingsModel> get styleSettings => [
getSubtitle: () =>
'当前:${GStorage.mediumCardWidth.toInt()}dp屏幕宽度:${MediaQuery.of(Get.context!).size.width.toPrecision(2)}dp。宽度越小列数越多。',
),
SettingsModel(
settingsType: SettingsType.sw1tch,
title: '视频播放页使用深色主题',
leading: Icon(Icons.dark_mode_outlined),
setKey: SettingBoxKey.darkVideoPage,
defaultVal: false,
onChanged: (value) {
if (value && MyApp.darkThemeData == null) {
Get.forceAppUpdate();
}
},
),
SettingsModel(
settingsType: SettingsType.sw1tch,
title: '播放页移除安全边距',
@@ -496,7 +509,8 @@ List<SettingsModel> get styleSettings => [
setKey: SettingBoxKey.isPureBlackTheme,
defaultVal: false,
onChanged: (value) {
if (Theme.of(Get.context!).brightness == Brightness.dark) {
if (Theme.of(Get.context!).brightness == Brightness.dark ||
GStorage.darkVideoPage) {
Get.forceAppUpdate();
}
},

View File

@@ -944,6 +944,7 @@ class VideoDetailController extends GetxController
savedDanmaku = null;
plPlayerController.danmakuController?.addDanmaku(danmakuModel);
},
darkVideoPage: plPlayerController.darkVideoPage,
);
},
transitionDuration: const Duration(milliseconds: 500),

View File

@@ -60,6 +60,7 @@ class ReplyItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: InkWell(
// 点击整个评论区 评论详情/回复
onTap: () {

View File

@@ -1,10 +1,12 @@
import 'dart:async';
import 'package:PiliPlus/http/video.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/pages/common/common_publish_page.dart';
import 'package:PiliPlus/pages/emote/view.dart';
import 'package:PiliPlus/pages/video/detail/reply_new/toolbar_icon_button.dart';
import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -36,39 +38,47 @@ class ReplyPage extends CommonPublishPage {
class _ReplyPageState extends CommonPublishPageState<ReplyPage> {
final RxBool _syncToDynamic = false.obs;
@override
Widget build(BuildContext context) {
return MediaQuery.removePadding(
removeTop: true,
context: context,
child: GestureDetector(
onTap: Get.back,
child: LayoutBuilder(
builder: (context, constraints) {
bool isH = constraints.maxWidth > constraints.maxHeight;
late double padding = constraints.maxWidth * 0.12;
return Padding(
padding: EdgeInsets.symmetric(horizontal: isH ? padding : 0),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.transparent,
body: GestureDetector(
onTap: () {},
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
buildInputView(),
buildImagePreview(),
buildPanelContainer(),
],
Widget get child => MediaQuery.removePadding(
removeTop: true,
context: context,
child: GestureDetector(
onTap: Get.back,
child: LayoutBuilder(
builder: (context, constraints) {
bool isH = constraints.maxWidth > constraints.maxHeight;
late double padding = constraints.maxWidth * 0.12;
return Padding(
padding: EdgeInsets.symmetric(horizontal: isH ? padding : 0),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.transparent,
body: GestureDetector(
onTap: () {},
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
buildInputView(),
buildImagePreview(),
buildPanelContainer(themeData.colorScheme.surface),
],
),
),
),
),
);
},
);
},
),
),
),
);
);
late final darkVideoPage =
Get.currentRoute.startsWith('/video') && GStorage.darkVideoPage;
late final ThemeData themeData = darkVideoPage
? MyApp.darkThemeData ?? Theme.of(context)
: Theme.of(context);
@override
Widget build(BuildContext context) {
return darkVideoPage ? Theme(data: themeData, child: child) : child;
}
@override
@@ -83,7 +93,7 @@ class _ReplyPageState extends CommonPublishPageState<ReplyPage> {
if (pathList.isNotEmpty) {
return Container(
height: 85,
color: Theme.of(context).colorScheme.surface,
color: themeData.colorScheme.surface,
padding: const EdgeInsets.only(bottom: 10),
child: ListView.separated(
scrollDirection: Axis.horizontal,
@@ -112,7 +122,7 @@ class _ReplyPageState extends CommonPublishPageState<ReplyPage> {
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
color: Theme.of(context).colorScheme.surface,
color: themeData.colorScheme.surface,
),
child: Column(
mainAxisSize: MainAxisSize.min,
@@ -150,7 +160,7 @@ class _ReplyPageState extends CommonPublishPageState<ReplyPage> {
hintText: "输入回复内容",
border: InputBorder.none,
hintStyle: TextStyle(fontSize: 14)),
style: Theme.of(context).textTheme.bodyLarge,
style: themeData.textTheme.bodyLarge,
),
),
),
@@ -158,7 +168,7 @@ class _ReplyPageState extends CommonPublishPageState<ReplyPage> {
),
Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
color: themeData.dividerColor.withOpacity(0.1),
),
Container(
height: 52,
@@ -213,8 +223,8 @@ class _ReplyPageState extends CommonPublishPageState<ReplyPage> {
vertical: -2,
),
foregroundColor: _syncToDynamic.value
? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.outline,
? themeData.colorScheme.secondary
: themeData.colorScheme.outline,
),
onPressed: () {
_syncToDynamic.value = !_syncToDynamic.value;

View File

@@ -5,6 +5,7 @@ import 'dart:math';
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/list_sheet.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/models/bangumi/info.dart';
import 'package:PiliPlus/models/common/reply_type.dart';
import 'package:PiliPlus/pages/bangumi/introduction/widgets/intro_detail.dart'
@@ -797,7 +798,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
// child: Divider(
// indent: 12,
// endIndent: 12,
// color: Theme.of(context).dividerColor.withOpacity(0.06),
// color: themeData.dividerColor.withOpacity(0.06),
// ),
// ),
// const RelatedVideoPanel(),
@@ -1153,8 +1154,12 @@ class _VideoDetailPageState extends State<VideoDetailPage>
return childWhenDisabled;
}
@override
Widget build(BuildContext context) {
late final ThemeData themeData =
videoDetailController.plPlayerController.darkVideoPage
? MyApp.darkThemeData ?? Theme.of(context)
: Theme.of(context);
Widget get child {
if (!horizontalScreen) {
return autoChoose(childWhenDisabled);
}
@@ -1162,7 +1167,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// if (!isShowing) {
// return ColoredBox(color: Theme.of(context).colorScheme.surface);
// return ColoredBox(color: themeData.colorScheme.surface);
// }
if (constraints.maxWidth > constraints.maxHeight * 1.25) {
// hideStatusBar();
@@ -1212,6 +1217,13 @@ class _VideoDetailPageState extends State<VideoDetailPage>
);
}
@override
Widget build(BuildContext context) {
return videoDetailController.plPlayerController.darkVideoPage
? Theme(data: themeData, child: child)
: child;
}
Widget buildTabbar({
bool needIndicator = true,
String introText = '简介',
@@ -1234,7 +1246,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
Widget tabbar() => TabBar(
labelColor: needIndicator.not || tabs.length == 1
? Theme.of(context).colorScheme.onSurface
? themeData.colorScheme.onSurface
: null,
indicator: needIndicator.not || tabs.length == 1
? const BoxDecoration()
@@ -1281,7 +1293,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
border: Border(
bottom: BorderSide(
width: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
color: themeData.dividerColor.withOpacity(0.1),
),
),
),
@@ -1311,7 +1323,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
'发弹幕',
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.onSurfaceVariant,
color: themeData.colorScheme.onSurfaceVariant,
),
),
),
@@ -1339,8 +1351,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
// ignore: deprecated_member_use
color: videoDetailController
.plPlayerController.isOpenDanmu.value
? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.outline,
? themeData.colorScheme.secondary
: themeData.colorScheme.outline,
),
),
),
@@ -1463,9 +1475,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
backgroundColor: Theme.of(context)
.colorScheme
.secondaryContainer
backgroundColor: themeData
.colorScheme.secondaryContainer
.withOpacity(0.8),
padding: const EdgeInsets.symmetric(
horizontal: 15,
@@ -1524,10 +1535,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
height: 1,
indent: 12,
endIndent: 12,
color: Theme.of(context)
.colorScheme
.outline
.withOpacity(0.08),
color: themeData.colorScheme.outline.withOpacity(0.08),
),
),
),
@@ -1578,9 +1586,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
height: 54,
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.secondaryContainer
color: themeData.colorScheme.secondaryContainer
.withOpacity(0.95),
borderRadius: const BorderRadius.all(Radius.circular(14)),
),
@@ -1591,9 +1597,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
Text(
videoDetailController.watchLaterTitle,
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
color: themeData.colorScheme.onSecondaryContainer,
fontWeight: FontWeight.bold,
letterSpacing: 0.2,
),
@@ -1660,7 +1664,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
const SizedBox(height: 8),
Divider(
height: 1,
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
color: themeData.colorScheme.outline.withOpacity(0.1),
),
],
Padding(
@@ -1780,7 +1784,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
showIntroDetail(videoDetail, videoTags) {
videoDetailController.childKey.currentState?.showBottomSheet(
shape: const RoundedRectangleBorder(),
backgroundColor: Theme.of(context).colorScheme.surface,
backgroundColor: themeData.colorScheme.surface,
(context) => videoDetail is BangumiInfoModel
? bangumi.IntroDetail(
bangumiDetail: videoDetail,
@@ -1945,7 +1949,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
void onShowMemberPage(mid) {
videoDetailController.childKey.currentState?.showBottomSheet(
shape: const RoundedRectangleBorder(),
backgroundColor: Theme.of(context).colorScheme.surface,
backgroundColor: themeData.colorScheme.surface,
(context) {
return HorizontalMemberPage(
mid: mid,

View File

@@ -6,6 +6,7 @@ import 'dart:ui';
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/list_sheet.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/models/bangumi/info.dart';
import 'package:PiliPlus/models/common/reply_type.dart';
import 'package:PiliPlus/pages/bangumi/introduction/widgets/intro_detail.dart'
@@ -652,26 +653,22 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
statusBarIconBrightness:
Brightness.light,
systemNavigationBarIconBrightness:
Theme.of(context)
.brightness
.reverse,
themeData.brightness.reverse,
)
: null,
),
if (shouldShow)
AppBar(
backgroundColor: Theme.of(context)
.colorScheme
.surface
backgroundColor: themeData.colorScheme.surface
.withOpacity(
videoDetailController.scrollRatio.value),
toolbarHeight: 0,
systemOverlayStyle: Platform.isAndroid
? SystemUiOverlayStyle(
statusBarIconBrightness:
Theme.of(context).brightness.reverse,
themeData.brightness.reverse,
systemNavigationBarIconBrightness:
Theme.of(context).brightness.reverse,
themeData.brightness.reverse,
)
: null,
),
@@ -797,7 +794,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
opacity:
videoDetailController.scrollRatio.value,
child: Container(
color: Theme.of(context).colorScheme.surface,
color: themeData.colorScheme.surface,
alignment: Alignment.topCenter,
child: SizedBox(
height: kToolbarHeight,
@@ -816,9 +813,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
icon: Icon(
FontAwesomeIcons.arrowLeft,
size: 15,
color: Theme.of(context)
.colorScheme
.onSurface,
color: themeData
.colorScheme.onSurface,
),
onPressed: Get.back,
),
@@ -831,9 +827,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
icon: Icon(
FontAwesomeIcons.house,
size: 15,
color: Theme.of(context)
.colorScheme
.onSurface,
color: themeData
.colorScheme.onSurface,
),
onPressed: () {
videoDetailController
@@ -853,16 +848,14 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
children: [
Icon(
Icons.play_arrow_rounded,
color: Theme.of(context)
.colorScheme
.primary,
color: themeData
.colorScheme.primary,
),
Text(
'${videoDetailController.playedTime == null ? '立即' : plPlayerController!.playerStatus.status.value == PlayerStatus.completed ? '重新' : '继续'}播放',
style: TextStyle(
color: Theme.of(context)
.colorScheme
.primary,
color: themeData
.colorScheme.primary,
),
),
],
@@ -875,9 +868,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
child: PopupMenuButton<String>(
icon: Icon(
Icons.more_vert,
color: Theme.of(context)
.colorScheme
.onSurface,
color: themeData
.colorScheme.onSurface,
),
onSelected: (String type) async {
switch (type) {
@@ -1184,7 +1176,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
// child: Divider(
// indent: 12,
// endIndent: 12,
// color: Theme.of(context).dividerColor.withOpacity(0.06),
// color: themeData.dividerColor.withOpacity(0.06),
// ),
// ),
// const RelatedVideoPanel(),
@@ -1541,8 +1533,12 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
return childWhenDisabled;
}
@override
Widget build(BuildContext context) {
late final ThemeData themeData =
videoDetailController.plPlayerController.darkVideoPage
? MyApp.darkThemeData ?? Theme.of(context)
: Theme.of(context);
Widget get child {
if (!horizontalScreen) {
return autoChoose(childWhenDisabled);
}
@@ -1550,7 +1546,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// if (!isShowing) {
// return ColoredBox(color: Theme.of(context).colorScheme.surface);
// return ColoredBox(color: themeData.colorScheme.surface);
// }
if (constraints.maxWidth > constraints.maxHeight * 1.25) {
// hideStatusBar();
@@ -1600,6 +1596,13 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
);
}
@override
Widget build(BuildContext context) {
return videoDetailController.plPlayerController.darkVideoPage
? Theme(data: themeData, child: child)
: child;
}
Widget buildTabbar({
bool needIndicator = true,
String introText = '简介',
@@ -1623,7 +1626,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
Widget tabbar() => TabBar(
labelColor: needIndicator.not || tabs.length == 1
? Theme.of(context).colorScheme.onSurface
? themeData.colorScheme.onSurface
: null,
indicator: needIndicator.not || tabs.length == 1
? const BoxDecoration()
@@ -1674,7 +1677,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
border: Border(
bottom: BorderSide(
width: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
color: themeData.dividerColor.withOpacity(0.1),
),
),
),
@@ -1704,7 +1707,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
'发弹幕',
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.onSurfaceVariant,
color: themeData.colorScheme.onSurfaceVariant,
),
),
),
@@ -1732,8 +1735,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
// ignore: deprecated_member_use
color: videoDetailController
.plPlayerController.isOpenDanmu.value
? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.outline,
? themeData.colorScheme.secondary
: themeData.colorScheme.outline,
),
),
),
@@ -1866,9 +1869,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
backgroundColor: Theme.of(context)
.colorScheme
.secondaryContainer
backgroundColor: themeData
.colorScheme.secondaryContainer
.withOpacity(0.8),
padding: const EdgeInsets.symmetric(
horizontal: 15,
@@ -1936,10 +1938,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
height: 1,
indent: 12,
endIndent: 12,
color: Theme.of(context)
.colorScheme
.outline
.withOpacity(0.08),
color: themeData.colorScheme.outline.withOpacity(0.08),
),
),
),
@@ -1992,9 +1991,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
height: 54,
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.secondaryContainer
color: themeData.colorScheme.secondaryContainer
.withOpacity(0.95),
borderRadius: const BorderRadius.all(Radius.circular(14)),
),
@@ -2005,9 +2002,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
Text(
videoDetailController.watchLaterTitle,
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
color: themeData.colorScheme.onSecondaryContainer,
fontWeight: FontWeight.bold,
letterSpacing: 0.2,
),
@@ -2074,7 +2069,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
const SizedBox(height: 8),
Divider(
height: 1,
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
color: themeData.colorScheme.outline.withOpacity(0.1),
),
],
Padding(
@@ -2359,7 +2354,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
void onShowMemberPage(mid) {
videoDetailController.childKey.currentState?.showBottomSheet(
shape: const RoundedRectangleBorder(),
backgroundColor: Theme.of(context).colorScheme.surface,
backgroundColor: themeData.colorScheme.surface,
(context) {
return HorizontalMemberPage(
mid: mid,

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:PiliPlus/common/widgets/icon_button.dart';
import 'package:PiliPlus/http/danmaku.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/pages/common/common_publish_page.dart';
import 'package:PiliPlus/pages/setting/slide_color_picker.dart';
import 'package:PiliPlus/utils/extension.dart';
@@ -16,6 +17,7 @@ class SendDanmakuPanel extends CommonPublishPage {
final dynamic bvid;
final dynamic progress;
final ValueChanged<DanmakuContentItem> callback;
final bool darkVideoPage;
const SendDanmakuPanel({
super.key,
@@ -25,6 +27,7 @@ class SendDanmakuPanel extends CommonPublishPage {
required this.bvid,
required this.progress,
required this.callback,
required this.darkVideoPage,
});
@override
@@ -81,8 +84,7 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
width: 40,
height: 40,
decoration: BoxDecoration(
color:
Theme.of(context).colorScheme.secondaryContainer,
color: themeData.colorScheme.secondaryContainer,
borderRadius: BorderRadius.circular(8),
),
alignment: Alignment.center,
@@ -90,9 +92,7 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
child: Icon(
size: 22,
Icons.edit,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
color: themeData.colorScheme.onSecondaryContainer,
),
),
);
@@ -107,38 +107,44 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
),
);
@override
Widget build(BuildContext context) {
return MediaQuery.removePadding(
removeTop: true,
context: context,
child: GestureDetector(
onTap: Get.back,
child: LayoutBuilder(
builder: (context, constraints) {
bool isH = constraints.maxWidth > constraints.maxHeight;
late double padding = constraints.maxWidth * 0.12;
return Padding(
padding: EdgeInsets.symmetric(horizontal: isH ? padding : 0),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.transparent,
body: GestureDetector(
onTap: () {},
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildInputView(),
buildPanelContainer(),
],
Widget get child => MediaQuery.removePadding(
removeTop: true,
context: context,
child: GestureDetector(
onTap: Get.back,
child: LayoutBuilder(
builder: (context, constraints) {
bool isH = constraints.maxWidth > constraints.maxHeight;
late double padding = constraints.maxWidth * 0.12;
return Padding(
padding: EdgeInsets.symmetric(horizontal: isH ? padding : 0),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.transparent,
body: GestureDetector(
onTap: () {},
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildInputView(),
buildPanelContainer(themeData.colorScheme.surface),
],
),
),
),
),
);
},
);
},
),
),
),
);
);
late final ThemeData themeData = widget.darkVideoPage
? MyApp.darkThemeData ?? Theme.of(context)
: Theme.of(context);
@override
Widget build(BuildContext context) {
return widget.darkVideoPage ? Theme(data: themeData, child: child) : child;
}
@override
@@ -148,7 +154,7 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
color: themeData.colorScheme.outline.withOpacity(0.1),
),
),
),
@@ -209,7 +215,7 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
? null
: Border.all(
width: 2,
color: Theme.of(context).colorScheme.primary,
color: themeData.colorScheme.primary,
),
),
child: Container(
@@ -236,8 +242,8 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
alignment: Alignment.center,
decoration: BoxDecoration(
color: _mode.value == mode
? Theme.of(context).colorScheme.secondaryContainer
: Theme.of(context).colorScheme.onInverseSurface,
? themeData.colorScheme.secondaryContainer
: themeData.colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.symmetric(vertical: 5),
@@ -245,8 +251,8 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
title,
style: TextStyle(
color: _mode.value == mode
? Theme.of(context).colorScheme.onSecondaryContainer
: Theme.of(context).colorScheme.outline,
? themeData.colorScheme.onSecondaryContainer
: themeData.colorScheme.outline,
),
),
),
@@ -268,8 +274,8 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
alignment: Alignment.center,
decoration: BoxDecoration(
color: _fontsize.value == fontsize
? Theme.of(context).colorScheme.secondaryContainer
: Theme.of(context).colorScheme.onInverseSurface,
? themeData.colorScheme.secondaryContainer
: themeData.colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.symmetric(vertical: 5),
@@ -277,8 +283,8 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
title,
style: TextStyle(
color: _fontsize.value == fontsize
? Theme.of(context).colorScheme.onSecondaryContainer
: Theme.of(context).colorScheme.outline,
? themeData.colorScheme.onSecondaryContainer
: themeData.colorScheme.outline,
),
),
),
@@ -297,7 +303,7 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
color: Theme.of(context).colorScheme.surface,
color: themeData.colorScheme.surface,
),
child: Row(
children: [
@@ -318,8 +324,8 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
iconSize: 24,
icon: Icons.text_format,
iconColor: selectKeyboard.value.not
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurfaceVariant,
? themeData.colorScheme.primary
: themeData.colorScheme.onSurfaceVariant,
),
),
const SizedBox(width: 12),
@@ -362,10 +368,10 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
border: InputBorder.none,
hintStyle: TextStyle(
fontSize: 15,
color: Theme.of(context).colorScheme.outline,
color: themeData.colorScheme.outline,
),
),
style: Theme.of(context).textTheme.bodyLarge,
style: themeData.textTheme.bodyLarge,
),
),
),
@@ -379,8 +385,8 @@ class _SendDanmakuPanelState extends CommonPublishPageState<SendDanmakuPanel> {
bgColor: Colors.transparent,
iconSize: 22,
iconColor: enablePublish.value
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.outline,
? themeData.colorScheme.primary
: themeData.colorScheme.outline,
onPressed: enablePublish.value ? onPublish : null,
icon: Icons.send,
),

View File

@@ -256,6 +256,7 @@ class PlPlayerController {
late final showFSActionItem = GStorage.showFSActionItem;
late final enableShrinkVideoSize = GStorage.enableShrinkVideoSize;
late final darkVideoPage = GStorage.darkVideoPage;
/// 弹幕权重
int danmakuWeight = 0;

View File

@@ -403,6 +403,9 @@ class GStorage {
static bool get showDynActionBar =>
GStorage.setting.get(SettingBoxKey.showDynActionBar, defaultValue: true);
static bool get darkVideoPage =>
GStorage.setting.get(SettingBoxKey.darkVideoPage, defaultValue: false);
static List<double> get dynamicDetailRatio => List<double>.from(setting
.get(SettingBoxKey.dynamicDetailRatio, defaultValue: [60.0, 40.0]));
@@ -661,6 +664,7 @@ class SettingBoxKey {
showFSActionItem = 'showFSActionItem',
enableShrinkVideoSize = 'enableShrinkVideoSize',
showDynActionBar = 'showDynActionBar',
darkVideoPage = 'darkVideoPage',
// Sponsor Block
enableSponsorBlock = 'enableSponsorBlock',

View File

@@ -14,6 +14,7 @@ import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/member.dart';
import 'package:PiliPlus/http/search.dart';
import 'package:PiliPlus/http/video.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/models/bangumi/info.dart';
import 'package:PiliPlus/models/common/search_type.dart';
import 'package:PiliPlus/models/dynamics/result.dart';
@@ -33,6 +34,7 @@ import 'package:PiliPlus/utils/url_utils.dart';
import 'package:crypto/crypto.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:flex_seed_scheme/flex_seed_scheme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -50,6 +52,74 @@ class Utils {
static const channel = MethodChannel("PiliPlus");
static ThemeData getThemeData({
required ColorScheme colorScheme,
required bool isDynamic,
bool isDark = false,
required FlexSchemeVariant variant,
}) {
ThemeData themeData = ThemeData(
colorScheme: colorScheme,
useMaterial3: true,
appBarTheme: AppBarTheme(
elevation: 0,
titleSpacing: 0,
centerTitle: false,
scrolledUnderElevation: 0,
backgroundColor: isDynamic ? null : colorScheme.surface,
titleTextStyle: TextStyle(fontSize: 16, color: colorScheme.onSurface),
),
navigationBarTheme: NavigationBarThemeData(
surfaceTintColor: isDynamic ? colorScheme.onSurfaceVariant : null,
),
snackBarTheme: SnackBarThemeData(
actionTextColor: colorScheme.primary,
backgroundColor: colorScheme.secondaryContainer,
closeIconColor: colorScheme.secondary,
contentTextStyle: TextStyle(color: colorScheme.secondary),
elevation: 20,
),
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder(
allowEnterRouteSnapshotting: false,
),
},
),
popupMenuTheme: PopupMenuThemeData(
surfaceTintColor: isDynamic ? colorScheme.onSurfaceVariant : null,
),
cardTheme: CardTheme(
elevation: 1,
surfaceTintColor: isDynamic
? colorScheme.onSurfaceVariant
: isDark
? colorScheme.onSurfaceVariant
: null,
shadowColor: Colors.transparent,
),
// dialogTheme: DialogTheme(
// surfaceTintColor: isDark ? colorScheme.onSurfaceVariant : null,
// ),
progressIndicatorTheme: ProgressIndicatorThemeData(
refreshBackgroundColor: colorScheme.onSecondary,
),
dialogTheme: DialogTheme(
titleTextStyle: TextStyle(
fontSize: 18,
color: colorScheme.onSurface,
),
),
);
if (isDark && GStorage.isPureBlackTheme) {
themeData = Utils.darkenTheme(themeData);
}
if (isDark && GStorage.darkVideoPage) {
MyApp.darkThemeData = themeData;
}
return themeData;
}
static final regExp =
RegExp(r'(@(\d+[a-z]_?)*)(\..*)?$', caseSensitive: false);