network_ninja 1.4.0 copy "network_ninja: ^1.4.0" to clipboard
network_ninja: ^1.4.0 copied to clipboard

A powerful network logger library with floating bubble UI for monitoring API calls in Flutter applications

example/lib/main.dart

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

void main() {
  runApp(const NetworkNinjaExampleApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Network Ninja Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ExampleHomePage(),
    );
  }
}

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

  @override
  State<ExampleHomePage> createState() => _ExampleHomePageState();
}

class _ExampleHomePageState extends State<ExampleHomePage> {
  late final Dio _dio;
  bool _isLoading = false;
  String _lastResponse = '';

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

  void _setupDio() {
    _dio = Dio(
      BaseOptions(
        baseUrl: 'https://httpbin.org',
        connectTimeout: const Duration(seconds: 4),
        receiveTimeout: const Duration(seconds: 4),
        validateStatus: (status) {
          // Accept all status codes to see them in the logs
          return status != null && status < 500;
        },
        headers: {
          'User-Agent': 'NetworkNinja/1.0',
          'Accept': 'application/json',
        },
      ),
    );

    // Add Network Ninja interceptor
    NetworkNinjaController.addInterceptor(_dio);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Network Ninja Example'),
        actions: [
          IconButton(
            icon: const Icon(Icons.bug_report),
            onPressed: () => context.showNetworkNinjaBubble(),
            tooltip: 'Show Network Ninja Bubble',
          ),
          IconButton(
            icon: const Icon(Icons.list),
            onPressed: () => context.showNetworkLogs(),
            tooltip: 'View Network Logs',
          ),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Network Ninja Demo',
                      style: Theme.of(context).textTheme.headlineSmall,
                    ),
                    const SizedBox(height: 8),
                    Text(
                      'This example demonstrates the Network Ninja package features. '
                      'Make some API requests and then check the network logs!',
                      style: Theme.of(context).textTheme.bodyMedium,
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),
            Expanded(
              child: Column(
                children: [
                  _buildApiSection(),
                  const SizedBox(height: 16),
                  _buildResponseSection(),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildApiSection() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('API Requests', style: Theme.of(context).textTheme.titleLarge),
            const SizedBox(height: 16),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _makeGetRequest,
                  icon: const Icon(Icons.download),
                  label: const Text('GET Request'),
                ),
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _makePostRequest,
                  icon: const Icon(Icons.upload),
                  label: const Text('POST Request'),
                ),
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _makePutRequest,
                  icon: const Icon(Icons.edit),
                  label: const Text('PUT Request'),
                ),
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _makeDeleteRequest,
                  icon: const Icon(Icons.delete),
                  label: const Text('DELETE Request'),
                ),
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _makeSlowRequest,
                  icon: const Icon(Icons.timer),
                  label: const Text('Slow Request'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildResponseSection() {
    return Expanded(
      child: Card(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  Text(
                    'Last Response',
                    style: Theme.of(context).textTheme.titleLarge,
                  ),
                  const Spacer(),
                  if (_lastResponse.isNotEmpty)
                    IconButton(
                      icon: const Icon(Icons.clear),
                      onPressed: () => setState(() => _lastResponse = ''),
                      tooltip: 'Clear Response',
                    ),
                ],
              ),
              const SizedBox(height: 8),
              Expanded(
                child: Container(
                  width: double.infinity,
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: Theme.of(
                      context,
                    ).colorScheme.surfaceContainerHighest,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: _isLoading
                      ? const Center(child: CircularProgressIndicator())
                      : _lastResponse.isEmpty
                      ? Center(
                          child: Text(
                            'Make an API request to see the response here',
                            style: Theme.of(context).textTheme.bodyMedium
                                ?.copyWith(
                                  color: Theme.of(context).colorScheme.outline,
                                ),
                          ),
                        )
                      : SingleChildScrollView(
                          child: SelectableText(
                            _lastResponse,
                            style: Theme.of(context).textTheme.bodySmall,
                          ),
                        ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _makeGetRequest() async {
    setState(() => _isLoading = true);
    try {
      final response = await _dio.get(
        '/get',
        queryParameters: {'param1': 'value1', 'param2': 'value2'},
      );
      setState(() {
        _lastResponse = _formatResponse(response);
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _lastResponse = 'Error: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _makePostRequest() async {
    setState(() => _isLoading = true);
    try {
      final response = await _dio.post(
        '/post',
        data: {
          'title': 'Network Ninja Test Post',
          'body': 'This is a test post from Network Ninja example app',
          'userId': 1,
        },
      );
      setState(() {
        _lastResponse = _formatResponse(response);
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _lastResponse = 'Error: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _makePutRequest() async {
    setState(() => _isLoading = true);
    try {
      final response = await _dio.put(
        '/put',
        data: {
          'id': 1,
          'title': 'Updated Network Ninja Test Post',
          'body': 'This post was updated by Network Ninja example app',
          'userId': 1,
        },
      );
      setState(() {
        _lastResponse = _formatResponse(response);
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _lastResponse = 'Error: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _makeDeleteRequest() async {
    setState(() => _isLoading = true);
    try {
      final response = await _dio.delete('/delete');
      setState(() {
        _lastResponse = _formatResponse(response);
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _lastResponse = 'Error: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _makeSlowRequest() async {
    setState(() => _isLoading = true);
    try {
      // Use httpbin's delay endpoint to simulate a slow request
      final response = await _dio.get('/delay/2');
      setState(() {
        _lastResponse = _formatResponse(response);
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _lastResponse = 'Error: $e';
        _isLoading = false;
      });
    }
  }

  String _formatResponse(Response response) {
    return '''
Status: ${response.statusCode}
Headers: ${response.headers.map}
Data: ${response.data}
''';
  }
}
8
likes
150
points
626
downloads

Publisher

verified publisherinfydex.com

Weekly Downloads

A powerful network logger library with floating bubble UI for monitoring API calls in Flutter applications

Repository (GitHub)
View/report issues
Contributing

Documentation

API reference

License

MIT (license)

Dependencies

dio, flutter, intl, url_launcher

More

Packages that depend on network_ninja