130 lines
3.8 KiB
Dart
130 lines
3.8 KiB
Dart
import 'dart:async';
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:flutter_new_badger/flutter_new_badger.dart';
|
||
import 'package:qhd_prevention/common/route_service.dart';
|
||
import 'package:qhd_prevention/http/ApiService.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:qhd_prevention/http/modules/notif_api.dart';
|
||
|
||
|
||
/// 优化版 BadgeManager:每个接口超时保护、增量更新、notify 合并、原生角标 debounce
|
||
class BadgeManager extends ChangeNotifier {
|
||
BadgeManager._internal();
|
||
static final BadgeManager _instance = BadgeManager._internal();
|
||
factory BadgeManager() => _instance;
|
||
// 添加完整的工作数据存储
|
||
Map<String, dynamic> _workData = {};
|
||
Map<String, dynamic> get workData => _workData;
|
||
// 各模块未读
|
||
int _notifCount = 0;
|
||
|
||
|
||
// 读取接口值的公开 getter
|
||
int get count => _notifCount ;
|
||
int get notifCount => _notifCount;
|
||
|
||
|
||
|
||
// 通知合并控制(短时间内多次更新只触发一次 notify)
|
||
Timer? _notifyTimer;
|
||
Duration _notifyDelay = const Duration(milliseconds: 180);
|
||
void _scheduleNotify() {
|
||
// 如果已有计划,不需要再立即计划(合并)
|
||
_notifyTimer?.cancel();
|
||
_notifyTimer = Timer(_notifyDelay, () {
|
||
try {
|
||
notifyListeners();
|
||
} catch (e) {
|
||
debugPrint('BadgeManager.notifyListeners error: $e');
|
||
}
|
||
_notifyTimer = null;
|
||
});
|
||
}
|
||
|
||
// 原生角标同步 debounce(防止短时间内频繁调用)
|
||
Timer? _syncTimer;
|
||
Duration _syncDelay = const Duration(milliseconds: 250);
|
||
void _syncNativeDebounced() {
|
||
_syncTimer?.cancel();
|
||
_syncTimer = Timer(_syncDelay, () {
|
||
try {
|
||
final total = count;
|
||
if (total > 0) {
|
||
FlutterNewBadger.setBadge(total);
|
||
} else {
|
||
FlutterNewBadger.removeBadge();
|
||
}
|
||
} catch (e) {
|
||
debugPrint('BadgeManager._syncNativeDebounced error: $e');
|
||
}
|
||
_syncTimer = null;
|
||
});
|
||
}
|
||
|
||
// safe wrapper: 给单个 future 加超时与兜底返回
|
||
Future<T> _safe<T>(Future<T> future, T fallback, {Duration timeout = const Duration(seconds: 5)}) async {
|
||
try {
|
||
return await future.timeout(timeout);
|
||
} catch (e, st) {
|
||
// 报错不抛出到外层,记录并返回 fallback
|
||
debugPrint('BadgeManager._safe error: $e\n$st');
|
||
return fallback;
|
||
}
|
||
}
|
||
|
||
/// 初始化所有模块(并行发起,但每个接口独立 timeout & 提交结果)
|
||
Future<void> initAllModules() async {
|
||
// 不 await 整个 Future.wait,使调用方不会因为单个慢接口阻塞
|
||
try {
|
||
// 每个请求都通过 _safe 包裹,设置超时与兜底
|
||
final fNotif = _safe<Map<String, dynamic>>(
|
||
NotifApi.getNotifRedPoint().then((r) => r as Map<String, dynamic>),
|
||
<String, dynamic>{},
|
||
timeout: const Duration(seconds: 4),
|
||
);
|
||
|
||
|
||
fNotif.then((notifJson) {
|
||
try {
|
||
_notifCount = ((notifJson['data'] as int?) ?? 0);
|
||
} catch (e, st) {
|
||
debugPrint('BadgeManager.parse notifJson error: $e\n$st');
|
||
}
|
||
_scheduleNotify();
|
||
_syncNativeDebounced();
|
||
});
|
||
|
||
|
||
} catch (e, st) {
|
||
debugPrint('BadgeManager.initAllModules unexpected error: $e\n$st');
|
||
}
|
||
}
|
||
|
||
// 下面的 updateX 方法也做了超时保护并使用 _onModuleChanged 合并通知
|
||
|
||
void updateNotifCount() async {
|
||
try {
|
||
final notifJson = await _safe<Map<String, dynamic>>(
|
||
NotifApi.getNotifRedPoint().then((r) => r as Map<String, dynamic>),
|
||
<String, dynamic>{},
|
||
timeout: const Duration(seconds: 4),
|
||
);
|
||
_notifCount = (notifJson['data'] as int?) ?? 0;
|
||
_onModuleChanged();
|
||
} catch (e) {
|
||
debugPrint('updateNotifCount error: $e');
|
||
}
|
||
}
|
||
|
||
|
||
void clearAll() {
|
||
_syncNativeDebounced();
|
||
_scheduleNotify();
|
||
}
|
||
|
||
void _onModuleChanged() {
|
||
_syncNativeDebounced();
|
||
_scheduleNotify();
|
||
}
|
||
}
|