Merge pull request #393 from pangeachat/analytics-target-languages

populate space analytics language dropdown from space student's analy…
pull/1384/head
ggurdin 1 year ago committed by GitHub
commit 35f5731f41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -4,14 +4,17 @@ import 'dart:developer';
import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart';
import 'package:fluffychat/pangea/constants/language_keys.dart';
import 'package:fluffychat/pangea/constants/model_keys.dart'; import 'package:fluffychat/pangea/constants/model_keys.dart';
import 'package:fluffychat/pangea/constants/pangea_room_types.dart'; import 'package:fluffychat/pangea/constants/pangea_room_types.dart';
import 'package:fluffychat/pangea/controllers/language_list_controller.dart';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/models/analytics/analytics_event.dart'; import 'package:fluffychat/pangea/models/analytics/analytics_event.dart';
import 'package:fluffychat/pangea/models/analytics/constructs_event.dart'; import 'package:fluffychat/pangea/models/analytics/constructs_event.dart';
import 'package:fluffychat/pangea/models/analytics/summary_analytics_event.dart'; import 'package:fluffychat/pangea/models/analytics/summary_analytics_event.dart';
import 'package:fluffychat/pangea/models/analytics/summary_analytics_model.dart'; import 'package:fluffychat/pangea/models/analytics/summary_analytics_model.dart';
import 'package:fluffychat/pangea/models/bot_options_model.dart'; import 'package:fluffychat/pangea/models/bot_options_model.dart';
import 'package:fluffychat/pangea/models/language_model.dart';
import 'package:fluffychat/pangea/models/space_model.dart'; import 'package:fluffychat/pangea/models/space_model.dart';
import 'package:fluffychat/pangea/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/models/tokens_event_content_model.dart';
import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart';
@ -129,6 +132,9 @@ extension PangeaRoom on Room {
Event? get pangeaRoomRulesStateEvent => _pangeaRoomRulesStateEvent; Event? get pangeaRoomRulesStateEvent => _pangeaRoomRulesStateEvent;
Future<List<LanguageModel>> targetLanguages() async =>
await _targetLanguages();
// events // events
Future<bool> leaveIfFull() async => await _leaveIfFull(); Future<bool> leaveIfFull() async => await _leaveIfFull();

@ -92,6 +92,34 @@ extension SpaceRoomExtension on Room {
return null; return null;
} }
Future<List<LanguageModel>> _targetLanguages() async {
await requestParticipants();
final students = _students;
final Map<LanguageModel, int> langCounts = {};
final List<Room> allRooms = client.rooms;
for (final User student in students) {
for (final Room room in allRooms) {
if (!room.isAnalyticsRoomOfUser(student.id)) continue;
final String? langCode = room.madeForLang;
if (langCode == null ||
langCode.isEmpty ||
langCode == LanguageKeys.unknownLanguage) {
continue;
}
final LanguageModel lang = PangeaLanguage.byLangCode(langCode);
langCounts[lang] ??= 0;
langCounts[lang] = langCounts[lang]! + 1;
}
}
// get a list of language models, sorted
// by the number of students who are learning that language
return langCounts.entries.map((entry) => entry.key).toList()
..sort(
(a, b) => langCounts[b]!.compareTo(langCounts[a]!),
);
}
// DateTime? get _languageSettingsUpdatedAt { // DateTime? get _languageSettingsUpdatedAt {
// if (!isSpace) return null; // if (!isSpace) return null;
// return languageSettingsStateEvent?.originServerTs ?? creationTime; // return languageSettingsStateEvent?.originServerTs ?? creationTime;

