import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../providers/disk_provider.dart'; import '../../core/theme/app_theme.dart'; class DiskIntegrationScreen extends ConsumerStatefulWidget { const DiskIntegrationScreen({super.key}); @override ConsumerState createState() => _DiskIntegrationScreenState(); } class _DiskIntegrationScreenState extends ConsumerState { @override void initState() { super.initState(); Future.microtask(() => ref.read(diskProvider.notifier).load()); } @override Widget build(BuildContext context) { final state = ref.watch(diskProvider); final notifier = ref.read(diskProvider.notifier); return Scaffold( appBar: AppBar(title: const Text('Облачные диски')), body: state.isLoading ? const Center(child: CircularProgressIndicator()) : ListView( padding: const EdgeInsets.all(16), children: [ Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ const Icon(Icons.cloud, size: 48, color: VoIdeaColors.primary), const SizedBox(height: 12), const Text( 'Подключите облачный диск для сохранения презентаций и экспорта', textAlign: TextAlign.center, ), ], ), ), ), const SizedBox(height: 16), ...state.availableProviders.map((provider) { final connected = state.isConnected(provider); final info = connected ? state.connectedProviders.firstWhere( (p) => p['provider'] == provider, orElse: () => {}, ) : null; final icon = _providerIcon(provider); final label = _providerLabel(provider); return Card( margin: const EdgeInsets.only(bottom: 8), child: ListTile( leading: CircleAvatar( backgroundColor: connected ? VoIdeaColors.success.withOpacity(0.1) : VoIdeaColors.muted.withOpacity(0.1), child: Icon(icon, color: connected ? VoIdeaColors.success : VoIdeaColors.muted), ), title: Text(label), subtitle: connected ? Text( info?['email'] ?? 'Подключён', style: const TextStyle(fontSize: 12), ) : const Text('Не подключён', style: TextStyle(fontSize: 12)), trailing: connected ? TextButton( onPressed: () => _confirmDisconnect(context, notifier, provider), child: const Text('Отключить', style: TextStyle(color: VoIdeaColors.error)), ) : ElevatedButton( onPressed: () => _connect(context, notifier, provider), child: const Text('Подключить'), ), ), ); }), ], ), ); } IconData _providerIcon(String provider) { switch (provider) { case 'google': return Icons.g_mobiledata; case 'yandex': return Icons.cloud; case 'apple': return Icons.apple; default: return Icons.drive_file_rename_outline; } } String _providerLabel(String provider) { switch (provider) { case 'google': return 'Google Диск'; case 'yandex': return 'Яндекс Диск'; case 'apple': return 'iCloud'; default: return provider; } } Future _connect( BuildContext context, DiskNotifier notifier, String provider) async { final url = await notifier.getOAuthUrl(provider); if (url != null && await canLaunchUrl(Uri.parse(url))) { await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication); // After OAuth callback, app returns with code in URL // For simplicity, show a dialog to paste the code if (mounted) _showCodeDialog(context, notifier, provider); } } void _showCodeDialog( BuildContext context, DiskNotifier notifier, String provider) { final controller = TextEditingController(); showDialog( context: context, builder: (ctx) => AlertDialog( title: Text('Подключить ${_providerLabel(provider)}'), content: Column( mainAxisSize: MainAxisSize.min, children: [ const Text('После авторизации вставьте код из URL-параметра'), const SizedBox(height: 12), TextField( controller: controller, decoration: const InputDecoration( labelText: 'Код авторизации', hintText: 'Вставьте code из URL', ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Отмена'), ), ElevatedButton( onPressed: () async { if (controller.text.isNotEmpty) { await notifier.connect(provider, controller.text.trim()); if (ctx.mounted) Navigator.pop(ctx); } }, child: const Text('Подключить'), ), ], ), ); } void _confirmDisconnect( BuildContext context, DiskNotifier notifier, String provider) { showDialog( context: context, builder: (ctx) => AlertDialog( title: Text('Отключить ${_providerLabel(provider)}?'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Отмена'), ), ElevatedButton( onPressed: () { notifier.disconnect(provider); Navigator.pop(ctx); }, child: const Text('Отключить'), ), ], ), ); } }