droido 1.0.3 copy "droido: ^1.0.3" to clipboard
droido: ^1.0.3 copied to clipboard

A lightweight debug-only network inspector for Flutter apps using Dio HTTP client. Features persistent notification UI and clean modern design. Zero impact on release builds.

example/lib/main.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:droido/droido.dart';

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

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

  // Create Dio instance
  final dio = Dio(
    BaseOptions(
      baseUrl: 'http://jsonplaceholder.typicode.com/',
      connectTimeout: const Duration(seconds: 10),
      receiveTimeout: const Duration(seconds: 10),
    ),
  );

  // Initialize Droido
  await Droido.init(
    dio: dio,
    config: const DroidoConfig(
      maxLogs: 500,
      enableNotification: true,
      notificationTitle: 'Droido Example',
    ),
  );

  // Set notification tap callback
  Droido.setNotificationCallback(() {
    navigatorKey.currentState?.push(
      MaterialPageRoute(builder: (_) => const DroidoPanel()),
    );
  });

  runApp(MyApp(dio: dio));
}

class MyApp extends StatelessWidget {
  const MyApp({required this.dio, super.key});

  final Dio dio;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Droido Example',
      navigatorKey: navigatorKey,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: ExampleHomePage(dio: dio),
    );
  }
}

class ExampleHomePage extends StatelessWidget {
  const ExampleHomePage({required this.dio, super.key});

  final Dio dio;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Droido Example'),
        actions: [
          IconButton(
            icon: const Icon(Icons.bug_report),
            onPressed: () {
              Navigator.of(
                context,
              ).push(MaterialPageRoute(builder: (_) => const DroidoPanel()));
            },
            tooltip: 'Open Debug Panel',
          ),
        ],
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          const Text(
            'Network Testing',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 16),
          _buildButton(
            context,
            'GET Request',
            Icons.download,
            Colors.green,
            () => _testGet(context),
          ),
          _buildButton(
            context,
            'POST Request',
            Icons.upload,
            Colors.blue,
            () => _testPost(context),
          ),
          _buildButton(
            context,
            'Failed Request (404)',
            Icons.error,
            Colors.orange,
            () => _testFailed(context),
          ),
          _buildButton(
            context,
            'Multiple Requests',
            Icons.refresh,
            Colors.purple,
            () => _testMultiple(context),
          ),
          const SizedBox(height: 32),
          const Text(
            'Log Management',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 16),
          _buildButton(
            context,
            'Clear Logs',
            Icons.delete,
            Colors.red,
            () => _clearLogs(context),
          ),
          _buildButton(
            context,
            'Show Log Count',
            Icons.info,
            Colors.grey,
            () => _showLogCount(context),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(
    BuildContext context,
    String label,
    IconData icon,
    Color color,
    VoidCallback onPressed,
  ) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: ElevatedButton.icon(
        onPressed: onPressed,
        icon: Icon(icon),
        label: Text(label),
        style: ElevatedButton.styleFrom(
          backgroundColor: color,
          foregroundColor: Colors.white,
          minimumSize: const Size(double.infinity, 56),
        ),
      ),
    );
  }

  Future<void> _testGet(BuildContext context) async {
    try {
      await dio.get('/posts/1');
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('GET request successful')));
      }
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Error: $e')));
      }
    }
  }

  Future<void> _testPost(BuildContext context) async {
    try {
      await dio.post(
        '/posts',
        data: {
          'title': 'Test Post',
          'body': 'This is a test post from Droido example',
          'userId': 1,
        },
      );
      if (context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('POST request successful')),
        );
      }
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Error: $e')));
      }
    }
  }

  Future<void> _testFailed(BuildContext context) async {
    try {
      await dio.get('/posts/99999999');
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Expected 404 error logged')),
        );
      }
    }
  }

  Future<void> _testMultiple(BuildContext context) async {
    ScaffoldMessenger.of(
      context,
    ).showSnackBar(const SnackBar(content: Text('Sending 5 requests...')));

    for (int i = 1; i <= 5; i++) {
      await dio.get('/posts/$i');
    }

    if (context.mounted) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('All requests completed')));
    }
  }

  Future<void> _clearLogs(BuildContext context) async {
    await Droido.clearLogs();
    if (context.mounted) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('Logs cleared')));
    }
  }

  void _showLogCount(BuildContext context) {
    final count = Droido.logCount;
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Log Count'),
        content: Text('Currently tracking $count network requests'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('OK'),
          ),
        ],
      ),
    );
  }
}
7
likes
160
points
0
downloads

Publisher

unverified uploader

Weekly Downloads

A lightweight debug-only network inspector for Flutter apps using Dio HTTP client. Features persistent notification UI and clean modern design. Zero impact on release builds.

Repository (GitHub)
View/report issues

Topics

#debug #network #inspector #dio #logging

Documentation

API reference

License

MIT (license)

Dependencies

dio, flutter, flutter_local_notifications, freezed_annotation, intl, json_annotation, rxdart

More

Packages that depend on droido