Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-04-24 10:48:51 +08:00
parent 490a08fa79
commit 73484f1f72
4 changed files with 273 additions and 236 deletions

View File

@@ -168,21 +168,55 @@ class VideoDetailController extends GetxController
late final scrollKey = GlobalKey<ExtendedNestedScrollViewState>();
late final RxBool isVertical;
late final RxDouble scrollRatio = 0.0.obs;
ScrollController? _scrollCtr;
ScrollController get scrollCtr =>
_scrollCtr ??= ScrollController()..addListener(scrollListener);
late bool isExpanding = false;
late bool isCollapsing = false;
AnimationController? animController;
AnimationController get animationController =>
animController ??= AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
);
late double minVideoHeight;
late double maxVideoHeight;
late double videoHeight;
late double animHeight;
AnimationController? animController;
AnimationController get animationController =>
animController ??= (AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
)..addListener(_animListener));
void refreshPage() {
if (scrollKey.currentState?.mounted ?? false) {
(scrollKey.currentState!.context as Element).markNeedsBuild();
}
}
void _animListener() {
if (animationController.isForwardOrCompleted) {
_calcAnimHeight();
refreshPage();
}
}
void _calcAnimHeight() {
if (isExpanding) {
animHeight = clampDouble(
videoHeight * animationController.value,
kToolbarHeight,
videoHeight,
);
} else if (isCollapsing) {
animHeight = clampDouble(
maxVideoHeight -
(maxVideoHeight - minVideoHeight) * animationController.value,
minVideoHeight,
maxVideoHeight,
);
}
}
void animToTop() {
final outerController = scrollKey.currentState!.outerController;
@@ -195,8 +229,18 @@ class VideoDetailController extends GetxController
}
}
bool _needAnimOnDimensionChanged(bool isVertical) {
if (isFullScreen) {
if (PlatformUtils.isMobile) {
plPlayerController.changeOrientation(isVertical: isVertical);
}
return false;
}
return true;
}
@pragma('vm:notify-debugger-on-exception')
void setVideoHeight() {
void _setVideoHeight() {
try {
var width = firstVideo.width;
var height = firstVideo.height;
@@ -205,10 +249,11 @@ class VideoDetailController extends GetxController
final ugcIntroCtr = Get.find<UgcIntroController>(tag: heroTag);
final data = ugcIntroCtr.videoDetail.value;
if (data.cid == cid.value) {
width = data.dimension!.width!;
height = data.dimension!.height!;
final dimension = data.dimension!;
width = dimension.width!;
height = dimension.height!;
} else {
ugcIntroCtr.queryVideoIntro().whenComplete(setVideoHeight);
ugcIntroCtr.queryVideoIntro().whenComplete(_setVideoHeight);
return;
}
} else {
@@ -227,10 +272,12 @@ class VideoDetailController extends GetxController
if (this.videoHeight != videoHeight) {
if (videoHeight > this.videoHeight) {
// current minVideoHeight
isExpanding = true;
animationController.forward(
from: (minVideoHeight - scrollCtr.offset) / maxVideoHeight,
);
if (_needAnimOnDimensionChanged(isVertical)) {
isExpanding = true;
animationController.forward(
from: (minVideoHeight - scrollCtr.offset) / maxVideoHeight,
);
}
this.videoHeight = maxVideoHeight;
} else {
// current maxVideoHeight
@@ -238,20 +285,28 @@ class VideoDetailController extends GetxController
.toPrecision(2);
double minVideoHeightPrecise = minVideoHeight.toPrecision(2);
if (currentHeight == minVideoHeightPrecise) {
isExpanding = true;
this.videoHeight = minVideoHeight;
if (_needAnimOnDimensionChanged(isVertical)) {
isExpanding = true;
this.videoHeight = minVideoHeight;
}
animationController.forward(from: 1);
} else if (currentHeight < minVideoHeightPrecise) {
// expand
isExpanding = true;
animationController.forward(from: currentHeight / minVideoHeight);
if (_needAnimOnDimensionChanged(isVertical)) {
isExpanding = true;
animationController.forward(
from: currentHeight / minVideoHeight,
);
}
this.videoHeight = minVideoHeight;
} else {
// collapse
isCollapsing = true;
animationController.forward(
from: scrollCtr.offset / (maxVideoHeight - minVideoHeight),
);
if (_needAnimOnDimensionChanged(isVertical)) {
isCollapsing = true;
animationController.forward(
from: scrollCtr.offset / (maxVideoHeight - minVideoHeight),
);
}
this.videoHeight = minVideoHeight;
}
}
@@ -313,7 +368,7 @@ class VideoDetailController extends GetxController
defaultST = Duration.zero;
}
data = PlayUrlModel(timeLength: entry.totalTimeMilli);
setVideoHeight();
_setVideoHeight();
}
@override
@@ -844,7 +899,7 @@ class VideoDetailController extends GetxController
codecs: 'avc1',
quality: videoQuality,
);
setVideoHeight();
_setVideoHeight();
currentDecodeFormats = VideoDecodeFormatType.fromString('avc1');
currentVideoQa.value = videoQuality;
await _initPlayerIfNeeded(autoFullScreenFlag);
@@ -856,7 +911,7 @@ class VideoDetailController extends GetxController
_autoPlay.value = false;
videoState.value = false;
if (plPlayerController.isFullScreen.value) {
plPlayerController.toggleFullScreen(false);
plPlayerController.triggerFullScreen(status: false);
}
isQuerying = false;
return;
@@ -918,7 +973,7 @@ class VideoDetailController extends GetxController
(e) => currentDecodeFormats.codes.any(e.codecs!.startsWith),
orElse: () => videosList.first,
);
setVideoHeight();
_setVideoHeight();
videoUrl = VideoUtils.getCdnUrl(firstVideo.playUrls);
@@ -951,8 +1006,9 @@ class VideoDetailController extends GetxController
_autoPlay.value = false;
videoState.value = false;
if (plPlayerController.isFullScreen.value) {
plPlayerController.toggleFullScreen(false);
plPlayerController.triggerFullScreen(status: false);
}
result.toast();
}
isQuerying = false;
}
@@ -1217,7 +1273,9 @@ class VideoDetailController extends GetxController
_scrollCtr
?..removeListener(scrollListener)
..dispose();
animController?.dispose();
animController
?..removeListener(_animListener)
..dispose();
subtitles.clear();
vttSubtitles.clear();
super.onClose();