- lib/presentation : pages legacy (explore/network, notifications) avec BLoC - lib/shared/design_system : UnionFlow Design System v2 (tokens, components) + MD3 tokens + module_colors par feature - lib/shared/widgets : widgets transversaux (core_card, core_shimmer, error_widget, loading_widget, powered_by_lions_dev, etc.) - lib/shared/constants + utils
215 lines
6.1 KiB
Dart
215 lines
6.1 KiB
Dart
/// Centralized helper for showing consistent Snackbar messages
|
|
library snackbar_helper;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import '../../core/error/failures.dart';
|
|
import '../design_system/tokens/app_colors.dart';
|
|
|
|
/// Helper class for showing consistent Snackbar messages throughout the app
|
|
class SnackbarHelper {
|
|
/// Show success message
|
|
static void showSuccess(
|
|
BuildContext context,
|
|
String message, {
|
|
Duration duration = const Duration(seconds: 3),
|
|
SnackBarAction? action,
|
|
}) {
|
|
final snackBar = SnackBar(
|
|
content: Row(
|
|
children: [
|
|
const Icon(Icons.check_circle, color: AppColors.onPrimary),
|
|
const SizedBox(width: 12),
|
|
Expanded(child: Text(message)),
|
|
],
|
|
),
|
|
backgroundColor: AppColors.success,
|
|
behavior: SnackBarBehavior.floating,
|
|
duration: duration,
|
|
action: action,
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
/// Show error message
|
|
static void showError(
|
|
BuildContext context,
|
|
String message, {
|
|
Duration duration = const Duration(seconds: 4),
|
|
VoidCallback? onRetry,
|
|
}) {
|
|
final snackBar = SnackBar(
|
|
content: Row(
|
|
children: [
|
|
const Icon(Icons.error_outline, color: AppColors.onPrimary),
|
|
const SizedBox(width: 12),
|
|
Expanded(child: Text(message)),
|
|
],
|
|
),
|
|
backgroundColor: AppColors.error,
|
|
behavior: SnackBarBehavior.floating,
|
|
duration: duration,
|
|
action: onRetry != null
|
|
? SnackBarAction(
|
|
label: 'Réessayer',
|
|
textColor: AppColors.onPrimary,
|
|
onPressed: onRetry,
|
|
)
|
|
: null,
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
/// Show warning message
|
|
static void showWarning(
|
|
BuildContext context,
|
|
String message, {
|
|
Duration duration = const Duration(seconds: 4),
|
|
}) {
|
|
final snackBar = SnackBar(
|
|
content: Row(
|
|
children: [
|
|
const Icon(Icons.warning_amber, color: AppColors.onPrimary),
|
|
const SizedBox(width: 12),
|
|
Expanded(child: Text(message)),
|
|
],
|
|
),
|
|
backgroundColor: AppColors.warning,
|
|
behavior: SnackBarBehavior.floating,
|
|
duration: duration,
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
/// Show info message
|
|
static void showInfo(
|
|
BuildContext context,
|
|
String message, {
|
|
Duration duration = const Duration(seconds: 3),
|
|
}) {
|
|
final snackBar = SnackBar(
|
|
content: Row(
|
|
children: [
|
|
const Icon(Icons.info_outline, color: AppColors.onPrimary),
|
|
const SizedBox(width: 12),
|
|
Expanded(child: Text(message)),
|
|
],
|
|
),
|
|
backgroundColor: AppColors.info,
|
|
behavior: SnackBarBehavior.floating,
|
|
duration: duration,
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
/// Show "not implemented" message with appropriate styling
|
|
static void showNotImplemented(
|
|
BuildContext context,
|
|
String? featureName,
|
|
) {
|
|
final message = featureName != null
|
|
? '$featureName sera bientôt disponible !'
|
|
: 'Cette fonctionnalité sera bientôt disponible !';
|
|
|
|
final snackBar = SnackBar(
|
|
content: Row(
|
|
children: [
|
|
const Icon(Icons.construction, color: AppColors.onPrimary),
|
|
const SizedBox(width: 12),
|
|
Expanded(child: Text(message)),
|
|
],
|
|
),
|
|
backgroundColor: AppColors.info,
|
|
behavior: SnackBarBehavior.floating,
|
|
duration: const Duration(seconds: 4),
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
/// Show failure with appropriate styling based on failure type
|
|
static void showFailure(
|
|
BuildContext context,
|
|
Failure failure, {
|
|
VoidCallback? onRetry,
|
|
}) {
|
|
// Handle NotImplementedFailure specially
|
|
if (failure is NotImplementedFailure) {
|
|
showNotImplemented(context, null);
|
|
return;
|
|
}
|
|
|
|
Color backgroundColor;
|
|
IconData icon;
|
|
|
|
if (failure is NetworkFailure) {
|
|
backgroundColor = AppColors.warning;
|
|
icon = Icons.wifi_off;
|
|
} else if (failure is UnauthorizedFailure) {
|
|
backgroundColor = AppColors.error;
|
|
icon = Icons.lock_outline;
|
|
} else if (failure is ForbiddenFailure) {
|
|
backgroundColor = AppColors.warning;
|
|
icon = Icons.block;
|
|
} else if (failure is ValidationFailure) {
|
|
backgroundColor = AppColors.warningUI;
|
|
icon = Icons.error_outline;
|
|
} else {
|
|
backgroundColor = AppColors.error;
|
|
icon = Icons.error_outline;
|
|
}
|
|
|
|
final snackBar = SnackBar(
|
|
content: Row(
|
|
children: [
|
|
Icon(icon, color: AppColors.onPrimary),
|
|
const SizedBox(width: 12),
|
|
Expanded(child: Text(failure.getUserMessage())),
|
|
],
|
|
),
|
|
backgroundColor: backgroundColor,
|
|
behavior: SnackBarBehavior.floating,
|
|
duration: Duration(seconds: failure.isRetryable ? 6 : 4),
|
|
action: failure.isRetryable && onRetry != null
|
|
? SnackBarAction(
|
|
label: 'Réessayer',
|
|
textColor: AppColors.onPrimary,
|
|
onPressed: onRetry,
|
|
)
|
|
: null,
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
/// Show loading message (use with caution - prefer progress indicators)
|
|
static void showLoading(
|
|
BuildContext context,
|
|
String message, {
|
|
Duration duration = const Duration(seconds: 2),
|
|
}) {
|
|
final snackBar = SnackBar(
|
|
content: Row(
|
|
children: [
|
|
const SizedBox(
|
|
width: 16,
|
|
height: 16,
|
|
child: CircularProgressIndicator(
|
|
strokeWidth: 2,
|
|
valueColor: AlwaysStoppedAnimation<Color>(AppColors.onPrimary),
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(child: Text(message)),
|
|
],
|
|
),
|
|
backgroundColor: AppColors.surfaceDark,
|
|
behavior: SnackBarBehavior.floating,
|
|
duration: duration,
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
/// Dismiss current Snackbar
|
|
static void dismiss(BuildContext context) {
|
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
|
}
|
|
}
|