refa: segment progressbar

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-01-18 22:21:48 +08:00
parent 395893fc7d
commit 68464e4e34
6 changed files with 464 additions and 296 deletions

View File

@@ -1740,106 +1740,69 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
right: 0,
child: Obx(
() {
if (plPlayerController.showControls.value) {
return const SizedBox.shrink();
}
switch (plPlayerController.progressType) {
case BtmProgressBehavior.onlyShowFullScreen:
if (!isFullScreen) {
return const SizedBox.shrink();
}
case BtmProgressBehavior.onlyHideFullScreen:
if (isFullScreen) {
return const SizedBox.shrink();
}
default:
}
return Stack(
clipBehavior: Clip.none,
alignment: Alignment.bottomCenter,
children: [
IgnorePointer(
child: RepaintBoundary.wrap(
Obx(() {
final int value =
plPlayerController.sliderPositionSeconds.value;
final int max = plPlayerController
.durationSeconds
.value
.inSeconds;
final int buffer =
plPlayerController.bufferedSeconds.value;
return ProgressBar(
progress: Duration(seconds: value),
buffered: Duration(seconds: buffer),
total: Duration(seconds: max),
progressBarColor: primary,
baseBarColor: const Color(0x33FFFFFF),
bufferedBarColor: bufferedBarColor,
thumbColor: primary,
thumbGlowColor: thumbGlowColor,
barHeight: 3.5,
thumbRadius: 2.5,
);
}),
0,
),
),
if (plPlayerController.enableBlock &&
videoDetailController.segmentProgressList.isNotEmpty)
Positioned(
left: 0,
right: 0,
bottom: 0.75,
child: IgnorePointer(
child: RepaintBoundary.wrap(
CustomPaint(
size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar(
segmentColors:
videoDetailController.segmentProgressList,
),
),
1,
final offstage = switch (plPlayerController.progressType) {
BtmProgressBehavior.onlyShowFullScreen => !isFullScreen,
BtmProgressBehavior.onlyHideFullScreen => isFullScreen,
_ => plPlayerController.showControls.value,
};
return Offstage(
offstage: offstage,
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.bottomCenter,
children: [
Obx(() {
final int value =
plPlayerController.sliderPositionSeconds.value;
final int max =
plPlayerController.durationSeconds.value.inSeconds;
final int buffer =
plPlayerController.bufferedSeconds.value;
return ProgressBar(
progress: Duration(seconds: value),
buffered: Duration(seconds: buffer),
total: Duration(seconds: max),
progressBarColor: primary,
baseBarColor: const Color(0x33FFFFFF),
bufferedBarColor: bufferedBarColor,
thumbColor: primary,
thumbGlowColor: thumbGlowColor,
barHeight: 3.5,
thumbRadius: 2.5,
);
}),
if (plPlayerController.enableBlock &&
videoDetailController.segmentProgressList.isNotEmpty)
Positioned(
left: 0,
right: 0,
bottom: 0.75,
child: SegmentProgressBar(
segments: videoDetailController.segmentProgressList,
),
),
),
if (plPlayerController.showViewPoints &&
videoDetailController.viewPointList.isNotEmpty &&
videoDetailController.showVP.value) ...[
Positioned(
left: 0,
right: 0,
bottom: 0.75,
child: IgnorePointer(
child: RepaintBoundary.wrap(
CustomPaint(
size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar(
segmentColors:
videoDetailController.viewPointList,
),
),
2,
if (plPlayerController.showViewPoints &&
videoDetailController.viewPointList.isNotEmpty &&
videoDetailController.showVP.value)
Padding(
padding: const .only(bottom: 4.25),
child: ViewPointSegmentProgressBar(
segments: videoDetailController.viewPointList,
onSeek: PlatformUtils.isMobile
? (position) => plPlayerController.seekTo(
position,
isSeek: false,
)
: null,
),
),
),
if (PlatformUtils.isMobile)
buildViewPointWidget(
videoDetailController,
plPlayerController,
4.25,
maxWidth,
),
if (plPlayerController.showDmChart &&
videoDetailController.showDmTrendChart.value)
if (videoDetailController.dmTrend.value?.dataOrNull
case final list?)
buildDmChart(primary, list, videoDetailController),
],
if (plPlayerController.showDmChart &&
videoDetailController.showDmTrendChart.value)
if (videoDetailController.dmTrend.value?.dataOrNull
case final list?)
buildDmChart(primary, list, videoDetailController),
],
),
);
},
),
@@ -2325,7 +2288,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
// fullscreen
if (dx > maxWidth) {
_removeDmAction();
return const Positioned(left: 0, top: 0, child: SizedBox.shrink());
return const SizedBox.shrink();
}
final seekOffset = _getValidOffset(item.content.text);
@@ -2346,7 +2309,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
if (right > (maxWidth - item.xPosition)) {
_removeDmAction();
return const Positioned(left: 0, top: 0, child: SizedBox.shrink());
return const SizedBox.shrink();
}
final extra = item.content.extra;

View File

@@ -22,9 +22,31 @@ class BottomControl extends StatelessWidget {
final double maxWidth;
final bool isFullScreen;
final PlPlayerController controller;
final Widget Function() buildBottomControl;
final ValueGetter<Widget> buildBottomControl;
final VideoDetailController videoDetailController;
void onDragStart(ThumbDragDetails duration) {
feedBack();
controller.onChangedSliderStart(duration.timeStamp);
}
void onDragUpdate(ThumbDragDetails duration, int max) {
if (!controller.isFileSource && controller.showSeekPreview) {
controller.updatePreviewIndex(duration.timeStamp.inSeconds);
}
controller.onUpdatedSliderProgress(duration.timeStamp);
}
void onSeek(Duration duration, int max) {
if (controller.showSeekPreview) {
controller.showPreview.value = false;
}
controller
..onChangedSliderEnd()
..onChangedSlider(duration.inSeconds.toDouble())
..seekTo(Duration(seconds: duration.inSeconds), isSeek: false);
}
@override
Widget build(BuildContext context) {
final colorScheme = ColorScheme.of(context);
@@ -33,27 +55,6 @@ class BottomControl extends StatelessWidget {
: colorScheme.primary;
final thumbGlowColor = primary.withAlpha(80);
final bufferedBarColor = primary.withValues(alpha: 0.4);
void onDragStart(ThumbDragDetails duration) {
feedBack();
controller.onChangedSliderStart(duration.timeStamp);
}
void onDragUpdate(ThumbDragDetails duration, int max) {
if (!controller.isFileSource && controller.showSeekPreview) {
controller.updatePreviewIndex(duration.timeStamp.inSeconds);
}
controller.onUpdatedSliderProgress(duration.timeStamp);
}
void onSeek(Duration duration, int max) {
if (controller.showSeekPreview) {
controller.showPreview.value = false;
}
controller
..onChangedSliderEnd()
..onChangedSlider(duration.inSeconds.toDouble())
..seekTo(Duration(seconds: duration.inSeconds), isSeek: false);
}
Widget progressBar() {
final child = Obx(() {
@@ -93,63 +94,42 @@ class BottomControl extends StatelessWidget {
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 7),
child: Obx(
() => Stack(
clipBehavior: Clip.none,
alignment: Alignment.bottomCenter,
children: [
progressBar(),
if (controller.enableBlock &&
videoDetailController.segmentProgressList.isNotEmpty)
Positioned(
left: 0,
right: 0,
bottom: 5.25,
child: IgnorePointer(
child: RepaintBoundary(
child: CustomPaint(
key: const Key('segmentList'),
size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar(
segmentColors:
videoDetailController.segmentProgressList,
),
),
() => Offstage(
offstage: !controller.showControls.value,
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.bottomCenter,
children: [
progressBar(),
if (controller.enableBlock &&
videoDetailController.segmentProgressList.isNotEmpty)
Positioned(
left: 0,
right: 0,
bottom: 5.25,
child: SegmentProgressBar(
segments: videoDetailController.segmentProgressList,
),
),
),
if (controller.showViewPoints &&
videoDetailController.viewPointList.isNotEmpty &&
videoDetailController.showVP.value) ...[
Positioned(
left: 0,
right: 0,
bottom: 5.25,
child: IgnorePointer(
child: RepaintBoundary(
child: CustomPaint(
key: const Key('viewPointList'),
size: const Size(double.infinity, 3.5),
painter: SegmentProgressBar(
segmentColors:
videoDetailController.viewPointList,
),
),
if (controller.showViewPoints &&
videoDetailController.viewPointList.isNotEmpty &&
videoDetailController.showVP.value)
Padding(
padding: const .only(bottom: 8.75),
child: ViewPointSegmentProgressBar(
segments: videoDetailController.viewPointList,
onSeek: PlatformUtils.isDesktop
? (position) =>
controller.seekTo(position, isSeek: false)
: null,
),
),
),
if (!PlatformUtils.isMobile)
buildViewPointWidget(
videoDetailController,
controller,
8.75,
maxWidth - 40,
),
if (videoDetailController.showDmTrendChart.value)
if (videoDetailController.dmTrend.value?.dataOrNull
case final list?)
buildDmChart(primary, list, videoDetailController, 4.5),
],
if (videoDetailController.showDmTrendChart.value)
if (videoDetailController.dmTrend.value?.dataOrNull
case final list?)
buildDmChart(primary, list, videoDetailController, 4.5),
],
),
),
),
),