mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-08-05 02:00:13 +08:00
@@ -564,30 +564,32 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
List<ReplyInfo> replies,
|
||||
) {
|
||||
final extraRow = replies.length < replyItem.count.toInt();
|
||||
late final length = replies.length + (extraRow ? 1 : 0);
|
||||
final length = replies.length + (extraRow ? 1 : 0);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 42, right: 4),
|
||||
padding: const .only(left: 42, right: 4),
|
||||
child: Material(
|
||||
animationDuration: .zero,
|
||||
color: colorScheme.onInverseSurface,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
animationDuration: Duration.zero,
|
||||
borderRadius: const .all(.circular(6)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
crossAxisAlignment: .stretch,
|
||||
children: [
|
||||
if (replies.isNotEmpty)
|
||||
...List.generate(replies.length, (index) {
|
||||
final childReply = replies[index];
|
||||
EdgeInsets padding;
|
||||
...replies.mapIndexed((index, childReply) {
|
||||
final EdgeInsets padding;
|
||||
BorderRadius? borderRadius;
|
||||
if (length == 1) {
|
||||
padding = const EdgeInsets.fromLTRB(8, 5, 8, 5);
|
||||
padding = const .fromLTRB(8, 5, 8, 5);
|
||||
borderRadius = const .all(.circular(6));
|
||||
} else {
|
||||
if (index == 0) {
|
||||
padding = const EdgeInsets.fromLTRB(8, 8, 8, 4);
|
||||
padding = const .fromLTRB(8, 8, 8, 4);
|
||||
borderRadius = const .vertical(top: .circular(6));
|
||||
} else if (index == length - 1) {
|
||||
padding = const EdgeInsets.fromLTRB(8, 4, 8, 8);
|
||||
padding = const .fromLTRB(8, 4, 8, 8);
|
||||
borderRadius = const .vertical(bottom: .circular(6));
|
||||
} else {
|
||||
padding = const EdgeInsets.fromLTRB(8, 4, 8, 4);
|
||||
padding = const .fromLTRB(8, 4, 8, 4);
|
||||
}
|
||||
}
|
||||
void showMore() => showModalBottomSheet(
|
||||
@@ -607,6 +609,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
return InkWell(
|
||||
borderRadius: borderRadius,
|
||||
onTap: () =>
|
||||
replyReply?.call(replyItem, childReply.id.toInt()),
|
||||
onLongPress: showMore,
|
||||
@@ -670,10 +673,13 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
if (extraRow)
|
||||
InkWell(
|
||||
onTap: () => replyReply?.call(replyItem, null),
|
||||
borderRadius: length == 1
|
||||
? const .all(.circular(6))
|
||||
: const .vertical(bottom: .circular(6)),
|
||||
child: Padding(
|
||||
padding: length == 1
|
||||
? const EdgeInsets.fromLTRB(8, 6, 8, 6)
|
||||
: const EdgeInsets.fromLTRB(8, 5, 8, 8),
|
||||
? const .fromLTRB(8, 6, 8, 6)
|
||||
: const .fromLTRB(8, 5, 8, 8),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
style: const TextStyle(fontSize: 12),
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:PiliPlus/common/widgets/scroll_behavior.dart'
|
||||
show NoOverscrollIndicator;
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart'
|
||||
show tabBarView, platformAlwaysClampingPhysics, platformClampingPhysics;
|
||||
import 'package:PiliPlus/common/widgets/simple_app_bar.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/video_header.dart';
|
||||
import 'package:PiliPlus/common/widgets/svg/play_icon.dart';
|
||||
import 'package:PiliPlus/models/common/episode_panel_type.dart';
|
||||
@@ -60,13 +61,13 @@ import 'package:PiliPlus/utils/max_screen_size.dart';
|
||||
import 'package:PiliPlus/utils/mobile_observer.dart';
|
||||
import 'package:PiliPlus/utils/num_utils.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:PiliPlus/utils/theme_utils.dart';
|
||||
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
||||
import 'package:flutter/foundation.dart' show kDebugMode, clampDouble;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart' show SystemUiOverlayStyle;
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -471,12 +472,13 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
? maxVideoHeight
|
||||
: minVideoHeight;
|
||||
|
||||
themeData = videoDetailController.plPlayerController.darkVideoPage
|
||||
theme = videoDetailController.plPlayerController.darkVideoPage
|
||||
? ThemeUtils.darkTheme
|
||||
: Theme.of(context);
|
||||
}
|
||||
|
||||
bool removeAppBar(bool isFullScreen) =>
|
||||
PlatformUtils.isDesktop ||
|
||||
videoDetailController.removeSafeArea ||
|
||||
(isWindowMode && isFullScreen && !isPortrait);
|
||||
|
||||
@@ -489,30 +491,30 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
appBar: removeAppBar(isFullScreen)
|
||||
? null
|
||||
: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(0),
|
||||
preferredSize: const .fromHeight(0),
|
||||
child: Obx(
|
||||
() {
|
||||
final scrollRatio =
|
||||
videoDetailController.scrollRatio.value;
|
||||
return AppBar(
|
||||
toolbarHeight: 0,
|
||||
backgroundColor: isPortrait && scrollRatio > 0
|
||||
? Color.lerp(
|
||||
Colors.black,
|
||||
themeData.colorScheme.surface,
|
||||
scrollRatio,
|
||||
)
|
||||
: Colors.black,
|
||||
systemOverlayStyle: Platform.isAndroid
|
||||
? SystemUiOverlayStyle(
|
||||
statusBarIconBrightness:
|
||||
isPortrait && scrollRatio >= 0.5
|
||||
? themeData.brightness.reverse
|
||||
: .light,
|
||||
systemNavigationBarIconBrightness:
|
||||
themeData.brightness.reverse,
|
||||
)
|
||||
: null,
|
||||
Brightness? statusBarIconBrightness;
|
||||
if (Platform.isAndroid) {
|
||||
statusBarIconBrightness =
|
||||
isPortrait && scrollRatio >= 0.5
|
||||
? colorScheme.brightness.reverse
|
||||
: .light;
|
||||
}
|
||||
final backgroundColor = isPortrait && scrollRatio > 0
|
||||
? Color.lerp(
|
||||
Colors.black,
|
||||
colorScheme.surface,
|
||||
scrollRatio,
|
||||
)!
|
||||
: Colors.black;
|
||||
return SimpleAppBar(
|
||||
height: padding.top,
|
||||
backgroundColor: backgroundColor,
|
||||
brightness: colorScheme.brightness,
|
||||
statusBarIconBrightness: statusBarIconBrightness,
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -624,17 +626,17 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
spacing: 2,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Icon(icon, color: themeData.colorScheme.primary),
|
||||
Icon(icon, color: colorScheme.primary),
|
||||
Text(
|
||||
'$playStat播放',
|
||||
style: TextStyle(color: themeData.colorScheme.primary),
|
||||
style: TextStyle(color: colorScheme.primary),
|
||||
),
|
||||
],
|
||||
);
|
||||
return Opacity(
|
||||
opacity: videoDetailController.scrollRatio.value,
|
||||
child: Container(
|
||||
color: themeData.colorScheme.surface,
|
||||
color: colorScheme.surface,
|
||||
alignment: .topCenter,
|
||||
child: SizedBox(
|
||||
height: kToolbarHeight,
|
||||
@@ -654,7 +656,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
icon: Icon(
|
||||
FontAwesomeIcons.arrowLeft,
|
||||
size: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
onPressed: Get.back,
|
||||
),
|
||||
@@ -667,7 +669,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
icon: Icon(
|
||||
FontAwesomeIcons.house,
|
||||
size: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
onPressed:
|
||||
videoDetailController.plPlayerController.onCloseAll,
|
||||
@@ -680,7 +682,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
Align(
|
||||
alignment: .centerRight,
|
||||
child: videoDetailController.playedTime == null
|
||||
? _moreBtn(themeData.colorScheme.onSurface)
|
||||
? _moreBtn(colorScheme.onSurface)
|
||||
: SizedBox(
|
||||
width: 42,
|
||||
height: 34,
|
||||
@@ -696,7 +698,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
icon: Icon(
|
||||
Icons.more_vert_outlined,
|
||||
size: 19,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -757,7 +759,13 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: removeAppBar(isFullScreen)
|
||||
? null
|
||||
: AppBar(backgroundColor: Colors.black, toolbarHeight: 0),
|
||||
: PreferredSize(
|
||||
preferredSize: const .fromHeight(0),
|
||||
child: SimpleAppBar(
|
||||
height: padding.top,
|
||||
brightness: colorScheme.brightness,
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: isFullScreen
|
||||
? EdgeInsets.zero
|
||||
@@ -992,7 +1000,13 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: removeAppBar(isFullScreen)
|
||||
? null
|
||||
: AppBar(backgroundColor: Colors.black, toolbarHeight: 0),
|
||||
: PreferredSize(
|
||||
preferredSize: const .fromHeight(0),
|
||||
child: SimpleAppBar(
|
||||
height: padding.top,
|
||||
brightness: colorScheme.brightness,
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: isFullScreen
|
||||
? EdgeInsets.zero
|
||||
@@ -1088,57 +1102,49 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: AppBar(
|
||||
primary: false,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: Colors.transparent,
|
||||
automaticallyImplyLeading: false,
|
||||
title: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 42,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
tooltip: '返回',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.arrowLeft,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
blurRadius: 1.5,
|
||||
color: Colors.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: Get.back,
|
||||
height: kToolbarHeight,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 42,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
tooltip: '返回',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.arrowLeft,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
blurRadius: 1.5,
|
||||
color: Colors.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: Get.back,
|
||||
),
|
||||
SizedBox(
|
||||
width: 42,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
tooltip: '返回主页',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.house,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
blurRadius: 1.5,
|
||||
color: Colors.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed:
|
||||
videoDetailController.plPlayerController.onCloseAll,
|
||||
),
|
||||
SizedBox(
|
||||
width: 42,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
tooltip: '返回主页',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.house,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
blurRadius: 1.5,
|
||||
color: Colors.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed:
|
||||
videoDetailController.plPlayerController.onCloseAll,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
),
|
||||
const Spacer(),
|
||||
_moreBtn(
|
||||
Colors.white,
|
||||
shadows: const [
|
||||
@@ -1262,7 +1268,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
),
|
||||
);
|
||||
|
||||
late ThemeData themeData;
|
||||
late ThemeData theme;
|
||||
ColorScheme get colorScheme => theme.colorScheme;
|
||||
late bool isPortrait;
|
||||
late double maxWidth;
|
||||
late double maxHeight;
|
||||
@@ -1300,7 +1307,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
);
|
||||
}
|
||||
return videoDetailController.plPlayerController.darkVideoPage
|
||||
? Theme(data: themeData, child: child)
|
||||
? Theme(data: theme, child: child)
|
||||
: child;
|
||||
}
|
||||
|
||||
@@ -1336,7 +1343,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
dividerColor: Colors.transparent,
|
||||
controller: videoDetailController.tabCtr,
|
||||
indicator: flag ? const BoxDecoration() : null,
|
||||
labelColor: flag ? themeData.colorScheme.onSurface : null,
|
||||
labelColor: flag ? colorScheme.onSurface : null,
|
||||
labelStyle:
|
||||
TabBarTheme.of(context).labelStyle?.copyWith(fontSize: 13) ??
|
||||
const TextStyle(fontSize: 13),
|
||||
@@ -1387,7 +1394,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: themeData.dividerColor.withValues(alpha: 0.1),
|
||||
color: theme.dividerColor.withValues(alpha: 0.1),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1418,7 +1425,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
'发弹幕',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: themeData.colorScheme.onSurfaceVariant,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1446,8 +1453,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
? CustomIcons.dm_on
|
||||
: CustomIcons.dm_off,
|
||||
color: enableShowDanmaku
|
||||
? themeData.colorScheme.secondary
|
||||
: themeData.colorScheme.outline,
|
||||
? colorScheme.secondary
|
||||
: colorScheme.outline,
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -1577,7 +1584,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: .all(.circular(6)),
|
||||
),
|
||||
backgroundColor: themeData
|
||||
backgroundColor: theme
|
||||
.colorScheme
|
||||
.secondaryContainer
|
||||
.withValues(alpha: 0.8),
|
||||
@@ -1674,9 +1681,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
height: 1,
|
||||
indent: 12,
|
||||
endIndent: 12,
|
||||
color: themeData.colorScheme.outline.withValues(
|
||||
alpha: 0.08,
|
||||
),
|
||||
color: colorScheme.outline.withValues(alpha: .08),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1730,7 +1735,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
height: 54,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: themeData.colorScheme.secondaryContainer.withValues(
|
||||
color: colorScheme.secondaryContainer.withValues(
|
||||
alpha: 0.95,
|
||||
),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(14)),
|
||||
@@ -1742,7 +1747,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
Text(
|
||||
videoDetailController.watchLaterTitle,
|
||||
style: TextStyle(
|
||||
color: themeData.colorScheme.onSecondaryContainer,
|
||||
color: colorScheme.onSecondaryContainer,
|
||||
fontWeight: FontWeight.bold,
|
||||
letterSpacing: 0.2,
|
||||
),
|
||||
@@ -1807,7 +1812,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
const SizedBox(height: 8),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: themeData.colorScheme.outline.withValues(alpha: 0.1),
|
||||
color: colorScheme.outline.withValues(alpha: 0.1),
|
||||
),
|
||||
],
|
||||
Padding(
|
||||
@@ -1946,7 +1951,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
PageUtils.showVideoBottomSheet(
|
||||
context,
|
||||
child: videoDetailController.plPlayerController.darkVideoPage
|
||||
? Theme(data: themeData, child: child)
|
||||
? Theme(data: theme, child: child)
|
||||
: child,
|
||||
);
|
||||
} else {
|
||||
@@ -2027,7 +2032,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
PageUtils.showVideoBottomSheet(
|
||||
context,
|
||||
child: videoDetailController.plPlayerController.darkVideoPage
|
||||
? Theme(data: themeData, child: child)
|
||||
? Theme(data: theme, child: child)
|
||||
: child,
|
||||
);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user