scrollToBottom method

void scrollToBottom([
  1. Duration? duration,
  2. Curve? curve
])

Scrolls to the bottom of the message list

Implementation

void scrollToBottom([
  Duration? duration,
  Curve? curve,
]) {
  if (_scrollController?.hasClients != true) return;

  // Don't interrupt user's manual scrolling
  // if (_isManuallyScrolling) {
  //   debugPrint('SCROLL BOTTOM CANCELED: User is manually scrolling');
  //   return;
  // }

  // Apply debounce for scrollToBottom to prevent jitter
  // (less strict than for force scroll)
  final now = DateTime.now();
  const minInterval = 200; // ms
  if (now.difference(_lastScrollTime).inMilliseconds < minInterval) {
    debugPrint('SCROLL TO BOTTOM DEBOUNCED: Too soon after last scroll');
    return;
  }
  _lastScrollTime = now;

  // Use slightly longer animation for onNewMessage to reduce jitter
  final effectiveDuration = duration ?? scrollBehaviorConfig.scrollAnimationDuration;
  final effectiveCurve = curve ?? scrollBehaviorConfig.scrollAnimationCurve;

  // Log the animation being used
  debugPrint(
      'SCROLL TO BOTTOM: Using duration=${effectiveDuration.inMilliseconds}ms, curve=${effectiveCurve.runtimeType}');

  try {
    if (paginationConfig.reverseOrder) {
      // In reverse mode, "bottom" is actually the top (0.0)
      _scrollController!.animateTo(
        0.0,
        duration: effectiveDuration,
        curve: effectiveCurve,
      );
    } else {
      // In chronological mode, bottom is maxScrollExtent
      _scrollController!.animateTo(
        _scrollController!.position.maxScrollExtent,
        duration: effectiveDuration,
        curve: effectiveCurve,
      );
    }
  } catch (e) {
    // If we get an error (eg. because widget is disposing), just ignore it
    // This prevents errors when scrolling during state changes
    debugPrint('SCROLL TO BOTTOM ERROR: $e');
  }
}