flutter_offline_queue_pro 1.0.1
flutter_offline_queue_pro: ^1.0.1 copied to clipboard
A production-grade offline-first networking layer for Flutter. Automatically captures API calls when offline and syncs them with exponential backoff when connectivity returns. Features include request [...]
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),
),
);
}
}