From 9c964e7b414084def406fa15a57f1d34b6f87fb0 Mon Sep 17 00:00:00 2001 From: PartyDonut Date: Sat, 30 Aug 2025 09:31:53 +0200 Subject: [PATCH] fix: Fetching overlay for library search screen --- lib/providers/library_search_provider.dart | 77 +++++++++++++++++----- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/lib/providers/library_search_provider.dart b/lib/providers/library_search_provider.dart index 9f6489b..05947cb 100644 --- a/lib/providers/library_search_provider.dart +++ b/lib/providers/library_search_provider.dart @@ -2,10 +2,12 @@ import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:async/async.dart'; import 'package:auto_route/auto_route.dart'; import 'package:chopper/chopper.dart'; import 'package:collection/collection.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:iconsax_plus/iconsax_plus.dart'; import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart'; import 'package:fladder/models/collection_types.dart'; @@ -579,17 +581,14 @@ class LibrarySearchNotifier extends StateNotifier { } Future playLibraryItems(BuildContext context, WidgetRef ref, {bool shuffle = false}) async { - state = state.copyWith(fetchingItems: true); List itemsToPlay = []; if (state.selectedPosters.isNotEmpty) { itemsToPlay = shuffle ? state.selectedPosters.random() : state.selectedPosters; } else { - itemsToPlay = await _loadAllItems(shuffle: shuffle); + itemsToPlay = await showLoadingOverlay(context, callBack: _loadAllItems(shuffle: shuffle)); } - state = state.copyWith(fetchingItems: false); - //Only try to load video items itemsToPlay = itemsToPlay.where((element) => FladderItemType.playable.contains(element.type)).toList(); @@ -662,26 +661,68 @@ class LibrarySearchNotifier extends StateNotifier { } Future viewGallery(BuildContext context, {PhotoModel? selected, bool shuffle = false}) async { - state = state.copyWith(fetchingItems: true); - final allItems = await fetchGallery(shuffle: shuffle); - + List allItems = []; + allItems = await showLoadingOverlay(context, callBack: fetchGallery(shuffle: shuffle)); if (allItems.isNotEmpty) { - if (state.fetchingItems == true) { - state = state.copyWith(fetchingItems: false); - final newItemList = shuffle ? allItems.shuffled() : allItems; - await context.navigateTo(PhotoViewerRoute( - items: newItemList, - selected: selected?.id, - )); - } + final newItemList = shuffle ? allItems.shuffled() : allItems; + await context.navigateTo(PhotoViewerRoute( + items: newItemList, + selected: selected?.id, + )); } else { fladderSnackbar(context, title: context.localized.libraryFetchNoItemsFound); } - state = state.copyWith(fetchingItems: false); } - void cancelFetch() { - state = state.copyWith(fetchingItems: false); + Future showLoadingOverlay( + BuildContext context, { + required Future callBack, + }) async { + state = state.copyWith(fetchingItems: true); + BuildContext? dialogContext; + var cancelAble = CancelableOperation.fromFuture(callBack); + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + dialogContext = context; + return Center( + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primaryContainer, + borderRadius: BorderRadius.circular(16), + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisSize: MainAxisSize.min, + spacing: 16, + children: [ + const CircularProgressIndicator.adaptive(), + Text(context.localized.fetchingLibrary, style: Theme.of(context).textTheme.titleMedium), + IconButton( + onPressed: () { + cancelAble.cancel(); + context.pop(); + }, + icon: const Icon(IconsaxPlusLinear.close_square), + ) + ], + ), + ), + ), + ); + }, + ); + + try { + return await cancelAble.value; + } finally { + state = state.copyWith(fetchingItems: false); + if (dialogContext != null && Navigator.of(dialogContext!).canPop()) { + Navigator.of(dialogContext!).pop(); + } + } } Future openRandom(BuildContext context) async {