mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-18 18:33:49 +02:00
fix: let the chats align to the top
This commit is contained in:
parent
dd70e7344e
commit
100683f554
1 changed files with 50 additions and 20 deletions
|
@ -249,6 +249,7 @@ class _ChatBody extends HookWidget {
|
|||
|
||||
var isLoadingOlder = useState(false);
|
||||
var isLoadingNewer = useState(false);
|
||||
var autoScrollEnabled = useState(true);
|
||||
|
||||
var messagesStream = useMemoized(
|
||||
() => service.getMessages(chatId: chatId),
|
||||
|
@ -320,14 +321,21 @@ class _ChatBody extends HookWidget {
|
|||
|
||||
var offset = scrollController.offset;
|
||||
var maxScroll = scrollController.position.maxScrollExtent;
|
||||
var threshold = options.paginationControls.scrollOffset;
|
||||
|
||||
if ((maxScroll - offset) <= options.paginationControls.scrollOffset &&
|
||||
!isLoadingOlder.value) {
|
||||
var distanceFromBottom = maxScroll - offset;
|
||||
|
||||
if (distanceFromBottom > 50) {
|
||||
autoScrollEnabled.value = false;
|
||||
} else {
|
||||
autoScrollEnabled.value = true;
|
||||
}
|
||||
|
||||
if (offset <= threshold && !isLoadingOlder.value) {
|
||||
unawaited(loadOlderMessages());
|
||||
}
|
||||
|
||||
if (offset <= options.paginationControls.scrollOffset &&
|
||||
!isLoadingNewer.value) {
|
||||
if (distanceFromBottom <= threshold && !isLoadingNewer.value) {
|
||||
unawaited(loadNewerMessages());
|
||||
}
|
||||
}
|
||||
|
@ -341,6 +349,34 @@ class _ChatBody extends HookWidget {
|
|||
chat,
|
||||
]);
|
||||
|
||||
useEffect(
|
||||
() {
|
||||
var disposed = false;
|
||||
|
||||
/// Continuously scroll to the bottom of the chat
|
||||
Future<void> scrollLoop() async {
|
||||
while (!disposed && autoScrollEnabled.value) {
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
if (disposed || !autoScrollEnabled.value) break;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (disposed || !autoScrollEnabled.value) return;
|
||||
if (scrollController.hasClients) {
|
||||
scrollController.jumpTo(
|
||||
scrollController.position.maxScrollExtent,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
unawaited(scrollLoop());
|
||||
|
||||
return () => disposed = true;
|
||||
},
|
||||
[autoScrollEnabled.value],
|
||||
);
|
||||
|
||||
if (chat == null) {
|
||||
if (!options.enableLoadingIndicator) return const SizedBox.shrink();
|
||||
return options.builders.loadingWidgetBuilder.call(context);
|
||||
|
@ -361,17 +397,13 @@ class _ChatBody extends HookWidget {
|
|||
? options.builders.loadingChatMessageBuilder.call(context)
|
||||
: const SizedBox.shrink();
|
||||
|
||||
var reversedMessages = messages.reversed.toList();
|
||||
var bubbleChildren = <Widget>[];
|
||||
if (reversedMessages.isEmpty) {
|
||||
if (messages.isEmpty) {
|
||||
bubbleChildren
|
||||
.add(ChatNoMessages(isGroupChat: chat?.isGroupChat ?? false));
|
||||
} else {
|
||||
for (var (index, msg) in reversedMessages.indexed) {
|
||||
var nextIndex = index + 1;
|
||||
var prevMsg = nextIndex < reversedMessages.length
|
||||
? reversedMessages[nextIndex]
|
||||
: null;
|
||||
for (var (index, msg) in messages.indexed) {
|
||||
var prevMsg = index > 0 ? messages[index - 1] : null;
|
||||
|
||||
bubbleChildren.add(
|
||||
ChatBubble(
|
||||
|
@ -393,15 +425,13 @@ class _ChatBody extends HookWidget {
|
|||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: options.chatAlignment ?? Alignment.bottomCenter,
|
||||
child: ListView(
|
||||
reverse: true,
|
||||
controller: scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
children: listViewChildren,
|
||||
),
|
||||
child: ListView.builder(
|
||||
reverse: false,
|
||||
controller: scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
itemCount: listViewChildren.length,
|
||||
itemBuilder: (context, index) => listViewChildren[index],
|
||||
),
|
||||
),
|
||||
ChatBottomInputSection(
|
||||
|
|
Loading…
Reference in a new issue