QinGang_interested/lib/pages/badge_manager.dart

130 lines
3.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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();
}
}