commonkit 0.1.4 copy "commonkit: ^0.1.4" to clipboard
commonkit: ^0.1.4 copied to clipboard

CommonKit is a lightweight package with widgets, helpers, and extensions to simplify app development. Optimized for mobile, desktop, and web (WASM-compatible), it streamlines network requests, image c [...]

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:commonkit/commonkit.dart';
import 'dart:io' if (dart.library.io) 'dart:io';
import 'package:image_picker/image_picker.dart' if (dart.library.io) 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart' if (dart.library.io) 'package:permission_handler/permission_handler.dart';

/// Initializes the app with global configuration and runs the [CommonKitExampleApp].
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // Initialize storage for non-web platforms (WASM-safe)
  if (!kIsWeb) {
    await StorageHelper.init();
  }

  // Set up global configuration with theme, API base URL, and session data
  await GlobalConfig().init(
    baseUrl: 'https://jsonplaceholder.typicode.com',
    variables: {'apiKey': '12345'},
    isDebugMode: true,
    theme: CommonKitTheme(
      primaryColor: Colors.teal,
      secondaryColor: Colors.grey[800]!,
      accentColor: Colors.tealAccent,
      backgroundColor: Colors.grey[900]!,
      textColor: Colors.white,
      highContrast: true,
      isDarkMode: true,
      borderRadius: 12.0,
      animationDuration: Duration(milliseconds: 400),
    ),
    locale: Locale('en', 'US'),
    apiTimeout: Duration(seconds: 20),
    environment: 'development',
    isAnalyticsEnabled: false,
  );

  runApp(const CommonKitExampleApp());
}

/// The main application demonstrating `commonkit` features.
///
/// This app provides a tabbed interface to test widgets, helpers, extensions, and
/// configurations, with full WASM compatibility for web platforms. Non-web features
/// (e.g., file uploads, directory management) are disabled on web with user-friendly
/// feedback via toasts.
///
/// Run this app to explore:
/// - Themed UI with `CommonKitTheme`
/// - Network requests and image caching
/// - Session management and form validation
/// - Clipboard, animations, and more
class CommonKitExampleApp extends StatelessWidget {
  const CommonKitExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    final theme = GlobalConfig().theme ?? CommonKitTheme();
    return MaterialApp(
      theme: ThemeData(
        primaryColor: theme.primaryColor,
        scaffoldBackgroundColor: theme.backgroundColor,
        textTheme: TextTheme(
          bodyMedium: theme.bodyTextStyle ??
              TextStyle(color: theme.textColor, fontSize: 16),
          titleLarge: theme.headingTextStyle ??
              TextStyle(
                color: theme.textColor,
                fontSize: 20,
                fontWeight: FontWeight.bold,
              ),
        ),
        buttonTheme: ButtonThemeData(
          textTheme: ButtonTextTheme.primary,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(theme.borderRadius),
          ),
        ),
        brightness: theme.isDarkMode ? Brightness.dark : Brightness.light,
      ),
      home: const ExamplePage(),
    );
  }
}

/// A tabbed page showcasing `commonkit` features in an organized, user-friendly way.
///
/// Tabs include:
/// - **Network & Media**: Test network requests, image caching, and file uploads.
/// - **Session & Forms**: Explore session management and form validation.
/// - **System & Utils**: Try directory management, permissions, clipboard, and animations.
///
/// Each feature includes status updates and toasts for clear feedback, with non-web
/// features disabled on WASM platforms.
class ExamplePage extends StatefulWidget {
  const ExamplePage({super.key});

  @override
  State<ExamplePage> createState() => _ExamplePageState();
}

