import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:worldhopper/config/constants.dart'; import 'package:worldhopper/helpers/snackbar_helper.dart'; import 'package:worldhopper/providers/server_provider.dart'; import 'package:worldhopper/providers/connectivity_provider.dart'; import 'package:worldhopper/widgets/server_card.dart'; import 'package:worldhopper/widgets/worldhopper_app_bar.dart'; /// Screen displaying the list of configured OPDS servers class ServerListScreen extends ConsumerWidget { const ServerListScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final serversAsync = ref.watch(serverListProvider); return Scaffold( appBar: const WorldhopperAppBar( title: Text('My Servers'), ), body: serversAsync.when( data: (servers) { if (servers.isEmpty) { return _buildEmptyState(context); } return RefreshIndicator( onRefresh: () async { ref.invalidate(serverListProvider); }, child: ListView.builder( padding: const EdgeInsets.all(16), itemCount: servers.length, itemBuilder: (context, index) { final server = servers[index]; return ServerCard( server: server, onTap: () { // Check connectivity before browsing server final connectivityState = ref.read(connectivityStateProvider); final isOnline = connectivityState.whenOrNull( data: (online) => online, ) ?? true; if (!isOnline) { // Block navigation when offline context.showInfoSnackBar( 'You are offline. Connect to the internet to browse servers.', duration: const Duration(seconds: 3), ); return; } // Navigate to library browser context.push('/browse/${server.id}'); }, onEdit: () { context.push( '${AppConstants.routeEditServer}/${server.id}', ); }, onDelete: () async { final confirmed = await _confirmDelete(context, server.name); if (confirmed) { await ref .read(serverNotifierProvider.notifier) .deleteServer(server.id); if (context.mounted) { context.showInfoSnackBar('${server.name} deleted'); } } }, ); }, ), ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (error, stack) => Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error_outline, size: 48, color: Colors.red), const SizedBox(height: 16), Text('Error loading servers: $error'), const SizedBox(height: 16), ElevatedButton( onPressed: () => ref.invalidate(serverListProvider), child: const Text('Retry'), ), ], ), ), ), floatingActionButton: FloatingActionButton.extended( onPressed: () { context.push(AppConstants.routeAddServer); }, icon: const Icon(Icons.add), label: const Text('Add Server'), ), ); } Widget _buildEmptyState(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.cloud_off, size: 100, color: Theme.of(context).colorScheme.secondary.withValues(alpha: 0.5), ), const SizedBox(height: 24), Text( 'No Servers Yet', style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 32), child: Text( 'Add your first OPDS server to start browsing and reading', textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Theme.of(context) .colorScheme .onSurface .withValues(alpha: 0.7), ), ), ), ], ), ); } Future _confirmDelete(BuildContext context, String serverName) async { final result = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Delete Server'), content: Text('Are you sure you want to delete "$serverName"?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('Cancel'), ), FilledButton( onPressed: () => Navigator.of(context).pop(true), style: FilledButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.error, ), child: const Text('Delete'), ), ], ), ); return result ?? false; } }