avy_debug_panel 1.1.1
avy_debug_panel: ^1.1.1 copied to clipboard
A powerful in-app developer debug console for Flutter apps. Features gesture triggers, logs viewer, network inspector, device info, storage viewer, and feature toggles.
/// Example app demonstrating avy_debug_panel usage.
library;
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:avy_debug_panel/flutter_debug_panel.dart';
void main() {
// Initialize the debug panel
FlutterDebugPanel.init(
enable: true,
enableShake: true,
enableLongPress: true,
enableThreeFingerTap: true,
);
// Register environments for the Environment Switcher
DebugEnvironmentManager.registerAll([
Environment(
id: 'dev',
name: 'Development',
baseUrl: 'https://dev-api.example.com',
socketUrl: 'wss://dev-ws.example.com',
description: 'Development environment',
config: {'timeout': 30000, 'debug': true},
),
Environment(
id: 'staging',
name: 'Staging',
baseUrl: 'https://staging-api.example.com',
socketUrl: 'wss://staging-ws.example.com',
description: 'Staging environment',
config: {'timeout': 20000, 'debug': false},
),
Environment(
id: 'prod',
name: 'Production',
baseUrl: 'https://api.example.com',
socketUrl: 'wss://ws.example.com',
description: 'Production environment',
config: {'timeout': 15000, 'debug': false},
),
]);
// Register providers for State Inspector
DebugStateInspector.registerProvider(
id: 'counter_state',
name: 'Counter State',
stateType: StateManagementType.custom,
initialValue: '0',
);
DebugStateInspector.registerProvider(
id: 'user_state',
name: 'User State',
stateType: StateManagementType.provider,
initialValue: 'null',
);
// Register some feature flags
DebugFeatureFlags.register(
'new_checkout',
'New Checkout Flow',
description: 'Enable the redesigned checkout experience',
category: 'Commerce',
defaultValue: false,
);
DebugFeatureFlags.register(
'dark_mode',
'Dark Mode',
description: 'Enable dark mode theme',
category: 'UI',
defaultValue: false,
);
DebugFeatureFlags.register(
'analytics',
'Analytics',
description: 'Enable analytics tracking',
defaultValue: true,
);
DebugFeatureFlags.register(
'beta_features',
'Beta Features',
description: 'Enable beta features',
category: 'Experimental',
defaultValue: false,
);
// Wrap the app with the debug panel
runApp(
FlutterDebugPanel.wrap(
const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Debug Panel Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final Dio _dio = Dio();
int _counter = 0;
@override
void initState() {
super.initState();
// Add the debug network interceptor
_dio.interceptors.add(DebugNetworkInterceptor());
}
void _incrementCounter() {
final previousValue = _counter;
setState(() {
_counter++;
});
// Log the counter change
DebugLogger.log(
'Counter incremented to $_counter',
level: LogLevel.info,
tag: 'Counter',
);
// Log state change for State Inspector
DebugStateInspector.logChange(
providerId: 'counter_state',
previousValue: previousValue.toString(),
newValue: _counter.toString(),
description: 'Counter incremented',
);
}
Future<void> _makeApiRequest() async {
DebugLogger.log('Making API request...', tag: 'Network');
try {
final response = await _dio.get('https://jsonplaceholder.typicode.com/posts/1');
DebugLogger.log(
'API request successful: ${response.statusCode}',
level: LogLevel.info,
tag: 'Network',
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('API request successful: ${response.statusCode}'),
backgroundColor: Colors.green,
),
);
}
} catch (e) {
DebugLogger.log(
'API request failed: $e',
level: LogLevel.error,
tag: 'Network',
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('API request failed: $e'),
backgroundColor: Colors.red,
),
);
}
}
}
Future<void> _makePostRequest() async {
DebugLogger.log('Making POST request...', tag: 'Network');
try {
final response = await _dio.post(
'https://jsonplaceholder.typicode.com/posts',
data: {
'title': 'Test Post',
'body': 'This is a test post body',
'userId': 1,
},
);
DebugLogger.log(
'POST request successful: ${response.statusCode}',
level: LogLevel.info,
tag: 'Network',
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('POST request successful: ${response.statusCode}'),
backgroundColor: Colors.green,
),
);
}
} catch (e) {
DebugLogger.log(
'POST request failed: $e',
level: LogLevel.error,
tag: 'Network',
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('POST request failed: $e'),
backgroundColor: Colors.red,
),
);
}
}
}
void _logMessages() {
DebugLogger.debug('This is a debug message', tag: 'Demo');
DebugLogger.info('This is an info message', tag: 'Demo');
DebugLogger.warning('This is a warning message', tag: 'Demo');
DebugLogger.error('This is an error message', tag: 'Demo');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Log messages added! Check the Logs tab.'),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Debug Panel Demo'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Flutter Debug Panel Demo',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
const Text(
'Long press, shake, or triple-tap to open debug panel',
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
Text(
'Counter: $_counter',
style: const TextStyle(fontSize: 48),
),
const SizedBox(height: 32),
Wrap(
spacing: 12,
runSpacing: 12,
alignment: WrapAlignment.center,
children: [
ElevatedButton.icon(
onPressed: _incrementCounter,
icon: const Icon(Icons.add),
label: const Text('Increment'),
),
ElevatedButton.icon(
onPressed: _makeApiRequest,
icon: const Icon(Icons.http),
label: const Text('GET Request'),
),
ElevatedButton.icon(
onPressed: _makePostRequest,
icon: const Icon(Icons.upload),
label: const Text('POST Request'),
),
ElevatedButton.icon(
onPressed: _logMessages,
icon: const Icon(Icons.article),
label: const Text('Log Messages'),
),
],
),
const SizedBox(height: 32),
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
const Text(
'Feature Flags Status',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
_buildFlagStatus('new_checkout'),
_buildFlagStatus('dark_mode'),
_buildFlagStatus('analytics'),
_buildFlagStatus('beta_features'),
],
),
),
],
),
),
),
);
}
Widget _buildFlagStatus(String key) {
final flag = DebugFeatureFlags.getFlag(key);
if (flag == null) return const SizedBox.shrink();
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 12,
height: 12,
decoration: BoxDecoration(
color: flag.isEnabled ? Colors.green : Colors.grey,
shape: BoxShape.circle,
),
),
const SizedBox(width: 8),
Text(flag.name),
const SizedBox(width: 8),
Text(
flag.isEnabled ? 'Enabled' : 'Disabled',
style: TextStyle(
color: flag.isEnabled ? Colors.green : Colors.grey,
fontSize: 12,
),
),
],
),
);
}
}