2021-08-31 14:00:55 +02:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
|
|
|
import 'package:nc_photos/k.dart' as k;
|
|
|
|
import 'package:nc_photos/snack_bar_manager.dart';
|
|
|
|
|
|
|
|
class NotifiedAction {
|
|
|
|
NotifiedAction(
|
|
|
|
this.action,
|
|
|
|
this.processingText,
|
|
|
|
this.successText, {
|
|
|
|
this.failureText,
|
|
|
|
});
|
|
|
|
|
|
|
|
Future<void> call() async {
|
|
|
|
if (processingText != null) {
|
2022-07-25 07:04:22 +02:00
|
|
|
SnackBarManager().showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
content: Text(processingText!),
|
|
|
|
duration: k.snackBarDurationShort,
|
|
|
|
),
|
|
|
|
canBeReplaced: true,
|
|
|
|
);
|
2021-08-31 14:00:55 +02:00
|
|
|
}
|
|
|
|
try {
|
|
|
|
await action();
|
|
|
|
SnackBarManager().showSnackBar(SnackBar(
|
|
|
|
content: Text(successText),
|
|
|
|
duration: k.snackBarDurationNormal,
|
|
|
|
));
|
|
|
|
} catch (e) {
|
|
|
|
SnackBarManager().showSnackBar(SnackBar(
|
|
|
|
content: Text(
|
|
|
|
(failureText?.isNotEmpty == true ? "$failureText: " : "") +
|
|
|
|
exception_util.toUserString(e)),
|
|
|
|
duration: k.snackBarDurationNormal,
|
|
|
|
));
|
2021-09-08 11:31:24 +02:00
|
|
|
rethrow;
|
2021-08-31 14:00:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final FutureOr<void> Function() action;
|
|
|
|
|
|
|
|
/// Message to be shown before performing [action]
|
|
|
|
final String? processingText;
|
|
|
|
|
|
|
|
/// Message to be shown after [action] finished without throwing
|
|
|
|
final String successText;
|
|
|
|
|
|
|
|
/// Message to be shown if [action] threw, prepending the exception
|
|
|
|
final String? failureText;
|
|
|
|
}
|
2021-09-08 11:39:24 +02:00
|
|
|
|
|
|
|
class NotifiedListAction<T> {
|
|
|
|
NotifiedListAction({
|
|
|
|
required this.list,
|
|
|
|
required this.action,
|
|
|
|
this.processingText,
|
|
|
|
required this.successText,
|
|
|
|
this.getFailureText,
|
|
|
|
this.onActionError,
|
|
|
|
});
|
|
|
|
|
2022-01-22 13:02:24 +01:00
|
|
|
/// Perform the action and return the success count
|
|
|
|
Future<int> call() async {
|
2021-09-08 11:39:24 +02:00
|
|
|
if (processingText != null) {
|
2022-07-25 07:04:22 +02:00
|
|
|
SnackBarManager().showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
content: Text(processingText!),
|
|
|
|
duration: k.snackBarDurationShort,
|
|
|
|
),
|
|
|
|
canBeReplaced: true,
|
|
|
|
);
|
2021-09-08 11:39:24 +02:00
|
|
|
}
|
|
|
|
final failedItems = <T>[];
|
|
|
|
for (final item in list) {
|
|
|
|
try {
|
|
|
|
await action(item);
|
|
|
|
} catch (e, stackTrace) {
|
|
|
|
onActionError?.call(item, e, stackTrace);
|
|
|
|
failedItems.add(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (failedItems.isEmpty) {
|
|
|
|
SnackBarManager().showSnackBar(SnackBar(
|
|
|
|
content: Text(successText),
|
|
|
|
duration: k.snackBarDurationNormal,
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
final failureText = getFailureText?.call(failedItems);
|
|
|
|
if (failureText?.isNotEmpty == true) {
|
|
|
|
SnackBarManager().showSnackBar(SnackBar(
|
|
|
|
content: Text(failureText!),
|
|
|
|
duration: k.snackBarDurationNormal,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
2022-01-22 13:02:24 +01:00
|
|
|
return list.length - failedItems.length;
|
2021-09-08 11:39:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
final List<T> list;
|
|
|
|
|
|
|
|
/// Action to be applied to every items in [list]
|
|
|
|
final FutureOr<void> Function(T item) action;
|
|
|
|
|
|
|
|
/// Message to be shown before performing [action]
|
|
|
|
final String? processingText;
|
|
|
|
|
|
|
|
/// Message to be shown after [action] finished for each elements in [list]
|
|
|
|
/// without throwing
|
|
|
|
final String successText;
|
|
|
|
|
|
|
|
/// Message to be shown if one or more [action] threw
|
|
|
|
final String Function(List<T> failedItems)? getFailureText;
|
|
|
|
|
|
|
|
/// Called when [action] threw when processing [item]
|
|
|
|
final void Function(T item, Object e, StackTrace stackTrace)? onActionError;
|
|
|
|
}
|