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

Powerful in-app debug console for Flutter apps with network inspector, storage monitor, and password protection

example/lib/main.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:logarte/logarte.dart';
import 'package:share_plus/share_plus.dart';

final Logarte logarte = Logarte(
  onShare: Share.share,
  onExport: Share.share,
  password: '1234',
  customTab: const MyCustomTab(),
  onRocketDoubleTapped: (context) {
    showDialog(
      context: context,
      builder: (context) {
        return const AlertDialog(
          title: Text(
            'onRocketDoubleTapped',
          ),
          content: Text(
            'This callback is useful when you want to quickly access some pages or perform actions without leaving the currently page (toggle theme, change language and etc.).',
          ),
        );
      },
    );
  },
  onRocketLongPressed: (context) {
    showDialog(
      context: context,
      builder: (context) {
        return const AlertDialog(
          title: Text(
            'onRocketLongPressed',
          ),
          content: Text(
            'This callback is useful when you want to quickly access some pages or perform actions without leaving the currently page (toggle theme, change language and etc.).',
          ),
        );
      },
    );
  },
);

enum Environment { dev, prod }

const Environment environment = Environment.dev;

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Logarte Example',
      debugShowCheckedModeBanner: false,
      themeMode: ThemeMode.dark,
      theme: ThemeData(
        useMaterial3: true,
        colorSchemeSeed: Colors.blueGrey.shade900,
      ),
      navigatorObservers: [
        LogarteNavigatorObserver(logarte),
      ],
      home: const HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => HomePageState();
}

class HomePageState extends State<HomePage> {
  late final Dio _dio;

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

    _dio = Dio()
      ..interceptors.add(
        LogarteDioInterceptor(logarte),
      );

    logarte.attach(
      context: context,
      visible: false,
    );
  }

  @override
  void dispose() {
    _dio.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Logarte Example'),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.symmetric(horizontal: 16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const SizedBox(height: 16),
            LogarteMagicalTap(
              logarte: logarte,
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.blueGrey.shade50,
                  borderRadius: BorderRadius.circular(12),
                ),
                child: const ListTile(
                  leading: Icon(Icons.touch_app_rounded),
                  title: Text('LogarteMagicalTap'),
                  subtitle: Text(
                    'Tap 10 times to attach the magical button.',
                  ),
                ),
              ),
            ),
            ListTile(
              leading: const Icon(Icons.dashboard_outlined),
              title: const Text('Logarte console'),
              subtitle: const Text(
                'Tap to open the console directly.',
              ),
              onTap: () {
                logarte.openConsole(context);
              },
            ),
            const Divider(
              height: 40,
            ),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'HTTP Requests',
                  style: Theme.of(context).textTheme.titleMedium,
                ),
                const SizedBox(height: 12),
                FilledButton.tonal(
                  onPressed: () async {
                    await _dio
                        .get('https://jsonplaceholder.typicode.com/posts');
                  },
                  child: const Text('GET'),
                ),
                FilledButton.tonal(
                  onPressed: () async {
                    await _dio.post(
                      'https://jsonplaceholder.typicode.com/posts',
                      data: {
                        'title': 'Logarte Test Post',
                        'body': 'This is a test post body',
                        'userId': 1,
                      },
                    );
                  },
                  child: const Text('POST'),
                ),
                FilledButton.tonal(
                  onPressed: () async {
                    await _dio
                        .put('https://jsonplaceholder.typicode.com/posts');
                  },
                  child: const Text('PUT'),
                ),
                FilledButton.tonal(
                  onPressed: () async {
                    await _dio
                        .delete('https://jsonplaceholder.typicode.com/posts');
                  },
                  child: const Text('DELETE'),
                ),
              ],
            ),
            const Divider(
              height: 40,
            ),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Other logs',
                  style: Theme.of(context).textTheme.titleMedium,
                ),
                const SizedBox(height: 12),
                FilledButton.tonalIcon(
                  onPressed: () {
                    logarte.database(
                      target: 'language',
                      value: 'en',
                      source: 'SharedPreferences',
                    );
                  },
                  label: const Text('Write to database'),
                  icon: const Icon(Icons.storage_outlined),
                ),
                FilledButton.tonalIcon(
                  onPressed: () {
                    showDialog(
                      context: context,
                      routeSettings: const RouteSettings(
                        name: '/test-dialog',
                      ),
                      builder: (BuildContext context) {
                        return const AlertDialog(
                          title: Text('Dialog'),
                          content: Text(
                            'Opening of this dialog was logged to Logarte',
                          ),
                        );
                      },
                    );
                  },
                  label: const Text('Open dialog'),
                  icon: const Icon(Icons.open_in_new),
                ),
                FilledButton.tonalIcon(
                  onPressed: () {
                    try {
                      throw Exception('Exception');
                    } catch (e, s) {
                      logarte.log(e, stackTrace: s);
                    }
                  },
                  label: const Text('Exception'),
                  icon: const Icon(Icons.error_outline),
                ),
                FilledButton.tonalIcon(
                  onPressed: () {
                    logarte.log('Printed to console');
                  },
                  label: const Text('Plain log'),
                  icon: const Icon(Icons.print_outlined),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  State<MyCustomTab> createState() => _MyCustomTabState();
}

class _MyCustomTabState extends State<MyCustomTab> {
  Environment _environment = environment;

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          ListTile(
            contentPadding: EdgeInsets.zero,
            leading: const Icon(Icons.settings_outlined),
            title: const Text('Environment'),
            trailing: DropdownButton<Environment>(
              padding: EdgeInsets.zero,
              value: _environment,
              onChanged: (value) {
                setState(() {
                  _environment = value!;
                });
              },
              items: Environment.values.map((e) {
                return DropdownMenuItem(
                  value: e,
                  child: Text(e.name.toUpperCase()),
                );
              }).toList(),
            ),
          ),
          ListTile(
            contentPadding: EdgeInsets.zero,
            leading: const Icon(Icons.notifications_outlined),
            title: const Text('FCM token'),
            subtitle: const Text(
              'dJkH8Hs9_dKpQm2nLxY:APA91bGj8g_QxL3xJ2K9pQm2nLxYdJkH8Hs9_dKpQm2nLxY',
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
            ),
            trailing: TextButton(
              onPressed: () {},
              child: const Text('Copy'),
            ),
          ),

          // Cache size and clear button
          ListTile(
            contentPadding: EdgeInsets.zero,
            leading: const Icon(Icons.storage_outlined),
            title: const Text('Local cache'),
            subtitle: const Text('100 MB'),
            trailing: TextButton(
              onPressed: () {},
              child: const Text('Clear All'),
            ),
          ),

          const SizedBox(height: 16),
          TextField(
            controller: TextEditingController(
              text: 'https://api.example.com/v3/',
            ),
            decoration: const InputDecoration(
              labelText: 'API URL',
              filled: true,
            ),
          ),
        ],
      ),
    );
  }
}
225
likes
120
points
3.99k
downloads

Publisher

verified publisherkamranbekirov.com

Weekly Downloads

Powerful in-app debug console for Flutter apps with network inspector, storage monitor, and password protection

Homepage
Repository (GitHub)
View/report issues

Topics

#logging #debugger

Documentation

API reference

License

MIT (license)

Dependencies

dio, flutter

More

Packages that depend on logarte