2026-04-05-maplibra succsess for all and add navigation paage
This commit is contained in:
@@ -8,239 +8,501 @@ import '../../constant/colors.dart';
|
||||
import '../../constant/style.dart';
|
||||
import '../../controller/functions/tts.dart';
|
||||
|
||||
class DialogConfig {
|
||||
static const Duration animationDuration = Duration(milliseconds: 200);
|
||||
static const double blurStrength = 8.0;
|
||||
static const double cornerRadius = 14.0;
|
||||
static final BoxDecoration decoration = BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(cornerRadius),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withAlpha(38), // 0.15 opacity
|
||||
blurRadius: 16,
|
||||
offset: const Offset(0, 8),
|
||||
),
|
||||
],
|
||||
);
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Config
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class _DC {
|
||||
static const Duration animDuration = Duration(milliseconds: 280);
|
||||
static const double blur = 20.0;
|
||||
static const double radius = 24.0;
|
||||
static const Color barrierColor = Color(0x66000000);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Shared animated wrapper — every dialog uses this
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class _DialogShell extends StatelessWidget {
|
||||
final Widget child;
|
||||
const _DialogShell({required this.child});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TweenAnimationBuilder<double>(
|
||||
duration: _DC.animDuration,
|
||||
tween: Tween(begin: 0.0, end: 1.0),
|
||||
curve: Curves.easeOutBack,
|
||||
builder: (_, v, c) => Transform.scale(
|
||||
scale: 0.88 + (0.12 * v),
|
||||
child: Opacity(opacity: v.clamp(0.0, 1.0), child: c),
|
||||
),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: _DC.blur, sigmaY: _DC.blur),
|
||||
child: Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
insetPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 28, vertical: 40),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Shared glass card
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class _GlassCard extends StatelessWidget {
|
||||
final Widget child;
|
||||
const _GlassCard({required this.child});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(_DC.radius),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Colors.white.withOpacity(0.95),
|
||||
Colors.white.withOpacity(0.88),
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.18),
|
||||
blurRadius: 40,
|
||||
spreadRadius: -4,
|
||||
offset: const Offset(0, 16),
|
||||
),
|
||||
BoxShadow(
|
||||
color: AppColor.primaryColor.withOpacity(0.08),
|
||||
blurRadius: 20,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
border: Border.all(
|
||||
color: Colors.white.withOpacity(0.6),
|
||||
width: 1.2,
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Shared bottom action row
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class _ActionRow extends StatelessWidget {
|
||||
final VoidCallback onCancel;
|
||||
final VoidCallback onConfirm;
|
||||
final String confirmLabel;
|
||||
final bool isDestructive;
|
||||
|
||||
const _ActionRow({
|
||||
required this.onCancel,
|
||||
required this.onConfirm,
|
||||
this.confirmLabel = 'OK',
|
||||
this.isDestructive = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(color: Colors.grey.withOpacity(0.15), width: 1),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// Cancel
|
||||
Expanded(
|
||||
child: _ActionButton(
|
||||
label: 'Cancel'.tr,
|
||||
color: Colors.grey[600]!,
|
||||
backgroundColor: Colors.grey.withOpacity(0.07),
|
||||
onPressed: () {
|
||||
HapticFeedback.lightImpact();
|
||||
onCancel();
|
||||
},
|
||||
isLeft: true,
|
||||
),
|
||||
),
|
||||
Container(width: 1, height: 52, color: Colors.grey.withOpacity(0.15)),
|
||||
// Confirm
|
||||
Expanded(
|
||||
child: _ActionButton(
|
||||
label: confirmLabel,
|
||||
color: isDestructive ? AppColor.redColor : AppColor.primaryColor,
|
||||
backgroundColor: isDestructive
|
||||
? AppColor.redColor.withOpacity(0.07)
|
||||
: AppColor.primaryColor.withOpacity(0.07),
|
||||
onPressed: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
onConfirm();
|
||||
},
|
||||
isLeft: false,
|
||||
isBold: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ActionButton extends StatelessWidget {
|
||||
final String label;
|
||||
final Color color;
|
||||
final Color backgroundColor;
|
||||
final VoidCallback onPressed;
|
||||
final bool isLeft;
|
||||
final bool isBold;
|
||||
|
||||
const _ActionButton({
|
||||
required this.label,
|
||||
required this.color,
|
||||
required this.backgroundColor,
|
||||
required this.onPressed,
|
||||
required this.isLeft,
|
||||
this.isBold = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: onPressed,
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: isLeft ? const Radius.circular(_DC.radius) : Radius.zero,
|
||||
bottomRight:
|
||||
!isLeft ? const Radius.circular(_DC.radius) : Radius.zero,
|
||||
),
|
||||
child: Container(
|
||||
height: 52,
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft:
|
||||
isLeft ? const Radius.circular(_DC.radius) : Radius.zero,
|
||||
bottomRight:
|
||||
!isLeft ? const Radius.circular(_DC.radius) : Radius.zero,
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: 15,
|
||||
fontWeight: isBold ? FontWeight.w700 : FontWeight.w500,
|
||||
letterSpacing: -0.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// TTS speak button
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class _SpeakButton extends StatefulWidget {
|
||||
final List<String> texts;
|
||||
const _SpeakButton({required this.texts});
|
||||
|
||||
@override
|
||||
State<_SpeakButton> createState() => _SpeakButtonState();
|
||||
}
|
||||
|
||||
class _SpeakButtonState extends State<_SpeakButton>
|
||||
with SingleTickerProviderStateMixin {
|
||||
bool _speaking = false;
|
||||
late AnimationController _pulse;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_pulse = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 900),
|
||||
lowerBound: 0.92,
|
||||
upperBound: 1.0,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pulse.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _onTap() async {
|
||||
if (_speaking) return;
|
||||
HapticFeedback.selectionClick();
|
||||
setState(() => _speaking = true);
|
||||
_pulse.repeat(reverse: true);
|
||||
|
||||
final tts = Get.put(TextToSpeechController());
|
||||
for (final t in widget.texts) {
|
||||
await tts.speakText(t);
|
||||
}
|
||||
|
||||
_pulse.stop();
|
||||
_pulse.reset();
|
||||
if (mounted) setState(() => _speaking = false);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: _onTap,
|
||||
child: AnimatedBuilder(
|
||||
animation: _pulse,
|
||||
builder: (_, child) =>
|
||||
Transform.scale(scale: _pulse.value, child: child),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 250),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: _speaking
|
||||
? AppColor.primaryColor.withOpacity(0.15)
|
||||
: AppColor.primaryColor.withOpacity(0.08),
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
border: Border.all(
|
||||
color: AppColor.primaryColor.withOpacity(_speaking ? 0.4 : 0.15),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
_speaking
|
||||
? CupertinoIcons.speaker_3_fill
|
||||
: CupertinoIcons.speaker_2_fill,
|
||||
color: AppColor.primaryColor,
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
_speaking ? 'Speaking...'.tr : 'Listen'.tr,
|
||||
style: TextStyle(
|
||||
color: AppColor.primaryColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MyDialog — title + text content
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class MyDialog extends GetxController {
|
||||
void getDialog(String title, String? midTitle, VoidCallback onPressed) {
|
||||
final textToSpeechController = Get.put(TextToSpeechController());
|
||||
|
||||
void getDialog(
|
||||
String title,
|
||||
String? midTitle,
|
||||
VoidCallback onPressed, {
|
||||
IconData? icon,
|
||||
bool isDestructive = false,
|
||||
}) {
|
||||
HapticFeedback.mediumImpact();
|
||||
|
||||
Get.dialog(
|
||||
TweenAnimationBuilder<double>(
|
||||
duration: DialogConfig.animationDuration,
|
||||
tween: Tween(begin: 0.0, end: 1.0),
|
||||
builder: (context, value, child) {
|
||||
return Transform.scale(
|
||||
scale: 0.95 + (0.05 * value),
|
||||
child: Opacity(opacity: value, child: child),
|
||||
);
|
||||
},
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(
|
||||
sigmaX: DialogConfig.blurStrength,
|
||||
sigmaY: DialogConfig.blurStrength,
|
||||
),
|
||||
child: Theme(
|
||||
data: ThemeData.light().copyWith(
|
||||
dialogBackgroundColor: CupertinoColors.systemBackground,
|
||||
),
|
||||
child: CupertinoAlertDialog(
|
||||
title: Column(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: AppStyle.title.copyWith(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: -0.5,
|
||||
color: AppColor.primaryColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
children: [
|
||||
CupertinoButton(
|
||||
padding: const EdgeInsets.all(8),
|
||||
onPressed: () async {
|
||||
HapticFeedback.selectionClick();
|
||||
await textToSpeechController.speakText(title);
|
||||
await textToSpeechController.speakText(midTitle!);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
_DialogShell(
|
||||
child: _GlassCard(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// ── Body ──────────────────────────────────────────────
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(24, 28, 24, 20),
|
||||
child: Column(
|
||||
children: [
|
||||
// Icon badge
|
||||
Container(
|
||||
width: 56,
|
||||
height: 56,
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
AppColor.primaryColor.withAlpha(26), // 0.1 opacity
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
shape: BoxShape.circle,
|
||||
color: (isDestructive
|
||||
? AppColor.redColor
|
||||
: AppColor.primaryColor)
|
||||
.withOpacity(0.1),
|
||||
border: Border.all(
|
||||
color: (isDestructive
|
||||
? AppColor.redColor
|
||||
: AppColor.primaryColor)
|
||||
.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
child: Icon(
|
||||
CupertinoIcons.speaker_2_fill,
|
||||
color: AppColor.primaryColor,
|
||||
size: 24,
|
||||
icon ??
|
||||
(isDestructive
|
||||
? Icons.warning_amber_rounded
|
||||
: Icons.info_outline_rounded),
|
||||
color: isDestructive
|
||||
? AppColor.redColor
|
||||
: AppColor.primaryColor,
|
||||
size: 26,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
midTitle!,
|
||||
style: AppStyle.title.copyWith(
|
||||
fontSize: 16,
|
||||
height: 1.3,
|
||||
color: Colors.black87,
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Title
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.title.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: -0.4,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
|
||||
if (midTitle != null && midTitle.isNotEmpty) ...[
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
midTitle,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.subtitle.copyWith(
|
||||
fontSize: 14.5,
|
||||
height: 1.5,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// TTS button
|
||||
_SpeakButton(
|
||||
texts: [title, if (midTitle.isNotEmpty) midTitle]),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
onPressed: () {
|
||||
HapticFeedback.lightImpact();
|
||||
Get.back();
|
||||
},
|
||||
child: Text(
|
||||
'Cancel'.tr,
|
||||
style: TextStyle(
|
||||
color: AppColor.redColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
onPressed: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
onPressed();
|
||||
},
|
||||
child: Text(
|
||||
'OK'.tr,
|
||||
style: TextStyle(
|
||||
color: AppColor.greenColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// ── Actions ───────────────────────────────────────────
|
||||
_ActionRow(
|
||||
onCancel: () => Get.back(),
|
||||
onConfirm: onPressed,
|
||||
confirmLabel: 'OK'.tr,
|
||||
isDestructive: isDestructive,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.black.withAlpha(102), // 0.4 opacity
|
||||
barrierColor: _DC.barrierColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MyDialogContent — title + arbitrary widget content
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
class MyDialogContent extends GetxController {
|
||||
void getDialog(String title, Widget? content, VoidCallback onPressed) {
|
||||
final textToSpeechController = Get.put(TextToSpeechController());
|
||||
|
||||
void getDialog(
|
||||
String title,
|
||||
Widget? content,
|
||||
VoidCallback onPressed, {
|
||||
IconData? icon,
|
||||
bool isDestructive = false,
|
||||
String confirmLabel = 'OK',
|
||||
}) {
|
||||
HapticFeedback.mediumImpact();
|
||||
|
||||
Get.dialog(
|
||||
TweenAnimationBuilder<double>(
|
||||
duration: DialogConfig.animationDuration,
|
||||
tween: Tween(begin: 0.0, end: 1.0),
|
||||
builder: (context, value, child) {
|
||||
return Transform.scale(
|
||||
scale: 0.95 + (0.05 * value),
|
||||
child: Opacity(opacity: value, child: child),
|
||||
);
|
||||
},
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(
|
||||
sigmaX: DialogConfig.blurStrength,
|
||||
sigmaY: DialogConfig.blurStrength,
|
||||
),
|
||||
child: Theme(
|
||||
data: ThemeData.light().copyWith(
|
||||
dialogBackgroundColor: CupertinoColors.systemBackground,
|
||||
),
|
||||
child: CupertinoAlertDialog(
|
||||
title: Column(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: AppStyle.title.copyWith(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: -0.5,
|
||||
color: AppColor.primaryColor,
|
||||
_DialogShell(
|
||||
child: _GlassCard(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// ── Body ──────────────────────────────────────────────
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(24, 28, 24, 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Header row: icon + title + TTS
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: (isDestructive
|
||||
? AppColor.redColor
|
||||
: AppColor.primaryColor)
|
||||
.withOpacity(0.1),
|
||||
),
|
||||
child: Icon(
|
||||
icon ??
|
||||
(isDestructive
|
||||
? Icons.warning_amber_rounded
|
||||
: Icons.tune_rounded),
|
||||
color: isDestructive
|
||||
? AppColor.redColor
|
||||
: AppColor.primaryColor,
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: AppStyle.title.copyWith(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: -0.3,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
_SpeakButton(texts: [title]),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
children: [
|
||||
CupertinoButton(
|
||||
padding: const EdgeInsets.all(8),
|
||||
onPressed: () async {
|
||||
HapticFeedback.selectionClick();
|
||||
await textToSpeechController.speakText(title);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
AppColor.primaryColor.withAlpha(26), // 0.1 opacity
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Icon(
|
||||
CupertinoIcons.headphones,
|
||||
color: AppColor.primaryColor,
|
||||
size: 24,
|
||||
|
||||
// Divider
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Divider(
|
||||
height: 1,
|
||||
color: Colors.grey.withOpacity(0.15),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
content!,
|
||||
],
|
||||
|
||||
// Content
|
||||
if (content != null) content,
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
onPressed: () {
|
||||
HapticFeedback.lightImpact();
|
||||
Get.back();
|
||||
},
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: TextStyle(
|
||||
color: AppColor.redColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
onPressed: () {
|
||||
HapticFeedback.mediumImpact();
|
||||
onPressed();
|
||||
},
|
||||
child: Text(
|
||||
'OK'.tr,
|
||||
style: TextStyle(
|
||||
color: AppColor.greenColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// ── Actions ───────────────────────────────────────────
|
||||
_ActionRow(
|
||||
onCancel: () => Get.back(),
|
||||
onConfirm: onPressed,
|
||||
confirmLabel: confirmLabel.tr,
|
||||
isDestructive: isDestructive,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.black.withAlpha(102), // 0.4 opacity
|
||||
barrierColor: _DC.barrierColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user