63 lines
1.8 KiB
Dart
63 lines
1.8 KiB
Dart
import 'package:oktoast/oktoast.dart' as ok;
|
|
|
|
import 'debug_log.dart';
|
|
|
|
/// Toast 位置
|
|
enum ToastGravity { top, center, bottom }
|
|
|
|
const _duration = Duration(seconds: 2);
|
|
|
|
/// Toast 队列:一条消失后回调里再弹下一条(时序由 oktoast 精确控制)
|
|
final _queue = <_ToastItem>[];
|
|
bool _isShowing = false;
|
|
|
|
class _ToastItem {
|
|
final String message;
|
|
final ToastGravity gravity;
|
|
_ToastItem(this.message, this.gravity);
|
|
}
|
|
|
|
/// 显示 Toast 消息(连续调用会排队,一条消失后再弹下一条)
|
|
void showToast(String message, {ToastGravity? gravity}) {
|
|
if (message.isEmpty) return;
|
|
// 相邻重复的直接忽略,避免同一句刷屏
|
|
if (_queue.isNotEmpty && _queue.last.message == message) return;
|
|
_queue.add(_ToastItem(message, gravity ?? ToastGravity.center));
|
|
_drain();
|
|
}
|
|
|
|
void _drain() {
|
|
if (_isShowing || _queue.isEmpty) return;
|
|
_isShowing = true;
|
|
final item = _queue.removeAt(0);
|
|
|
|
var done = false;
|
|
void next() {
|
|
if (done) return;
|
|
done = true;
|
|
_isShowing = false;
|
|
_drain();
|
|
}
|
|
|
|
try {
|
|
ok.showToast(
|
|
item.message,
|
|
duration: _duration,
|
|
position: switch (item.gravity) {
|
|
ToastGravity.top => ok.ToastPosition.top,
|
|
ToastGravity.bottom => ok.ToastPosition.bottom,
|
|
ToastGravity.center => ok.ToastPosition.center,
|
|
},
|
|
onDismiss: next,
|
|
);
|
|
} catch (e) {
|
|
// OKToast 未挂载(启动早期)时 oktoast 直接抛错,不兜住的话 _isShowing 永久为 true → 全 App toast 静默失效
|
|
debugLog("showToast()...error:$e");
|
|
_queue.clear();
|
|
_isShowing = false;
|
|
return;
|
|
}
|
|
// 兜底:toast 被提前 dismiss 或 overlay 已销毁时 oktoast 不回调 onDismiss,超时自愈
|
|
Future.delayed(_duration + const Duration(milliseconds: 500), next);
|
|
}
|