125 lines
4.1 KiB
Dart
125 lines
4.1 KiB
Dart
|
|
import 'dart:convert';
|
||
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
||
|
|
import 'package:guru_app/account/model/account_profile.dart';
|
||
|
|
import 'package:guru_app/account/model/user.dart';
|
||
|
|
import 'package:guru_app/analytics/guru_analytics.dart';
|
||
|
|
import 'package:guru_app/api/guru_api.dart';
|
||
|
|
import 'package:guru_app/guru_app.dart';
|
||
|
|
import 'package:guru_app/property/app_property.dart';
|
||
|
|
import 'package:guru_utils/device/device_info.dart';
|
||
|
|
import 'package:guru_utils/extensions/extensions.dart';
|
||
|
|
|
||
|
|
import 'package:http/http.dart' as http;
|
||
|
|
|
||
|
|
/// Created by Haoyi on 6/3/21
|
||
|
|
///
|
||
|
|
enum AccountDataStatus { idle, initializing, initialized, waiting, error }
|
||
|
|
|
||
|
|
class AccountDataStore {
|
||
|
|
static final AccountDataStore instance = AccountDataStore._();
|
||
|
|
|
||
|
|
final BehaviorSubject<DeviceInfo?> _deviceInfoSubject = BehaviorSubject.seeded(null);
|
||
|
|
final BehaviorSubject<SaasUser?> _saasUserSubject = BehaviorSubject.seeded(null);
|
||
|
|
final BehaviorSubject<User?> _firebaseUser = BehaviorSubject.seeded(null);
|
||
|
|
final BehaviorSubject<AccountProfile?> _accountProfile = BehaviorSubject.seeded(null);
|
||
|
|
final BehaviorSubject<AccountDataStatus> _accountDataStatus =
|
||
|
|
BehaviorSubject<AccountDataStatus>.seeded(AccountDataStatus.idle);
|
||
|
|
int initRetryCount = 0;
|
||
|
|
|
||
|
|
Stream<AccountProfile?> get observableAccountProfile => _accountProfile.stream;
|
||
|
|
|
||
|
|
// final EnvConfig envConfig;
|
||
|
|
|
||
|
|
AccountDataStore._();
|
||
|
|
|
||
|
|
String? get saasToken => _saasUserSubject.value?.token;
|
||
|
|
|
||
|
|
String? get uid => _saasUserSubject.value?.uid;
|
||
|
|
|
||
|
|
AccountProfile? get accountProfile => _accountProfile.value;
|
||
|
|
|
||
|
|
String? get nickname => _accountProfile.value?.nickname;
|
||
|
|
|
||
|
|
String? get countryCode => _accountProfile.value?.countryCode;
|
||
|
|
|
||
|
|
SaasUser? get user => _saasUserSubject.value;
|
||
|
|
|
||
|
|
String? get avatar => _accountProfile.value?.avatar;
|
||
|
|
|
||
|
|
DeviceInfo? get currentDevice => _deviceInfoSubject.value;
|
||
|
|
|
||
|
|
AccountDataStatus get accountDataStatus => _accountDataStatus.value;
|
||
|
|
|
||
|
|
bool get initialized => _accountDataStatus.value == AccountDataStatus.initialized;
|
||
|
|
|
||
|
|
Stream<bool> get observableInitialized =>
|
||
|
|
_accountDataStatus.stream.map((status) => status == AccountDataStatus.initialized);
|
||
|
|
|
||
|
|
Stream<SaasUser?> get observableSaasUser => _saasUserSubject.stream;
|
||
|
|
|
||
|
|
void dispose() {
|
||
|
|
_deviceInfoSubject.close();
|
||
|
|
_saasUserSubject.close();
|
||
|
|
_firebaseUser.close();
|
||
|
|
_accountProfile.close();
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<SaasUser?> signInAnonymousInLocked() async {
|
||
|
|
// 这里需要使用原始的http post请求。否则这里将会死锁DIO所有请求
|
||
|
|
final secret = await AppProperty.getInstance().getAnonymousSecretKey();
|
||
|
|
final headers = {
|
||
|
|
"X-APP-ID": GuruApp.instance.details.saasAppId,
|
||
|
|
"content-type": "application/json"
|
||
|
|
};
|
||
|
|
try {
|
||
|
|
final uri = Uri.parse("${GuruApi.saasApiHost}/auth/api/v1/tokens/provider/secret");
|
||
|
|
final response = await http
|
||
|
|
.post(uri,
|
||
|
|
headers: headers,
|
||
|
|
body: jsonEncode(AnonymousLoginReqBody(secret: secret)),
|
||
|
|
encoding: utf8)
|
||
|
|
.timeout(const Duration(seconds: 30));
|
||
|
|
final data = const Utf8Decoder().convert(response.bodyBytes);
|
||
|
|
if (data.isNotEmpty) {
|
||
|
|
final result = json.decode(data);
|
||
|
|
return SaasUser.fromJson(result["data"]);
|
||
|
|
}
|
||
|
|
} catch (error, stacktrace) {
|
||
|
|
Log.v("signInAnonymousInLocked error:$error", tag: "Account");
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future refreshAuth() async {
|
||
|
|
final saasUser = await signInAnonymousInLocked();
|
||
|
|
if (saasUser != null) {
|
||
|
|
updateSaasUser(saasUser);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void updateDeviceInfo(DeviceInfo deviceInfo) {
|
||
|
|
_deviceInfoSubject.addEx(deviceInfo);
|
||
|
|
}
|
||
|
|
|
||
|
|
void updateSaasUser(SaasUser saasUser) {
|
||
|
|
_saasUserSubject.addEx(saasUser);
|
||
|
|
|
||
|
|
if (saasUser.createAtTimestamp > 0) {
|
||
|
|
GuruAnalytics.instance
|
||
|
|
.setUserProperty("user_created_timestamp", saasUser.createAtTimestamp.toString());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void updateFirebaseUser(User user) {
|
||
|
|
_firebaseUser.addEx(user);
|
||
|
|
}
|
||
|
|
|
||
|
|
void updateAccountProfile(AccountProfile profile) {
|
||
|
|
_accountProfile.addEx(profile);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool transitionTo(AccountDataStatus status, {AccountDataStatus? expectStatus}) {
|
||
|
|
return _accountDataStatus.addIfChanged(status);
|
||
|
|
}
|
||
|
|
}
|