💫 Optimize the chat message animation and performance
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user