scrollToTopChat method
void
scrollToTopChat(
{ - bool withAnimation = false,
})
Implementation
void scrollToTopChat({bool withAnimation = false}) {
if (!chatScrollController.hasClients || conversation.value == null) {
return;
}
void performScroll() async {
await Future.delayed(const Duration(milliseconds: 150));
if (!chatScrollController.hasClients) return;
final position = chatScrollController.positions.lastOrNull;
if (position == null) return;
final minScrollExtent = position.minScrollExtent;
final currentScrollPosition = position.pixels;
// Don't scroll if there's no content to scroll
if (minScrollExtent >= currentScrollPosition &&
currentScrollPosition <= 0) {
return;
}
// Don't scroll if already very close to top (within 50px) to prevent bounce
const nearTopThreshold = 50.0;
final distanceFromTop = currentScrollPosition - minScrollExtent;
if (distanceFromTop <= nearTopThreshold) return;
final scrollDistance = distanceFromTop.abs();
// For large scroll distances (>1500px) or when animation is not requested,
// use jumpTo for instant, lag-free scrolling
// For small distances with animation requested, use animateTo for smooth UX
const largeScrollThreshold = 1500.0;
if (!withAnimation || scrollDistance > largeScrollThreshold) {
// Instant jump - much faster for large content
chatScrollController.jumpTo(minScrollExtent);
} else {
// Smooth animation only for small scrolls when explicitly requested
// Use easeInOut to prevent bounce - it smoothly accelerates and decelerates
chatScrollController.animateTo(
minScrollExtent,
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOut,
);
}
}
// Try immediately first
performScroll();
// Ensure it happens after layout if needed (for very large content)
WidgetsBinding.instance.addPostFrameCallback((_) {
performScroll();
});
}