class _ExamplePageState extends State<ExamplePage>
    with SingleTickerProviderStateMixin {
  // Helpers and managers
  final _networkHelper = NetworkHelper();
  final _directoryManager = kIsWeb ? null : DirectoryManager();
  final _sessionManager = SessionManager();
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  String _status = 'Ready';
  bool _isLoading = false;

  // Animation controller for fade effects
  late AnimationController _animationController;
  late Animation<double> _fadeAnimation;

  @override
  void initState() {
    super.initState();
    // Initialize animation for UI effects
    _animationController = AnimationController(
      vsync: this,
      duration: GlobalConfig().theme?.animationDuration ?? Duration(milliseconds: 400),
    );
    _fadeAnimation = CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    );
    _animationController.forward();

    // Preload an image to demonstrate ImageCacheHelper
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _preloadImage();
    });
  }

  @override
  void dispose() {
    _emailController.dispose();
    _animationController.dispose();
    super.dispose();
  }

  /// Preloads a sample image for performance
  Future<void> _preloadImage() async {
    if (!mounted) return;
    setState(() => _status = 'Preloading image...');
    final failed = await ImageCacheHelper.preloadImages(
      ['https://via.placeholder.com/150'],
      context,
      onProgress: (loaded, total) => setState(() => _status = 'Images: $loaded/$total'),
    );
    if (!mounted) return;
    setState(() => _status = failed.isEmpty ? 'Image preloaded' : 'Preload failed: $failed');
    if (failed.isEmpty) {
      showToast(context, message: 'Image Cached');
    }
  }

  /// Tests a network GET request
  Future<void> _testNetwork() async {
    if (!mounted) return;
    setState(() {
      _isLoading = true;
      _status = 'Fetching data...';
    });
    try {
      final data = await _networkHelper.get('/posts/1');
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Title: ${(data['title'] as String).capitalize()}';
      });
      Logger.info('Network test succeeded');
      showToast(context, message: 'Network Success');
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Network Error: $e';
      });
      Logger.error('Network test failed', e);
      showCustomDialog(context, title: 'Error', content: e.toString());
    }
  }

  /// Tests file upload with ImagePicker (non-web only)
  Future<void> _testFileUpload() async {
    if (kIsWeb) {
      setState(() => _status = 'File upload not supported on web');
      showToast(context, message: 'Feature unavailable on web');
      return;
    }
    setState(() {
      _isLoading = true;
      _status = 'Picking image...';
    });
    try {
      final picker = ImagePicker();
      final pickedFile = await picker.pickImage(source: ImageSource.gallery);
      if (pickedFile == null) {
        if (!mounted) return;
        setState(() {
          _isLoading = false;
          _status = 'No image selected';
        });
        return;
      }
      final file = File(pickedFile.path);
      setState(() => _status = 'Uploading...');
      final data = await _networkHelper.post(
        '/upload',
        body: {'title': 'Example Upload'},
        files: [file],
      );
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Upload: $data';
      });
      Logger.info('File upload succeeded');
      showToast(context, message: 'Upload Success');
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Upload Error: $e';
      });
      Logger.error('File upload failed', e);
      showToast(context, message: 'Upload Error');
    }
  }

  /// Tests directory management (non-web only)
  Future<void> _testDirectory() async {
    if (kIsWeb || _directoryManager == null) {
      setState(() => _status = 'Directory management not supported on web');
      showToast(context, message: 'Feature unavailable on web');
      return;
    }
    setState(() {
      _isLoading = true;
      _status = 'Creating directory...';
    });
    try {
      final dir = await _directoryManager.createDirectory('example_dir');
      await _directoryManager.createFile('example_dir/test.txt', content: 'Example');
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Directory: ${dir.path}';
      });
      Logger.info('Directory test succeeded');
      showToast(context, message: 'Directory Created');
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Directory Error: $e';
      });
      Logger.error('Directory test failed', e);
      showToast(context, message: 'Directory Error');
    }
  }

  /// Tests clipboard operations
  Future<void> _testClipboard() async {
    setState(() => _status = 'Testing clipboard...');
    try {
      await ClipboardManager.copy('Example Text');
      final pasted = await ClipboardManager.paste();
      if (!mounted) return;
      setState(() => _status = 'Clipboard: $pasted');
      Logger.info('Clipboard test succeeded');
      showToast(context, message: 'Copied and Pasted');
    } catch (e) {
      if (!mounted) return;
      setState(() => _status = 'Clipboard Error: $e');
      Logger.error('Clipboard test failed', e);
      showToast(context, message: 'Clipboard Error');
    }
  }

  /// Tests permission handling (non-web only)
  Future<void> _testPermission() async {
    if (kIsWeb) {
      setState(() => _status = 'Permissions not supported on web');
      showToast(context, message: 'Feature unavailable on web');
      return;
    }
    setState(() {
      _isLoading = true;
      _status = 'Requesting permission...';
    });
    try {
      final granted = await PermissionManager.request(Permission.storage);
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Permission: ${granted ? "Granted" : "Denied"}';
      });
      Logger.info('Permission test: ${granted ? "Granted" : "Denied"}');
      showCustomDialog(
        context,
        title: 'Permission',
        content: granted ? 'Storage granted' : 'Storage denied',
        negativeText: granted ? null : 'Settings',
        onNegative: granted ? null : () => PermissionManager.openSettings(),
      );
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Permission Error: $e';
      });
      Logger.error('Permission test failed', e);
      showToast(context, message: 'Permission Error');
    }
  }

  /// Tests session management with login/logout
  Future<void> _testSession() async {
    setState(() {
      _isLoading = true;
      _status = 'Logging in...';
    });
    try {
      // Fixed: Use named parameters for login
      await _sessionManager.login(
        username: 'test_user',
        password: 'password123',
      );
      await GlobalConfig().updateSession(
        username: 'test_user',
        token: 'abc123',
        expiry: DateTime.now().add(Duration(days: 1)),
      );
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Logged in as ${GlobalConfig().username}';
      });
      Logger.info('Session test succeeded');
      showToast(context, message: 'Login Success');
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _isLoading = false;
        _status = 'Session Error: $e';
      });
      Logger.error('Session test failed', e);
      showToast(context, message: 'Login Error');
    }
  }

  /// Tests form validation with email input
  Future<void> _testValidation() async {
    if (_formKey.currentState!.validate()) {
      setState(() => _status = 'Email valid: ${_emailController.text}');
      showToast(context, message: 'Validation Success');
    } else {
      setState(() => _status = 'Invalid email');
      showToast(context, message: 'Validation Failed');
    }
  }

  /// Tests image picker widget
  Future<void> _testImagePicker() async {
    if (kIsWeb) {
      setState(() => _status = 'Image picker not supported on web');
      showToast(context, message: 'Feature unavailable on web');
      return;
    }
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => Scaffold(
          appBar: AppBar(title: const Text('Image Picker Test')),
          body: AdvancedImagePicker(
            onImagePicked: (image) {
              if (!mounted) return;
              setState(() => _status = 'Image: $image');
              showToast(context, message: 'Image Picked');
              Navigator.pop(context);
            },
          ),
        ),
      ),
    );
  }

  /// Tests animation helper with a fade effect
  Future<void> _testAnimation() async {
    setState(() => _status = 'Starting animation...');
    _animationController.reset();
    await _animationController.forward();
    if (!mounted) return;
    setState(() => _status = 'Animation completed');
    showToast(context, message: 'Animation Success');
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: Text('CommonKit Demo', style: Theme.of(context).textTheme.titleLarge),
          bottom: TabBar(
            tabs: [
              Tab(text: 'Network & Media'),
              Tab(text: 'Session & Forms'),
              Tab(text: 'System & Utils'),
            ],
          ),
        ),
        body: Stack(
          children: [
            TabBarView(
              children: [
                // Network & Media Tab
                SingleChildScrollView(
                  padding: const EdgeInsets.all(16.0),
                  child: FadeTransition(
                    opacity: _fadeAnimation,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Test network, images, and uploads',
                          style: Theme.of(context).textTheme.titleLarge,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test Network Request',
                          onPressed: _testNetwork,
                          icon: Icons.network_check,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test File Upload',
                          onPressed: _testFileUpload,
                          icon: Icons.upload_file,
                          isDisabled: kIsWeb,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test Image Picker',
                          onPressed: _testImagePicker,
                          icon: Icons.image,
                          isDisabled: kIsWeb,
                        ),
                        SizedBox(height: 16),
                        Image.network(
                          'https://via.placeholder.com/150',
                          width: 150,
                          height: 150,
                          loadingBuilder: (context, child, progress) =>
                          progress == null ? child : CircularProgressIndicator(),
                        ),
                        SizedBox(height: 16),
                        Text('Status: $_status', style: Theme.of(context).textTheme.bodyMedium),
                      ],
                    ),
                  ),
                ),
                // Session & Forms Tab
                SingleChildScrollView(
                  padding: const EdgeInsets.all(16.0),
                  child: FadeTransition(
                    opacity: _fadeAnimation,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Test session and validation',
                          style: Theme.of(context).textTheme.titleLarge,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test Session Login',
                          onPressed: _testSession,
                          icon: Icons.person,
                        ),
                        SizedBox(height: 16),
                        Form(
                          key: _formKey,
                          child: TextFormField(
                            controller: _emailController,
                            decoration: InputDecoration(
                              labelText: 'Email',
                              border: OutlineInputBorder(),
                            ),
                            validator: (value) => Validators.email(value ?? '') != null
                                ? null
                                : 'Invalid email address',
                          ),
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Validate Email',
                          onPressed: _testValidation,
                          icon: Icons.check_circle,
                        ),
                        SizedBox(height: 16),
                        Text('Status: $_status', style: Theme.of(context).textTheme.bodyMedium),
                      ],
                    ),
                  ),
                ),
                // System & Utils Tab
                SingleChildScrollView(
                  padding: const EdgeInsets.all(16.0),
                  child: FadeTransition(
                    opacity: _fadeAnimation,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Test system features and utilities',
                          style: Theme.of(context).textTheme.titleLarge,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test Directory Management',
                          onPressed: _testDirectory,
                          icon: Icons.folder,
                          isDisabled: kIsWeb,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test Permission',
                          onPressed: _testPermission,
                          icon: Icons.security,
                          isDisabled: kIsWeb,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test Clipboard',
                          onPressed: _testClipboard,
                          icon: Icons.copy,
                        ),
                        SizedBox(height: 16),
                        CustomButton(
                          text: 'Test Animation',
                          onPressed: _testAnimation,
                          icon: Icons.animation,
                        ),
                        SizedBox(height: 16),
                        Text('Status: $_status', style: Theme.of(context).textTheme.bodyMedium),
                      ],
                    ),
                  ),
                ),
              ],
            ),
            if (_isLoading)
              LoadingOverlay(
                isLoading: _isLoading,
                // Fixed: Use correct parameter names from CommonKitTheme
                overlayColor: GlobalConfig().theme?.loadingOverlayColor,
                progressIndicatorColor: GlobalConfig().theme?.loadingSpinnerColor,
              ),
          ],
        ),
      ),
    );
  }
}
2
likes
0
points
94
downloads

Publisher

unverified uploader

Weekly Downloads

CommonKit is a lightweight package with widgets, helpers, and extensions to simplify app development. Optimized for mobile, desktop, and web (WASM-compatible), it streamlines network requests, image caching, session management, form validation, and responsive layouts. Features include customizable UI components (LoadingOverlay, CustomButton, Toast), advanced utilities (ImageCacheHelper, NetworkHelper, SessionManager), and extensions (StringExtensions for capitalize, truncate). Null-safe

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_cache_manager, http, image_picker, intl, path_provider, permission_handler, shared_preferences

More

Packages that depend on commonkit