fluxy 1.1.0 copy "fluxy: ^1.1.0" to clipboard
fluxy: ^1.1.0 copied to clipboard

Core engine of the Fluxy framework including UI, state management, HTTP, and motion.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:fluxy/fluxy.dart';
import 'package:fluxy_connectivity/fluxy_connectivity.dart';
import 'package:fluxy_haptics/fluxy_haptics.dart';
import 'package:fluxy_device/fluxy_device.dart';
import 'package:fluxy_logger/fluxy_logger.dart';
import 'package:fluxy_websocket/fluxy_websocket.dart';
import 'package:fluxy_sync/fluxy_sync.dart';
import 'package:fluxy_presence/fluxy_presence.dart';
import 'package:fluxy_geo/fluxy_geo.dart';
import 'core/registry/fluxy_registry.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 1. Setup the registry (The "Right Way")
  Fluxy.registerRegistry(() => registerFluxyPlugins());
  
  // 2. Scan and register all modules
  Fluxy.autoRegister();

  // 3. Manual registration for any custom/local plugins
  Fluxy.register(FluxyHapticsPlugin());
  Fluxy.register(FluxyDevicePlugin());
  Fluxy.register(FluxyLoggerPlugin());

  // 4. POWER ON the engine (Initializes all plugins in strict order)
  await Fluxy.init();
  
  FluxyVault.init(salt: 'fluxy_example_secure_salt_2026'); // Secondary Layer

  runApp(Fluxy.debug(child: FluxyExampleApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return FluxyApp(
      title: 'Fluxy Framework Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const FluxyErrorBoundary(child: HomePage()),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // Reactive state with persistence
  final counter = flux(0, key: 'counter', persist: true, label: 'counter_value');
  final userName = flux('', key: 'user_name', persist: true, label: 'user_name');
  final isConnected = flux(true, key: 'connection_status', label: 'is_connected');
  final connectionType = flux(
    FluxyConnectionType.none,
    key: 'connection_type',
    label: 'connection_type',
    fromJson: (j) => FluxyConnectionType.values.byName(j as String),
  );
  final isAuthenticated = flux(false, key: 'auth_status', label: 'is_authenticated');
  
  Map<String, dynamic>? _savedSnapshot;
  
  // NEW: Resource Management Demo
  final activeUsers = flux(0);
  final resourceStatus = flux('Sleeping');
  late final mockGps = FluxyResource<String>(
    name: 'Industrial GPS Engine',
    onStart: () async {
      resourceStatus.value = 'WAKING UP...';
      await Future.delayed(const Duration(seconds: 1));
      resourceStatus.value = 'ACTIVE (10Hz Polling)';
      return 'GPS_INSTANCE_ID_001';
    },
    onStop: (instance) async {
      resourceStatus.value = 'ENTERING DEEP SLEEP...';
      await Future.delayed(const Duration(milliseconds: 500));
      resourceStatus.value = 'Sleeping';
    },
    idleTimeout: const Duration(seconds: 3), // Faster for demo
  );

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

  void _initializeConnectivity() {
    // The "Right Way": Use the Unified Platform API (Fx.platform)
    final connectivity = Fx.platform.connectivity;
    
    if (connectivity != null) {
      // Set initial values
      isConnected.value = connectivity.isOnline.value;
      connectionType.value = connectivity.connectionType.value;
      
      // Create reactive subscription to connectivity changes
      FluxEffect(() {
        isConnected.value = connectivity.isOnline.value;
        connectionType.value = connectivity.connectionType.value;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Fx.text('Fluxy Framework Demo')
            .style(FxStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold)),
        backgroundColor: Colors.blue.shade600,
        actions: [
          Fx(() => Fx.icon(
                isConnected.value ? Icons.wifi : Icons.wifi_off,
                color: isConnected.value ? Colors.green : Colors.red,
              ))
        ],
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Fx.col(
          gap: 24,
          children: [
            // User Authentication Section
            _buildAuthSection(),
            
            // Counter Demo Section
            _buildCounterSection(),
            
            // Connectivity Demo Section
            _buildConnectivitySection(),
            
            // Storage Demo Section
            _buildStorageSection(),
            
            // Platform Features Section
            _buildPlatformSection(),
            
            // Biometric Section
            _buildBiometricSection(),

            // Industrial Control Center (Kill Switches)
            _buildControlCenterSection(),

            // NEW: Haptics Demo Section
            _buildHapticsSection(),

            // NEW: Device Info Section
            _buildDeviceSection(),

            // NEW: Logger Audit Section
            _buildLoggerSection(),

            // NEW: Real-Time & Advanced Sections
            _buildWebSocketSection(),
            _buildSyncSection(),
            _buildPresenceSection(),
            Fx.feature('geo', child: _buildGeoSection()),
            _buildBridgeSection(),
            _buildResourceSection(),
            _buildObservabilitySection(),
            // NEW: Programmatic Snapshots Demo
            _buildSnapshotSection(),

            Fx.feature('security', child: _buildSecuritySection()),
            _buildStabilitySection(),
          ],
        ),
      ),
    );
  }

  Widget _buildSnapshotSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.teal.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
        border: Border.all(color: Colors.teal.shade200),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Programmatic Snapshots').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.teal.shade800,
            ),
          ),
          Fx.text('Capture the state of all labeled signals and restore it instantly.').muted(),
          Fx.row(
            gap: 12,
            children: [
              Expanded(
                child: Fx.primaryButton(
                  'Capture',
                  onTap: () {
                    _savedSnapshot = FluxRegistry.captureSnapshot();
                    Fx.toast.success('Snapshot Saved Locally');
                  },
                ),
              ),
              Expanded(
                child: Fx.outlineButton(
                  'Restore',
                  onTap: () {
                    if (_savedSnapshot != null) {
                      FluxRegistry.restoreSnapshot(_savedSnapshot!);
                      Fx.toast.info('State Restored');
                    } else {
                      Fx.toast.error('No Snapshot Found');
                    }
                  },
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildWebSocketSection() {
    final ws = Fluxy.use<FluxyWebSocketPlugin>();
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.blue.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
        border: Border.all(color: Colors.blue.shade200),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('WebSocket (Real-Time)').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.blue.shade800,
            ),
          ),
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx(
                () => Fx.text('Status: ${ws.status.value.name.toUpperCase()}')
                    .style(
                      FxStyle(
                        color: ws.status.value == FluxySocketStatus.connected
                            ? Colors.green
                            : Colors.red,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
              ),
              Fx.secondaryButton(
                'Connect',
                onTap: () => ws.connect('wss://echo.websocket.org'),
              ),
            ],
          ),
          Fx.row(
            gap: 12,
            children: [
              Expanded(
                child: Fx.secondaryButton(
                  'Send Hello',
                  onTap: () => ws.send({'type': 'hello', 'data': 'Fluxy Echo'}),
                ),
              ),
              Fx.dangerButton('Disconnect', onTap: ws.disconnect),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildSyncSection() {
    final sync = Fluxy.use<FluxySyncPlugin>();
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.orange.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
        border: Border.all(color: Colors.orange.shade200),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Sync Engine (Offline-First)').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.orange.shade800,
            ),
          ),
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx(() => Fx.text('Pending Tasks: ${sync.pendingCount.value}')),
              Fx(
                () => Fx.text(
                  sync.isSyncing.value ? '🔄 Syncing...' : '✅ Idle',
                ).style(FxStyle(color: Colors.orange.shade700)),
              ),
            ],
          ),
          Fx.primaryButton(
            'Add Mock Task',
            onTap: () {
              sync.queue(
                'POST',
                '/api/profile',
                body: {
                  'name': 'Fluxy User',
                  'ts': DateTime.now().toIso8601String(),
                },
              );
            },
          ),
        ],
      ),
    );
  }

  Widget _buildPresenceSection() {
    final presence = Fluxy.use<FluxyPresencePlugin>();
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.purple.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
        border: Border.all(color: Colors.purple.shade200),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Presence & Collaboration').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.purple.shade800,
            ),
          ),
          Fx(() {
            final userList = presence.users.value;
            return Fx.text('Online Users: ${userList.length}');
          }),
          Fx.row(
            gap: 12,
            children: [
              Fx.secondaryButton(
                'Set Online',
                onTap: () => presence.setOnline(true),
              ),
              Fx.secondaryButton(
                'Set Typing',
                onTap: () => presence.setTyping(true),
              ),
            ],
          ),
          Fx(() {
            final typing = presence.typingUsers.value;
            if (typing.isEmpty) return const SizedBox.shrink();
            return Fx.text('Someone is typing...').style(
              FxStyle(
                fontSize: 12,
                color: Colors.purple,
                fontStyle: FontStyle.italic,
              ),
            );
          }),
        ],
      ),
    );
  }

  Widget _buildGeoSection() {
    final geo = Fluxy.use<FluxyGeoPlugin>();
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.teal.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
        border: Border.all(color: Colors.teal.shade200),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Geo & Geofencing').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.teal.shade800,
            ),
          ),
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx(
                () => Fx.text(
                  geo.isTracking.value ? '🛰️ Tracking On' : '🛰️ Offline',
                ),
              ),
              Fx.secondaryButton(
                geo.isTracking.value ? 'Stop' : 'Start',
                onTap: () async {
                  if (geo.isTracking.value) {
                    geo.stopTracking();
                  } else {
                    try {
                      await geo.startTracking();
                      geo.addGeofence('hq', 0.0, 0.0, 100.0); // Mock Geofence
                    } catch (e) {
                      Fx.toast.error(
                        e.toString().replaceAll('Exception: ', ''),
                      );
                    }
                  }
                },
              ),
            ],
          ),
          Fx(
            () => Fx.col(
              alignItems: CrossAxisAlignment.start,
              children: [
                Fx.text('Lat: ${geo.latitude.value.toStringAsFixed(4)}'),
                Fx.text('Lng: ${geo.longitude.value.toStringAsFixed(4)}'),
                Fx.text(
                  'Active Geofences: ${geo.activeGeofences.value.join(", ")}',
                ).style(
                  FxStyle(
                    color: Colors.teal.shade700,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildBridgeSection() {
    final timerSignal = flux(0);

    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.blue.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Stream Bridge (Async Integration)').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.blue.shade800,
            ),
          ),
          Fx.text(
            'Fluxy bridges native Dart Streams into reactive Signals flawlessly.',
          ),
          Fx.row(
            gap: 12,
            children: [
              Fx.icon(Icons.timer_outlined, color: Colors.blue),
              Fx(
                () =>
                    Fx.text('Live Timer Stream: ${timerSignal.value}s').bold(),
              ),
            ],
          ),
          Fx.primaryButton(
            'START BRIDGE',
            onTap: () {
              // Bridge a standard Dart Stream to a Fluxy Signal
              Stream.periodic(const Duration(seconds: 1), (i) => i + 1)
                  .take(10) // Only for 10 seconds to avoid memory leaks in demo
                  .listen((val) => timerSignal.value = val);

              Fx.toast.info('Stream Bridged for 10s');
            },
          ),
        ],
      ),
    );
  }

  Widget _buildResourceSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.indigo.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
        border: Border.all(color: Colors.indigo.shade100),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Managed Resource (Battery Save)').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.indigo.shade800,
            ),
          ),
          Fx.text('Automatic "Graceful Sleep" when features are unused.'),
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx(
                () => Fx.text('Hardware Status: ${resourceStatus.value}').style(
                  FxStyle(
                    fontWeight: FontWeight.bold,
                    color: resourceStatus.value.contains('ACTIVE')
                        ? Colors.green
                        : Colors.grey,
                  ),
                ),
              ),
              Fx(
                () => Fx.box(
                  style: FxStyle(
                    backgroundColor: Colors.indigo,
                    borderRadius: BorderRadius.circular(20),
                    padding: const EdgeInsets.symmetric(
                      horizontal: 10,
                      vertical: 4,
                    ),
                  ),
                  child: Fx.text(
                    activeUsers.value.toString(),
                  ).color(Colors.white).bold(),
                ),
              ),
            ],
          ),
          Fx.row(
            gap: 10,
            children: [
              Fx.secondaryButton(
                'SIMULATE USER IN',
                onTap: () async {
                  activeUsers.value++;
                  await mockGps.acquire();
                },
              ).expanded(),
              Fx.outlineButton(
                'SIMULATE USER OUT',
                onTap: () {
                  if (activeUsers.value > 0) {
                    activeUsers.value--;
                    mockGps.release();
                  }
                },
              ).expanded(),
            ],
          ),
          Fx.text(
            'Try removing all users and wait 3 seconds to see "Deep Sleep".',
          ).font.xs().muted(),
        ],
      ),
    );
  }

  Widget _buildObservabilitySection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.black,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx.text('Fluxy X-Ray (Observability)').style(
                FxStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                  color: Colors.greenAccent,
                ),
              ),
              Fx.badge(
                child: Fx.text('LIVE').font.xs().bold(),
                color: Colors.red,
              ),
            ],
          ),
          Fx.text('Real-time Signal Churn & Rebuild Audit').color(Colors.grey),

          Fx.box(
            style: FxStyle(
              backgroundColor: Colors.white10,
              borderRadius: BorderRadius.circular(8),
              padding: const EdgeInsets.all(12),
              width: double.infinity,
            ),
            child: Fx(() {
              final signals = FluxyObservability.signalStats;
              final rebuilds = FluxyObservability.rebuildStats;

              if (signals.isEmpty && rebuilds.isEmpty) {
                return Fx.text(
                  'Interact with the app to see metrics...',
                ).color(Colors.grey);
              }

              return Fx.col(
                gap: 8,
                alignItems: CrossAxisAlignment.start,
                children: [
                  Fx.text(
                    'Signal Activity',
                  ).bold().color(Colors.greenAccent).font.xs(),
                  ...signals.entries
                      .take(3)
                      .map(
                        (e) => Fx.row(
                          justify: MainAxisAlignment.spaceBetween,
                          children: [
                            Fx.text(e.key).color(Colors.white70).font.xs(),
                            Fx.text(
                              '${e.value} updates',
                            ).color(Colors.white).bold().font.xs(),
                          ],
                        ),
                      ),
                  const Divider(color: Colors.white24),
                  Fx.text(
                    'Widget Rebuilds',
                  ).bold().color(Colors.orangeAccent).font.xs(),
                  ...rebuilds.entries
                      .take(3)
                      .map(
                        (e) => Fx.row(
                          justify: MainAxisAlignment.spaceBetween,
                          children: [
                            Fx.text(e.key).color(Colors.white70).font.xs(),
                            Fx.text(
                              '${e.value} frames',
                            ).color(Colors.white).bold().font.xs(),
                          ],
                        ),
                      ),
                ],
              );
            }),
          ),

          Fx.row(
            gap: 10,
            children: [
              Fx.outlineButton(
                'CLEAR STATS',
                onTap: FluxyObservability.clear,
              ).expanded(),
              Fx.primaryButton(
                'SIMULATE CHURN',
                onTap: () {
                  // Create a burst of state changes to test the engine
                  for (int i = 0; i < 50; i++) {
                    counter.value++;
                  }
                },
              ).expanded(),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildSecuritySection() {
    final vaultInput = flux('');
    final decryptedData = flux('No data decrypted');

    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.blueGrey.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Industrial Security Vault').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.blueGrey.shade800,
            ),
          ),
          Fx.text('Hardware-backed storage with secondary scrambling.'),
          Fx.input(signal: vaultInput, placeholder: 'Enter secret data...'),
          Fx.row(
            gap: 10,
            children: [
              Fx.primaryButton(
                'SECURE RECORD',
                onTap: () async {
                  if (vaultInput.value.isNotEmpty) {
                    await FluxyVault.write('secret_token', vaultInput.value);
                    Fx.toast.success('Layered Encryption Applied');
                    vaultInput.value = '';
                  }
                },
              ).expanded(),
              Fx.outlineButton(
                'RETRIEVE',
                onTap: () async {
                  final data = await FluxyVault.read('secret_token');
                  decryptedData.value = data ?? 'Not Found';
                },
              ).expanded(),
            ],
          ),
          Fx(
            () => Fx.text(
              'Decrypted: ${decryptedData.value}',
            ).italic().color(Colors.blueGrey.shade700),
          ),
        ],
      ),
    );
  }

  Widget _buildStabilitySection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.orange.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Stability Engine (Crash-Free)').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.orange.shade800,
            ),
          ),
          Fx.text('The framework intercepts crashes to maintain uptime.'),
          Fx.dangerButton(
            'TRIGGER LAYOUT CRASH',
            onTap: () {
              // This would normally cause a red screen
              FluxyError.report(
                'SIMULATED_INDUSTRIAL_FAILURE',
                StackTrace.current,
              );
            },
          ).w(double.infinity),
        ],
      ),
    );
  }

  Widget _buildHapticsSection() {
    final haptics = Fluxy.use<FluxyHapticsPlugin>();
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Haptic Feedback (Sensory)').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.blue.shade800,
            ),
          ),
          Fx.row(
            gap: 12,
            children: [
              Fx.secondaryButton('Light', onTap: haptics.light),
              Fx.secondaryButton('Medium', onTap: haptics.medium),
              Fx.secondaryButton('Heavy', onTap: haptics.heavy),
            ],
          ),
          Fx.row(
            gap: 12,
            children: [
              Fx.successButton('Success', onTap: haptics.success),
              Fx.dangerButton('Error', onTap: haptics.error),
              Fx.primaryButton('Selection', onTap: haptics.selection),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildDeviceSection() {
    final device = Fluxy.use<FluxyDevicePlugin>();
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Device & Environment').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.blue.shade800,
            ),
          ),
          Fx(() => Fx.text('App Version: ${device.appVersion.value}')),
          Fx(() {
            final info = device.meta.value;
            if (info.isEmpty) return Fx.text('Loading device info...');
            return Fx.col(
              alignItems: CrossAxisAlignment.start,
              children: info.entries
                  .map((e) => Fx.text('${e.key}: ${e.value}'))
                  .toList(),
            );
          }),
        ],
      ),
    );
  }

  Widget _buildLoggerSection() {
    final logger = Fluxy.use<FluxyLoggerPlugin>();
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx.text('Logger Audit pipeline').style(
                FxStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                  color: Colors.blue.shade800,
                ),
              ),
              Fx.textButton('Clear', onTap: logger.clear),
            ],
          ),
          Fx.secondaryButton(
            'Generate Log',
            onTap: () {
              logger.sys('User triggered manual log entry', tag: 'EXAMPLE');
            },
          ),
          Fx.box(
            style: FxStyle(
              backgroundColor: Colors.black.withOpacity(0.05),
              borderRadius: BorderRadius.circular(8),
              padding: const EdgeInsets.all(8),
              width: double.infinity,
              height: 150,
            ),
            child: Fx(() {
              final logs = logger.logs.value;
              if (logs.isEmpty) return Fx.text('No logs yet.');
              return ListView.builder(
                itemCount: logs.length,
                itemBuilder: (context, index) {
                  final log =
                      logs[logs.length - 1 - index]; // Show latest first
                  return Fx.text(
                    log,
                  ).style(FxStyle(fontSize: 10, color: Colors.grey.shade800));
                },
              );
            }),
          ),
        ],
      ),
    );
  }

  Widget _buildAuthSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Authentication Demo')
              .style(FxStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue.shade800)),
          Fx(() => Fx.text(
                isAuthenticated.value ? 'Authenticated' : 'Not Authenticated',
              ).style(FxStyle(color: isAuthenticated.value ? Colors.green : Colors.red))),
          Fx.row(
            gap: 12,
            children: [
              Fx.primaryButton('Login', onTap: _handleLogin),
              Fx.dangerButton('Logout', onTap: _handleLogout),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildCounterSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Reactive State Demo')
              .style(FxStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue.shade800)),
          Fx(() => Fx.text('Counter: ${counter.value}')
              .style(FxStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Colors.blue.shade600))),
          Fx.row(
            gap: 12,
            children: [
              Fx.primaryButton(
                'Increment',
                onTap: () {
                  counter.value++;
                  Fluxy.use<FluxyHapticsPlugin>().light();
                  Fluxy.use<FluxyLoggerPlugin>().sys(
                    'Counter incremented to ${counter.value}',
                    tag: 'COUNTER',
                  );
                },
              ),
              Fx.secondaryButton(
                'Decrement',
                onTap: () {
                  counter.value--;
                  Fluxy.use<FluxyHapticsPlugin>().selection();
                },
              ),
              Fx.textButton('Reset', onTap: () => counter.value = 0),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildConnectivitySection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Connectivity Demo').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.blue.shade800,
            ),
          ),
          Fx.row(
            gap: 28,
            children: [
              Fx(
                () => Fx.icon(
                  isConnected.value ? Icons.wifi : Icons.wifi_off,
                  color: isConnected.value ? Colors.green : Colors.red,
                  size: 32,
                ),
              ),
              Fx.col(
                alignItems: CrossAxisAlignment.start,
                children: [
                  Fx(
                    () => Fx.text(
                      isConnected.value ? 'Online' : 'Offline',
                    ).style(FxStyle(fontSize: 20, fontWeight: FontWeight.bold)),
                  ),
                  Fx(
                    () => Fx.text(
                      'Type: ${connectionType.value.name.toUpperCase()}',
                    ).style(FxStyle(color: Colors.grey.shade600)),
                  ),
                ],
              ),
            ],
          ),
          Fx.primaryButton(
            'Re-check Connection',
            onTap: () async {
              final connectivity = Fx.platform.connectivity;
              if (connectivity != null) {
                final result = await connectivity.check();
                Fx.toast.info(
                  'Connection refreshed: ${result ? "Online" : "Offline"}',
                );
              }
            },
          ),
        ],
      ),
    );
  }

  Widget _buildStorageSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Storage Demo')
              .style(FxStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue.shade800)),
          Fx.field(
            label: 'Enter your name',
            signal: userName,
            placeholder: 'Type your name here...',
          ),
          Fx(() => Fx.text('Stored Name: ${userName.value.isEmpty ? 'None' : userName.value}')
              .style(FxStyle(color: Colors.grey.shade700))),
        ],
      ),
    );
  }

  Widget _buildPlatformSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Platform Features')
              .style(FxStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue.shade800)),
          Fx.row(
            gap: 12,
            children: [
              Fx.secondaryButton('Check Permissions', onTap: _checkPermissions),
              Fx.secondaryButton('Get Platform Info', onTap: _getPlatformInfo),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildBiometricSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.grey.shade100,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Biometric Authentication')
              .style(FxStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.blue.shade800)),
          Fx.successButton('Authenticate with Biometrics', onTap: _authenticateWithBiometrics),
        ],
      ),
    );
  }

  Widget _buildControlCenterSection() {
    return Fx.box(
      style: FxStyle(
        backgroundColor: Colors.red.shade50,
        borderRadius: BorderRadius.circular(12),
        padding: const EdgeInsets.all(16),
        border: Border.all(color: Colors.red.shade200),
      ),
      child: Fx.col(
        gap: 12,
        alignItems: CrossAxisAlignment.start,
        children: [
          Fx.text('Industrial Control Center').style(
            FxStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.red.shade900,
            ),
          ),
          Fx.text('Emergency Kill-Switch (Production Safety)').font.xs().bold(),
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx.text('Geo Module'),
              Fx(
                () => Fx.icon(
                  FluxyFeatureToggle.isEnabled('geo')
                      ? Icons.check_circle
                      : Icons.dangerous,
                  color: FluxyFeatureToggle.isEnabled('geo')
                      ? Colors.green
                      : Colors.red,
                ),
              ),
              Fx(
                () => Fx.secondaryButton(
                  FluxyFeatureToggle.isEnabled('geo')
                      ? 'KILL GEO'
                      : 'RESTORE GEO',
                  onTap: () {
                    if (FluxyFeatureToggle.isEnabled('geo')) {
                      FluxyFeatureToggle.kill('geo');
                    } else {
                      FluxyFeatureToggle.restore('geo');
                    }
                  },
                ),
              ),
            ],
          ),
          Fx.row(
            justify: MainAxisAlignment.spaceBetween,
            children: [
              Fx.text('Security Module'),
              Fx(
                () => Fx.icon(
                  FluxyFeatureToggle.isEnabled('security')
                      ? Icons.check_circle
                      : Icons.dangerous,
                  color: FluxyFeatureToggle.isEnabled('security')
                      ? Colors.green
                      : Colors.red,
                ),
              ),
              Fx(
                () => Fx.secondaryButton(
                  FluxyFeatureToggle.isEnabled('security')
                      ? 'KILL SECURITY'
                      : 'RESTORE SECURITY',
                  onTap: () {
                    if (FluxyFeatureToggle.isEnabled('security')) {
                      FluxyFeatureToggle.kill('security');
                    } else {
                      FluxyFeatureToggle.restore('security');
                    }
                  },
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  void _handleLogin() {
    // Simulate login
    userName.value = 'John Doe';
    isAuthenticated.value = true;
    
    Fx.toast.success('Logged in successfully!');
  }

  void _handleLogout() {
    // Simulate logout
    userName.value = '';
    isAuthenticated.value = false;
    
    Fx.toast.error('Logged out successfully!');
  }

  void _checkPermissions() async {
    // Simulate permission checking
    Fx.toast.info('Camera: Granted, Storage: Granted');
  }

  void _getPlatformInfo() async {
    // Simulate platform info
    Fx.toast('Platform: Android, Version: 13');
  }

  void _authenticateWithBiometrics() async {
    // Simulate biometric authentication
    Fx.toast.success('Biometric authentication successful!');
  }
}
3
likes
0
points
1.77k
downloads

Publisher

unverified uploader

Weekly Downloads

Core engine of the Fluxy framework including UI, state management, HTTP, and motion.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

args, crypto, flutter, flutter_secure_storage, flutter_timezone, http, path, path_provider, shared_preferences, timezone, vector_math

More

Packages that depend on fluxy