Skip to content

Commit

Permalink
msglist: MessageList now has a scroll to bottom button
Browse files Browse the repository at this point in the history
  • Loading branch information
sirpengi committed Jul 18, 2023
1 parent 71ec0cc commit 013c739
Showing 1 changed file with 49 additions and 2 deletions.
51 changes: 49 additions & 2 deletions lib/widgets/message_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class _MessageListPageState extends State<MessageListPage> {

child: Expanded(
child: MessageList(narrow: widget.narrow))),

ComposeBox(controllerKey: _composeBoxKey, narrow: widget.narrow),
]))));
}
Expand Down Expand Up @@ -97,6 +96,31 @@ class MessageListAppBarTitle extends StatelessWidget {
}
}

class ScrollToBottomButton extends StatelessWidget {
const ScrollToBottomButton({super.key, required this.scrollController, required this.visibleValue});
final ValueNotifier<bool> visibleValue;
final ScrollController scrollController;

Future<void> _navigateToBottom(BuildContext context) async {
scrollController.animateTo(0, duration: const Duration(milliseconds: 300), curve: Curves.easeIn);
}

@override
Widget build(BuildContext context) {
return ValueListenableBuilder<bool>(
builder: (BuildContext context, bool value, Widget? child) {
return (value && child != null) ? child : const SizedBox.shrink();
},
valueListenable: visibleValue,
// TODO: fix hardcoded values for size and style here
child: IconButton(
tooltip: "Scroll to bottom",
icon: const Icon(Icons.expand_circle_down_rounded),
iconSize: 40,
style: IconButton.styleFrom(foregroundColor: const HSLColor.fromAHSL(0.5,240,0.96,0.68).toColor()),
onPressed: () => _navigateToBottom(context)));
}
}

class MessageList extends StatefulWidget {
const MessageList({super.key, required this.narrow});
Expand All @@ -109,6 +133,9 @@ class MessageList extends StatefulWidget {

class _MessageListState extends State<MessageList> {
MessageListView? model;
final ScrollController scrollController = ScrollController();

final ValueNotifier<bool> _scrollToBottomVisibleValue = ValueNotifier<bool>(false);

@override
void didChangeDependencies() {
Expand Down Expand Up @@ -161,7 +188,26 @@ class _MessageListState extends State<MessageList> {
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 760),
child: _buildListView(context))))));
child: NotificationListener<ScrollEndNotification>(
onNotification: (scrollEnd) {
final metrics = scrollEnd.metrics;
if (metrics.atEdge && metrics.pixels == 0) {
_scrollToBottomVisibleValue.value = false;
} else {
_scrollToBottomVisibleValue.value = true;
}
return true;
},
child: Stack(
children: <Widget>[
_buildListView(context),
Container(
alignment: Alignment.bottomRight,
child: ScrollToBottomButton(scrollController: scrollController, visibleValue: _scrollToBottomVisibleValue),
),
]
),
))))));
}

Widget _buildListView(context) {
Expand All @@ -179,6 +225,7 @@ class _MessageListState extends State<MessageList> {
_ => ScrollViewKeyboardDismissBehavior.manual,
},

controller: scrollController,
itemCount: length,
// Setting reverse: true means the scroll starts at the bottom.
// Flipping the indexes (in itemBuilder) means the start/bottom
Expand Down

0 comments on commit 013c739

Please sign in to comment.