Skip to content

Commit

Permalink
1370 space analytics download (#1381)
Browse files Browse the repository at this point in the history
* fix: reassign eventID metadata when turning locally saved draft uses into locally saved uses with assosiated eventID

* feat: initial work for space analytics download

* feat: updated spreadsheet columns in space analytics download

* feat: move space analytics download logic to widget

* feat: improved download loading UI

* feat: added error logging to space analytics download dialog
  • Loading branch information
ggurdin authored Jan 8, 2025
1 parent 7b1cccf commit 26285ea
Show file tree
Hide file tree
Showing 22 changed files with 1,254 additions and 172 deletions.
37 changes: 36 additions & 1 deletion assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -4661,5 +4661,40 @@
"clickWordsInstructions": "Click on individual words for more activities.",
"chooseBestDefinition": "Choose the best definition",
"chooseBaseForm": "Choose the base form",
"notTheCodeError": "Sorry, that's not the code!"
"notTheCodeError": "Sorry, that's not the code!",
"totalXP": "Total XP",
"numLemmas": "Number of lemmas",
"listOfLemmas": "List of lemmas",
"numLemmasUsedCorrectly": "Number of lemmas used correctly at least once",
"listLemmasUsedCorrectly": "List of lemmas used correctly at least once",
"numLemmasUsedIncorrectly": "Number of lemmas used incorrectly at least once",
"listLemmasUsedIncorrectly": "List of lemmas used incorrectly at least once",
"numLemmasSmallXP": "Number of lemmas with 0 - 30 XP",
"numLemmasMediumXP": "Number of lemmas with 31 - 200 XP",
"numLemmasLargeXP": "Number of lemmas with > 200 XP",
"listLemmasSmallXP": "List of lemmas with 0 - 30 XP",
"listLemmasMediumXP": "List of lemmas with 31 - 200 XP",
"listLemmasLargeXP": "List of lemmas with > 200 XP",
"numGrammarConcepts": "Number of grammar concepts",
"listGrammarConcepts": "List of grammar concepts",
"listGrammarConceptsUsedCorrectly": "List of grammar concepts used correctly at least 80% of the time",
"listGrammarConceptsUsedIncorrectly": "List of grammar concepts used correctly less than 80% of the time",
"incorrectGrammarConceptsUseCases": "Use cases of grammar concepts used incorrectly",
"listGrammarConceptsSmallXP": "List of grammar concepts with 0 - 30 XP",
"listGrammarConceptsMediumXP": "List of grammar concepts with 31 - 200 XP",
"listGrammarConceptsLargeXP": "List of grammar concepts with 201 - 500 XP",
"listGrammarConceptsHugeXP": "List of grammar concepts with > 500 XP",
"numMessagesSent": "Number of messages sent",
"numWordsTyped": "Number of words typed in original messages",
"numCorrectChoices": "Number of correct words chosen from system-generated suggestions",
"numIncorrectChoices": "Number of incorrect words chosen from system-generated suggestions",
"downloadSpaceAnalytics": "Download space analytics",
"commaSeparatedFile": "CSV",
"excelFile": "Excel",
"fileType": "File type",
"download": "Download",
"analyticsNotAvailable": "User analytics not available",
"downloading": "Downloading...",
"failedFetchUserAnalytics": "Failed to download user analytics",
"downloadComplete": "Download complete!"
}
1 change: 1 addition & 0 deletions lib/pangea/controllers/get_analytics_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import 'package:fluffychat/pangea/utils/error_handler.dart';
class GetAnalyticsController {
late PangeaController _pangeaController;
late MessageAnalyticsController perMessage;

final List<AnalyticsCacheEntry> _cache = [];
StreamSubscription<AnalyticsUpdate>? _analyticsUpdateSubscription;
StreamController<AnalyticsStreamUpdate> analyticsStream =
Expand Down
11 changes: 11 additions & 0 deletions lib/pangea/controllers/put_analytics_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,17 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
try {
final currentCache = _pangeaController.getAnalytics.messagesSinceUpdate;
constructs.addAll(currentCache[cacheKey] ?? []);

// if this is not a draft message, add the eventId to the metadata
// if it's missing (it will be missing for draft constructs)
if (!cacheKey.startsWith('draft')) {
constructs = constructs.map((construct) {
if (construct.metadata.eventId != null) return construct;
construct.metadata.eventId = cacheKey;
return construct;
}).toList();
}

currentCache[cacheKey] = constructs;

await _setMessagesSinceUpdate(currentCache);
Expand Down
108 changes: 108 additions & 0 deletions lib/pangea/enum/analytics/analytics_summary_enum.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import 'package:flutter_gen/gen_l10n/l10n.dart';

enum AnalyticsSummaryEnum {
username,
level,
totalXP,
numLemmas,
numLemmasUsedCorrectly,
numLemmasUsedIncorrectly,
// listLemmas,
// listLemmasUsedCorrectly,
// listLemmasUsedIncorrectly,

/// 0 - 30 XP
numLemmasSmallXP,
// listLemmasSmallXP,

/// 31 - 200 XP
numLemmasMediumXP,
// listLemmasMediumXP,

/// > 200 XP
numLemmasLargeXP,
// listLemmasLargeXP,

numMorphConstructs,
listMorphConstructs,
listMorphConstructsUsedCorrectly,
listMorphConstructsUsedIncorrectly,

// list morph 0 - 30 XP
listMorphSmallXP,

// list morph 31 - 200 XP
listMorphMediumXP,

// list morph 200 - 500 XP
listMorphLargeXP,

// list morph > 500 XP
listMorphHugeXP,

numMessagesSent,
numWordsTyped,
numChoicesCorrect,
numChoicesIncorrect,
}

extension AnalyticsSummaryEnumExtension on AnalyticsSummaryEnum {
String header(L10n l10n) {
switch (this) {
case AnalyticsSummaryEnum.username:
return l10n.username;
case AnalyticsSummaryEnum.level:
return l10n.level;
case AnalyticsSummaryEnum.totalXP:
return l10n.totalXP;
case AnalyticsSummaryEnum.numLemmas:
return l10n.numLemmas;
case AnalyticsSummaryEnum.numLemmasUsedCorrectly:
return l10n.numLemmasUsedCorrectly;
case AnalyticsSummaryEnum.numLemmasUsedIncorrectly:
return l10n.numLemmasUsedIncorrectly;
// case AnalyticsSummaryEnum.listLemmas:
// return l10n.listOfLemmas;
// case AnalyticsSummaryEnum.listLemmasUsedCorrectly:
// return l10n.listLemmasUsedCorrectly;
// case AnalyticsSummaryEnum.listLemmasUsedIncorrectly:
// return l10n.listLemmasUsedIncorrectly;
case AnalyticsSummaryEnum.numLemmasSmallXP:
return l10n.numLemmasSmallXP;
case AnalyticsSummaryEnum.numLemmasMediumXP:
return l10n.numLemmasMediumXP;
case AnalyticsSummaryEnum.numLemmasLargeXP:
return l10n.numLemmasLargeXP;
// case AnalyticsSummaryEnum.listLemmasSmallXP:
// return l10n.listLemmasSmallXP;
// case AnalyticsSummaryEnum.listLemmasMediumXP:
// return l10n.listLemmasMediumXP;
// case AnalyticsSummaryEnum.listLemmasLargeXP:
// return l10n.listLemmasLargeXP;
case AnalyticsSummaryEnum.numMorphConstructs:
return l10n.numGrammarConcepts;
case AnalyticsSummaryEnum.listMorphConstructs:
return l10n.listGrammarConcepts;
case AnalyticsSummaryEnum.listMorphConstructsUsedCorrectly:
return l10n.listGrammarConceptsUsedCorrectly;
case AnalyticsSummaryEnum.listMorphConstructsUsedIncorrectly:
return l10n.listGrammarConceptsUsedIncorrectly;
case AnalyticsSummaryEnum.listMorphSmallXP:
return l10n.listGrammarConceptsSmallXP;
case AnalyticsSummaryEnum.listMorphMediumXP:
return l10n.listGrammarConceptsMediumXP;
case AnalyticsSummaryEnum.listMorphLargeXP:
return l10n.listGrammarConceptsLargeXP;
case AnalyticsSummaryEnum.listMorphHugeXP:
return l10n.listGrammarConceptsHugeXP;
case AnalyticsSummaryEnum.numMessagesSent:
return l10n.numMessagesSent;
case AnalyticsSummaryEnum.numWordsTyped:
return l10n.numWordsTyped;
case AnalyticsSummaryEnum.numChoicesCorrect:
return l10n.numCorrectChoices;
case AnalyticsSummaryEnum.numChoicesIncorrect:
return l10n.numIncorrectChoices;
}
}
}
73 changes: 73 additions & 0 deletions lib/pangea/enum/construct_use_type_enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';

import 'package:fluffychat/pangea/enum/activity_type_enum.dart';
import 'package:fluffychat/pangea/enum/analytics/analytics_summary_enum.dart';

enum ConstructUseTypeEnum {
/// produced in chat by user, igc was run, and we've judged it to be a correct use
Expand Down Expand Up @@ -215,6 +216,78 @@ extension ConstructUseTypeExtension on ConstructUseTypeEnum {
return -3;
}
}

bool get sentByUser {
switch (this) {
case ConstructUseTypeEnum.wa:
case ConstructUseTypeEnum.ga:
case ConstructUseTypeEnum.unk:
case ConstructUseTypeEnum.corIt:
case ConstructUseTypeEnum.ignIt:
case ConstructUseTypeEnum.incIt:
case ConstructUseTypeEnum.corIGC:
case ConstructUseTypeEnum.incIGC:
case ConstructUseTypeEnum.ignIGC:
return true;

case ConstructUseTypeEnum.corPA:
case ConstructUseTypeEnum.ignPA:
case ConstructUseTypeEnum.incPA:
case ConstructUseTypeEnum.corWL:
case ConstructUseTypeEnum.incWL:
case ConstructUseTypeEnum.ignWL:
case ConstructUseTypeEnum.corHWL:
case ConstructUseTypeEnum.incHWL:
case ConstructUseTypeEnum.ignHWL:
case ConstructUseTypeEnum.corL:
case ConstructUseTypeEnum.incL:
case ConstructUseTypeEnum.ignL:
case ConstructUseTypeEnum.corM:
case ConstructUseTypeEnum.incM:
case ConstructUseTypeEnum.ignM:
case ConstructUseTypeEnum.em:
case ConstructUseTypeEnum.nan:
return false;
}
}

AnalyticsSummaryEnum? get summaryEnumType {
switch (this) {
case ConstructUseTypeEnum.wa:
case ConstructUseTypeEnum.ga:
case ConstructUseTypeEnum.unk:
return AnalyticsSummaryEnum.numWordsTyped;

case ConstructUseTypeEnum.corIt:
case ConstructUseTypeEnum.corPA:
case ConstructUseTypeEnum.corIGC:
case ConstructUseTypeEnum.corWL:
case ConstructUseTypeEnum.corHWL:
case ConstructUseTypeEnum.corL:
case ConstructUseTypeEnum.corM:
case ConstructUseTypeEnum.em:
return AnalyticsSummaryEnum.numChoicesCorrect;

case ConstructUseTypeEnum.incIt:
case ConstructUseTypeEnum.incIGC:
case ConstructUseTypeEnum.incPA:
case ConstructUseTypeEnum.incWL:
case ConstructUseTypeEnum.incHWL:
case ConstructUseTypeEnum.incL:
case ConstructUseTypeEnum.incM:
return AnalyticsSummaryEnum.numChoicesIncorrect;

case ConstructUseTypeEnum.ignIt:
case ConstructUseTypeEnum.ignPA:
case ConstructUseTypeEnum.ignIGC:
case ConstructUseTypeEnum.ignWL:
case ConstructUseTypeEnum.ignHWL:
case ConstructUseTypeEnum.ignL:
case ConstructUseTypeEnum.ignM:
case ConstructUseTypeEnum.nan:
return null;
}
}
}

class ConstructUseTypeUtil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,25 @@ extension AnalyticsClientExtension on Client {
// so they will appear in the space hierarchy
Future<void> _updateAnalyticsRoomVisibility() async {
if (userID == null || userID == BotName.byEnvironment) return;

final visibilityFutures = allMyAnalyticsRooms.map((room) async {
final visability = await getRoomVisibilityOnDirectory(room.id);
if (visability != Visibility.private) {
await setRoomVisibilityOnDirectory(
room.id,
visibility: Visibility.private,
);
}
}).toList();

final joinRulesFutures = allMyAnalyticsRooms.map((room) async {
if (room.joinRules != JoinRules.public) {
await room.setJoinRules(JoinRules.public);
}
}).toList();

await Future.wait(
allMyAnalyticsRooms.map((room) async {
final visability = await getRoomVisibilityOnDirectory(room.id);
if (visability != Visibility.public) {
await setRoomVisibilityOnDirectory(
room.id,
visibility: Visibility.public,
);
}
}),
visibilityFutures + joinRulesFutures,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ extension AnalyticsRoomExtension on Room {
}

Future<DateTime?> _analyticsLastUpdated(String userId) async {
final List<Event> events = await getRoomAnalyticsEvents(count: 1);
final List<Event> events =
await getRoomAnalyticsEvents(count: 1, userID: userId);
if (events.isEmpty) return null;
return events.first.originServerTs;
}
Expand All @@ -161,7 +162,7 @@ extension AnalyticsRoomExtension on Room {
required String userId,
DateTime? since,
}) async {
final events = await getRoomAnalyticsEvents();
final events = await getRoomAnalyticsEvents(userID: userId);
final List<ConstructAnalyticsEvent> analyticsEvents = [];
for (final Event event in events) {
analyticsEvents.add(ConstructAnalyticsEvent(event: event));
Expand Down
Loading

0 comments on commit 26285ea

Please sign in to comment.