merge: 合并 K86.13 评论面板半屏高度
This commit is contained in:
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 '../../../l10n/app_localizations.dart';
|
||||||
import 'comment_tile.dart';
|
import 'comment_tile.dart';
|
||||||
|
|
||||||
const double _minSheetHeight = 280;
|
|
||||||
const double _maxSheetHeight = 520;
|
|
||||||
const int _maxCommentLength = 300;
|
const int _maxCommentLength = 300;
|
||||||
const double _composerRadius = 22;
|
const double _composerRadius = 22;
|
||||||
const double _composerHeight = 44;
|
const double _composerHeight = 44;
|
||||||
@@ -50,14 +48,11 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
|||||||
final _input = TextEditingController();
|
final _input = TextEditingController();
|
||||||
final _inputFocus = FocusNode();
|
final _inputFocus = FocusNode();
|
||||||
final _keyboardInset = KeyboardInsetNotifier.instance;
|
final _keyboardInset = KeyboardInsetNotifier.instance;
|
||||||
final _sheetMeasureKey = GlobalKey();
|
|
||||||
late final CommentRepository _comments;
|
late final CommentRepository _comments;
|
||||||
late final CommentController _controller;
|
late final CommentController _controller;
|
||||||
DramaComment? _replyTo;
|
DramaComment? _replyTo;
|
||||||
int? _serverCount;
|
int? _serverCount;
|
||||||
int _countRequest = 0;
|
int _countRequest = 0;
|
||||||
double? _sheetHeightWithoutKeyboard;
|
|
||||||
bool _sheetMeasureScheduled = false;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -105,27 +100,6 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
|||||||
_keyboardInset.value / MediaQuery.devicePixelRatioOf(context),
|
_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 {
|
Future<void> _post() async {
|
||||||
if (_controller.submitting) return;
|
if (_controller.submitting) return;
|
||||||
if (!await ensureSignedIn(context) || !mounted) return;
|
if (!await ensureSignedIn(context) || !mounted) return;
|
||||||
@@ -190,20 +164,14 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final screenLimit = MediaQuery.sizeOf(context).height - 24;
|
final screenHeight = MediaQuery.sizeOf(context).height;
|
||||||
final maxHeight = screenLimit < _maxSheetHeight
|
final topSafeArea = MediaQuery.paddingOf(context).top;
|
||||||
? screenLimit
|
final halfHeight = (screenHeight * 0.5).roundToDouble();
|
||||||
: _maxSheetHeight;
|
final maxHeight = math.max(0.0, screenHeight - topSafeArea);
|
||||||
|
final sheetHeight = math.min(halfHeight, maxHeight);
|
||||||
final inputFocused = _inputFocus.hasFocus;
|
final inputFocused = _inputFocus.hasFocus;
|
||||||
final keyboardHeight = _keyboardHeight(context);
|
final keyboardHeight = _keyboardHeight(context);
|
||||||
final keyboardOpen = keyboardHeight > 0;
|
|
||||||
final expanded = inputFocused;
|
final expanded = inputFocused;
|
||||||
final availableHeight = math.max(0.0, screenLimit - keyboardHeight);
|
|
||||||
final keyboardPanelHeight = math.min(
|
|
||||||
_sheetHeightWithoutKeyboard ?? maxHeight,
|
|
||||||
availableHeight,
|
|
||||||
);
|
|
||||||
_measureSheetWithoutKeyboard(keyboardHeight);
|
|
||||||
return Stack(
|
return Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
@@ -225,53 +193,31 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
|||||||
onTap: () {},
|
onTap: () {},
|
||||||
child: KeyedSubtree(
|
child: KeyedSubtree(
|
||||||
key: const Key('player-comments-sheet'),
|
key: const Key('player-comments-sheet'),
|
||||||
child: Container(
|
child: SizedBox(
|
||||||
decoration: const BoxDecoration(
|
key: const Key('comment-sheet-constraints'),
|
||||||
color: AppColors.card,
|
height: sheetHeight,
|
||||||
borderRadius: BorderRadius.vertical(
|
child: Container(
|
||||||
top: Radius.circular(_sheetRadius),
|
decoration: const BoxDecoration(
|
||||||
|
color: AppColors.card,
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.circular(_sheetRadius),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
child: SafeArea(
|
||||||
child: SafeArea(
|
top: false,
|
||||||
top: false,
|
child: ListenableBuilder(
|
||||||
child: ListenableBuilder(
|
listenable: _controller,
|
||||||
listenable: _controller,
|
builder: (context, _) {
|
||||||
builder: (context, _) {
|
return Padding(
|
||||||
final minHeight = _controller.comments.isEmpty
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
? (_minSheetHeight < maxHeight
|
child: _content(
|
||||||
? _minSheetHeight
|
context,
|
||||||
: maxHeight)
|
expanded: expanded,
|
||||||
: 0.0;
|
keyboardHeight: keyboardHeight,
|
||||||
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,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -334,8 +280,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Flexible(
|
Expanded(
|
||||||
fit: FlexFit.loose,
|
|
||||||
child: _list(
|
child: _list(
|
||||||
l10n,
|
l10n,
|
||||||
composerReserve: composerReserve,
|
composerReserve: composerReserve,
|
||||||
@@ -395,7 +340,6 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
|||||||
}
|
}
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
key: const Key('comment-list'),
|
key: const Key('comment-list'),
|
||||||
shrinkWrap: true,
|
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: 4,
|
top: 4,
|
||||||
bottom: composerReserve + keyboardHeight,
|
bottom: composerReserve + keyboardHeight,
|
||||||
|
|||||||
@@ -581,7 +581,7 @@ void main() {
|
|||||||
expect(find.byIcon(Icons.more_horiz_rounded), findsNothing);
|
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.physicalSize = const Size(390, 844);
|
||||||
tester.view.devicePixelRatio = 1;
|
tester.view.devicePixelRatio = 1;
|
||||||
addTearDown(tester.view.resetPhysicalSize);
|
addTearDown(tester.view.resetPhysicalSize);
|
||||||
@@ -589,10 +589,7 @@ void main() {
|
|||||||
final repository = FakeCommentRepository(
|
final repository = FakeCommentRepository(
|
||||||
pages: [
|
pages: [
|
||||||
CommentPage(
|
CommentPage(
|
||||||
comments: [
|
comments: [commentFixture(id: '10', content: 'One comment')],
|
||||||
commentFixture(id: '10', content: 'Short list one'),
|
|
||||||
commentFixture(id: '11', content: 'Short list two'),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -600,14 +597,7 @@ void main() {
|
|||||||
await _pumpSheet(tester, repository: repository);
|
await _pumpSheet(tester, repository: repository);
|
||||||
|
|
||||||
final sheet = find.byKey(const Key('player-comments-sheet'));
|
final sheet = find.byKey(const Key('player-comments-sheet'));
|
||||||
expect(tester.getSize(sheet).height, lessThan(520));
|
expect(tester.getSize(sheet).height, closeTo(844 / 2, 0.1));
|
||||||
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));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_keep_minimum_height_for_empty_state', (tester) async {
|
testWidgets('should_keep_minimum_height_for_empty_state', (tester) async {
|
||||||
@@ -627,7 +617,7 @@ void main() {
|
|||||||
addTearDown(tester.view.resetPhysicalSize);
|
addTearDown(tester.view.resetPhysicalSize);
|
||||||
addTearDown(tester.view.resetDevicePixelRatio);
|
addTearDown(tester.view.resetDevicePixelRatio);
|
||||||
final repository = FakeCommentRepository(
|
final repository = FakeCommentRepository(
|
||||||
pages: [CommentPage(comments: _comments(30))],
|
pages: [CommentPage(comments: _comments(20))],
|
||||||
);
|
);
|
||||||
|
|
||||||
await _pumpSheet(tester, repository: repository);
|
await _pumpSheet(tester, repository: repository);
|
||||||
@@ -649,7 +639,7 @@ void main() {
|
|||||||
expect(position.pixels, greaterThan(0));
|
expect(position.pixels, greaterThan(0));
|
||||||
expect(
|
expect(
|
||||||
tester.getSize(find.byKey(const Key('player-comments-sheet'))).height,
|
tester.getSize(find.byKey(const Key('player-comments-sheet'))).height,
|
||||||
520,
|
closeTo(844 / 2, 0.1),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user