263 lines
6.4 KiB
Dart
263 lines
6.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
enum SnackBarType {
|
|
success,
|
|
error,
|
|
warning,
|
|
info,
|
|
}
|
|
|
|
class AppSnackBar {
|
|
static void show({
|
|
required BuildContext context,
|
|
required String message,
|
|
SnackBarType type = SnackBarType.info,
|
|
Duration duration = const Duration(seconds: 3),
|
|
String? actionLabel,
|
|
VoidCallback? onActionPressed,
|
|
}) {
|
|
// Remove any existing snackbars
|
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
|
|
|
final snackBar = SnackBar(
|
|
content: _SnackBarContent(
|
|
message: message,
|
|
type: type,
|
|
),
|
|
backgroundColor: Colors.transparent,
|
|
elevation: 0,
|
|
duration: duration,
|
|
behavior: SnackBarBehavior.floating,
|
|
margin: const EdgeInsets.all(16),
|
|
padding: EdgeInsets.zero,
|
|
action: actionLabel != null
|
|
? SnackBarAction(
|
|
label: actionLabel,
|
|
textColor: _getActionColor(type),
|
|
onPressed: onActionPressed ?? () {},
|
|
)
|
|
: null,
|
|
);
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
|
|
static void showSuccess({
|
|
required BuildContext context,
|
|
required String message,
|
|
Duration duration = const Duration(seconds: 3),
|
|
String? actionLabel,
|
|
VoidCallback? onActionPressed,
|
|
}) {
|
|
show(
|
|
context: context,
|
|
message: message,
|
|
type: SnackBarType.success,
|
|
duration: duration,
|
|
actionLabel: actionLabel,
|
|
onActionPressed: onActionPressed,
|
|
);
|
|
}
|
|
|
|
static void showError({
|
|
required BuildContext context,
|
|
required String message,
|
|
Duration duration = const Duration(seconds: 4),
|
|
String? actionLabel,
|
|
VoidCallback? onActionPressed,
|
|
}) {
|
|
show(
|
|
context: context,
|
|
message: message,
|
|
type: SnackBarType.error,
|
|
duration: duration,
|
|
actionLabel: actionLabel,
|
|
onActionPressed: onActionPressed,
|
|
);
|
|
}
|
|
|
|
static void showWarning({
|
|
required BuildContext context,
|
|
required String message,
|
|
Duration duration = const Duration(seconds: 3),
|
|
String? actionLabel,
|
|
VoidCallback? onActionPressed,
|
|
}) {
|
|
show(
|
|
context: context,
|
|
message: message,
|
|
type: SnackBarType.warning,
|
|
duration: duration,
|
|
actionLabel: actionLabel,
|
|
onActionPressed: onActionPressed,
|
|
);
|
|
}
|
|
|
|
static void showInfo({
|
|
required BuildContext context,
|
|
required String message,
|
|
Duration duration = const Duration(seconds: 3),
|
|
String? actionLabel,
|
|
VoidCallback? onActionPressed,
|
|
}) {
|
|
show(
|
|
context: context,
|
|
message: message,
|
|
type: SnackBarType.info,
|
|
duration: duration,
|
|
actionLabel: actionLabel,
|
|
onActionPressed: onActionPressed,
|
|
);
|
|
}
|
|
|
|
static Color _getActionColor(SnackBarType type) {
|
|
switch (type) {
|
|
case SnackBarType.success:
|
|
return Colors.green.shade100;
|
|
case SnackBarType.error:
|
|
return Colors.red.shade100;
|
|
case SnackBarType.warning:
|
|
return Colors.orange.shade100;
|
|
case SnackBarType.info:
|
|
return Colors.blue.shade100;
|
|
}
|
|
}
|
|
}
|
|
|
|
class _SnackBarContent extends StatelessWidget {
|
|
final String message;
|
|
final SnackBarType type;
|
|
|
|
const _SnackBarContent({
|
|
required this.message,
|
|
required this.type,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
|
decoration: BoxDecoration(
|
|
color: _getBackgroundColor(),
|
|
borderRadius: BorderRadius.circular(12),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.1),
|
|
blurRadius: 8,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
border: Border.all(
|
|
color: _getBorderColor(),
|
|
width: 1,
|
|
),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: _getIconBackgroundColor(),
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: Icon(
|
|
_getIcon(),
|
|
color: _getIconColor(),
|
|
size: 20,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Text(
|
|
message,
|
|
style: TextStyle(
|
|
color: _getTextColor(),
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Color _getBackgroundColor() {
|
|
switch (type) {
|
|
case SnackBarType.success:
|
|
return Colors.green.shade50;
|
|
case SnackBarType.error:
|
|
return Colors.red.shade50;
|
|
case SnackBarType.warning:
|
|
return Colors.orange.shade50;
|
|
case SnackBarType.info:
|
|
return Colors.blue.shade50;
|
|
}
|
|
}
|
|
|
|
Color _getBorderColor() {
|
|
switch (type) {
|
|
case SnackBarType.success:
|
|
return Colors.green.shade200;
|
|
case SnackBarType.error:
|
|
return Colors.red.shade200;
|
|
case SnackBarType.warning:
|
|
return Colors.orange.shade200;
|
|
case SnackBarType.info:
|
|
return Colors.blue.shade200;
|
|
}
|
|
}
|
|
|
|
Color _getIconBackgroundColor() {
|
|
switch (type) {
|
|
case SnackBarType.success:
|
|
return Colors.green.shade100;
|
|
case SnackBarType.error:
|
|
return Colors.red.shade100;
|
|
case SnackBarType.warning:
|
|
return Colors.orange.shade100;
|
|
case SnackBarType.info:
|
|
return Colors.blue.shade100;
|
|
}
|
|
}
|
|
|
|
Color _getIconColor() {
|
|
switch (type) {
|
|
case SnackBarType.success:
|
|
return Colors.green.shade700;
|
|
case SnackBarType.error:
|
|
return Colors.red.shade700;
|
|
case SnackBarType.warning:
|
|
return Colors.orange.shade700;
|
|
case SnackBarType.info:
|
|
return Colors.blue.shade700;
|
|
}
|
|
}
|
|
|
|
Color _getTextColor() {
|
|
switch (type) {
|
|
case SnackBarType.success:
|
|
return Colors.green.shade800;
|
|
case SnackBarType.error:
|
|
return Colors.red.shade800;
|
|
case SnackBarType.warning:
|
|
return Colors.orange.shade800;
|
|
case SnackBarType.info:
|
|
return Colors.blue.shade800;
|
|
}
|
|
}
|
|
|
|
IconData _getIcon() {
|
|
switch (type) {
|
|
case SnackBarType.success:
|
|
return Icons.check_circle;
|
|
case SnackBarType.error:
|
|
return Icons.error;
|
|
case SnackBarType.warning:
|
|
return Icons.warning;
|
|
case SnackBarType.info:
|
|
return Icons.info;
|
|
}
|
|
}
|
|
}
|