yumi-flutter/lib/ui_kit/widgets/entry_popup/entry_popup_dialog.dart
2026-05-08 22:52:12 +08:00

121 lines
3.5 KiB
Dart

import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:yumi/shared/business_logic/models/res/sc_entry_popup_res.dart';
import 'package:yumi/shared/tools/sc_network_image_utils.dart';
class SCEntryPopupDialog extends StatefulWidget {
const SCEntryPopupDialog({
super.key,
required this.popup,
required this.onTap,
this.imageUrl,
this.onDisplayed,
});
static const String dialogTag = 'showEntryPopupDialog';
final SCEntryPopupItem popup;
final VoidCallback onTap;
final String? imageUrl;
final VoidCallback? onDisplayed;
static Future<void> show(
BuildContext context, {
required SCEntryPopupItem popup,
required VoidCallback onTap,
String? imageUrl,
VoidCallback? onDisplayed,
}) async {
SmartDialog.dismiss(tag: dialogTag);
await SmartDialog.show(
tag: dialogTag,
alignment: Alignment.center,
maskColor: Colors.black.withValues(alpha: 0.58),
animationType: SmartAnimationType.fade,
clickMaskDismiss: true,
builder:
(_) => SCEntryPopupDialog(
popup: popup,
onTap: onTap,
imageUrl: imageUrl,
onDisplayed: onDisplayed,
),
);
}
@override
State<SCEntryPopupDialog> createState() => _SCEntryPopupDialogState();
}
class _SCEntryPopupDialogState extends State<SCEntryPopupDialog> {
bool _hasNotifiedDisplayed = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted || _hasNotifiedDisplayed) {
return;
}
_hasNotifiedDisplayed = true;
widget.onDisplayed?.call();
});
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.sizeOf(context).width;
final dialogWidth = math.min(screenWidth - 42.w, 326.w);
final imageUrl = (widget.imageUrl ?? widget.popup.image).trim();
return Material(
color: Colors.transparent,
child: Center(
child: SizedBox(
width: dialogWidth,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: widget.onTap,
child: ClipRRect(
borderRadius: BorderRadius.circular(12.w),
child: Image(
image: buildCachedImageProvider(
imageUrl,
logicalWidth: dialogWidth,
),
width: dialogWidth,
fit: BoxFit.contain,
errorBuilder: (_, __, ___) => const SizedBox.shrink(),
),
),
),
SizedBox(height: 18.w),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap:
() =>
SmartDialog.dismiss(tag: SCEntryPopupDialog.dialogTag),
child: Padding(
padding: EdgeInsets.all(8.w),
child: Image.asset(
'sc_images/general/sc_icon_pic_close.png',
width: 30.w,
height: 30.w,
fit: BoxFit.contain,
),
),
),
],
),
),
),
);
}
}