stopou_blocker 0.4.1 copy "stopou_blocker: ^0.4.1" to clipboard
stopou_blocker: ^0.4.1 copied to clipboard

Plugin do Stopou para bloqueio por VPN local (preparado para estratégias futuras).

example/lib/main.dart

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

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Stopou Blocker Demo',
      theme: ThemeData(useMaterial3: true),
      home: const DemoPage(),
    );
  }
}

class DemoPage extends StatefulWidget {
  const DemoPage({super.key});
  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  final _log = <String>[];
  bool _vpnRunning = false;
  bool _keywordBlockerRunning = false;
  bool _hasVpnPermission = false;
  bool _hasAccessibilityPermission = false;
  bool _hasNotificationPermission = false;

  @override
  void initState() {
    super.initState();
    // ✅ Assina o stream de eventos do plugin.
    StopouBlocker.events.listen((e) {
      setState(() {
        _log.add(
          "${e.ts.toIso8601String()}   ${e.protocol.padRight(5)}   ${e.host}   ${e.appPackage ?? ''}",
        );
      });
    });

    // ✅ Verifica status inicial
    _updateStatus();
  }

  Future<void> _updateStatus() async {
    final vpnRunning = await StopouBlocker.isVpnRunning();
    final keywordRunning = await StopouBlocker.isKeywordBlockerRunning();
    final hasVpn = await StopouBlocker.hasVpnPermission();
    final hasAccessibility = await StopouBlocker.hasAccessibilityPermission();
    final hasNotification = await StopouBlocker.hasNotificationPermission();

    setState(() {
      _vpnRunning = vpnRunning;
      _keywordBlockerRunning = keywordRunning;
      _hasVpnPermission = hasVpn;
      _hasAccessibilityPermission = hasAccessibility;
      _hasNotificationPermission = hasNotification;
    });
  }