@ -25,8 +25,9 @@ class BaseAnalyticsPage extends StatefulWidget {
final AnalyticsSelected defaultSelected; final AnalyticsSelected defaultSelected;
final AnalyticsSelected? alwaysSelected; final AnalyticsSelected? alwaysSelected;
final StudentAnalyticsController? myAnalyticsController; final StudentAnalyticsController? myAnalyticsController;
final List<LanguageModel> targetLanguages;
const BaseAnalyticsPage({ BaseAnalyticsPage({
super.key, super.key,
required this.pageTitle, required this.pageTitle,
required this.tabs, required this.tabs,
@ -34,7 +35,10 @@ class BaseAnalyticsPage extends StatefulWidget {
required this.defaultSelected, required this.defaultSelected,
this.selectedView, this.selectedView,
this.myAnalyticsController, this.myAnalyticsController,
}); targetLanguages,
}) : targetLanguages = (targetLanguages?.isNotEmpty ?? false)
? targetLanguages
: MatrixState.pangeaController.pLanguageStore.targetOptions;
@override @override
State<BaseAnalyticsPage> createState() => BaseAnalyticsController(); State<BaseAnalyticsPage> createState() => BaseAnalyticsController();

@ -128,8 +128,7 @@ class BaseAnalyticsView extends StatelessWidget {
value: controller.pangeaController.analytics value: controller.pangeaController.analytics
.currentAnalyticsSpaceLang, .currentAnalyticsSpaceLang,
onChange: (lang) => controller.toggleSpaceLang(lang), onChange: (lang) => controller.toggleSpaceLang(lang),
languages: controller languages: controller.widget.targetLanguages,
.pangeaController.pLanguageStore.targetOptions,
), ),
], ],
), ),

