import 'dart:async'; import 'dart:io' show Platform; import 'package:flutter/foundation.dart'; import 'package:umeng_common_sdk/umeng_common_sdk.dart'; import 'package:umeng_push_sdk/umeng_push_sdk.dart'; import '../config/umeng_config.dart'; import '../privacy/privacy_gate.dart'; import '../services/device_header_service.dart'; import '../storage/storage_keys.dart'; import '../storage/storage_service.dart'; abstract final class UmengPushService { static const _maxPendingNotificationOpens = 20; static final _tokens = StreamController.broadcast(); static Future? _starting; static bool _started = false; static void Function(String payload)? _onNotificationOpen; static final List _pendingNotificationOpens = []; static Stream get onDeviceToken => _tokens.stream; static void configureNotificationOpen( void Function(String payload) callback, ) { _onNotificationOpen = callback; final pending = List.of(_pendingNotificationOpens); _pendingNotificationOpens.clear(); for (final payload in pending) { callback(payload); } } static Future startIfAllowed() { if (kIsWeb || _started || requiresAndroidPrivacyConsent( isWeb: kIsWeb, platform: defaultTargetPlatform, privacyAgreed: StorageService.to.getBool(storagePrivacyAgreed), )) { return Future.value(); } return _starting ??= _start().whenComplete(() => _starting = null); } static Future _start() async { await DeviceHeaderService.to.ensureInitialized(); await UmengCommonSdk.initCommon( UmengConfig.androidAppKey, UmengConfig.iosAppKey, DeviceHeaderService.to.commonHeaders()['User-Channel'] ?? 'test', UmengConfig.androidPushSecret, ); UmengPushSdk.setTokenCallback(_emit); UmengPushSdk.setNotificationCallback((_) {}, (payload) { final callback = _onNotificationOpen; if (callback == null) { if (_pendingNotificationOpens.length == _maxPendingNotificationOpens) { _pendingNotificationOpens.removeAt(0); } _pendingNotificationOpens.add(payload); } else { callback(payload); } }); await UmengPushSdk.register( UmengConfig.iosAppKey, DeviceHeaderService.to.commonHeaders()['User-Channel'] ?? 'test', ); if (Platform.isAndroid) await UmengPushSdk.setPushEnable(true); _started = true; await refreshDeviceToken(); } static Future refreshDeviceToken() async { if (!_started || kIsWeb) return; _emit(await UmengPushSdk.getRegisteredId()); } static void emitCachedToken() => _emit(StorageService.to.getString(storageDeviceToken)); static void _emit(String? token) { if (token == null || token.isEmpty) return; _tokens.add(token); unawaited(StorageService.to.setString(storageDeviceToken, token)); } }