  void _showAccessibilityInstructions() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('⚠️ Permissão de Acessibilidade'),
        content: const SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Se o Android mostrar "permissão restrita", siga estes passos:',
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 12),
              Text('1. Nas configurações de Acessibilidade, encontre "Stopou"'),
              SizedBox(height: 8),
              Text('2. Toque em "Stopou" para abrir as configurações'),
              SizedBox(height: 8),
              Text(
                '3. Se aparecer aviso de "permissão restrita", toque em "Aprenda a conceder acesso"',
              ),
              SizedBox(height: 8),
              Text('4. Ative o toggle para "Usar Stopou"'),
              SizedBox(height: 8),
              Text('5. Confirme tocando em "OK" quando perguntado'),
              SizedBox(height: 12),
              Text(
                'ℹ️ O Stopou é seguro: apenas detecta palavras específicas e exibe alertas. Não coleta dados pessoais.',
                style: TextStyle(fontStyle: FontStyle.italic),
              ),
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Entendi'),
          ),
          ElevatedButton(
            onPressed: () async {
              Navigator.of(context).pop();
              await StopouBlocker.openAccessibilitySettings();
            },
            child: const Text('Abrir Configurações'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Stopou Blocker Demo'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: _updateStatus,
            tooltip: 'Atualizar Status',
          ),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            // Status Section
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      '📊 Status dos Serviços',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 12),
                    Row(
                      children: [
                        Icon(
                          _vpnRunning
                              ? Icons.vpn_lock
                              : Icons.vpn_lock_outlined,
                          color: _vpnRunning ? Colors.green : Colors.grey,
                        ),
                        const SizedBox(width: 8),
                        Text('VPN: ${_vpnRunning ? "Ativo" : "Inativo"}'),
                      ],
                    ),
                    const SizedBox(height: 8),
                    Row(
                      children: [
                        Icon(
                          _keywordBlockerRunning
                              ? Icons.accessibility
                              : Icons.accessibility_outlined,
                          color: _keywordBlockerRunning
                              ? Colors.green
                              : Colors.grey,
                        ),
                        const SizedBox(width: 8),
                        Text(
                          'Bloqueador Keywords: ${_keywordBlockerRunning ? "Ativo" : "Inativo"}',
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Permissions Section
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      '🔑 Permissões',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 12),

                    ElevatedButton.icon(
                      onPressed: () async {
                        final ok = await StopouBlocker.requestPermission();
                        await _updateStatus();
                        if (mounted) {
                          ScaffoldMessenger.of(context).showSnackBar(
                            SnackBar(content: Text('Permissão VPN: $ok')),
                          );
                        }
                      },
                      icon: Icon(
                        _hasVpnPermission ? Icons.check : Icons.vpn_key,
                      ),
                      label: Text('VPN ${_hasVpnPermission ? "✓" : "✗"}'),
                    ),
                    const SizedBox(height: 8),

                    ElevatedButton.icon(
                      onPressed: () async {
                        final ok =
                            await StopouBlocker.requestAccessibilityPermission();
                        await _updateStatus();
                        if (mounted) {
                          if (!ok) {
                            _showAccessibilityInstructions();
                          } else {
                            ScaffoldMessenger.of(context).showSnackBar(
                              const SnackBar(
                                content: Text('Permissão Acessibilidade: ✓'),
                              ),
                            );
                          }
                        }
                      },
                      icon: Icon(
                        _hasAccessibilityPermission
                            ? Icons.check
                            : Icons.accessibility,
                      ),
                      label: Text(
                        'Acessibilidade ${_hasAccessibilityPermission ? "✓" : "✗"}',
                      ),
                    ),
                    const SizedBox(height: 8),

                    ElevatedButton.icon(
                      onPressed: () async {
                        final ok =
                            await StopouBlocker.requestNotificationPermission();
                        await _updateStatus();
                        if (mounted) {
                          ScaffoldMessenger.of(context).showSnackBar(
                            SnackBar(
                              content: Text('Permissão Notificação: $ok'),
                            ),
                          );
                        }
                      },
                      icon: Icon(
                        _hasNotificationPermission
                            ? Icons.check
                            : Icons.notifications,
                      ),
                      label: Text(
                        'Notificações ${_hasNotificationPermission ? "✓" : "✗"}',
                      ),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Controls Section
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      '🎛️ Controles',
                      style: TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 12),

                    ElevatedButton.icon(
                      onPressed: _vpnRunning
                          ? null
                          : () async {
                              await StopouBlocker.start(
                                blocklist: const ['.bet.br', 'exemplo.com'],
                                logAttempts: true,
                                dnsServers: const ['1.1.1.1', '8.8.8.8'],
                                strategies: const [BlockStrategies.vpn],
                              );
                              await _updateStatus();
                            },
                      icon: const Icon(Icons.play_arrow),
                      label: const Text('Iniciar VPN'),
                    ),
                    const SizedBox(height: 8),

                    ElevatedButton.icon(
                      onPressed: _keywordBlockerRunning
                          ? null
                          : () async {
                              await StopouBlocker.startKeywordBlocker([
                                'bet',
                                'casino',
                                'apostas',
                              ]);
                              await _updateStatus();
                            },
                      icon: const Icon(Icons.block),
                      label: const Text('Iniciar Bloqueador Keywords'),
                    ),
                    const SizedBox(height: 8),

                    ElevatedButton.icon(
                      onPressed: (!_vpnRunning && !_keywordBlockerRunning)
                          ? null
                          : () async {
                              await StopouBlocker.stop();
                              await StopouBlocker.stopKeywordBlocker();
                              await _updateStatus();
                            },
                      icon: const Icon(Icons.stop),
                      label: const Text('Parar Tudo'),
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.red[100],
                      ),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Events Log
            const Align(
              alignment: Alignment.centerLeft,
              child: Text(
                '📝 Log de Eventos:',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
            ),
            const SizedBox(height: 8),
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey.shade300),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: _log.isEmpty
                    ? const Center(
                        child: Text('Nenhum evento registrado ainda...'),
                      )
                    : ListView.builder(
                        itemCount: _log.length,
                        itemBuilder: (_, i) => Padding(
                          padding: const EdgeInsets.symmetric(
                            horizontal: 8,
                            vertical: 4,
                          ),
                          child: Text(
                            _log[_log.length - 1 - i], // Mais recentes primeiro
                            style: const TextStyle(
                              fontFamily: 'monospace',
                              fontSize: 12,
                            ),
                          ),
                        ),
                      ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
0
points
30
downloads

Publisher

unverified uploader

Weekly Downloads

Plugin do Stopou para bloqueio por VPN local (preparado para estratégias futuras).

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on stopou_blocker

Packages that implement stopou_blocker