flutter_chat_paginator 0.0.2 copy "flutter_chat_paginator: ^0.0.2" to clipboard
flutter_chat_paginator: ^0.0.2 copied to clipboard

A powerful and lightweight chat pagination system built for Flutter, designed for smooth infinite scrolling and state management with Riverpod

example/lib/main.dart

import 'package:flutter_chat_paginator/flutter_chat_paginator.dart';
import 'package:easy_bubble_container/easy_bubble_container.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(const ProviderScope(child: ChatApp()));
}

class ChatApp extends ConsumerStatefulWidget {
  const ChatApp({super.key});

  @override
  ConsumerState<ChatApp> createState() => _ChatAppState();
}

class _ChatAppState extends ConsumerState<ChatApp> {
  late final ChatPaginationController controller;
  final TextEditingController textController = TextEditingController();

  @override
  void initState() {
    super.initState();

    controller = ChatPaginationController(
      ref: ref,
      preloadOffset: 5,
      onPageRequestCallback: (pageIndex, pageSize) async {
        await Future.delayed(const Duration(seconds: 2));

        final newMessages = List.generate(
          pageSize,
          (i) => (
            id: 'msg-$pageIndex-$i',
            text: 'Message ${pageIndex + 1}-${pageSize - i}',
            user: i % 2 == 0,
            createdAt: DateTime.now(),
          ),
        );

        controller.addMessages(newMessages, prepend: true);
      },
    );

    controller.loadFirstPage();
  }

  void _sendMessage() {
    final text = textController.text.trim();
    if (text.isEmpty) return;

    final newMessage = (
      id: 'local-${DateTime.now().millisecondsSinceEpoch}',
      text: text,
      user: true,
      createdAt: DateTime.now(),
    );

    controller.addMessage(newMessage);
    textController.clear();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Chat Pagination')),
        body: Column(
          children: [
            Expanded(
              child: ChatPaginationView(
                showLoadingIndicator: true,
                controller: controller,
                itemBuilder: (context, index, message) {
                  final isUser = message.user == true;

                  return _BubbleItem(
                    key: ValueKey(message.id),
                    label: message.text,
                    side: isUser ? BubbleSide.right : BubbleSide.left,
                    color:
                        isUser ? Colors.green.shade50 : Colors.orange.shade50,
                    alignment:
                        isUser ? Alignment.centerRight : Alignment.centerLeft,
                  );
                },

                onItemKey: (index) => controller.messages[index].id,
              ),
            ),

            // 👇 Input area
            SafeArea(
              top: false,
              child: Padding(
                padding: const EdgeInsets.fromLTRB(12, 8, 12, 8),
                child: Row(
                  children: [
                    Expanded(
                      child: TextField(
                        controller: textController,
                        decoration: InputDecoration(
                          hintText: "Type a message...",
                          contentPadding: const EdgeInsets.symmetric(
                            horizontal: 16,
                          ),
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(24),
                          ),
                        ),
                        onSubmitted: (_) => _sendMessage(),
                      ),
                    ),
                    const SizedBox(width: 8),
                    IconButton(
                      icon: const Icon(Icons.send),
                      onPressed: _sendMessage,
                      color: Theme.of(context).primaryColor,
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    textController.dispose();
    super.dispose();
  }
}

class _BubbleItem extends StatelessWidget {
  final String label;
  final BubbleSide side;
  final Color color;
  final AlignmentGeometry alignment;

  const _BubbleItem({
    super.key,
    required this.label,
    required this.side,
    required this.color,
    required this.alignment,
  });

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: alignment,
      child: Padding(
        padding: EdgeInsets.symmetric(vertical: 8),
        child: BubbleContainer(
          side: side,
          color: color,
          borderColor: Colors.transparent,
          arrowSize: 14,
          borderRadius: 12,
          arrowPosition: 9,
          padding: EdgeInsets.all(16),
          child: Text(label, style: Theme.of(context).textTheme.bodyLarge),
        ),
      ),
    );
  }
}
1
likes
160
points
13
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful and lightweight chat pagination system built for Flutter, designed for smooth infinite scrolling and state management with Riverpod

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

easy_bubble_container, flutter, flutter_list_view, flutter_riverpod

More

Packages that depend on flutter_chat_paginator