flutter_offline_queue_pro 1.0.2 copy "flutter_offline_queue_pro: ^1.0.2" to clipboard
flutter_offline_queue_pro: ^1.0.2 copied to clipboard

Offline-first queue for Flutter with retries, sync, and request fingerprinting.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_offline_queue_pro/flutter_offline_queue_pro.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize the queue
  await OfflineQueue.init(
    baseUrl: 'https://jsonplaceholder.typicode.com',
    debug: true,
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Offline Queue Pro Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  int _pendingCount = 0;

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

  Future<void> _updatePendingCount() async {
    final count = await OfflineQueue.pendingCount;
    setState(() {
      _pendingCount = count;
    });
  }

  void _likePost() async {
    setState(() {
      _counter++;
    });

    // Capture action offline-first
    await OfflineQueue.post(
      '/posts',
      body: {
        'title': 'Awesome Post',
        'body': 'Content of the post',
        'userId': 1,
        'like_count': _counter,
      },
    );

    await _updatePendingCount();

    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
            content: Text('Action captured! It will sync once online.')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Offline Queue Pro'),
        actions: [
          IconButton(
            icon: const Icon(Icons.sync),
            onPressed: () async {
              await OfflineQueue.sync();
              await _updatePendingCount();
            },
          ),
          IconButton(
            icon: const Icon(Icons.delete_sweep),
            onPressed: () async {
              await OfflineQueue.clear();
              await _updatePendingCount();
            },
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Pending Requests in Queue:',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            Text(
              '$_pendingCount',
              style: Theme.of(context).textTheme.displayLarge?.copyWith(
                    color: _pendingCount > 0 ? Colors.orange : Colors.green,
                  ),
            ),
            const SizedBox(height: 32),
            ElevatedButton.icon(
              onPressed: _likePost,
              icon: const Icon(Icons.thumb_up),
              label: const Text('Like Post (Offline-mode supported)'),
              style: ElevatedButton.styleFrom(
                padding:
                    const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
              ),
            ),
            const SizedBox(height: 20),
            StreamBuilder<QueueStatus>(
              stream: OfflineQueue.statusStream,
              builder: (context, snapshot) {
                final status = snapshot.data ?? QueueStatus.idle;
                return Chip(
                  label: Text('Status: ${status.name.toUpperCase()}'),
                  backgroundColor: status == QueueStatus.syncing
                      ? Colors.blue.shade100
                      : Colors.grey.shade200,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _updatePendingCount,
        tooltip: 'Refresh',
        child: const Icon(Icons.refresh),
      ),
    );
  }
}