network_inspector_pro 0.1.0
network_inspector_pro: ^0.1.0 copied to clipboard
Professional Flutter network debugging with a revolutionary single-class API. Beautiful UI, real-time monitoring, zero configuration. Only one public class - all implementation stays private.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
import 'package:network_inspector_pro/network_inspector_pro.dart';
void main() {
// Setup Dio with interceptor
setupDio();
runApp(const MyApp());
}
void setupDio() {
final dio = Dio();
// Use the new public API - only this class is exposed!
dio.interceptors.add(FlutterNetworkInspector.dioInterceptor);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Network Inspector Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
// Use the new public API - wrap the home page instead
home: FlutterNetworkInspector.wrapApp(const MyHomePage()),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final dio = Dio();
bool _isLoading = false;
String _lastResponse = 'No requests made yet';
@override
void initState() {
super.initState();
// Use the new public API
dio.interceptors.add(FlutterNetworkInspector.dioInterceptor);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme
.of(context)
.colorScheme
.inversePrimary,
title: const Text('Network Inspector Demo'),
actions: [
IconButton(
icon: const Icon(Icons.monitor),
tooltip: 'View Network Inspector',
onPressed: () {
// Show statistics in a dialog instead of navigating
_showStatistics();
},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'🚀 Network Inspector Demo',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
const Text(
'Tap the floating button or the monitor icon to view network requests',
style: TextStyle(color: Colors.grey),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
const Text(
'Test API Calls:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
const SizedBox(height: 16),
_buildButtonGrid(),
const SizedBox(height: 24),
if (_isLoading)
const Center(child: CircularProgressIndicator())
else
Expanded(
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey[300]!),
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Last Response:',
style: TextStyle(fontWeight: FontWeight.w600),
),
const SizedBox(height: 8),
Text(
_lastResponse,
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 12,
),
),
],
),
),
),
),
],
),
),
);
}
Widget _buildButtonGrid() {
return GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
childAspectRatio: 3,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
children: [
_buildApiButton('GET Success', Colors.green, _testGetSuccess),
_buildApiButton('GET Error', Colors.red, _testGetError),
_buildApiButton('POST Data', Colors.blue, _testPostData),
_buildApiButton('PUT Update', Colors.orange, _testPutData),
_buildApiButton('DELETE', Colors.purple, _testDelete),
_buildApiButton('Slow Request', Colors.brown, _testSlowRequest),
_buildApiButton('Multiple Calls', Colors.indigo, _testMultipleCalls),
_buildApiButton('HTTP Package', Colors.teal, _testHttpPackage),
],
);
}
Widget _buildApiButton(String text, Color color, VoidCallback onPressed) {
return ElevatedButton(
onPressed: _isLoading ? null : onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: color,
foregroundColor: Colors.white,
),
child: Text(
text,
style: const TextStyle(fontSize: 12),
textAlign: TextAlign.center,
),
);
}
Future<void> _makeRequest(Future<void> Function() request) async {
setState(() {
_isLoading = true;
_lastResponse = 'Loading...';
});
try {
await request();
} catch (e) {
setState(() {
_lastResponse = 'Error: $e';
});
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> _testGetSuccess() async {
await _makeRequest(() async {
final response = await dio.get(
'https://jsonplaceholder.typicode.com/posts/1');
setState(() {
_lastResponse =
'GET Success (${response.statusCode}): ${response.data.toString()
.substring(0, 100)}...';
});
});
}
Future<void> _testGetError() async {
await _makeRequest(() async {
try {
await dio.get('https://httpstat.us/404');
} on DioException catch (e) {
setState(() {
_lastResponse = 'GET Error (${e.response?.statusCode}): ${e.message}';
});
}
});
}
Future<void> _testPostData() async {
await _makeRequest(() async {
final data = {
'title': 'Network Inspector Test',
'body': 'This is a test POST request from the demo app',
'userId': 1,
};
final response = await dio.post(
'https://jsonplaceholder.typicode.com/posts', data: data);
setState(() {
_lastResponse =
'POST Success (${response.statusCode}): Created post with ID ${response
.data['id']}';
});
});
}
Future<void> _testPutData() async {
await _makeRequest(() async {
final data = {
'id': 1,
'title': 'Updated Title',
'body': 'Updated body content',
'userId': 1,
};
final response = await dio.put(
'https://jsonplaceholder.typicode.com/posts/1', data: data);
setState(() {
_lastResponse = 'PUT Success (${response.statusCode}): Updated post';
});
});
}
Future<void> _testDelete() async {
await _makeRequest(() async {
final response = await dio.delete(
'https://jsonplaceholder.typicode.com/posts/1');
setState(() {
_lastResponse = 'DELETE Success (${response.statusCode}): Post deleted';
});
});
}
Future<void> _testSlowRequest() async {
await _makeRequest(() async {
final response = await dio.get('https://httpbin.org/delay/3');
setState(() {
_lastResponse = 'Slow Request (${response
.statusCode}): Completed after 3 seconds delay';
});
});
}
Future<void> _testMultipleCalls() async {
await _makeRequest(() async {
// Make multiple concurrent requests
final futures = List.generate(5, (index) =>
dio.get('https://jsonplaceholder.typicode.com/posts/${index + 1}')
);
final responses = await Future.wait(futures);
setState(() {
_lastResponse =
'Multiple Calls: Made ${responses.length} concurrent requests';
});
});
}
Future<void> _testHttpPackage() async {
await _makeRequest(() async {
// Note: This demonstrates standard http package usage
// For full interception, consider using Dio
final response = await http.get(
Uri.parse('https://jsonplaceholder.typicode.com/users/1'));
setState(() {
_lastResponse =
'HTTP Package (${response.statusCode}): ${response.body.substring(0,
100)}...\n\nNote: For full request inspection, use Dio with FlutterNetworkInspector.dioInterceptor';
});
});
}
void _showStatistics() {
final stats = FlutterNetworkInspector.getStatistics();
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Network Statistics'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Total Requests: ${stats.totalRequests}'),
Text('Successful: ${stats.successfulRequests}'),
Text('Failed: ${stats.failedRequests}'),
Text('Success Rate: ${stats.successRate.toStringAsFixed(1)}%'),
Text('Avg Response Time: ${stats.averageResponseTime.toStringAsFixed(1)}ms'),
if (stats.totalRequests > 0) ...[
Text('Fastest: ${stats.fastestRequest}ms'),
Text('Slowest: ${stats.slowestRequest}ms'),
],
const SizedBox(height: 16),
const Text('💡 Tip: Use the floating purple button to view detailed request logs!'),
],
),
actions: [
TextButton(
onPressed: () {
FlutterNetworkInspector.clearAllRequests();
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('All requests cleared!')),
);
},
child: const Text('Clear All'),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Close'),
),
],
),
);
}
}