merge: 合并 K86.13 评论面板半屏高度

This commit is contained in:
Zhou Weidong committed 2026-10-21 13:20:33 +08:00
commit aa14d0a835
2 files changed
+34 -100

No files matched your search

@@ -21,8 +21,6 @@ import '../../../core/widgets/empty_state.dart';
import '../../../l10n/app_localizations.dart';
import 'comment_tile.dart';
const double _minSheetHeight = 280;
const double _maxSheetHeight = 520;
const int _maxCommentLength = 300;
const double _composerRadius = 22;
const double _composerHeight = 44;
@@ -50,14 +48,11 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
final _input = TextEditingController();
final _inputFocus = FocusNode();
final _keyboardInset = KeyboardInsetNotifier.instance;
final _sheetMeasureKey = GlobalKey();
late final CommentRepository _comments;
late final CommentController _controller;
DramaComment? _replyTo;
int? _serverCount;
int _countRequest = 0;
double? _sheetHeightWithoutKeyboard;
bool _sheetMeasureScheduled = false;
@override
void initState() {
@@ -105,27 +100,6 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
_keyboardInset.value / MediaQuery.devicePixelRatioOf(context),
);
void _measureSheetWithoutKeyboard(double keyboardHeight) {
if (keyboardHeight > 0 || _inputFocus.hasFocus || _sheetMeasureScheduled) {
return;
}
_sheetMeasureScheduled = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
_sheetMeasureScheduled = false;
if (!mounted) return;
if (_inputFocus.hasFocus || _keyboardHeight(context) > 0) return;
final box = _sheetMeasureKey.currentContext?.findRenderObject();
if (box is! RenderBox || !box.hasSize) return;
final height = box.size.height;
if (!height.isFinite ||
(_sheetHeightWithoutKeyboard != null &&
(height - _sheetHeightWithoutKeyboard!).abs() < 0.5)) {
return;
}
setState(() => _sheetHeightWithoutKeyboard = height);
});
}
Future<void> _post() async {
if (_controller.submitting) return;
if (!await ensureSignedIn(context) || !mounted) return;
@@ -190,20 +164,14 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
@override
Widget build(BuildContext context) {
final screenLimit = MediaQuery.sizeOf(context).height - 24;
final maxHeight = screenLimit < _maxSheetHeight
? screenLimit
: _maxSheetHeight;
final screenHeight = MediaQuery.sizeOf(context).height;
final topSafeArea = MediaQuery.paddingOf(context).top;
final halfHeight = (screenHeight * 0.5).roundToDouble();
final maxHeight = math.max(0.0, screenHeight - topSafeArea);
final sheetHeight = math.min(halfHeight, maxHeight);
final inputFocused = _inputFocus.hasFocus;
final keyboardHeight = _keyboardHeight(context);
final keyboardOpen = keyboardHeight > 0;
final expanded = inputFocused;
final availableHeight = math.max(0.0, screenLimit - keyboardHeight);
final keyboardPanelHeight = math.min(
_sheetHeightWithoutKeyboard ?? maxHeight,
availableHeight,
);
_measureSheetWithoutKeyboard(keyboardHeight);
return Stack(
fit: StackFit.expand,
children: [
@@ -225,53 +193,31 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
onTap: () {},
child: KeyedSubtree(
key: const Key('player-comments-sheet'),
child: Container(
decoration: const BoxDecoration(
color: AppColors.card,
borderRadius: BorderRadius.vertical(
top: Radius.circular(_sheetRadius),
child: SizedBox(
key: const Key('comment-sheet-constraints'),
height: sheetHeight,
child: Container(
decoration: const BoxDecoration(
color: AppColors.card,
borderRadius: BorderRadius.vertical(
top: Radius.circular(_sheetRadius),
),
),
),
child: SafeArea(
top: false,
child: ListenableBuilder(
listenable: _controller,
builder: (context, _) {
final minHeight = _controller.comments.isEmpty
? (_minSheetHeight < maxHeight
? _minSheetHeight
: maxHeight)
: 0.0;
return AnimatedSize(
duration: const Duration(milliseconds: 200),
curve: Curves.easeOut,
alignment: Alignment.bottomCenter,
child: KeyedSubtree(
key: const Key('comment-sheet-constraints'),
child: ConstrainedBox(
key: _sheetMeasureKey,
constraints: keyboardOpen
? BoxConstraints.tightFor(
height: keyboardPanelHeight,
)
: BoxConstraints(
minHeight: minHeight,
maxHeight: maxHeight,
),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
child: _content(
context,
expanded: expanded,
keyboardHeight: keyboardHeight,
),
),
child: SafeArea(
top: false,
child: ListenableBuilder(
listenable: _controller,
builder: (context, _) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: _content(
context,
expanded: expanded,
keyboardHeight: keyboardHeight,
),
),
);
},
);
},
),
),
),
),
@@ -334,8 +280,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
],
),
),
Flexible(
fit: FlexFit.loose,
Expanded(
child: _list(
l10n,
composerReserve: composerReserve,
@@ -395,7 +340,6 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
}
return ListView.builder(
key: const Key('comment-list'),
shrinkWrap: true,
padding: EdgeInsets.only(
top: 4,
bottom: composerReserve + keyboardHeight,
+5 -15
View File
@@ -581,7 +581,7 @@ void main() {
expect(find.byIcon(Icons.more_horiz_rounded), findsNothing);
});
testWidgets('should_size_short_list_to_content', (tester) async {
testWidgets('should_use_half_screen_height_for_one_comment', (tester) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
@@ -589,10 +589,7 @@ void main() {
final repository = FakeCommentRepository(
pages: [
CommentPage(
comments: [
commentFixture(id: '10', content: 'Short list one'),
commentFixture(id: '11', content: 'Short list two'),
],
comments: [commentFixture(id: '10', content: 'One comment')],
),
],
);
@@ -600,14 +597,7 @@ void main() {
await _pumpSheet(tester, repository: repository);
final sheet = find.byKey(const Key('player-comments-sheet'));
expect(tester.getSize(sheet).height, lessThan(520));
final lastCommentBottom = tester
.getBottomLeft(find.byKey(const Key('comment-item-11')))
.dy;
final composerTop = tester
.getTopLeft(find.byKey(const Key('comment-composer')))
.dy;
expect(composerTop - lastCommentBottom, lessThan(80));
expect(tester.getSize(sheet).height, closeTo(844 / 2, 0.1));
});
testWidgets('should_keep_minimum_height_for_empty_state', (tester) async {
@@ -627,7 +617,7 @@ void main() {
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
final repository = FakeCommentRepository(
pages: [CommentPage(comments: _comments(30))],
pages: [CommentPage(comments: _comments(20))],
);
await _pumpSheet(tester, repository: repository);
@@ -649,7 +639,7 @@ void main() {
expect(position.pixels, greaterThan(0));
expect(
tester.getSize(find.byKey(const Key('player-comments-sheet'))).height,
520,
closeTo(844 / 2, 0.1),
);
});