💫 Optimize the chat message animation and performance

This commit is contained in:
2026-01-10 22:56:08 +08:00
parent d443343052
commit 1b2620e957
4 changed files with 218 additions and 212 deletions

View File

@@ -4,9 +4,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/chat/chat_room.dart';
import 'package:island/database/message.dart';
import 'package:island/pods/chat/messages_notifier.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
class RoomScrollManager {
final ScrollController scrollController;
final ListController listController;
final ValueNotifier<double> bottomGradientOpacity;
bool isScrollingToMessage;
final void Function({
@@ -17,6 +19,7 @@ class RoomScrollManager {
RoomScrollManager({
required this.scrollController,
required this.listController,
required this.bottomGradientOpacity,
required this.scrollToMessage,
this.isScrollingToMessage = false,
@@ -30,6 +33,7 @@ RoomScrollManager useRoomScrollManager(
AsyncValue<List<LocalChatMessage>> messagesAsync,
) {
final scrollController = useScrollController();
final listController = useMemoized(() => ListController(), []);
final bottomGradientOpacity = useState(ValueNotifier<double>(0.0));
var isLoading = false;
@@ -43,23 +47,14 @@ RoomScrollManager useRoomScrollManager(
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) {
try {
messagesAsync.when(
data: (messageList) {
if (!scrollController.hasClients) return;
final messageIndex = index;
final totalMessages = messageList.length;
if (messageIndex < 0 || messageIndex >= totalMessages) return;
scrollController.animateTo(
messageIndex * 80.0,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOutCubic,
);
},
loading: () {},
error: (_, _) {},
listController.animateToItem(
index: index,
scrollController: scrollController,
alignment: 0.5,
duration: (estimatedDistance) => Duration(
milliseconds: (estimatedDistance * 0.5).clamp(200, 800).toInt(),
),
curve: (estimatedDistance) => Curves.easeOutCubic,
);
Future.delayed(const Duration(milliseconds: 800), () {
@@ -114,7 +109,7 @@ RoomScrollManager useRoomScrollManager(
bottomGradientOpacity.value.value = (pixels / 500.0).clamp(0.0, 1.0);
},
loading: () {},
error: (_, _) => {},
error: (_, _) {},
);
}
@@ -124,6 +119,7 @@ RoomScrollManager useRoomScrollManager(
return RoomScrollManager(
scrollController: scrollController,
listController: listController,
bottomGradientOpacity: bottomGradientOpacity.value,
scrollToMessage: scrollToMessageWrapper,
isScrollingToMessage: isScrollingToMessage,