constraint video bottomsheet

Closes #2277

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-06-03 20:34:48 +08:00
parent 3446484d97
commit 508384c016
5 changed files with 118 additions and 2 deletions

View File

@@ -0,0 +1,112 @@
import 'dart:math' as math;
import 'package:flutter/rendering.dart' show RenderFractionallySizedOverflowBox;
import 'package:flutter/widgets.dart';
class CustomFractionallySizedBox extends FractionallySizedBox {
const CustomFractionallySizedBox({
super.key,
super.alignment,
super.widthFactor,
super.heightFactor,
super.child,
required this.maxWidth,
});
final double maxWidth;
@override
RenderFractionallySizedOverflowBox createRenderObject(BuildContext context) {
return CustomRenderFractionallySizedOverflowBox(
alignment: alignment,
widthFactor: widthFactor,
heightFactor: heightFactor,
textDirection: Directionality.maybeOf(context),
maxWidth: maxWidth,
);
}
}
class CustomRenderFractionallySizedOverflowBox
extends RenderFractionallySizedOverflowBox {
CustomRenderFractionallySizedOverflowBox({
super.child,
super.widthFactor,
super.heightFactor,
super.alignment,
super.textDirection,
required this._maxWidth,
});
final double _maxWidth;
BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
double minWidth = constraints.minWidth;
double maxWidth = constraints.maxWidth;
if (widthFactor != null) {
final double width = math.min(_maxWidth, maxWidth * widthFactor!);
minWidth = width;
maxWidth = width;
}
double minHeight = constraints.minHeight;
double maxHeight = constraints.maxHeight;
if (heightFactor != null) {
final double height = maxHeight * heightFactor!;
minHeight = height;
maxHeight = height;
}
return BoxConstraints(
minWidth: minWidth,
maxWidth: maxWidth,
minHeight: minHeight,
maxHeight: maxHeight,
);
}
@override
@protected
Size computeDryLayout(covariant BoxConstraints constraints) {
if (child != null) {
final Size childSize = child!.getDryLayout(
_getInnerConstraints(constraints),
);
return constraints.constrain(childSize);
}
return constraints.constrain(
_getInnerConstraints(constraints).constrain(Size.zero),
);
}
@override
double? computeDryBaseline(
covariant BoxConstraints constraints,
TextBaseline baseline,
) {
final RenderBox? child = this.child;
if (child == null) {
return null;
}
final BoxConstraints childConstraints = _getInnerConstraints(constraints);
final double? result = child.getDryBaseline(childConstraints, baseline);
if (result == null) {
return null;
}
final Size childSize = child.getDryLayout(childConstraints);
final Size size = getDryLayout(constraints);
return result +
resolvedAlignment.alongOffset(size - childSize as Offset).dy;
}
@override
void performLayout() {
if (child != null) {
child!.layout(_getInnerConstraints(constraints), parentUsesSize: true);
size = constraints.constrain(child!.size);
alignChild();
} else {
size = constraints.constrain(
_getInnerConstraints(constraints).constrain(Size.zero),
);
}
}
}

View File

@@ -480,7 +480,6 @@ class VideoDetailController extends GetxController
}
}
// 稍后再看面板展开
void showMediaListPanel(BuildContext context) {
if (mediaList.isNotEmpty) {
Widget panel() => MediaListPanel(

View File

@@ -18,6 +18,7 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
}) {
return PageUtils.showVideoBottomSheet(
context,
maxWidth: 512,
isFullScreen: () => isFullScreen,
padding: padding,
child: StatefulBuilder(

View File

@@ -147,6 +147,7 @@ class ShutdownTimerService {
}
PageUtils.showVideoBottomSheet(
context,
maxWidth: 512,
isFullScreen: () => isFullScreen,
child: StatefulBuilder(
builder: (_, setState) {

View File

@@ -1,5 +1,6 @@
import 'dart:math';
import 'package:PiliPlus/common/widgets/fractionally_sized_box.dart';
import 'package:PiliPlus/common/widgets/image_viewer/gallery_viewer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero_dialog_route.dart';
import 'package:PiliPlus/grpc/im.dart';
@@ -496,6 +497,7 @@ abstract final class PageUtils {
required Widget child,
required ValueGetter<bool> isFullScreen,
double? padding,
double maxWidth = 500,
}) {
if (!context.mounted) {
return null;
@@ -519,7 +521,8 @@ abstract final class PageUtils {
);
}
return SafeArea(
child: FractionallySizedBox(
child: CustomFractionallySizedBox(
maxWidth: maxWidth,
widthFactor: 0.5,
heightFactor: 1.0,
alignment: Alignment.centerRight,