scrollToBottomChat method

void scrollToBottomChat({
  1. bool withAnimation = false,
})

Implementation

void scrollToBottomChat({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 maxScrollExtent = position.maxScrollExtent;
    final currentScrollPosition = position.pixels;

    // Don't scroll if there's no content to scroll (maxScrollExtent is 0 or negative)
    if (maxScrollExtent <= 0) return;

    // Don't scroll if already very close to bottom (within 20px) to prevent bounce
    final distanceFromBottom = maxScrollExtent - currentScrollPosition;

    final scrollDistance = distanceFromBottom.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(maxScrollExtent);
    } else {
      // Smooth animation only for small scrolls when explicitly requested
      // Use easeInOut to prevent bounce - it smoothly accelerates and decelerates
      chatScrollController.animateTo(
        maxScrollExtent,
        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();
  });
}