network_inspector_pro 0.1.0 copy "network_inspector_pro: ^0.1.0" to clipboard
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'),
          ),
        ],
      ),
    );
  }
}
0
likes
150
points
4
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

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.

License

MIT (license)

Dependencies

dio, flutter, http

More

Packages that depend on network_inspector_pro