disposable_email_validator 0.0.1 copy "disposable_email_validator: ^0.0.1" to clipboard
disposable_email_validator: ^0.0.1 copied to clipboard

A Dart/Flutter package for validating disposable email addresses by checking against a regularly updated list of 4000+ disposable email domains.

example/lib/main.dart

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Disposable Email Validator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const EmailValidatorPage(),
    );
  }
}

class EmailValidatorPage extends StatefulWidget {
  const EmailValidatorPage({Key? key}) : super(key: key);

  @override
  State<EmailValidatorPage> createState() => _EmailValidatorPageState();
}

class _EmailValidatorPageState extends State<EmailValidatorPage> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _validator = DisposableEmailValidator();

  bool _isLoading = false;
  String? _validationResult;
  Color? _resultColor;

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

  Future<void> _prefetchDomains() async {
    try {
      await _validator.fetchDisposableDomains();
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Loaded ${_validator.cachedDomainsCount} domains'),
            backgroundColor: Colors.green,
          ),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Failed to load domains: $e'),
            backgroundColor: Colors.orange,
          ),
        );
      }
    }
  }

  Future<void> _validateEmail() async {
    if (!_formKey.currentState!.validate()) return;

    setState(() {
      _isLoading = true;
      _validationResult = null;
    });

    try {
      final email = _emailController.text.trim();
      final isDisposable = await _validator.isDisposable(
        email,
        throwOnInvalidFormat: true,
      );

      setState(() {
        if (isDisposable) {
          _validationResult = '❌ Disposable email detected!\n'
              'Please use a permanent email address.';
          _resultColor = Colors.red;
        } else {
          _validationResult = '✅ Valid email address!';
          _resultColor = Colors.green;
        }
      });
    } on InvalidEmailFormatException {
      setState(() {
        _validationResult = '⚠️ Invalid email format';
        _resultColor = Colors.orange;
      });
    } on NetworkTimeoutException {
      setState(() {
        _validationResult = '⚠️ Network timeout. Please try again.';
        _resultColor = Colors.orange;
      });
    } catch (e) {
      setState(() {
        _validationResult = '❌ Error: $e';
        _resultColor = Colors.red;
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Disposable Email Validator'),
        elevation: 2,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              const SizedBox(height: 20),
              const Text(
                'Enter an email address to check if it\'s disposable',
                style: TextStyle(fontSize: 16),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 30),
              TextFormField(
                controller: _emailController,
                keyboardType: TextInputType.emailAddress,
                decoration: const InputDecoration(
                  labelText: 'Email Address',
                  hintText: '[email protected]',
                  prefixIcon: Icon(Icons.email),
                  border: OutlineInputBorder(),
                ),
                validator: (value) {
                  if (value == null || value.trim().isEmpty) {
                    return 'Please enter an email address';
                  }
                  return null;
                },
                onFieldSubmitted: (_) => _validateEmail(),
              ),
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: _isLoading ? null : _validateEmail,
                style: ElevatedButton.styleFrom(
                  padding: const EdgeInsets.symmetric(vertical: 16),
                ),
                child: _isLoading
                    ? const SizedBox(
                        height: 20,
                        width: 20,
                        child: CircularProgressIndicator(strokeWidth: 2),
                      )
                    : const Text('Validate Email',
                        style: TextStyle(fontSize: 16)),
              ),
              const SizedBox(height: 30),
              if (_validationResult != null)
                Card(
                  color: _resultColor?.withOpacity(0.1),
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Text(
                      _validationResult!,
                      style: TextStyle(
                        fontSize: 16,
                        color: _resultColor,
                        fontWeight: FontWeight.bold,
                      ),
                      textAlign: TextAlign.center,
                    ),
                  ),
                ),
              const SizedBox(height: 30),
              _buildInfoCard(),
              const SizedBox(height: 20),
              _buildExamplesCard(),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildInfoCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              'Cache Information',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 12),
            _buildInfoRow(
              'Cached Domains',
              _validator.cachedDomainsCount?.toString() ?? 'Not loaded',
            ),
            _buildInfoRow(
              'Cache Valid',
              _validator.isCacheValid ? 'Yes' : 'No',
            ),
            if (_validator.lastFetchTime != null)
              _buildInfoRow(
                'Last Updated',
                _formatDateTime(_validator.lastFetchTime!),
              ),
            const SizedBox(height: 12),
            ElevatedButton.icon(
              onPressed: () async {
                try {
                  await _validator.fetchDisposableDomains();
                  setState(() {});
                  if (mounted) {
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(
                        content: Text('Cache refreshed successfully'),
                        backgroundColor: Colors.green,
                      ),
                    );
                  }
                } catch (e) {
                  if (mounted) {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(
                        content: Text('Failed to refresh: $e'),
                        backgroundColor: Colors.red,
                      ),
                    );
                  }
                }
              },
              icon: const Icon(Icons.refresh),
              label: const Text('Refresh Cache'),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildExamplesCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              'Try These Examples',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 12),
            _buildExampleButton('[email protected]', 'Valid email'),
            _buildExampleButton('[email protected]', 'Disposable'),
            _buildExampleButton('[email protected]', 'Disposable'),
            _buildExampleButton('invalid-email', 'Invalid format'),
          ],
        ),
      ),
    );
  }

  Widget _buildInfoRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(label, style: const TextStyle(fontWeight: FontWeight.w500)),
          Text(value, style: const TextStyle(color: Colors.grey)),
        ],
      ),
    );
  }

  Widget _buildExampleButton(String email, String type) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8.0),
      child: OutlinedButton(
        onPressed: () {
          _emailController.text = email;
          _validateEmail();
        },
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(email),
            Text(
              type,
              style: const TextStyle(fontSize: 12, color: Colors.grey),
            ),
          ],
        ),
      ),
    );
  }

  String _formatDateTime(DateTime dt) {
    return '${dt.hour}:${dt.minute.toString().padLeft(2, '0')} - ${dt.day}/${dt.month}/${dt.year}';
  }
}
3
likes
160
points
97
downloads

Publisher

unverified uploader

Weekly Downloads

A Dart/Flutter package for validating disposable email addresses by checking against a regularly updated list of 4000+ disposable email domains.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, http

More

Packages that depend on disposable_email_validator