@ -4,6 +4,7 @@ import 'dart:developer';
import 'package:fluffychat/pangea/constants/pangea_room_types.dart'; import 'package:fluffychat/pangea/constants/pangea_room_types.dart';
import 'package:fluffychat/pangea/enum/bar_chart_view_enum.dart'; import 'package:fluffychat/pangea/enum/bar_chart_view_enum.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/models/language_model.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart';
import 'package:fluffychat/pangea/widgets/common/p_circular_loader.dart'; import 'package:fluffychat/pangea/widgets/common/p_circular_loader.dart';
@ -33,6 +34,18 @@ class SpaceAnalyticsV2Controller extends State<SpaceAnalyticsPage> {
List<User> students = []; List<User> students = [];
String? get spaceId => GoRouterState.of(context).pathParameters['spaceid']; String? get spaceId => GoRouterState.of(context).pathParameters['spaceid'];
Room? _spaceRoom; Room? _spaceRoom;
List<LanguageModel> targetLanguages = [];
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () async {
if (spaceRoom == null || (!(spaceRoom?.isSpace ?? false))) {
context.go('/rooms');
}
getChatAndStudents();
});
}
Room? get spaceRoom { Room? get spaceRoom {
if (_spaceRoom == null || _spaceRoom!.id != spaceId) { if (_spaceRoom == null || _spaceRoom!.id != spaceId) {
@ -44,23 +57,11 @@ class SpaceAnalyticsV2Controller extends State<SpaceAnalyticsPage> {
context.go('/rooms/analytics'); context.go('/rooms/analytics');
return null; return null;
} }
getChatAndStudents(); getChatAndStudents().then((_) => setTargetLanguages());
} }
return _spaceRoom; return _spaceRoom;
} }
@override
void initState() {
super.initState();
debugPrint("init space analytics");
Future.delayed(Duration.zero, () async {
if (spaceRoom == null || (!(spaceRoom?.isSpace ?? false))) {
context.go('/rooms');
}
getChatAndStudents();
});
}
Future<void> getChatAndStudents() async { Future<void> getChatAndStudents() async {
try { try {
await spaceRoom?.postLoad(); await spaceRoom?.postLoad();
@ -97,12 +98,12 @@ class SpaceAnalyticsV2Controller extends State<SpaceAnalyticsPage> {
} }
} }
// @override Future<void> setTargetLanguages() async {
// void dispose() { // get a list of language models, sorted by the
// super.dispose(); // number of students who are learning that language
// refreshTimer?.cancel(); targetLanguages = await spaceRoom?.targetLanguages() ?? [];
// stateSub?.cancel(); setState(() {});
// } }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -59,6 +59,7 @@ class SpaceAnalyticsView extends StatelessWidget {
AnalyticsEntryType.space, AnalyticsEntryType.space,
controller.spaceRoom?.name ?? "", controller.spaceRoom?.name ?? "",
), ),
targetLanguages: controller.targetLanguages,
) )
: const SizedBox(); : const SizedBox();
} }

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:fluffychat/pangea/enum/time_span.dart'; import 'package:fluffychat/pangea/enum/time_span.dart';
import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart'; import 'package:fluffychat/pangea/extensions/client_extension/client_extension.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/models/language_model.dart'; import 'package:fluffychat/pangea/models/language_model.dart';
import 'package:fluffychat/pangea/pages/analytics/space_list/space_list_view.dart'; import 'package:fluffychat/pangea/pages/analytics/space_list/space_list_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -22,26 +23,47 @@ class AnalyticsSpaceList extends StatefulWidget {
class AnalyticsSpaceListController extends State<AnalyticsSpaceList> { class AnalyticsSpaceListController extends State<AnalyticsSpaceList> {
PangeaController pangeaController = MatrixState.pangeaController; PangeaController pangeaController = MatrixState.pangeaController;
List<Room> spaces = []; List<Room> spaces = [];
List<LanguageModel> targetLanguages = [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
Matrix.of(context).client.spacesImTeaching.then((spaceList) {
spaceList = spaceList setSpaceList().then((_) => setTargetLanguages());
.where(
(space) => !spaceList.any(
(parentSpace) => parentSpace.spaceChildren
.any((child) => child.roomId == space.id),
),
)
.toList();
spaces = spaceList;
setState(() {});
});
} }
StreamController refreshStream = StreamController.broadcast(); StreamController refreshStream = StreamController.broadcast();
Future<void> setSpaceList() async {
final spaceList = await Matrix.of(context).client.spacesImTeaching;
spaces = spaceList
.where(
(space) => !spaceList.any(
(parentSpace) => parentSpace.spaceChildren
.any((child) => child.roomId == space.id),
),
)
.toList();
setState(() {});
}
Future<void> setTargetLanguages() async {
if (spaces.isEmpty) return;
final Map<LanguageModel, int> langCounts = {};
for (final Room space in spaces) {
final List<LanguageModel> targetLangs = await space.targetLanguages();
for (final LanguageModel lang in targetLangs) {
langCounts[lang] ??= 0;
langCounts[lang] = langCounts[lang]! + 1;
}
}
targetLanguages = langCounts.entries.map((entry) => entry.key).toList()
..sort(
(a, b) => langCounts[b]!.compareTo(langCounts[a]!),
);
setState(() {});
}
void toggleTimeSpan(BuildContext context, TimeSpan timeSpan) { void toggleTimeSpan(BuildContext context, TimeSpan timeSpan) {
pangeaController.analytics.setCurrentAnalyticsTimeSpan(timeSpan); pangeaController.analytics.setCurrentAnalyticsTimeSpan(timeSpan);
refreshStream.add(false); refreshStream.add(false);

@ -45,7 +45,9 @@ class AnalyticsSpaceListView extends StatelessWidget {
value: value:
controller.pangeaController.analytics.currentAnalyticsSpaceLang, controller.pangeaController.analytics.currentAnalyticsSpaceLang,
onChange: (lang) => controller.toggleSpaceLang(lang), onChange: (lang) => controller.toggleSpaceLang(lang),
languages: controller.pangeaController.pLanguageStore.targetOptions, languages: controller.targetLanguages.isEmpty
? controller.pangeaController.pLanguageStore.targetOptions
: controller.targetLanguages,
), ),
], ],
), ),

Loading…
Cancel
Save