flutter_command_pattern 1.0.1 copy "flutter_command_pattern: ^1.0.1" to clipboard
flutter_command_pattern: ^1.0.1 copied to clipboard

A powerful and elegant command pattern implementation for Flutter with pipeline support, observers, and state management.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_command_pattern/flutter_command_pattern.dart';

void main() {
  // Setup global logging pipeline
  CommandPipelineRegistry.addPipeline((context, next) async {
    debugPrint('🚀 Command started: ${context.command.runtimeType}');
    final stopwatch = Stopwatch()..start();

    await next();

    stopwatch.stop();
    debugPrint(
      '✅ Command finished: ${context.command.runtimeType} '
      'in ${stopwatch.elapsedMilliseconds}ms',
    );
  });

  // Setup global error observer
  CommandObserverRegistry.addObserver((context) {
    if (context.state is CommandFailure) {
      debugPrint('❌ Command failed: ${context.error}');
    }
  });

  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Command Pattern Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const LoginPage(),
    );
  }
}

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

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  // Simple login command
  late final _loginCommand = Command(_performLogin);

  // Command with parameters example
  late final _fetchUserCommand = CommandWithParams<String>(_fetchUser);

  Future<void> _performLogin() async {
    await Future.delayed(const Duration(seconds: 2));

    if (_emailController.text.isEmpty || _passwordController.text.isEmpty) {
      throw Exception('Email and password are required');
    }

    if (_emailController.text != 'test@example.com' ||
        _passwordController.text != 'password') {
      throw Exception('Invalid credentials');
    }

    // Success!
  }

  Future<void> _fetchUser(String userId) async {
    await Future.delayed(const Duration(seconds: 1));
    debugPrint('Fetched user: $userId');
  }

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

    // Observe login command
    _loginCommand.observe(
      context,
      onLoading: _showLoadingDialog,
      onSuccess: _onLoginSuccess,
      onFailure: _onLoginFailure,
    );
  }

  void _showLoadingDialog(BuildContext context) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (_) => const Center(
        child: Card(
          child: Padding(
            padding: EdgeInsets.all(32),
            child: CircularProgressIndicator(),
          ),
        ),
      ),
    );
  }

  void _onLoginSuccess(BuildContext context) {
    Navigator.of(context).pop(); // Close loading dialog

    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('Login successful!'),
        backgroundColor: Colors.green,
      ),
    );

    // Navigate to home or fetch user data
    _fetchUserCommand.execute('user123');
  }

  void _onLoginFailure(BuildContext context, Object error) {
    Navigator.of(context).pop(); // Close loading dialog

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('Login failed: $error'),
        backgroundColor: Colors.red,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Command Pattern Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: _emailController,
              decoration: const InputDecoration(
                labelText: 'Email',
                hintText: 'test@example.com',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _passwordController,
              obscureText: true,
              decoration: const InputDecoration(
                labelText: 'Password',
                hintText: 'password',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 24),
            ListenableBuilder(
              listenable: _loginCommand,
              builder: (context, _) {
                return ElevatedButton(
                  onPressed:
                      _loginCommand.isRunning ? null : _loginCommand.execute,
                  style: ElevatedButton.styleFrom(
                    minimumSize: const Size(double.infinity, 48),
                  ),
                  child: Text(
                    _loginCommand.isRunning ? 'Loading...' : 'Login',
                  ),
                );
              },
            ),
            if (_loginCommand.hasError) ...[
              const SizedBox(height: 16),
              Text(
                'Error: ${_loginCommand.error}',
                style: const TextStyle(color: Colors.red),
              ),
            ],
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    _loginCommand.dispose();
    _fetchUserCommand.dispose();
    super.dispose();
  }
}
1
likes
160
points
74
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful and elegant command pattern implementation for Flutter with pipeline support, observers, and state management.

Repository (GitHub)
View/report issues

Topics

#command-pattern #state-management #architecture #pipeline

Documentation

API reference

License

MIT (license)

Dependencies

flutter, meta

More

Packages that depend on flutter_command_pattern