|
| 1 | +import 'dart:math'; |
| 2 | + |
1 | 3 | import 'package:flutter/material.dart'; |
2 | 4 |
|
3 | 5 | import '../api/exception.dart'; |
@@ -416,20 +418,21 @@ void showEmojiPickerSheet({ |
416 | 418 | // on my iPhone 13 Pro but is marked as "much slower": |
417 | 419 | // https://api.flutter.dev/flutter/dart-ui/Clip.html |
418 | 420 | clipBehavior: Clip.antiAlias, |
| 421 | + // This does remove the bottom inset. |
| 422 | + // Leave it to the descendent [ListView]. |
419 | 423 | useSafeArea: true, |
420 | 424 | isScrollControlled: true, |
421 | 425 | builder: (BuildContext context) { |
422 | | - return SafeArea( |
423 | | - child: Padding( |
424 | | - // By default, when software keyboard is opened, the ListView |
425 | | - // expands behind the software keyboard — resulting in some |
426 | | - // list entries being covered by the keyboard. Add explicit |
427 | | - // bottom padding the size of the keyboard, which fixes this. |
428 | | - padding: EdgeInsets.only(bottom: MediaQuery.viewInsetsOf(context).bottom), |
429 | | - // For _EmojiPickerItem, and RealmContentNetworkImage used in ImageEmojiWidget. |
430 | | - child: PerAccountStoreWidget( |
431 | | - accountId: store.accountId, |
432 | | - child: EmojiPicker(pageContext: pageContext, message: message)))); |
| 426 | + return Padding( |
| 427 | + // By default, when software keyboard is opened, the ListView |
| 428 | + // expands behind the software keyboard — resulting in some |
| 429 | + // list entries being covered by the keyboard. Add explicit |
| 430 | + // bottom padding the size of the keyboard, which fixes this. |
| 431 | + padding: EdgeInsets.only(bottom: MediaQuery.viewInsetsOf(context).bottom), |
| 432 | + // For _EmojiPickerItem, and RealmContentNetworkImage used in ImageEmojiWidget. |
| 433 | + child: PerAccountStoreWidget( |
| 434 | + accountId: store.accountId, |
| 435 | + child: EmojiPicker(pageContext: pageContext, message: message))); |
433 | 436 | }); |
434 | 437 | } |
435 | 438 |
|
@@ -494,6 +497,7 @@ class _EmojiPickerState extends State<EmojiPicker> with PerAccountStoreAwareStat |
494 | 497 | Widget build(BuildContext context) { |
495 | 498 | final zulipLocalizations = ZulipLocalizations.of(context); |
496 | 499 | final designVariables = DesignVariables.of(context); |
| 500 | + final mediaQuery = MediaQuery.of(context); |
497 | 501 |
|
498 | 502 | return Column(children: [ |
499 | 503 | Padding(padding: const EdgeInsetsDirectional.only(start: 8, top: 4), |
@@ -530,13 +534,22 @@ class _EmojiPickerState extends State<EmojiPicker> with PerAccountStoreAwareStat |
530 | 534 | Expanded(child: InsetShadowBox( |
531 | 535 | top: 8, bottom: 8, |
532 | 536 | color: designVariables.bgContextMenu, |
533 | | - child: ListView.builder( |
534 | | - padding: const EdgeInsets.symmetric(vertical: 8), |
535 | | - itemCount: _resultsToDisplay.length, |
536 | | - itemBuilder: (context, i) => EmojiPickerListEntry( |
537 | | - pageContext: widget.pageContext, |
538 | | - emoji: _resultsToDisplay[i].candidate, |
539 | | - message: widget.message)))), |
| 537 | + child: MediaQuery.removePadding( |
| 538 | + context: context, |
| 539 | + // The bottom is padded below with `padding` within the [ListView]. |
| 540 | + removeBottom: true, |
| 541 | + child: ListView.builder( |
| 542 | + padding: EdgeInsets.only( |
| 543 | + top: 8, |
| 544 | + // This mimics the behavior of [SafeArea.minimum], but with |
| 545 | + // the underlying [SliverPadding] added by [ListView], so that we |
| 546 | + // can always scroll past the shadow and the device bottom padding. |
| 547 | + bottom: max(8, mediaQuery.padding.bottom)), |
| 548 | + itemCount: _resultsToDisplay.length, |
| 549 | + itemBuilder: (context, i) => EmojiPickerListEntry( |
| 550 | + pageContext: widget.pageContext, |
| 551 | + emoji: _resultsToDisplay[i].candidate, |
| 552 | + message: widget.message))))), |
540 | 553 | ]); |
541 | 554 | } |
542 | 555 | } |
|
0 commit comments