* *Option 3:* `feat: add tourist landmarks support with UI sheets, data models
198 lines
5.0 KiB
Dart
198 lines
5.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import '../../core/constants/app_colors.dart';
|
|
|
|
enum SiroToastType {
|
|
success,
|
|
error,
|
|
info,
|
|
warning,
|
|
}
|
|
|
|
class SiroToast {
|
|
SiroToast._();
|
|
|
|
static void showSuccess(
|
|
BuildContext context,
|
|
String message, {
|
|
String? title,
|
|
Duration duration = const Duration(seconds: 4),
|
|
}) {
|
|
show(
|
|
context,
|
|
message: message,
|
|
title: title,
|
|
type: SiroToastType.success,
|
|
duration: duration,
|
|
);
|
|
}
|
|
|
|
static void showError(
|
|
BuildContext context,
|
|
String message, {
|
|
String? title,
|
|
Duration duration = const Duration(seconds: 4),
|
|
}) {
|
|
show(
|
|
context,
|
|
message: message,
|
|
title: title,
|
|
type: SiroToastType.error,
|
|
duration: duration,
|
|
);
|
|
}
|
|
|
|
static void showInfo(
|
|
BuildContext context,
|
|
String message, {
|
|
String? title,
|
|
Duration duration = const Duration(seconds: 4),
|
|
}) {
|
|
show(
|
|
context,
|
|
message: message,
|
|
title: title,
|
|
type: SiroToastType.info,
|
|
duration: duration,
|
|
);
|
|
}
|
|
|
|
static void showWarning(
|
|
BuildContext context,
|
|
String message, {
|
|
String? title,
|
|
Duration duration = const Duration(seconds: 4),
|
|
}) {
|
|
show(
|
|
context,
|
|
message: message,
|
|
title: title,
|
|
type: SiroToastType.warning,
|
|
duration: duration,
|
|
);
|
|
}
|
|
|
|
static void show(
|
|
BuildContext context, {
|
|
required String message,
|
|
String? title,
|
|
SiroToastType type = SiroToastType.info,
|
|
Duration duration = const Duration(seconds: 4),
|
|
}) {
|
|
// Trigger tactile haptic feedback
|
|
switch (type) {
|
|
case SiroToastType.success:
|
|
HapticFeedback.lightImpact();
|
|
break;
|
|
case SiroToastType.error:
|
|
HapticFeedback.heavyImpact();
|
|
break;
|
|
case SiroToastType.warning:
|
|
HapticFeedback.mediumImpact();
|
|
break;
|
|
case SiroToastType.info:
|
|
HapticFeedback.selectionClick();
|
|
break;
|
|
}
|
|
|
|
Color accentColor;
|
|
IconData iconData;
|
|
|
|
switch (type) {
|
|
case SiroToastType.success:
|
|
accentColor = AppColors.tacticalEmerald;
|
|
iconData = Icons.check_circle_rounded;
|
|
break;
|
|
case SiroToastType.error:
|
|
accentColor = AppColors.coralDanger;
|
|
iconData = Icons.error_rounded;
|
|
break;
|
|
case SiroToastType.warning:
|
|
accentColor = AppColors.sovereignGold;
|
|
iconData = Icons.warning_amber_rounded;
|
|
break;
|
|
case SiroToastType.info:
|
|
accentColor = AppColors.appleBlue;
|
|
iconData = Icons.info_rounded;
|
|
break;
|
|
}
|
|
|
|
final messenger = ScaffoldMessenger.of(context);
|
|
messenger.hideCurrentSnackBar();
|
|
|
|
messenger.showSnackBar(
|
|
SnackBar(
|
|
behavior: SnackBarBehavior.floating,
|
|
elevation: 10,
|
|
margin: EdgeInsets.only(
|
|
bottom: MediaQuery.of(context).size.height * 0.11,
|
|
left: 18,
|
|
right: 18,
|
|
),
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(18),
|
|
side: BorderSide(
|
|
color: accentColor.withValues(alpha: 0.35),
|
|
width: 1.2,
|
|
),
|
|
),
|
|
backgroundColor: const Color(0xFF1D1D1F).withValues(alpha: 0.95),
|
|
duration: duration,
|
|
content: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(7),
|
|
decoration: BoxDecoration(
|
|
color: accentColor.withValues(alpha: 0.18),
|
|
shape: BoxShape.circle,
|
|
border: Border.all(
|
|
color: accentColor.withValues(alpha: 0.3),
|
|
width: 1,
|
|
),
|
|
),
|
|
child: Icon(
|
|
iconData,
|
|
color: accentColor,
|
|
size: 18,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (title != null && title.isNotEmpty)
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 2),
|
|
child: Text(
|
|
title,
|
|
style: TextStyle(
|
|
color: accentColor,
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w700,
|
|
fontFamily: '.SF Pro Text',
|
|
),
|
|
),
|
|
),
|
|
Text(
|
|
message,
|
|
style: const TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 13,
|
|
fontWeight: FontWeight.w500,
|
|
height: 1.3,
|
|
fontFamily: '.SF Pro Text',
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|