added documentation to user controller and user model

pull/1384/head
ggurdin 1 year ago
parent 3759731d48
commit 8acc793f0c

@ -4,6 +4,7 @@ import 'package:collection/collection.dart';
import 'package:fluffychat/pangea/constants/language_constants.dart';
import 'package:fluffychat/pangea/controllers/base_controller.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:matrix/matrix.dart' as matrix;
@ -26,11 +27,16 @@ class UserController extends BaseController {
String? get _matrixAccessToken =>
_pangeaController.matrixState.client.accessToken;
/// Cached version of the user profile, so it doesn't have
/// to be read in from client's account data each time it is accessed.
Profile? _cachedProfile;
/// Listens for account updates and updates the cached profile
StreamSubscription? _profileListener;
/// Listen for updates to account data in syncs and update the cached profile
void addProfileListener() {
_pangeaController.matrixState.client.onSync.stream
_profileListener ??= _pangeaController.matrixState.client.onSync.stream
.where((sync) => sync.accountData != null)
.listen((sync) {
final Profile? fromAccountData = Profile.fromAccountData();
@ -64,11 +70,13 @@ class UserController extends BaseController {
return _cachedProfile ?? Profile.emptyProfile;
}
/// Updates the user's profile with the given [update] function and saves it.
void updateProfile(Profile Function(Profile) update) {
final Profile updatedProfile = update(profile);
updatedProfile.saveProfileData();
}
/// Creates a new profile for the user with the given date of birth.
Future<void> createProfile({required DateTime dob}) async {
final userSettings = UserSettings(
dateOfBirth: dob,
@ -81,6 +89,9 @@ class UserController extends BaseController {
/// A completer for the profile model of a user.
Completer<void>? _profileCompleter;
/// Initializes the user's profile. Runs a function to wait for account data to load,
/// read account data into profile, and migrate any missing info from the pangea profile.
/// Finally, it adds a listen to update the profile data when new account data comes in.
Future<void> initialize() async {
if (_profileCompleter?.isCompleted ?? false) {
return _profileCompleter!.future;
@ -105,11 +116,14 @@ class UserController extends BaseController {
return _profileCompleter!.future;
}
/// Initializes the user's profile by waiting for account data to load, reading in account
/// data to profile, and migrating from the pangea profile if the account data is not present.
Future<void> _initialize() async {
await waitForAccountData();
await _pangeaController.matrixState.client.waitForAccountData();
if (profile.userSettings.dateOfBirth != null) {
return;
}
final PangeaProfileResponse? resp = await PUserRepo.fetchPangeaUserInfo(
userID: userId!,
matrixAccessToken: _matrixAccessToken!,
@ -117,6 +131,7 @@ class UserController extends BaseController {
if (resp?.profile == null) {
return;
}
final userSetting = UserSettings.fromJson(resp!.profile.toJson());
final newProfile = Profile(userSettings: userSetting);
await newProfile.saveProfileData(waitForDataInSync: true);
@ -130,14 +145,6 @@ class UserController extends BaseController {
await initialize();
}
/// Account data comes through in the first sync, so wait for that
Future<void> waitForAccountData() async {
final client = _pangeaController.matrixState.client;
if (client.prevBatch == null) {
await client.onSync.stream.first;
}
}
/// Returns a boolean value indicating whether a new JWT (JSON Web Token) is needed.
bool needNewJWT(String token) => Jwt.isExpired(token);

@ -80,4 +80,6 @@ extension PangeaClient on Client {
String? powerLevelName(int powerLevel, L10n l10n) =>
_powerLevelName(powerLevel, l10n);
Future<void> waitForAccountData() async => await _waitForAccountData();
}

@ -78,4 +78,11 @@ extension GeneralInfoClientExtension on Client {
50: l10n.moderator,
100: l10n.admin,
}[powerLevel];
/// Account data comes through in the first sync, so wait for that
Future<void> _waitForAccountData() async {
if (prevBatch == null) {
await onSync.stream.first;
}
}
}

@ -7,6 +7,7 @@ import 'package:matrix/matrix.dart';
import 'language_model.dart';
/// The user's settings learning settings.
class UserSettings {
DateTime? dateOfBirth;
DateTime? createdAt;
@ -114,6 +115,7 @@ class UserSettings {
}
}
/// The user's language tool settings.
class UserToolSettings {
bool interactiveTranslator;
bool interactiveGrammar;
@ -177,6 +179,7 @@ class UserToolSettings {
}
}
/// The user's settings for whether or not to show instuction messages.
class UserInstructions {
bool showedItInstructions;
bool showedClickMessage;
@ -255,6 +258,7 @@ class Profile {
this.instructionSettings = instructionSettings ?? UserInstructions();
}
/// Load an instance of profile from the client's account data.
static Profile? fromAccountData() {
final profileData = MatrixState.pangeaController.matrixState.client
.accountData[ModelKey.userProfile]?.content;
@ -292,6 +296,8 @@ class Profile {
return json;
}
/// Migrate data from the old matrix account data
/// format to the new matrix account data format.
static Profile? migrateFromAccountData() {
final userSettings = UserSettings.migrateFromAccountData();
if (userSettings == null) return null;
@ -305,6 +311,9 @@ class Profile {
);
}
/// Saves the current configuration of the profile to the client's account data.
/// If [waitForDataInSync] is true, the function will wait for the updated account
/// data to come through in a sync, indicating that it has been set on the matrix server.
Future<void> saveProfileData({
waitForDataInSync = false,
}) async {

Loading…
Cancel
Save