Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-02-27 15:48:16 +08:00
parent 6a9795f561
commit 29c47cee78
5 changed files with 140 additions and 8 deletions

View File

@@ -109,9 +109,18 @@ class _ListSheetContentState extends State<ListSheetContent>
_indexStream?.add(_ctr?.index);
}
late bool _isInit = true;
@override
void initState() {
super.initState();
if (GStorage.collapsibleVideoPage) {
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_isInit = false;
});
});
}
if (_isList) {
_indexStream ??= StreamController<int>.broadcast();
_ctr = TabController(
@@ -127,7 +136,7 @@ class _ListSheetContentState extends State<ListSheetContent>
reverse = _isList
? List.generate(widget.season.sections.length, (_) => false)
: [false];
if (widget.bvid != null && widget.season != null) {
if (GStorage.isLogin && widget.bvid != null && widget.season != null) {
_favStream ??= StreamController<int>();
() async {
dynamic result = await VideoHttp.videoRelation(bvid: widget.bvid);
@@ -278,6 +287,12 @@ class _ListSheetContentState extends State<ListSheetContent>
@override
Widget build(BuildContext context) {
if (GStorage.collapsibleVideoPage && _isInit) {
return CustomScrollView(
physics: const NeverScrollableScrollPhysics(),
);
}
return Column(
children: [
Container(
@@ -473,6 +488,7 @@ class _ListSheetContentState extends State<ListSheetContent>
),
reverse: reverse[i ?? 0],
itemCount: episodes.length,
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return buildEpisodeListItem(
episodes[index],

View File

@@ -22,6 +22,7 @@ import 'package:PiliPlus/pages/search/widgets/search_text.dart';
import 'package:PiliPlus/pages/video/detail/introduction/controller.dart';
import 'package:PiliPlus/pages/video/detail/related/controller.dart';
import 'package:PiliPlus/pages/video/detail/reply/controller.dart';
import 'package:PiliPlus/pages/video/detail/view_v.dart' show ViewPointsPage;
import 'package:PiliPlus/pages/video/detail/widgets/send_danmaku_panel.dart';
import 'package:PiliPlus/pages/video/detail/widgets/watch_later_list.dart';
import 'package:PiliPlus/utils/extension.dart';
@@ -1329,8 +1330,10 @@ class VideoDetailController extends GetxController
} else {
childKey.currentState?.showBottomSheet(
enableDrag: false,
(context) => _postPanel(),
backgroundColor: Colors.transparent,
(context) => ViewPointsPage(
child: _postPanel(),
),
);
}
}
@@ -1496,6 +1499,8 @@ class VideoDetailController extends GetxController
? Stack(
children: [
SingleChildScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
...List.generate(

View File

@@ -107,7 +107,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
? null
: _videoReplyController.scrollController,
physics: widget.needController == false
? const NeverScrollableScrollPhysics(
? const AlwaysScrollableScrollPhysics(
parent: ClampingScrollPhysics(),
)
: const AlwaysScrollableScrollPhysics(),

View File

@@ -1796,13 +1796,13 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
);
Widget videoIntro([bool needRelated = true, bool needCtr = true]) {
Widget introPanel() => Material(
color: Colors.transparent,
child: CustomScrollView(
Widget introPanel() => Scaffold(
backgroundColor: Colors.transparent,
body: CustomScrollView(
key: const PageStorageKey<String>('简介'),
controller: needCtr ? _introController : null,
physics: needCtr.not
? const NeverScrollableScrollPhysics(
? const AlwaysScrollableScrollPhysics(
parent: ClampingScrollPhysics(),
)
: null,
@@ -2260,6 +2260,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
],
),
body: SingleChildScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
...List.generate(
@@ -2358,7 +2360,9 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
} else {
videoDetailController.childKey.currentState?.showBottomSheet(
backgroundColor: Colors.transparent,
(context) => listSheetContent(),
(context) => ViewPointsPage(
child: listSheetContent(),
),
);
}
}
@@ -2391,3 +2395,35 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
);
}
}
class ViewPointsPage extends StatefulWidget {
const ViewPointsPage({super.key, required this.child});
final Widget child;
@override
State<ViewPointsPage> createState() => _ViewPointsPageState();
}
class _ViewPointsPageState extends State<ViewPointsPage> {
bool _isInit = true;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_isInit = false;
});
});
}
@override
Widget build(BuildContext context) {
return _isInit
? CustomScrollView(
physics: const NeverScrollableScrollPhysics(),
)
: widget.child;
}
}

View File

@@ -1125,6 +1125,81 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
child: Semantics(
label: '双击开关控件',
child: GestureDetector(
onVerticalDragStart: (details) {
if (plPlayerController.controlsLock.value) return;
if (details.localPosition.dy < 40) return;
_initialFocalPoint = details.localPosition;
_gestureType = null;
},
onVerticalDragUpdate: (details) {
if (plPlayerController.controlsLock.value) return;
RenderBox renderBox =
_playerKey.currentContext!.findRenderObject() as RenderBox;
final double totalWidth = renderBox.size.width;
final double tapPosition = details.localPosition.dx;
final double sectionWidth = totalWidth / 3;
if (tapPosition < sectionWidth) {
// 左边区域
_gestureType = 'left';
} else if (tapPosition < sectionWidth * 2) {
// 全屏
_gestureType = 'center';
} else {
// 右边区域
_gestureType = 'right';
}
if (_gestureType == 'left') {
// 左边区域 👈
final double level = renderBox.size.height * 3;
final double brightness =
_brightnessValue.value - details.delta.dy / level;
final double result = brightness.clamp(0.0, 1.0);
setBrightness(result);
} else if (_gestureType == 'center') {
// 全屏
const double threshold = 2.5; // 滑动阈值
double cumulativeDy =
details.localPosition.dy - _initialFocalPoint.dy;
void fullScreenTrigger(bool status) {
EasyThrottle.throttle(
'fullScreen', const Duration(milliseconds: 800),
() async {
await plPlayerController.triggerFullScreen(
status: status);
});
}
if (cumulativeDy > threshold) {
_gestureType = 'center_down';
if (isFullScreen ^ fullScreenGestureReverse) {
fullScreenTrigger(fullScreenGestureReverse);
}
// debugPrint('center_down:$cumulativeDy');
} else if (cumulativeDy < -threshold) {
_gestureType = 'center_up';
if (!isFullScreen ^ fullScreenGestureReverse) {
fullScreenTrigger(!fullScreenGestureReverse);
}
// debugPrint('center_up:$cumulativeDy');
}
} else if (_gestureType == 'right') {
// 右边区域
final double level = renderBox.size.height * 0.5;
EasyThrottle.throttle(
'setVolume', const Duration(milliseconds: 20), () {
final double volume =
_volumeValue.value - details.delta.dy / level;
final double result = volume.clamp(0.0, 1.0);
setVolume(result);
});
}
},
onVerticalDragEnd: (details) {
interacting = false;
_initialFocalPoint = Offset.zero;
_gestureType = null;
},
onTap: () {
plPlayerController.controls =
!plPlayerController.showControls.value;