mirror of
https://github.com/Iconica-Development/flutter_chat.git
synced 2025-05-19 10:53:51 +02:00
fix: let the chats align to the top
This commit is contained in:
parent
7b3ddc5118
commit
02e668dd6f
1 changed files with 50 additions and 20 deletions
|
@ -249,6 +249,7 @@ class _ChatBody extends HookWidget {
|
||||||
|
|
||||||
var isLoadingOlder = useState(false);
|
var isLoadingOlder = useState(false);
|
||||||
var isLoadingNewer = useState(false);
|
var isLoadingNewer = useState(false);
|
||||||
|
var autoScrollEnabled = useState(true);
|
||||||
|
|
||||||
var messagesStream = useMemoized(
|
var messagesStream = useMemoized(
|
||||||
() => service.getMessages(chatId: chatId),
|
() => service.getMessages(chatId: chatId),
|
||||||
|
@ -317,14 +318,21 @@ class _ChatBody extends HookWidget {
|
||||||
|
|
||||||
var offset = scrollController.offset;
|
var offset = scrollController.offset;
|
||||||
var maxScroll = scrollController.position.maxScrollExtent;
|
var maxScroll = scrollController.position.maxScrollExtent;
|
||||||
|
var threshold = options.paginationControls.scrollOffset;
|
||||||
|
|
||||||
if ((maxScroll - offset) <= options.paginationControls.scrollOffset &&
|
var distanceFromBottom = maxScroll - offset;
|
||||||
!isLoadingOlder.value) {
|
|
||||||
|
if (distanceFromBottom > 50) {
|
||||||
|
autoScrollEnabled.value = false;
|
||||||
|
} else {
|
||||||
|
autoScrollEnabled.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset <= threshold && !isLoadingOlder.value) {
|
||||||
unawaited(loadOlderMessages());
|
unawaited(loadOlderMessages());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset <= options.paginationControls.scrollOffset &&
|
if (distanceFromBottom <= threshold && !isLoadingNewer.value) {
|
||||||
!isLoadingNewer.value) {
|
|
||||||
unawaited(loadNewerMessages());
|
unawaited(loadNewerMessages());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,6 +346,34 @@ class _ChatBody extends HookWidget {
|
||||||
chat,
|
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 (chat == null) {
|
||||||
if (!options.enableLoadingIndicator) return const SizedBox.shrink();
|
if (!options.enableLoadingIndicator) return const SizedBox.shrink();
|
||||||
return options.builders.loadingWidgetBuilder.call(context);
|
return options.builders.loadingWidgetBuilder.call(context);
|
||||||
|
@ -358,17 +394,13 @@ class _ChatBody extends HookWidget {
|
||||||
? options.builders.loadingChatMessageBuilder.call(context)
|
? options.builders.loadingChatMessageBuilder.call(context)
|
||||||
: const SizedBox.shrink();
|
: const SizedBox.shrink();
|
||||||
|
|
||||||
var reversedMessages = messages.reversed.toList();
|
|
||||||
var bubbleChildren = <Widget>[];
|
var bubbleChildren = <Widget>[];
|
||||||
if (reversedMessages.isEmpty) {
|
if (messages.isEmpty) {
|
||||||
bubbleChildren
|
bubbleChildren
|
||||||
.add(ChatNoMessages(isGroupChat: chat?.isGroupChat ?? false));
|
.add(ChatNoMessages(isGroupChat: chat?.isGroupChat ?? false));
|
||||||
} else {
|
} else {
|
||||||
for (var (index, msg) in reversedMessages.indexed) {
|
for (var (index, msg) in messages.indexed) {
|
||||||
var nextIndex = index + 1;
|
var prevMsg = index > 0 ? messages[index - 1] : null;
|
||||||
var prevMsg = nextIndex < reversedMessages.length
|
|
||||||
? reversedMessages[nextIndex]
|
|
||||||
: null;
|
|
||||||
|
|
||||||
bubbleChildren.add(
|
bubbleChildren.add(
|
||||||
ChatBubble(
|
ChatBubble(
|
||||||
|
@ -390,15 +422,13 @@ class _ChatBody extends HookWidget {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Align(
|
child: ListView.builder(
|
||||||
alignment: options.chatAlignment ?? Alignment.bottomCenter,
|
reverse: false,
|
||||||
child: ListView(
|
|
||||||
reverse: true,
|
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
padding: const EdgeInsets.only(top: 24),
|
padding: const EdgeInsets.only(top: 24),
|
||||||
children: listViewChildren,
|
itemCount: listViewChildren.length,
|
||||||
),
|
itemBuilder: (context, index) => listViewChildren[index],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ChatBottomInputSection(
|
ChatBottomInputSection(
|
||||||
|
|
Loading…
Reference in a new issue