mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: dark video page
Closes #420 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -944,6 +944,7 @@ class VideoDetailController extends GetxController
|
||||
savedDanmaku = null;
|
||||
plPlayerController.danmakuController?.addDanmaku(danmakuModel);
|
||||
},
|
||||
darkVideoPage: plPlayerController.darkVideoPage,
|
||||
);
|
||||
},
|
||||
transitionDuration: const Duration(milliseconds: 500),
|
||||
|
||||
@@ -60,6 +60,7 @@ class ReplyItem extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
// 点击整个评论区 评论详情/回复
|
||||
onTap: () {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
|
||||
@@ -256,6 +256,7 @@ class PlPlayerController {
|
||||
|
||||
late final showFSActionItem = GStorage.showFSActionItem;
|
||||
late final enableShrinkVideoSize = GStorage.enableShrinkVideoSize;
|
||||
late final darkVideoPage = GStorage.darkVideoPage;
|
||||
|
||||
/// 弹幕权重
|
||||
int danmakuWeight = 0;
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user