96 lines
2.6 KiB
Dart
96 lines
2.6 KiB
Dart
import 'dart:async';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
|
|
import '../network/dio_provider.dart';
|
|
import 'notification_permission.dart';
|
|
import 'umeng_push_service.dart';
|
|
|
|
class DevicePushRegistrar {
|
|
DevicePushRegistrar(this._read);
|
|
final T Function<T>(ProviderListenable<T>) _read;
|
|
StreamSubscription<String>? _subscription;
|
|
String? _lastToken;
|
|
bool? _lastPermission;
|
|
int _attempt = 0;
|
|
|
|
void start() {
|
|
_subscription ??= UmengPushService.onDeviceToken.listen(_register);
|
|
UmengPushService.emitCachedToken();
|
|
}
|
|
|
|
Future<void> stop() async => _subscription?.cancel();
|
|
Future<void> refresh() => UmengPushService.refreshDeviceToken();
|
|
void forceRegisterCurrentToken() {
|
|
_lastToken = null;
|
|
_lastPermission = null;
|
|
UmengPushService.emitCachedToken();
|
|
}
|
|
|
|
Future<void> _register(String token) async {
|
|
final permission = await NotificationPermission.isGranted();
|
|
if (token == _lastToken && permission == _lastPermission) return;
|
|
try {
|
|
final package = await PackageInfo.fromPlatform();
|
|
await _read(dioProvider).post<List<int>>(
|
|
'/api/v1/push/devices',
|
|
data: _PushRegisterRequest(
|
|
token: token,
|
|
platform: defaultTargetPlatform == TargetPlatform.iOS ? 1 : 2,
|
|
version: package.version,
|
|
permission: permission,
|
|
).toBytes(),
|
|
options: protobufOptions(),
|
|
);
|
|
_lastToken = token;
|
|
_lastPermission = permission;
|
|
_attempt = 0;
|
|
} catch (_) {
|
|
if (_attempt++ >= 3) return;
|
|
await Future<void>.delayed(Duration(seconds: 1 << (_attempt - 1)));
|
|
await _register(token);
|
|
}
|
|
}
|
|
}
|
|
|
|
class _PushRegisterRequest {
|
|
const _PushRegisterRequest({
|
|
required this.token,
|
|
required this.platform,
|
|
required this.version,
|
|
required this.permission,
|
|
});
|
|
final String token;
|
|
final int platform;
|
|
final String version;
|
|
final bool permission;
|
|
Uint8List toBytes() {
|
|
final bytes = BytesBuilder(copy: false);
|
|
void putInt(int value) {
|
|
while (value > 0x7f) {
|
|
bytes.addByte((value & 0x7f) | 0x80);
|
|
value >>= 7;
|
|
}
|
|
bytes.addByte(value);
|
|
}
|
|
|
|
void putString(int tag, String value) {
|
|
final raw = value.codeUnits;
|
|
putInt((tag << 3) | 2);
|
|
putInt(raw.length);
|
|
bytes.add(raw);
|
|
}
|
|
|
|
putString(1, token);
|
|
putInt(2 << 3);
|
|
putInt(platform);
|
|
putString(3, version);
|
|
putInt(4 << 3);
|
|
putInt(permission ? 1 : 0);
|
|
return bytes.toBytes();
|
|
}
|
|
}
|