feat: enhance library selection UI with refresh functionality and error handling

This commit is contained in:
Dr.Blank 2025-04-19 15:27:21 +05:30
parent 90111551d0
commit 6ce4537985
No known key found for this signature in database
GPG key ID: BA5F87FF0560C57B
3 changed files with 96 additions and 38 deletions

View file

@ -24,6 +24,7 @@ Future<Library?> currentLibrary(Ref ref, String id) async {
_logger.warning('No library found in the list of libraries'); _logger.warning('No library found in the list of libraries');
return null; return null;
} }
_logger.fine('Fetched library: ${library}');
return library.library; return library.library;
} }
@ -37,6 +38,7 @@ class Libraries extends _$Libraries {
_logger.warning('Failed to fetch libraries'); _logger.warning('Failed to fetch libraries');
return []; return [];
} }
_logger.fine('Fetched ${libraries.length} libraries');
return libraries; return libraries;
} }
} }

View file

@ -6,7 +6,7 @@ part of 'library_provider.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$currentLibraryHash() => r'f37904b8b43c88a523696d1ed7acf871c3e3326f'; String _$currentLibraryHash() => r'1b41abb16566d91cd5961973e45bccaad7c49c9a';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {
@ -157,7 +157,7 @@ class _CurrentLibraryProviderElement
String get id => (origin as CurrentLibraryProvider).id; String get id => (origin as CurrentLibraryProvider).id;
} }
String _$librariesHash() => r'a79954d0b68a8265859c577e36d5596620a72843'; String _$librariesHash() => r'a57828f3b875d56db6c5815d051eca93695aefe2';
/// See also [Libraries]. /// See also [Libraries].
@ProviderFor(Libraries) @ProviderFor(Libraries)

View file

@ -77,6 +77,14 @@ void showLibrarySwitcher(
child: Scrollbar(child: content), child: Scrollbar(child: content),
), ),
actions: [ actions: [
TextButton(
onPressed: () {
// Invalidate the provider to trigger a refetch
ref.invalidate(librariesProvider);
Navigator.pop(dialogContext);
},
child: const Text('Refresh'),
),
TextButton( TextButton(
onPressed: () => Navigator.pop(dialogContext), onPressed: () => Navigator.pop(dialogContext),
child: const Text('Cancel'), child: const Text('Cancel'),
@ -110,6 +118,15 @@ void showLibrarySwitcher(
// Allow the list to take remaining space and scroll // Allow the list to take remaining space and scroll
child: Scrollbar(child: content), child: Scrollbar(child: content),
), ),
const SizedBox(height: 10),
ElevatedButton.icon(
icon: const Icon(Icons.refresh),
label: const Text('Refresh'),
onPressed: () {
// Invalidate the provider to trigger a refetch
ref.invalidate(librariesProvider);
},
),
], ],
), ),
), ),
@ -121,23 +138,59 @@ void showLibrarySwitcher(
class _LibrarySelectionContent extends ConsumerWidget { class _LibrarySelectionContent extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
// Get the current library ID from the settings final librariesAsyncValue = ref.watch(librariesProvider);
final currentLibraryId = ref.watch( final currentLibraryId = ref.watch(
apiSettingsProvider.select( apiSettingsProvider.select((settings) => settings.activeLibraryId),
(settings) => settings.activeLibraryId,
),
); );
// Get the list of libraries from the settings final errorColor = Theme.of(context).colorScheme.error;
final libraries = ref.watch(librariesProvider).valueOrNull ?? return librariesAsyncValue.when(
[]; // Use null-aware operator to handle null case // --- Loading State ---
loading: () => const Center(child: CircularProgressIndicator()),
// If no libraries are available, show a message // --- Error State ---
error: (error, stackTrace) => Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.error_outline, color: errorColor),
const SizedBox(height: 10),
Text(
'Error loading libraries: $error',
textAlign: TextAlign.center,
style: TextStyle(color: errorColor),
),
const SizedBox(height: 16),
ElevatedButton.icon(
icon: const Icon(Icons.refresh),
label: const Text('Retry'),
onPressed: () {
// Invalidate the provider to trigger a refetch
ref.invalidate(librariesProvider);
},
),
],
),
),
),
// --- Data State ---
data: (libraries) {
// Handle case where data loaded successfully but is empty
if (libraries.isEmpty) { if (libraries.isEmpty) {
return const Center( return const Center(
child: Text('No libraries available'), child: Padding(
padding: EdgeInsets.all(16.0),
child: Text('No libraries available.'),
),
); );
} }
return ListView.builder(
// Build the list if libraries are available
return Scrollbar(
// Add scrollbar for potentially long lists
child: ListView.builder(
shrinkWrap: true, // Important for Dialog/BottomSheet sizing shrinkWrap: true, // Important for Dialog/BottomSheet sizing
itemCount: libraries.length, itemCount: libraries.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
@ -150,8 +203,8 @@ class _LibrarySelectionContent extends ConsumerWidget {
selected: isSelected, selected: isSelected,
trailing: isSelected ? const Icon(Icons.check) : null, trailing: isSelected ? const Icon(Icons.check) : null,
onTap: () { onTap: () {
appLogger appLogger.info(
.info('Selected library: ${library.name} (ID: ${library.id})'); 'Selected library: ${library.name} (ID: ${library.id})');
// Get current settings state // Get current settings state
final currentSettings = ref.read(apiSettingsProvider); final currentSettings = ref.read(apiSettingsProvider);
// Update the active library ID // Update the active library ID
@ -163,6 +216,9 @@ class _LibrarySelectionContent extends ConsumerWidget {
}, },
); );
}, },
),
);
},
); );
} }
} }