♻️ Refactor Sn Network Provider to use without context

This commit is contained in:
LittleSheep 2024-12-21 17:23:46 +08:00
parent eb125fc436
commit e458943f56
2 changed files with 38 additions and 10 deletions

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
@ -42,7 +43,7 @@ import 'package:workmanager/workmanager.dart';
@pragma('vm:entry-point') @pragma('vm:entry-point')
void appBackgroundDispatcher() { void appBackgroundDispatcher() {
Workmanager().executeTask((task, inputData) async { Workmanager().executeTask((task, inputData) async {
print("Native called background task: $task"); log("[WorkManager] Native called background task: $task");
switch (task) { switch (task) {
case Workmanager.iOSBackgroundTask: case Workmanager.iOSBackgroundTask:
await Future.wait([widgetUpdateRandomPost()]); await Future.wait([widgetUpdateRandomPost()]);
@ -50,6 +51,8 @@ void appBackgroundDispatcher() {
case "WidgetUpdateRandomPost": case "WidgetUpdateRandomPost":
await widgetUpdateRandomPost(); await widgetUpdateRandomPost();
return true; return true;
case "ChatReplyMessage":
return true;
default: default:
return true; return true;
} }

View File

@ -20,6 +20,8 @@ const kNetworkServerDirectory = [
('Local', 'http://localhost:8001'), ('Local', 'http://localhost:8001'),
]; ];
Completer<String?>? _refreshCompleter;
class SnNetworkProvider { class SnNetworkProvider {
late final Dio client; late final Dio client;
@ -90,6 +92,13 @@ class SnNetworkProvider {
RequestOptions options, RequestOptions options,
RequestInterceptorHandler handler, RequestInterceptorHandler handler,
) async { ) async {
final atk = await _getFreshAtk(client, prefs.getString(kAtkStoreKey), (atk, rtk) {
prefs.setString(kAtkStoreKey, atk);
prefs.setString(kRtkStoreKey, rtk);
});
if (atk != null) {
options.headers['Authorization'] = 'Bearer $atk';
}
options.headers['User-Agent'] = ua; options.headers['User-Agent'] = ua;
return handler.next(options); return handler.next(options);
}, },
@ -135,9 +144,13 @@ class SnNetworkProvider {
final tkLock = Lock(); final tkLock = Lock();
Completer<String?>? _refreshCompleter;
Future<String?> getFreshAtk() async { Future<String?> getFreshAtk() async {
return await _getFreshAtk(client, _prefs.getString(kAtkStoreKey), (atk, rtk) {
setTokenPair(atk, rtk);
});
}
static Future<String?> _getFreshAtk(Dio client, String? atk, Function(String atk, String rtk)? onRefresh) async {
if (_refreshCompleter != null) { if (_refreshCompleter != null) {
return await _refreshCompleter!.future; return await _refreshCompleter!.future;
} else { } else {
@ -145,7 +158,6 @@ class SnNetworkProvider {
} }
try { try {
var atk = _prefs.getString(kAtkStoreKey);
if (atk != null) { if (atk != null) {
final atkParts = atk.split('.'); final atkParts = atk.split('.');
if (atkParts.length != 3) { if (atkParts.length != 3) {
@ -171,7 +183,13 @@ class SnNetworkProvider {
final exp = jsonDecode(payload)['exp']; final exp = jsonDecode(payload)['exp'];
if (exp <= DateTime.now().millisecondsSinceEpoch ~/ 1000) { if (exp <= DateTime.now().millisecondsSinceEpoch ~/ 1000) {
log('Access token need refresh, doing it at ${DateTime.now()}'); log('Access token need refresh, doing it at ${DateTime.now()}');
atk = await refreshToken(); final result = await _refreshToken(client.options.baseUrl, atk);
if (result == null) {
atk = null;
} else {
atk = result.$1;
onRefresh?.call(atk, result.$2);
}
} }
if (atk != null) { if (atk != null) {
@ -209,21 +227,28 @@ class SnNetworkProvider {
Future<String?> refreshToken() async { Future<String?> refreshToken() async {
final rtk = _prefs.getString(kRtkStoreKey); final rtk = _prefs.getString(kRtkStoreKey);
final result = await _refreshToken(client.options.baseUrl, rtk);
if (result == null) return null;
_prefs.setString(kAtkStoreKey, result.$1);
_prefs.setString(kRtkStoreKey, result.$2);
return result.$1;
}
static Future<(String, String)?> _refreshToken(String baseUrl, String? rtk) async {
if (rtk == null) return null; if (rtk == null) return null;
final dio = Dio(); final dio = Dio();
dio.options.baseUrl = client.options.baseUrl; dio.options.baseUrl = baseUrl;
final resp = await dio.post('/cgi/id/auth/token', data: { final resp = await dio.post('/cgi/id/auth/token', data: {
'grant_type': 'refresh_token', 'grant_type': 'refresh_token',
'refresh_token': rtk, 'refresh_token': rtk,
}); });
final atk = resp.data['access_token']; final String atk = resp.data['access_token'];
final nRtk = resp.data['refresh_token']; final String nRtk = resp.data['refresh_token'];
setTokenPair(atk, nRtk);
return atk; return (atk, nRtk);
} }
void setBaseUrl(String url) { void setBaseUrl(String url) {