addressed some of Will's questions

This commit is contained in:
ggurdin 2024-11-07 10:03:34 -05:00
parent fd71a736ad
commit 8ee4ea31c8
No known key found for this signature in database
GPG key ID: A01CB41737CBB478
6 changed files with 54 additions and 38 deletions

View file

@ -1016,9 +1016,6 @@ class ChatListController extends State<ChatList>
}
// #Pangea
//@ggurdin why is are these two initialized separately? why not in the _initPangeaControllers?
MatrixState.pangeaController.putAnalytics.initialize();
MatrixState.pangeaController.getAnalytics.initialize();
await _initPangeaControllers(client);
// Pangea#
if (!mounted) return;
@ -1029,6 +1026,8 @@ class ChatListController extends State<ChatList>
// #Pangea
Future<void> _initPangeaControllers(Client client) async {
MatrixState.pangeaController.putAnalytics.initialize();
MatrixState.pangeaController.getAnalytics.initialize();
if (mounted) {
final PangeaController pangeaController = MatrixState.pangeaController;
GoogleAnalytics.analyticsUserUpdate(client.userID);

View file

@ -128,11 +128,11 @@ class GetAnalyticsController {
type: ConstructTypeEnum.vocab,
);
final errors = ConstructListModel(
final morphs = ConstructListModel(
uses: constructs,
type: ConstructTypeEnum.morph,
);
return words.points + errors.points;
return words.points + morphs.points;
}
List<OneConstructUse> get allConstructUses {

View file

@ -169,6 +169,13 @@ class PangeaController {
GoogleAnalytics.analyticsUserUpdate(matrixState.client.userID);
}
Future<void> resetAnalytics() async {
putAnalytics.dispose();
getAnalytics.dispose();
putAnalytics.initialize();
getAnalytics.initialize();
}
void startChatWithBotIfNotPresent() {
Future.delayed(const Duration(milliseconds: 10000), () async {
// check if user is logged in

View file

@ -24,6 +24,7 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
CachedStreamController<AnalyticsUpdate> analyticsUpdateStream =
CachedStreamController<AnalyticsUpdate>();
StreamSubscription<AnalyticsStream>? _analyticsStream;
StreamSubscription? _languageStream;
Timer? _updateTimer;
Client get _client => _pangeaController.matrixState.client;
@ -57,6 +58,15 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
_analyticsStream ??=
stateStream.listen((data) => _onNewAnalyticsData(data));
// Listen for changes to the user's language settings
_languageStream ??=
_pangeaController.userController.stateStream.listen((update) {
if (update is Map<String, dynamic>) {
final previousL2 = update['prev_target_lang'];
_onUpdateLanguages(previousL2);
}
});
_refreshAnalyticsIfOutdated();
}
@ -68,6 +78,8 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
lastUpdatedCompleter = Completer<DateTime?>();
_analyticsStream?.cancel();
_analyticsStream = null;
_languageStream?.cancel();
_languageStream = null;
_refreshAnalyticsIfOutdated();
clearMessagesSinceUpdate();
}
@ -131,6 +143,13 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
);
}
Future<void> _onUpdateLanguages(String previousL2) async {
await sendLocalAnalyticsToAnalyticsRoom(
l2Override: previousL2,
);
_pangeaController.resetAnalytics();
}
void addDraftUses(
List<PangeaToken> tokens,
String roomID,
@ -299,6 +318,7 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
/// since the last update and notifies the [analyticsUpdateStream].
Future<void> sendLocalAnalyticsToAnalyticsRoom({
onLogout = false,
String? l2Override,
}) async {
if (_pangeaController.matrixState.client.userID == null) return;
if (!(_updateCompleter?.isCompleted ?? true)) {
@ -307,7 +327,7 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
}
_updateCompleter = Completer<void>();
try {
await _updateAnalytics();
await _updateAnalytics(l2Override: l2Override);
clearMessagesSinceUpdate();
lastUpdated = DateTime.now();
@ -331,7 +351,7 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
/// Updates the analytics by sending cached analytics data to the analytics room.
/// The analytics room is determined based on the user's current target language.
Future<void> _updateAnalytics() async {
Future<void> _updateAnalytics({String? l2Override}) async {
// if there's no cached construct data, there's nothing to send
final cachedConstructs = _pangeaController.getAnalytics.messagesSinceUpdate;
final bool onlyDraft = cachedConstructs.length == 1 &&
@ -339,10 +359,11 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
if (cachedConstructs.isEmpty || onlyDraft) return;
// if missing important info, don't send analytics. Could happen if user just signed up.
if (userL2 == null || _client.userID == null) return;
final l2Code = l2Override ?? userL2;
if (l2Code == null || _client.userID == null) return;
// analytics room for the user and current target language
final Room? analyticsRoom = await _client.getMyAnalyticsRoom(userL2!);
final Room? analyticsRoom = await _client.getMyAnalyticsRoom(l2Code);
// and send cached analytics data to the room
await analyticsRoom?.sendConstructsEvent(

View file

@ -73,8 +73,14 @@ class UserController extends BaseController {
Profile Function(Profile) update, {
waitForDataInSync = false,
}) async {
final prevTargetLang = profile.userSettings.targetLanguage;
final Profile updatedProfile = update(profile);
await updatedProfile.saveProfileData(waitForDataInSync: waitForDataInSync);
if (prevTargetLang != updatedProfile.userSettings.targetLanguage) {
setState({'prev_target_lang': prevTargetLang});
}
}
/// Creates a new profile for the user with the given date of birth.

View file

@ -93,35 +93,18 @@ Future<void> pLanguageDialog(
context: context,
future: () async {
try {
//@ggurdin while this is obviously working, it feels pretty hidden
//and could lead to errors if someone where to change the user L2 via some
// other means. with analytics being dependent on languages, it probably
// would make sense for analytics to listen to the language stateStream
// and update in this case
pangeaController.putAnalytics
.sendLocalAnalyticsToAnalyticsRoom()
.then((_) {
pangeaController.userController.updateProfile(
(profile) {
profile.userSettings.sourceLanguage =
selectedSourceLanguage.langCode;
profile.userSettings.targetLanguage =
selectedTargetLanguage.langCode;
return profile;
},
waitForDataInSync: true,
);
}).then((_) {
// if the profile update is successful, reset cached analytics
// data, since analytics data corresponds to the user's L2
pangeaController.putAnalytics.dispose();
pangeaController.getAnalytics.dispose();
pangeaController.putAnalytics.initialize();
pangeaController.getAnalytics.initialize();
Navigator.pop(context);
});
await pangeaController.userController
.updateProfile(
(profile) {
profile.userSettings.sourceLanguage =
selectedSourceLanguage.langCode;
profile.userSettings.targetLanguage =
selectedTargetLanguage.langCode;
return profile;
},
waitForDataInSync: true,
);
Navigator.pop(context);
} catch (err, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: s);