import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:sxchnge_analytics/sxchnge_analytics.dart'; import 'package:sxchnge_auth/sxchnge_auth.dart'; import 'challenge.dart'; import '../generated/i18n/app_localizations.dart'; class SecuritySettings extends StatefulWidget { const SecuritySettings({super.key}); @override State createState() => _SecuritySettingsState(); } class _SecuritySettingsState extends State { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) context.read().refresh(); }); } Future _change(SecurityProvider p, bool enabled) async { final challenge = await p.prepare(enabled); if (!mounted || challenge == null) return; final grant = await verifyFactor( context, challenge: challenge, service: p.service, recorder: p.recorder, journey: JourneyKind.security, ); if (mounted && grant != null) await p.apply(enabled, grant); } @override Widget build(BuildContext context) { final p = context.watch(); final l = AppLocalizations.of(context)!; final t = Theme.of(context); return Card( child: Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text(l.factorSettings, style: t.textTheme.titleLarge), const SizedBox(height: 12), Text(l.factorSettingsHelp), const SizedBox(height: 16), if (p.busy) const LinearProgressIndicator(), if (p.data != null) ...[ Semantics( liveRegion: true, child: Text( p.data!.enabled ? l.factorOn : l.factorOff, key: const ValueKey('two-factor-status'), style: t.textTheme.titleMedium, ), ), const SizedBox(height: 8), Text( p.data!.method == FactorMethod.email ? l.factorEmailMethod : l.factorAppMethod, ), const SizedBox(height: 16), FilledButton.tonal( key: const ValueKey('two-factor-setting'), onPressed: p.busy ? null : () => _change(p, !p.data!.enabled), child: Text(p.data!.enabled ? l.factorDisable : l.factorEnable), ), ], if (p.error != null) ...[ const SizedBox(height: 12), Semantics( liveRegion: true, child: Text( factorErrorText(l, p.error!), style: TextStyle(color: t.colorScheme.error), ), ), TextButton( onPressed: p.busy ? null : p.refresh, child: Text(l.wRefresh), ), ], ], ), ), ); } }