import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:sunny_mochi/core/error/exception_mapper.dart'; import 'package:sunny_mochi/core/widgets/app_toast.dart'; import 'package:sunny_mochi/features/error_report/data/error_logger.dart'; extension BuildContextX on BuildContext { /// 弹一个 Toast 风格的 SnackBar(对应 iOS Mkt.makeToast(...))。 void showToast( String message, { ToastType type = ToastType.info, Duration duration = const Duration(seconds: 4), }) => AppToast.show(this, message, type: type, duration: duration); /// 异常 → ExceptionMapper.fromUnknown(e, st) → toast(Failure.message)。 /// /// 兜底替代散落的 `on Object catch (e, st) { mapper.fromUnknown; if(mounted) showToast }` /// 模板(5+ 处 mine 表单提交流程)。 void showError(WidgetRef ref, Object error, StackTrace stackTrace) { final failure = ref.read(exceptionMapperProvider).fromUnknown(error, stackTrace); // 写入本地错误日志(fire-and-forget,不阻塞 UI) unawaited(ref.read(errorLoggerProvider).log(failure)); if (mounted) showToast(failure.userMessage, type: ToastType.error); } /// 当前 Theme 快捷读取。 ThemeData get theme => Theme.of(this); ColorScheme get colors => theme.colorScheme; TextTheme get textTheme => theme.textTheme; /// 屏幕信息快捷读取。 Size get screenSize => MediaQuery.sizeOf(this); EdgeInsets get screenPadding => MediaQuery.paddingOf(this); double get screenWidth => screenSize.width; double get screenHeight => screenSize.height; }