Template
Core 基础设施:Flavor 三包体系、Drift+SQLCipher 加密数据库 7 拦截器 Dio 网络栈、CrashReporter 崩溃日志、Sealed Failure 错误体系 5 色板主题系统、Auth 认证骨架(Clean Architecture)、Dev Panel、Mock Adapter 通过验证:flutter analyze(0 errors)、flutter test(全绿)、staging APK 74.8MB
40 lines
1.6 KiB
Dart
40 lines
1.6 KiB
Dart
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;
|
||
}
|