diff --git a/lib/pages/AdministrationOccasion/UsersTab.dart b/lib/pages/AdministrationOccasion/UsersTab.dart index fb8665fa..749189eb 100644 --- a/lib/pages/AdministrationOccasion/UsersTab.dart +++ b/lib/pages/AdministrationOccasion/UsersTab.dart @@ -170,52 +170,51 @@ class _UsersTabState extends State { for (var user in users) user: 0 }; - // Prepare futures for progress dialog - List> inviteFutures = users.map((user) async { - while (retryAttempts[user]! < retryLimit) { - try { - // Send sign-in code and update progress - await AuthService.sendSignInCode(user); - ToastHelper.Show( - context, - "Invited: {user}.".tr(namedArgs: { - "user": user.data![Tb.occasion_users.data_email] - }), - ); - return; // Exit retry loop on success - } catch (e) { - retryAttempts[user] = retryAttempts[user]! + 1; - - if (retryAttempts[user]! >= retryLimit) { + List Function()> inviteFutures = users.map((user) { + return () async { + while (retryAttempts[user]! < retryLimit) { + try { + // Uncomment this line to send the actual sign-in code + await AuthService.sendSignInCode(user); + + // Show success toast ToastHelper.Show( context, - "Failed to invite {user}. Number of retries: ({retries}).".tr( - namedArgs: { - "retries": retryLimit.toString(), - "user": user.data![Tb.occasion_users.data_email] - } - ), - severity: ToastSeverity.NotOk, + "Invited: {user}.".tr(namedArgs: { + "user": user.data![Tb.occasion_users.data_email] + }), ); - print("Failed to invite user: ${user.data![Tb.occasion_users - .data_email]}. Error: $e"); - } else { - print("Retrying to invite user: ${user.data![Tb.occasion_users - .data_email]}. Attempt: ${retryAttempts[user]}"); + return; // Exit retry loop on success + } catch (e) { + retryAttempts[user] = retryAttempts[user]! + 1; + + if (retryAttempts[user]! >= retryLimit) { + ToastHelper.Show( + context, + "Failed to invite {user}. Number of retries: ({retries}).".tr( + namedArgs: { + "retries": retryLimit.toString(), + "user": user.data![Tb.occasion_users.data_email] + }), + severity: ToastSeverity.NotOk, + ); + print( + "Failed to invite user: ${user.data![Tb.occasion_users.data_email]}. Error: $e"); + } else { + print( + "Retrying to invite user: ${user.data![Tb.occasion_users.data_email]}. Attempt: ${retryAttempts[user]}"); + } } - } finally { - // Ensure delay happens regardless of success or failure - await Future.delayed(Duration(milliseconds: 500)); } - } + }; }).toList(); // Show progress dialog while processing await DialogHelper.showProgressDialogAsync( context, - "Invite".tr(), - users.length, + "Invite".tr(), inviteFutures.length, futures: inviteFutures, + delay: Duration(milliseconds: 500) ); } } diff --git a/lib/services/DialogHelper.dart b/lib/services/DialogHelper.dart index 081935bc..6f51cfad 100644 --- a/lib/services/DialogHelper.dart +++ b/lib/services/DialogHelper.dart @@ -311,12 +311,13 @@ class DialogHelper{ BuildContext context, String title, int total, { - List>? futures, + List Function()>? futures, + Duration? delay, }) async { - // Completer to control the dialog lifecycle final completer = Completer(); - var progressNotifier = ValueNotifier(0); - // Show the dialog immediately + final progressNotifier = ValueNotifier(0); + + // Show the dialog showDialog( context: context, barrierDismissible: false, @@ -332,16 +333,17 @@ class DialogHelper{ Text("${"Progress".tr()}: $progress/$total"), SizedBox(height: 20), LinearProgressIndicator(value: total > 0 ? progress / total : 0), - if (progress >= total) ...[ - SizedBox(height: 20), - ElevatedButton( - onPressed: () { - Navigator.of(context).pop(); - completer.complete(); - }, - child: Text("Ok".tr()), - ), - ], + if (progress >= total) + ...[ + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + Navigator.of(context).pop(); + completer.complete(); + }, + child: Text("Ok".tr()), + ), + ], ], ), ); @@ -350,19 +352,28 @@ class DialogHelper{ }, ); - // Process the futures, updating progress - if (futures != null) { + // Execute futures sequentially + if (futures !=null && futures.isNotEmpty) { for (var future in futures) { - await future; - progressNotifier.value++; + try { + await future.call(); // Wait for each future to finish + progressNotifier.value++; + if(delay!=null){ + await Future.delayed(delay); + } + } catch (e) { + ToastHelper.Show(context, e.toString(), severity: ToastSeverity.NotOk); + } } + } else { + // Complete immediately if no futures are provided + completer.complete(); + Navigator.of(context).pop(); } - // Wait for the user to press "OK" if not already completed + // Await the completer if not already completed if (!completer.isCompleted) { await completer.future; } } - - } \ No newline at end of file diff --git a/lib/services/UserManagementHelper.dart b/lib/services/UserManagementHelper.dart index 06a218d9..2b922230 100644 --- a/lib/services/UserManagementHelper.dart +++ b/lib/services/UserManagementHelper.dart @@ -96,7 +96,7 @@ class UserManagementHelper{ context, "Creating users".tr(), toBeCreated.length, - futures: toBeCreated.map((u) async { + futures: toBeCreated.map((u) => () async { await DbUsers.updateOccasionUser(OccasionUserModel.fromImportedJson(u)); ToastHelper.Show(context, "Created {item}.".tr(namedArgs: {"item": u[Tb.occasion_users.data_email]})); }).toList(), @@ -123,7 +123,7 @@ class UserManagementHelper{ context, "Updating users".tr(), toBeUpdated.length, - futures: toBeUpdated.map((u) async { + futures: toBeUpdated.map((u) => () async { var existing = existingUsers.firstWhere( (e) => e.data?[Tb.occasion_users.data_email] == u[Tb.occasion_users.data_email], ); @@ -154,7 +154,7 @@ class UserManagementHelper{ context, "Removing users".tr(), toBeDeleted.length, - futures: toBeDeleted.map((existing) async { + futures: toBeDeleted.map((existing) => () async { await DbUsers.deleteUser(existing.user!, existing.occasion!); ToastHelper.Show(context, "Removed {item}.".tr(namedArgs: {"item": existing.toBasicString()})); }).toList(),