make message analytics entry getter in practice activity card, split token update function into two functions

pull/1490/head
ggurdin 1 year ago
parent 9f8fef3de0
commit c72f250e1a
No known key found for this signature in database
GPG Key ID: A01CB41737CBB478

@ -33,24 +33,13 @@ class MessageAnalyticsEntry {
.map((token) => TokenWithXP(token: token)) .map((token) => TokenWithXP(token: token))
.toList(); .toList();
computeTargetTypesForMessage(); updateTargetTypesForMessage();
} }
List<TokenWithXP> get tokensThatCanBeHeard => List<TokenWithXP> get tokensThatCanBeHeard =>
tokensWithXp.where((t) => t.token.canBeHeard).toList(); tokensWithXp.where((t) => t.token.canBeHeard).toList();
// compute target tokens within async wrapper that adds a 250ms delay void updateTokenTargetTypes() {
// to avoid blocking the UI thread
Future<void> computeTargetTypesForMessageAsync() async {
await Future.delayed(const Duration(milliseconds: 250));
computeTargetTypesForMessage();
}
void computeTargetTypesForMessage() {
// reset
nextActivityToken = null;
nextActivityType = null;
// compute target types for each token // compute target types for each token
for (final token in tokensWithXp) { for (final token in tokensWithXp) {
token.targetTypes = []; token.targetTypes = [];
@ -81,26 +70,39 @@ class MessageAnalyticsEntry {
token.targetTypes.add(ActivityTypeEnum.hiddenWordListening); token.targetTypes.add(ActivityTypeEnum.hiddenWordListening);
} }
} }
}
/// Updates the target types for each token in the message and the next
/// activity token and type. Called before requesting the next new activity.
void updateTargetTypesForMessage() {
// reset
nextActivityToken = null;
nextActivityType = null;
updateTokenTargetTypes();
// from the tokens with hiddenWordListening in targetTypes, pick one at random // From the tokens with hiddenWordListening in targetTypes, pick one at random.
final List<int> withListening = tokensWithXp // Create a list of token indicies with hiddenWordListening type available.
final List<int> withHiddenWordIndices = tokensWithXp
.asMap() .asMap()
.entries .entries
.where( .where(
(entry) => entry.value.targetTypes (entry) => entry.value.targetTypes.contains(
.contains(ActivityTypeEnum.hiddenWordListening), ActivityTypeEnum.hiddenWordListening,
),
) )
.map((entry) => entry.key) .map((entry) => entry.key)
.toList(); .toList();
// randomly pick one entry in the list
if (withListening.isNotEmpty) { // randomly pick one index in the list and set the next activity
if (withHiddenWordIndices.isNotEmpty) {
final int randomIndex = final int randomIndex =
withListening[Random().nextInt(withListening.length)]; withHiddenWordIndices[Random().nextInt(withHiddenWordIndices.length)];
nextActivityToken = tokensWithXp[randomIndex]; nextActivityToken = tokensWithXp[randomIndex];
nextActivityType = ActivityTypeEnum.hiddenWordListening; nextActivityType = ActivityTypeEnum.hiddenWordListening;
// remove from all other tokens // remove hiddenWord type from all other tokens
// there can only be one hidden word activity for a message
for (int i = 0; i < tokensWithXp.length; i++) { for (int i = 0; i < tokensWithXp.length; i++) {
if (i != randomIndex) { if (i != randomIndex) {
tokensWithXp[i] tokensWithXp[i]

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer'; import 'dart:developer';
import 'package:fluffychat/pangea/controllers/message_analytics_controller.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/controllers/practice_activity_generation_controller.dart'; import 'package:fluffychat/pangea/controllers/practice_activity_generation_controller.dart';
import 'package:fluffychat/pangea/controllers/put_analytics_controller.dart'; import 'package:fluffychat/pangea/controllers/put_analytics_controller.dart';
@ -53,10 +54,11 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
List<PracticeActivityEvent> get practiceActivities => List<PracticeActivityEvent> get practiceActivities =>
widget.pangeaMessageEvent.practiceActivities; widget.pangeaMessageEvent.practiceActivities;
PracticeActivityEvent? get existingActivityMatchingNeeds { MessageAnalyticsEntry? get messageAnalyticsEntry =>
final messageAnalyticsEntry = pangeaController.getAnalytics.perMessage MatrixState.pangeaController.getAnalytics.perMessage
.get(widget.pangeaMessageEvent, false); .get(widget.pangeaMessageEvent, false);
PracticeActivityEvent? get existingActivityMatchingNeeds {
if (messageAnalyticsEntry?.nextActivityToken == null) { if (messageAnalyticsEntry?.nextActivityToken == null) {
debugger(when: kDebugMode); debugger(when: kDebugMode);
return null; return null;
@ -67,7 +69,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
if (existingActivity.practiceActivity.tgtConstructs if (existingActivity.practiceActivity.tgtConstructs
.any((tc) => tc == c.id) && .any((tc) => tc == c.id) &&
existingActivity.practiceActivity.activityType == existingActivity.practiceActivity.activityType ==
messageAnalyticsEntry.nextActivityType) { messageAnalyticsEntry!.nextActivityType) {
debugPrint('found existing activity'); debugPrint('found existing activity');
return existingActivity; return existingActivity;
} }
@ -163,9 +165,6 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
return null; return null;
} }
final messageAnalyticsEntry = pangeaController.getAnalytics.perMessage
.get(widget.pangeaMessageEvent, false);
// the client is going to be choosing the next activity now // the client is going to be choosing the next activity now
// if nothing is set then it must be done with practice // if nothing is set then it must be done with practice
if (messageAnalyticsEntry?.nextActivityToken == null || if (messageAnalyticsEntry?.nextActivityToken == null ||
@ -206,8 +205,8 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
: ActivityTypeEnum.values : ActivityTypeEnum.values
.where((type) => type != ActivityTypeEnum.wordFocusListening) .where((type) => type != ActivityTypeEnum.wordFocusListening)
.toList(), .toList(),
clientTokenRequest: messageAnalyticsEntry.nextActivityToken!, clientTokenRequest: messageAnalyticsEntry!.nextActivityToken!,
clientTypeRequest: messageAnalyticsEntry.nextActivityType!, clientTypeRequest: messageAnalyticsEntry!.nextActivityType!,
), ),
widget.pangeaMessageEvent, widget.pangeaMessageEvent,
); );
@ -277,13 +276,7 @@ class PracticeActivityCardState extends State<PracticeActivityCard> {
// previously we would update the tokens with the constructs // previously we would update the tokens with the constructs
// now the tokens themselves calculate their own points using the analytics // now the tokens themselves calculate their own points using the analytics
// we're going to see if this creates performance issues // we're going to see if this creates performance issues
final messageAnalytics = MatrixState messageAnalyticsEntry?.updateTargetTypesForMessage();
.pangeaController.getAnalytics.perMessage
.get(widget.pangeaMessageEvent, false);
// messageAnalytics will only be null if there are no tokens to update
// set the target types for the next activity
messageAnalytics!.computeTargetTypesForMessageAsync();
widget.overlayController.onActivityFinish(); widget.overlayController.onActivityFinish();
pangeaController.activityRecordController.completeActivity( pangeaController.activityRecordController.completeActivity(

Loading…
Cancel
Save