From 8ee4ea31c83eef93e788534e033723b6d839ceef Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 7 Nov 2024 10:03:34 -0500 Subject: [PATCH] addressed some of Will's questions --- lib/pages/chat_list/chat_list.dart | 5 +-- .../controllers/get_analytics_controller.dart | 4 +- lib/pangea/controllers/pangea_controller.dart | 7 ++++ .../controllers/put_analytics_controller.dart | 29 +++++++++++-- lib/pangea/controllers/user_controller.dart | 6 +++ .../user_settings/p_language_dialog.dart | 41 ++++++------------- 6 files changed, 54 insertions(+), 38 deletions(-) diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index 770d9204f..9ad418e36 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -1016,9 +1016,6 @@ class ChatListController extends State } // #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 // #Pangea Future _initPangeaControllers(Client client) async { + MatrixState.pangeaController.putAnalytics.initialize(); + MatrixState.pangeaController.getAnalytics.initialize(); if (mounted) { final PangeaController pangeaController = MatrixState.pangeaController; GoogleAnalytics.analyticsUserUpdate(client.userID); diff --git a/lib/pangea/controllers/get_analytics_controller.dart b/lib/pangea/controllers/get_analytics_controller.dart index dba450091..181279f3d 100644 --- a/lib/pangea/controllers/get_analytics_controller.dart +++ b/lib/pangea/controllers/get_analytics_controller.dart @@ -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 get allConstructUses { diff --git a/lib/pangea/controllers/pangea_controller.dart b/lib/pangea/controllers/pangea_controller.dart index e0b33b054..3e737113d 100644 --- a/lib/pangea/controllers/pangea_controller.dart +++ b/lib/pangea/controllers/pangea_controller.dart @@ -169,6 +169,13 @@ class PangeaController { GoogleAnalytics.analyticsUserUpdate(matrixState.client.userID); } + Future 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 diff --git a/lib/pangea/controllers/put_analytics_controller.dart b/lib/pangea/controllers/put_analytics_controller.dart index 37768cdf0..f887a6d66 100644 --- a/lib/pangea/controllers/put_analytics_controller.dart +++ b/lib/pangea/controllers/put_analytics_controller.dart @@ -24,6 +24,7 @@ class PutAnalyticsController extends BaseController { CachedStreamController analyticsUpdateStream = CachedStreamController(); StreamSubscription? _analyticsStream; + StreamSubscription? _languageStream; Timer? _updateTimer; Client get _client => _pangeaController.matrixState.client; @@ -57,6 +58,15 @@ class PutAnalyticsController extends BaseController { _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) { + final previousL2 = update['prev_target_lang']; + _onUpdateLanguages(previousL2); + } + }); + _refreshAnalyticsIfOutdated(); } @@ -68,6 +78,8 @@ class PutAnalyticsController extends BaseController { lastUpdatedCompleter = Completer(); _analyticsStream?.cancel(); _analyticsStream = null; + _languageStream?.cancel(); + _languageStream = null; _refreshAnalyticsIfOutdated(); clearMessagesSinceUpdate(); } @@ -131,6 +143,13 @@ class PutAnalyticsController extends BaseController { ); } + Future _onUpdateLanguages(String previousL2) async { + await sendLocalAnalyticsToAnalyticsRoom( + l2Override: previousL2, + ); + _pangeaController.resetAnalytics(); + } + void addDraftUses( List tokens, String roomID, @@ -299,6 +318,7 @@ class PutAnalyticsController extends BaseController { /// since the last update and notifies the [analyticsUpdateStream]. Future 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 { } _updateCompleter = Completer(); try { - await _updateAnalytics(); + await _updateAnalytics(l2Override: l2Override); clearMessagesSinceUpdate(); lastUpdated = DateTime.now(); @@ -331,7 +351,7 @@ class PutAnalyticsController extends BaseController { /// 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 _updateAnalytics() async { + Future _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 { 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( diff --git a/lib/pangea/controllers/user_controller.dart b/lib/pangea/controllers/user_controller.dart index 53893cb7b..c076063c3 100644 --- a/lib/pangea/controllers/user_controller.dart +++ b/lib/pangea/controllers/user_controller.dart @@ -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. diff --git a/lib/pangea/widgets/user_settings/p_language_dialog.dart b/lib/pangea/widgets/user_settings/p_language_dialog.dart index b0276e11c..5b7c7b73d 100644 --- a/lib/pangea/widgets/user_settings/p_language_dialog.dart +++ b/lib/pangea/widgets/user_settings/p_language_dialog.dart @@ -93,35 +93,18 @@ Future 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);