@@ -15,6 +15,15 @@ class LazyLoadScrollView extends StatefulWidget {
|
|||||||
/// Called when the [child] reaches the end of the list
|
/// Called when the [child] reaches the end of the list
|
||||||
final AsyncCallback onEndOfPage;
|
final AsyncCallback onEndOfPage;
|
||||||
|
|
||||||
|
/// Called when the list scrolling starts
|
||||||
|
final VoidCallback onPageScrollStart;
|
||||||
|
|
||||||
|
/// Called when the list scrolling ends
|
||||||
|
final VoidCallback onPageScrollEnd;
|
||||||
|
|
||||||
|
/// Called every time the [child] is in-between the list
|
||||||
|
final VoidCallback onInBetweenOfPage;
|
||||||
|
|
||||||
/// The offset to take into account when triggering [onEndOfPage]/[onStartOfPage] in pixels
|
/// The offset to take into account when triggering [onEndOfPage]/[onStartOfPage] in pixels
|
||||||
final double scrollOffset;
|
final double scrollOffset;
|
||||||
|
|
||||||
@@ -27,6 +36,9 @@ class LazyLoadScrollView extends StatefulWidget {
|
|||||||
@required this.child,
|
@required this.child,
|
||||||
this.onStartOfPage,
|
this.onStartOfPage,
|
||||||
this.onEndOfPage,
|
this.onEndOfPage,
|
||||||
|
this.onPageScrollStart,
|
||||||
|
this.onPageScrollEnd,
|
||||||
|
this.onInBetweenOfPage,
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
this.scrollOffset = 100,
|
this.scrollOffset = 100,
|
||||||
}) : assert(child != null),
|
}) : assert(child != null),
|
||||||
@@ -49,12 +61,34 @@ class _LazyLoadScrollViewState extends State<LazyLoadScrollView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool _onNotification(Notification notification) {
|
bool _onNotification(Notification notification) {
|
||||||
|
if (notification is ScrollStartNotification) {
|
||||||
|
if (widget.onPageScrollStart != null) {
|
||||||
|
widget.onPageScrollStart();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (notification is ScrollEndNotification) {
|
||||||
|
if (widget.onPageScrollEnd != null) {
|
||||||
|
widget.onPageScrollEnd();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (notification is ScrollUpdateNotification) {
|
if (notification is ScrollUpdateNotification) {
|
||||||
final pixels = notification.metrics.pixels;
|
final pixels = notification.metrics.pixels;
|
||||||
final extentBefore = notification.metrics.extentBefore;
|
final maxScrollExtent = notification.metrics.maxScrollExtent;
|
||||||
final extentAfter = notification.metrics.extentAfter;
|
final minScrollExtent = notification.metrics.minScrollExtent;
|
||||||
final scrollOffset = widget.scrollOffset;
|
final scrollOffset = widget.scrollOffset;
|
||||||
|
|
||||||
|
if (pixels > (minScrollExtent + scrollOffset) &&
|
||||||
|
pixels < (maxScrollExtent - scrollOffset)) {
|
||||||
|
if (widget.onInBetweenOfPage != null) {
|
||||||
|
widget.onInBetweenOfPage();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final extentBefore = notification.metrics.extentBefore;
|
||||||
|
final extentAfter = notification.metrics.extentAfter;
|
||||||
final scrollingDown = _scrollPosition < pixels;
|
final scrollingDown = _scrollPosition < pixels;
|
||||||
|
|
||||||
if (scrollOffset == null || scrollOffset == 0) {
|
if (scrollOffset == null || scrollOffset == 0) {
|
||||||
|
|||||||
@@ -212,6 +212,8 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
|
|
||||||
bool initialMessageHighlightComplete = false;
|
bool initialMessageHighlightComplete = false;
|
||||||
|
|
||||||
|
bool _inBetweenList = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final streamChannel = StreamChannel.of(context);
|
final streamChannel = StreamChannel.of(context);
|
||||||
@@ -264,7 +266,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
final newMessagesListLength = messages.length;
|
final newMessagesListLength = messages.length;
|
||||||
|
|
||||||
if (_messageListLength != null) {
|
if (_messageListLength != null) {
|
||||||
if (_bottomPaginationActive) {
|
if (_bottomPaginationActive || (_inBetweenList && _upToDate)) {
|
||||||
if (_itemPositionListener.itemPositions.value?.isNotEmpty ==
|
if (_itemPositionListener.itemPositions.value?.isNotEmpty ==
|
||||||
true) {
|
true) {
|
||||||
final first = _itemPositionListener.itemPositions.value.first;
|
final first = _itemPositionListener.itemPositions.value.first;
|
||||||
@@ -288,17 +290,27 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
children: [
|
children: [
|
||||||
LazyLoadScrollView(
|
LazyLoadScrollView(
|
||||||
onStartOfPage: () async {
|
onStartOfPage: () async {
|
||||||
|
_inBetweenList = false;
|
||||||
if (!_upToDate) {
|
if (!_upToDate) {
|
||||||
_topPaginationActive = false;
|
_topPaginationActive = false;
|
||||||
_bottomPaginationActive = true;
|
_bottomPaginationActive = true;
|
||||||
return _paginateData(
|
return _paginateData(
|
||||||
streamChannel, QueryDirection.bottom);
|
streamChannel,
|
||||||
|
QueryDirection.bottom,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEndOfPage: () async {
|
onEndOfPage: () async {
|
||||||
|
_inBetweenList = false;
|
||||||
_topPaginationActive = true;
|
_topPaginationActive = true;
|
||||||
_bottomPaginationActive = false;
|
_bottomPaginationActive = false;
|
||||||
return _paginateData(streamChannel, QueryDirection.top);
|
return _paginateData(
|
||||||
|
streamChannel,
|
||||||
|
QueryDirection.top,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onInBetweenOfPage: () {
|
||||||
|
_inBetweenList = true;
|
||||||
},
|
},
|
||||||
child: ScrollablePositionedList.builder(
|
child: ScrollablePositionedList.builder(
|
||||||
key: ValueKey(initialIndex + initialAlignment),
|
key: ValueKey(initialIndex + initialAlignment),
|
||||||
@@ -803,6 +815,10 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
|
|
||||||
_messageNewListener =
|
_messageNewListener =
|
||||||
streamChannel.channel.on(EventType.messageNew).listen((event) {
|
streamChannel.channel.on(EventType.messageNew).listen((event) {
|
||||||
|
if (_upToDate) {
|
||||||
|
_bottomPaginationActive = false;
|
||||||
|
_topPaginationActive = false;
|
||||||
|
}
|
||||||
if (event.message.user.id == streamChannel.channel.client.state.user.id) {
|
if (event.message.user.id == streamChannel.channel.client.state.user.id) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_scrollController.jumpTo(
|
_scrollController.jumpTo(
|
||||||
|
|||||||
Reference in New Issue
Block a user