|
|
|
@ -62,12 +62,13 @@ class AnalyticsController extends BaseController {
|
|
|
|
timeSpan.toString(),
|
|
|
|
timeSpan.toString(),
|
|
|
|
local: true,
|
|
|
|
local: true,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
setState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////// SPACE ANALYTICS LANGUAGES //////////
|
|
|
|
///////// SPACE ANALYTICS LANGUAGES //////////
|
|
|
|
String get _analyticsSpaceLangKey => "ANALYTICS_SPACE_LANG_KEY";
|
|
|
|
String get _analyticsSpaceLangKey => "ANALYTICS_SPACE_LANG_KEY";
|
|
|
|
|
|
|
|
|
|
|
|
LanguageModel get currentAnalyticsSpaceLang {
|
|
|
|
LanguageModel get currentAnalyticsLang {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
final String? str = _pangeaController.pStoreService.read(
|
|
|
|
final String? str = _pangeaController.pStoreService.read(
|
|
|
|
_analyticsSpaceLangKey,
|
|
|
|
_analyticsSpaceLangKey,
|
|
|
|
@ -83,41 +84,43 @@ class AnalyticsController extends BaseController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> setCurrentAnalyticsSpaceLang(LanguageModel lang) async {
|
|
|
|
Future<void> setCurrentAnalyticsLang(LanguageModel lang) async {
|
|
|
|
await _pangeaController.pStoreService.save(
|
|
|
|
await _pangeaController.pStoreService.save(
|
|
|
|
_analyticsSpaceLangKey,
|
|
|
|
_analyticsSpaceLangKey,
|
|
|
|
lang.langCode,
|
|
|
|
lang.langCode,
|
|
|
|
local: true,
|
|
|
|
local: true,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
setState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// given an analytics event type and the current analytics language,
|
|
|
|
|
|
|
|
/// get the last time the user updated their analytics
|
|
|
|
Future<DateTime?> myAnalyticsLastUpdated(String type) async {
|
|
|
|
Future<DateTime?> myAnalyticsLastUpdated(String type) async {
|
|
|
|
// given an analytics event type, get the last updated times
|
|
|
|
|
|
|
|
// for each of the user's analytics rooms and return the most recent
|
|
|
|
|
|
|
|
// Most Recent instead of the oldest because, for instance:
|
|
|
|
|
|
|
|
// My last Spanish event was sent 3 days ago.
|
|
|
|
|
|
|
|
// My last English event was sent 1 day ago.
|
|
|
|
|
|
|
|
// When I go to check if the cached data is out of date, the cached item was set 2 days ago.
|
|
|
|
|
|
|
|
// I know there’s new data available because the English update data (the most recent) is after the cache’s creation time.
|
|
|
|
|
|
|
|
// So, I should update the cache.
|
|
|
|
|
|
|
|
final List<Room> analyticsRooms = _pangeaController
|
|
|
|
final List<Room> analyticsRooms = _pangeaController
|
|
|
|
.matrixState.client.allMyAnalyticsRooms
|
|
|
|
.matrixState.client.allMyAnalyticsRooms
|
|
|
|
.where((room) => room.isAnalyticsRoom)
|
|
|
|
.where((room) => room.isAnalyticsRoom)
|
|
|
|
.toList();
|
|
|
|
.toList();
|
|
|
|
|
|
|
|
|
|
|
|
final List<DateTime> lastUpdates = [];
|
|
|
|
final Map<String, DateTime> langCodeLastUpdates = {};
|
|
|
|
for (final Room analyticsRoom in analyticsRooms) {
|
|
|
|
for (final Room analyticsRoom in analyticsRooms) {
|
|
|
|
|
|
|
|
final String? roomLang = analyticsRoom.madeForLang;
|
|
|
|
|
|
|
|
if (roomLang == null) continue;
|
|
|
|
final DateTime? lastUpdated = await analyticsRoom.analyticsLastUpdated(
|
|
|
|
final DateTime? lastUpdated = await analyticsRoom.analyticsLastUpdated(
|
|
|
|
type,
|
|
|
|
type,
|
|
|
|
_pangeaController.matrixState.client.userID!,
|
|
|
|
_pangeaController.matrixState.client.userID!,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (lastUpdated != null) {
|
|
|
|
if (lastUpdated != null) {
|
|
|
|
lastUpdates.add(lastUpdated);
|
|
|
|
langCodeLastUpdates[roomLang] = lastUpdated;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lastUpdates.isEmpty) return null;
|
|
|
|
if (langCodeLastUpdates.isEmpty) return null;
|
|
|
|
return lastUpdates.reduce(
|
|
|
|
final String? l2Code =
|
|
|
|
|
|
|
|
_pangeaController.languageController.userL2?.langCode;
|
|
|
|
|
|
|
|
if (l2Code != null && langCodeLastUpdates.containsKey(l2Code)) {
|
|
|
|
|
|
|
|
return langCodeLastUpdates[l2Code];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return langCodeLastUpdates.values.reduce(
|
|
|
|
(check, mostRecent) => check.isAfter(mostRecent) ? check : mostRecent,
|
|
|
|
(check, mostRecent) => check.isAfter(mostRecent) ? check : mostRecent,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -134,7 +137,7 @@ class AnalyticsController extends BaseController {
|
|
|
|
final List<Future<DateTime?>> lastUpdatedFutures = [];
|
|
|
|
final List<Future<DateTime?>> lastUpdatedFutures = [];
|
|
|
|
for (final student in space.students) {
|
|
|
|
for (final student in space.students) {
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
.analyticsRoomLocal(currentAnalyticsSpaceLang.langCode, student.id);
|
|
|
|
.analyticsRoomLocal(currentAnalyticsLang.langCode, student.id);
|
|
|
|
if (analyticsRoom == null) continue;
|
|
|
|
if (analyticsRoom == null) continue;
|
|
|
|
lastUpdatedFutures.add(
|
|
|
|
lastUpdatedFutures.add(
|
|
|
|
analyticsRoom.analyticsLastUpdated(
|
|
|
|
analyticsRoom.analyticsLastUpdated(
|
|
|
|
@ -177,28 +180,20 @@ class AnalyticsController extends BaseController {
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////// MESSAGE SUMMARY ANALYTICS ////////////////////////////
|
|
|
|
//////////////////////////// MESSAGE SUMMARY ANALYTICS ////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// get all the summary analytics events for the current user
|
|
|
|
|
|
|
|
/// in the current language's analytics room
|
|
|
|
Future<List<SummaryAnalyticsEvent>> mySummaryAnalytics() async {
|
|
|
|
Future<List<SummaryAnalyticsEvent>> mySummaryAnalytics() async {
|
|
|
|
// gets all the summary analytics events for the user
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
// since the current timespace's cut off date
|
|
|
|
.analyticsRoomLocal(currentAnalyticsLang.langCode);
|
|
|
|
final analyticsRooms =
|
|
|
|
if (analyticsRoom == null) return [];
|
|
|
|
_pangeaController.matrixState.client.allMyAnalyticsRooms;
|
|
|
|
|
|
|
|
|
|
|
|
final List<AnalyticsEvent>? roomEvents =
|
|
|
|
final List<SummaryAnalyticsEvent> allEvents = [];
|
|
|
|
await analyticsRoom.getAnalyticsEvents(
|
|
|
|
|
|
|
|
type: PangeaEventTypes.summaryAnalytics,
|
|
|
|
// TODO switch to using list of futures
|
|
|
|
since: currentAnalyticsTimeSpan.cutOffDate,
|
|
|
|
for (final Room analyticsRoom in analyticsRooms) {
|
|
|
|
userId: _pangeaController.matrixState.client.userID!,
|
|
|
|
final List<AnalyticsEvent>? roomEvents =
|
|
|
|
);
|
|
|
|
await analyticsRoom.getAnalyticsEvents(
|
|
|
|
return roomEvents?.cast<SummaryAnalyticsEvent>() ?? [];
|
|
|
|
type: PangeaEventTypes.summaryAnalytics,
|
|
|
|
|
|
|
|
since: currentAnalyticsTimeSpan.cutOffDate,
|
|
|
|
|
|
|
|
userId: _pangeaController.matrixState.client.userID!,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
allEvents.addAll(
|
|
|
|
|
|
|
|
roomEvents?.cast<SummaryAnalyticsEvent>() ?? [],
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return allEvents;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Future<List<SummaryAnalyticsEvent>> spaceMemberAnalytics(
|
|
|
|
Future<List<SummaryAnalyticsEvent>> spaceMemberAnalytics(
|
|
|
|
@ -216,7 +211,7 @@ class AnalyticsController extends BaseController {
|
|
|
|
final List<SummaryAnalyticsEvent> analyticsEvents = [];
|
|
|
|
final List<SummaryAnalyticsEvent> analyticsEvents = [];
|
|
|
|
for (final student in space.students) {
|
|
|
|
for (final student in space.students) {
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
.analyticsRoomLocal(currentAnalyticsSpaceLang.langCode, student.id);
|
|
|
|
.analyticsRoomLocal(currentAnalyticsLang.langCode, student.id);
|
|
|
|
|
|
|
|
|
|
|
|
if (analyticsRoom != null) {
|
|
|
|
if (analyticsRoom != null) {
|
|
|
|
final List<AnalyticsEvent>? roomEvents =
|
|
|
|
final List<AnalyticsEvent>? roomEvents =
|
|
|
|
@ -261,7 +256,7 @@ class AnalyticsController extends BaseController {
|
|
|
|
(e.defaultSelected.type == defaultSelected.type) &&
|
|
|
|
(e.defaultSelected.type == defaultSelected.type) &&
|
|
|
|
(e.selected?.id == selected?.id) &&
|
|
|
|
(e.selected?.id == selected?.id) &&
|
|
|
|
(e.selected?.type == selected?.type) &&
|
|
|
|
(e.selected?.type == selected?.type) &&
|
|
|
|
(e.langCode == currentAnalyticsSpaceLang.langCode),
|
|
|
|
(e.langCode == currentAnalyticsLang.langCode),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (index != -1) {
|
|
|
|
if (index != -1) {
|
|
|
|
@ -289,7 +284,7 @@ class AnalyticsController extends BaseController {
|
|
|
|
chartAnalyticsModel: chartAnalyticsModel,
|
|
|
|
chartAnalyticsModel: chartAnalyticsModel,
|
|
|
|
defaultSelected: defaultSelected,
|
|
|
|
defaultSelected: defaultSelected,
|
|
|
|
selected: selected,
|
|
|
|
selected: selected,
|
|
|
|
langCode: currentAnalyticsSpaceLang.langCode,
|
|
|
|
langCode: currentAnalyticsLang.langCode,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -525,20 +520,18 @@ class AnalyticsController extends BaseController {
|
|
|
|
//////////////////////////// CONSTRUCTS ////////////////////////////
|
|
|
|
//////////////////////////// CONSTRUCTS ////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
Future<List<ConstructAnalyticsEvent>> allMyConstructs() async {
|
|
|
|
Future<List<ConstructAnalyticsEvent>> allMyConstructs() async {
|
|
|
|
final List<Room> analyticsRooms =
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
_pangeaController.matrixState.client.allMyAnalyticsRooms;
|
|
|
|
.analyticsRoomLocal(currentAnalyticsLang.langCode);
|
|
|
|
|
|
|
|
if (analyticsRoom == null) return [];
|
|
|
|
final List<ConstructAnalyticsEvent> allConstructs = [];
|
|
|
|
|
|
|
|
for (final Room analyticsRoom in analyticsRooms) {
|
|
|
|
final List<ConstructAnalyticsEvent>? roomEvents =
|
|
|
|
final List<ConstructAnalyticsEvent>? roomEvents =
|
|
|
|
(await analyticsRoom.getAnalyticsEvents(
|
|
|
|
(await analyticsRoom.getAnalyticsEvents(
|
|
|
|
type: PangeaEventTypes.construct,
|
|
|
|
type: PangeaEventTypes.construct,
|
|
|
|
since: currentAnalyticsTimeSpan.cutOffDate,
|
|
|
|
since: currentAnalyticsTimeSpan.cutOffDate,
|
|
|
|
userId: _pangeaController.matrixState.client.userID!,
|
|
|
|
userId: _pangeaController.matrixState.client.userID!,
|
|
|
|
))
|
|
|
|
))
|
|
|
|
?.cast<ConstructAnalyticsEvent>();
|
|
|
|
?.cast<ConstructAnalyticsEvent>();
|
|
|
|
final List<ConstructAnalyticsEvent> allConstructs = roomEvents ?? [];
|
|
|
|
allConstructs.addAll(roomEvents ?? []);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final List<String> adminSpaceRooms =
|
|
|
|
final List<String> adminSpaceRooms =
|
|
|
|
await _pangeaController.matrixState.client.teacherRoomIds;
|
|
|
|
await _pangeaController.matrixState.client.teacherRoomIds;
|
|
|
|
@ -561,7 +554,7 @@ class AnalyticsController extends BaseController {
|
|
|
|
final List<ConstructAnalyticsEvent> constructEvents = [];
|
|
|
|
final List<ConstructAnalyticsEvent> constructEvents = [];
|
|
|
|
for (final student in space.students) {
|
|
|
|
for (final student in space.students) {
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
final Room? analyticsRoom = _pangeaController.matrixState.client
|
|
|
|
.analyticsRoomLocal(currentAnalyticsSpaceLang.langCode, student.id);
|
|
|
|
.analyticsRoomLocal(currentAnalyticsLang.langCode, student.id);
|
|
|
|
if (analyticsRoom != null) {
|
|
|
|
if (analyticsRoom != null) {
|
|
|
|
final List<ConstructAnalyticsEvent>? roomEvents =
|
|
|
|
final List<ConstructAnalyticsEvent>? roomEvents =
|
|
|
|
(await analyticsRoom.getAnalyticsEvents(
|
|
|
|
(await analyticsRoom.getAnalyticsEvents(
|
|
|
|
@ -661,7 +654,7 @@ class AnalyticsController extends BaseController {
|
|
|
|
e.defaultSelected.type == defaultSelected.type &&
|
|
|
|
e.defaultSelected.type == defaultSelected.type &&
|
|
|
|
e.selected?.id == selected?.id &&
|
|
|
|
e.selected?.id == selected?.id &&
|
|
|
|
e.selected?.type == selected?.type &&
|
|
|
|
e.selected?.type == selected?.type &&
|
|
|
|
e.langCode == currentAnalyticsSpaceLang.langCode,
|
|
|
|
e.langCode == currentAnalyticsLang.langCode,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (index > -1) {
|
|
|
|
if (index > -1) {
|
|
|
|
@ -687,7 +680,7 @@ class AnalyticsController extends BaseController {
|
|
|
|
events: List.from(events),
|
|
|
|
events: List.from(events),
|
|
|
|
defaultSelected: defaultSelected,
|
|
|
|
defaultSelected: defaultSelected,
|
|
|
|
selected: selected,
|
|
|
|
selected: selected,
|
|
|
|
langCode: currentAnalyticsSpaceLang.langCode,
|
|
|
|
langCode: currentAnalyticsLang.langCode,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
_cachedConstructs.add(entry);
|
|
|
|
_cachedConstructs.add(entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|