diff --git a/lib/pangea/analytics_data/analytics_data_service.dart b/lib/pangea/analytics_data/analytics_data_service.dart index f01371c9b..6fec64bca 100644 --- a/lib/pangea/analytics_data/analytics_data_service.dart +++ b/lib/pangea/analytics_data/analytics_data_service.dart @@ -273,7 +273,7 @@ class AnalyticsDataService { final Map cappedLastUseCache = {}; for (final use in uses) { if (blocked.contains(use.identifier)) continue; - if (use.category == 'other') continue; + if (use.identifier.isInvalid) continue; if (!cappedLastUseCache.containsKey(use.identifier)) { final constructs = await getConstructUse(use.identifier, language); diff --git a/lib/pangea/analytics_data/construct_merge_table.dart b/lib/pangea/analytics_data/construct_merge_table.dart index 77cb2b065..2e125a236 100644 --- a/lib/pangea/analytics_data/construct_merge_table.dart +++ b/lib/pangea/analytics_data/construct_merge_table.dart @@ -23,8 +23,7 @@ class ConstructMergeTable { ) { for (final use in uses) { final id = use.identifier; - if (exclude.contains(id)) continue; - if (id.category == 'other') continue; + if (exclude.contains(id) || id.isInvalid) continue; final composite = id.compositeKey; (lemmaTypeGroups[composite] ??= {}).add(id); @@ -32,8 +31,7 @@ class ConstructMergeTable { for (final use in uses) { final id = use.identifier; - if (exclude.contains(id)) continue; - if (id.category == 'other') continue; + if (exclude.contains(id) || id.isInvalid) continue; final group = lemmaTypeGroups[id.compositeKey]; if (group == null) continue; @@ -71,7 +69,7 @@ class ConstructMergeTable { Set exclude, ) { final keys = []; - if (exclude.contains(id) || id.category == 'other') { + if (exclude.contains(id) || id.isInvalid) { return keys; } diff --git a/lib/pangea/analytics_practice/analytics_practice_analytics_controller.dart b/lib/pangea/analytics_practice/analytics_practice_analytics_controller.dart index d9fe255a9..9a4fcdb39 100644 --- a/lib/pangea/analytics_practice/analytics_practice_analytics_controller.dart +++ b/lib/pangea/analytics_practice/analytics_practice_analytics_controller.dart @@ -1,9 +1,7 @@ import 'package:fluffychat/pangea/analytics_data/analytics_data_service.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; -import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/practice_activities/practice_target.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -24,21 +22,26 @@ class AnalyticsPracticeAnalyticsController { ) => analyticsService.updateService.addAnalytics(targetId, uses, language); Future addSkippedActivityAnalytics( - PangeaToken token, - ConstructTypeEnum type, + PracticeTarget target, String language, ) async { - final use = OneConstructUse( - useType: ConstructUseTypeEnum.ignPA, - constructType: type, - metadata: ConstructUseMetaData(roomId: null, timeStamp: DateTime.now()), - category: token.pos, - lemma: token.lemma.text, - form: token.lemma.text, - xp: 0, - ); - - await analyticsService.updateService.addAnalytics(null, [use], language); + final uses = target.tokens + .map( + (t) => OneConstructUse( + useType: ConstructUseTypeEnum.ignPA, + constructType: target.activityType.constructUsesType, + metadata: ConstructUseMetaData( + roomId: null, + timeStamp: DateTime.now(), + ), + category: t.pos, + lemma: t.lemma.text, + form: t.lemma.text, + xp: 0, + ), + ) + .toList(); + await analyticsService.updateService.addAnalytics(null, uses, language); } Future addSessionAnalytics( diff --git a/lib/pangea/analytics_practice/analytics_practice_page.dart b/lib/pangea/analytics_practice/analytics_practice_page.dart index d302488df..8c7d8a915 100644 --- a/lib/pangea/analytics_practice/analytics_practice_page.dart +++ b/lib/pangea/analytics_practice/analytics_practice_page.dart @@ -314,8 +314,7 @@ class AnalyticsPracticeState extends State // Record a 0 XP use so that activity isn't chosen again soon _sessionController.skipActivity(); await _analyticsController.addSkippedActivityAnalytics( - request.target.tokens.first, - widget.type, + request.target, _l2!.langCodeShort, ); } diff --git a/lib/pangea/constructs/construct_identifier.dart b/lib/pangea/constructs/construct_identifier.dart index da0cff3cf..e95b482b5 100644 --- a/lib/pangea/constructs/construct_identifier.dart +++ b/lib/pangea/constructs/construct_identifier.dart @@ -37,7 +37,6 @@ class ConstructIdentifier { if (type == ConstructTypeEnum.morph && MorphFeaturesEnumExtension.fromString(category) == MorphFeaturesEnum.Unknown) { - debugger(when: kDebugMode); ErrorHandler.logError( e: Exception("Morph feature not found"), data: {"category": category, "lemma": lemma, "type": type}, @@ -97,8 +96,8 @@ class ConstructIdentifier { other.lemma == lemma && other.type == type && (category == other.category || - category.toLowerCase() == "other" || - other.category.toLowerCase() == "other"); + category.toLowerCase() == 'other' || + other.category.toLowerCase() == 'other'); } @override @@ -190,4 +189,10 @@ class ConstructIdentifier { (isContentWord ? AnalyticsConstants.contentWordMultiplier : AnalyticsConstants.functionWordMultiplier); + + bool get isInvalid => + (type == ConstructTypeEnum.morph && + MorphFeaturesEnumExtension.fromString(category) == + MorphFeaturesEnum.Unknown) || + category == 'other'; } diff --git a/lib/pangea/practice_activities/activity_type_enum.dart b/lib/pangea/practice_activities/activity_type_enum.dart index 38724d88d..7acf3be0f 100644 --- a/lib/pangea/practice_activities/activity_type_enum.dart +++ b/lib/pangea/practice_activities/activity_type_enum.dart @@ -252,4 +252,17 @@ enum ActivityTypeEnum { return _grammarPracticeTypes; } } + + /// The type of construct uses that these activities produce. + /// NOTE: Grammar error activities create vocab uses, assosiated with the tokens in the + /// targeted error span – NOT morph uses. + ConstructTypeEnum get constructUsesType { + switch (this) { + case ActivityTypeEnum.grammarCategory: + case ActivityTypeEnum.morphId: + return ConstructTypeEnum.morph; + default: + return ConstructTypeEnum.vocab; + } + } } diff --git a/lib/pangea/practice_activities/practice_activity_model.dart b/lib/pangea/practice_activities/practice_activity_model.dart index 665bac0e1..c1f0963b8 100644 --- a/lib/pangea/practice_activities/practice_activity_model.dart +++ b/lib/pangea/practice_activities/practice_activity_model.dart @@ -1,6 +1,5 @@ import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart'; import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart'; import 'package:fluffychat/pangea/analytics_practice/analytics_practice_session_model.dart'; @@ -241,7 +240,7 @@ sealed class MultipleChoicePracticeActivityModel extends PracticeActivityModel { .map( (token) => OneConstructUse( useType: useType, - constructType: ConstructTypeEnum.vocab, + constructType: activityType.constructUsesType, metadata: ConstructUseMetaData( roomId: null, timeStamp: DateTime.now(), @@ -310,7 +309,7 @@ sealed class MorphPracticeActivityModel .map( (token) => OneConstructUse( useType: useType, - constructType: ConstructTypeEnum.morph, + constructType: activityType.constructUsesType, metadata: ConstructUseMetaData( roomId: null, timeStamp: DateTime.now(), @@ -390,7 +389,7 @@ class VocabAudioPracticeActivityModel return [ OneConstructUse( useType: useType, - constructType: ConstructTypeEnum.vocab, + constructType: activityType.constructUsesType, metadata: ConstructUseMetaData(roomId: null, timeStamp: DateTime.now()), category: matchingToken.pos, lemma: matchingToken.lemma.text,