diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index cb319c9c7..f0aba0219 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4058,5 +4058,12 @@ "suggestToSpaceDesc": "Suggested spaces will appear in the chat lists for their parent spaces", "practice": "Practice", "noLanguagesSet": "No languages set", - "noActivitiesFound": "No practice activities found for this message" + "noActivitiesFound": "No practice activities found for this message", + "languageButtonLabel": "Language: {currentLanguage}", + "@languageButtonLabel": { + "type": "text", + "placeholders": { + "currentLanguage": {} + } + } } \ No newline at end of file diff --git a/lib/pangea/controllers/message_analytics_controller.dart b/lib/pangea/controllers/message_analytics_controller.dart index 7083efbfd..1475c0e6e 100644 --- a/lib/pangea/controllers/message_analytics_controller.dart +++ b/lib/pangea/controllers/message_analytics_controller.dart @@ -62,12 +62,13 @@ class AnalyticsController extends BaseController { timeSpan.toString(), local: true, ); + setState(); } ///////// SPACE ANALYTICS LANGUAGES ////////// String get _analyticsSpaceLangKey => "ANALYTICS_SPACE_LANG_KEY"; - LanguageModel get currentAnalyticsSpaceLang { + LanguageModel get currentAnalyticsLang { try { final String? str = _pangeaController.pStoreService.read( _analyticsSpaceLangKey, @@ -83,41 +84,43 @@ class AnalyticsController extends BaseController { } } - Future setCurrentAnalyticsSpaceLang(LanguageModel lang) async { + Future setCurrentAnalyticsLang(LanguageModel lang) async { await _pangeaController.pStoreService.save( _analyticsSpaceLangKey, lang.langCode, local: true, ); + setState(); } + /// given an analytics event type and the current analytics language, + /// get the last time the user updated their analytics Future 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 analyticsRooms = _pangeaController .matrixState.client.allMyAnalyticsRooms .where((room) => room.isAnalyticsRoom) .toList(); - final List lastUpdates = []; + final Map langCodeLastUpdates = {}; for (final Room analyticsRoom in analyticsRooms) { + final String? roomLang = analyticsRoom.madeForLang; + if (roomLang == null) continue; final DateTime? lastUpdated = await analyticsRoom.analyticsLastUpdated( type, _pangeaController.matrixState.client.userID!, ); if (lastUpdated != null) { - lastUpdates.add(lastUpdated); + langCodeLastUpdates[roomLang] = lastUpdated; } } - if (lastUpdates.isEmpty) return null; - return lastUpdates.reduce( + if (langCodeLastUpdates.isEmpty) return null; + 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, ); } @@ -134,7 +137,7 @@ class AnalyticsController extends BaseController { final List> lastUpdatedFutures = []; for (final student in space.students) { final Room? analyticsRoom = _pangeaController.matrixState.client - .analyticsRoomLocal(currentAnalyticsSpaceLang.langCode, student.id); + .analyticsRoomLocal(currentAnalyticsLang.langCode, student.id); if (analyticsRoom == null) continue; lastUpdatedFutures.add( analyticsRoom.analyticsLastUpdated( @@ -177,28 +180,20 @@ class AnalyticsController extends BaseController { //////////////////////////// MESSAGE SUMMARY ANALYTICS //////////////////////////// + /// get all the summary analytics events for the current user + /// in the current language's analytics room Future> mySummaryAnalytics() async { - // gets all the summary analytics events for the user - // since the current timespace's cut off date - final analyticsRooms = - _pangeaController.matrixState.client.allMyAnalyticsRooms; - - final List allEvents = []; - - // TODO switch to using list of futures - for (final Room analyticsRoom in analyticsRooms) { - final List? roomEvents = - await analyticsRoom.getAnalyticsEvents( - type: PangeaEventTypes.summaryAnalytics, - since: currentAnalyticsTimeSpan.cutOffDate, - userId: _pangeaController.matrixState.client.userID!, - ); - - allEvents.addAll( - roomEvents?.cast() ?? [], - ); - } - return allEvents; + final Room? analyticsRoom = _pangeaController.matrixState.client + .analyticsRoomLocal(currentAnalyticsLang.langCode); + if (analyticsRoom == null) return []; + + final List? roomEvents = + await analyticsRoom.getAnalyticsEvents( + type: PangeaEventTypes.summaryAnalytics, + since: currentAnalyticsTimeSpan.cutOffDate, + userId: _pangeaController.matrixState.client.userID!, + ); + return roomEvents?.cast() ?? []; } Future> spaceMemberAnalytics( @@ -216,7 +211,7 @@ class AnalyticsController extends BaseController { final List analyticsEvents = []; for (final student in space.students) { final Room? analyticsRoom = _pangeaController.matrixState.client - .analyticsRoomLocal(currentAnalyticsSpaceLang.langCode, student.id); + .analyticsRoomLocal(currentAnalyticsLang.langCode, student.id); if (analyticsRoom != null) { final List? roomEvents = @@ -261,7 +256,7 @@ class AnalyticsController extends BaseController { (e.defaultSelected.type == defaultSelected.type) && (e.selected?.id == selected?.id) && (e.selected?.type == selected?.type) && - (e.langCode == currentAnalyticsSpaceLang.langCode), + (e.langCode == currentAnalyticsLang.langCode), ); if (index != -1) { @@ -289,7 +284,7 @@ class AnalyticsController extends BaseController { chartAnalyticsModel: chartAnalyticsModel, defaultSelected: defaultSelected, selected: selected, - langCode: currentAnalyticsSpaceLang.langCode, + langCode: currentAnalyticsLang.langCode, ), ); } @@ -525,20 +520,18 @@ class AnalyticsController extends BaseController { //////////////////////////// CONSTRUCTS //////////////////////////// Future> allMyConstructs() async { - final List analyticsRooms = - _pangeaController.matrixState.client.allMyAnalyticsRooms; - - final List allConstructs = []; - for (final Room analyticsRoom in analyticsRooms) { - final List? roomEvents = - (await analyticsRoom.getAnalyticsEvents( - type: PangeaEventTypes.construct, - since: currentAnalyticsTimeSpan.cutOffDate, - userId: _pangeaController.matrixState.client.userID!, - )) - ?.cast(); - allConstructs.addAll(roomEvents ?? []); - } + final Room? analyticsRoom = _pangeaController.matrixState.client + .analyticsRoomLocal(currentAnalyticsLang.langCode); + if (analyticsRoom == null) return []; + + final List? roomEvents = + (await analyticsRoom.getAnalyticsEvents( + type: PangeaEventTypes.construct, + since: currentAnalyticsTimeSpan.cutOffDate, + userId: _pangeaController.matrixState.client.userID!, + )) + ?.cast(); + final List allConstructs = roomEvents ?? []; final List adminSpaceRooms = await _pangeaController.matrixState.client.teacherRoomIds; @@ -561,7 +554,7 @@ class AnalyticsController extends BaseController { final List constructEvents = []; for (final student in space.students) { final Room? analyticsRoom = _pangeaController.matrixState.client - .analyticsRoomLocal(currentAnalyticsSpaceLang.langCode, student.id); + .analyticsRoomLocal(currentAnalyticsLang.langCode, student.id); if (analyticsRoom != null) { final List? roomEvents = (await analyticsRoom.getAnalyticsEvents( @@ -661,7 +654,7 @@ class AnalyticsController extends BaseController { e.defaultSelected.type == defaultSelected.type && e.selected?.id == selected?.id && e.selected?.type == selected?.type && - e.langCode == currentAnalyticsSpaceLang.langCode, + e.langCode == currentAnalyticsLang.langCode, ); if (index > -1) { @@ -687,7 +680,7 @@ class AnalyticsController extends BaseController { events: List.from(events), defaultSelected: defaultSelected, selected: selected, - langCode: currentAnalyticsSpaceLang.langCode, + langCode: currentAnalyticsLang.langCode, ); _cachedConstructs.add(entry); } diff --git a/lib/pangea/pages/analytics/analytics_language_button.dart b/lib/pangea/pages/analytics/analytics_language_button.dart index d74e07be1..2c3923fb4 100644 --- a/lib/pangea/pages/analytics/analytics_language_button.dart +++ b/lib/pangea/pages/analytics/analytics_language_button.dart @@ -16,7 +16,6 @@ class AnalyticsLanguageButton extends StatelessWidget { @override Widget build(BuildContext context) { return PopupMenuButton( - icon: const Icon(Icons.language_outlined), tooltip: L10n.of(context)!.changeAnalyticsLanguage, initialValue: value, onSelected: (LanguageModel? lang) { @@ -33,6 +32,21 @@ class AnalyticsLanguageButton extends StatelessWidget { child: Text(lang.getDisplayName(context) ?? lang.langCode), ); }).toList(), + child: TextButton.icon( + label: Text( + L10n.of(context)!.languageButtonLabel( + value.getDisplayName(context) ?? value.langCode, + ), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + ), + ), + icon: Icon( + Icons.language_outlined, + color: Theme.of(context).colorScheme.onSurface, + ), + onPressed: null, + ), ); } } diff --git a/lib/pangea/pages/analytics/base_analytics.dart b/lib/pangea/pages/analytics/base_analytics.dart index 3ab8fa0f2..146a5ac70 100644 --- a/lib/pangea/pages/analytics/base_analytics.dart +++ b/lib/pangea/pages/analytics/base_analytics.dart @@ -163,7 +163,7 @@ class BaseAnalyticsController extends State { } Future toggleSpaceLang(LanguageModel lang) async { - await pangeaController.analytics.setCurrentAnalyticsSpaceLang(lang); + await pangeaController.analytics.setCurrentAnalyticsLang(lang); await setChartData(); refreshStream.add(false); } diff --git a/lib/pangea/pages/analytics/base_analytics_view.dart b/lib/pangea/pages/analytics/base_analytics_view.dart index 8cab95396..3d70c9b4c 100644 --- a/lib/pangea/pages/analytics/base_analytics_view.dart +++ b/lib/pangea/pages/analytics/base_analytics_view.dart @@ -108,28 +108,26 @@ class BaseAnalyticsView extends StatelessWidget { ? Column( children: [ Row( - mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - if (controller.widget.defaultSelected.type == - AnalyticsEntryType.student) - IconButton( - icon: const Icon(Icons.refresh), - onPressed: controller.onRefresh, - tooltip: L10n.of(context)!.refresh, - ), + // if (controller.widget.defaultSelected.type == + // AnalyticsEntryType.student) + // IconButton( + // icon: const Icon(Icons.refresh), + // onPressed: controller.onRefresh, + // tooltip: L10n.of(context)!.refresh, + // ), TimeSpanMenuButton( value: controller.currentTimeSpan, onChange: (TimeSpan value) => controller.toggleTimeSpan(context, value), ), - if (controller.widget.defaultSelected.type == - AnalyticsEntryType.space) - AnalyticsLanguageButton( - value: controller.pangeaController.analytics - .currentAnalyticsSpaceLang, - onChange: (lang) => controller.toggleSpaceLang(lang), - languages: controller.widget.targetLanguages, - ), + AnalyticsLanguageButton( + value: controller + .pangeaController.analytics.currentAnalyticsLang, + onChange: (lang) => controller.toggleSpaceLang(lang), + languages: controller.widget.targetLanguages, + ), ], ), Expanded( diff --git a/lib/pangea/pages/analytics/construct_list.dart b/lib/pangea/pages/analytics/construct_list.dart index e169922ca..8651b7a74 100644 --- a/lib/pangea/pages/analytics/construct_list.dart +++ b/lib/pangea/pages/analytics/construct_list.dart @@ -355,15 +355,17 @@ class ConstructMessagesDialog extends StatelessWidget { final msgEventMatches = controller.getMessageEventMatches(); + final noData = controller.constructs![controller.lemmaIndex].uses.length > + controller._msgEvents.length; + return AlertDialog( title: Center(child: Text(controller.widget.controller.currentLemma!)), content: SizedBox( - height: 350, - width: 500, + height: noData ? 90 : 250, + width: noData ? 200 : 400, child: Column( children: [ - if (controller.constructs![controller.lemmaIndex].uses.length > - controller._msgEvents.length) + if (noData) Center( child: Padding( padding: const EdgeInsets.all(8.0), @@ -398,8 +400,8 @@ class ConstructMessagesDialog extends StatelessWidget { child: Text( L10n.of(context)!.close.toUpperCase(), style: TextStyle( - color: - Theme.of(context).textTheme.bodyMedium?.color?.withAlpha(150), + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, ), ), ), diff --git a/lib/pangea/pages/analytics/space_list/space_list.dart b/lib/pangea/pages/analytics/space_list/space_list.dart index e325e1e94..e65bb6152 100644 --- a/lib/pangea/pages/analytics/space_list/space_list.dart +++ b/lib/pangea/pages/analytics/space_list/space_list.dart @@ -23,13 +23,24 @@ class AnalyticsSpaceList extends StatefulWidget { class AnalyticsSpaceListController extends State { PangeaController pangeaController = MatrixState.pangeaController; List spaces = []; + StreamSubscription? stateSub; List targetLanguages = []; @override void initState() { super.initState(); - setSpaceList().then((_) => setTargetLanguages()); + + // reload dropdowns when their values change in analytics page + stateSub = pangeaController.analytics.stateStream.listen( + (_) => setState(() {}), + ); + } + + @override + void dispose() { + stateSub?.cancel(); + super.dispose(); } StreamController refreshStream = StreamController.broadcast(); @@ -71,7 +82,7 @@ class AnalyticsSpaceListController extends State { } Future toggleSpaceLang(LanguageModel lang) async { - await pangeaController.analytics.setCurrentAnalyticsSpaceLang(lang); + await pangeaController.analytics.setCurrentAnalyticsLang(lang); refreshStream.add(false); setState(() {}); } diff --git a/lib/pangea/pages/analytics/space_list/space_list_view.dart b/lib/pangea/pages/analytics/space_list/space_list_view.dart index 1837d35f2..7ef5fb45e 100644 --- a/lib/pangea/pages/analytics/space_list/space_list_view.dart +++ b/lib/pangea/pages/analytics/space_list/space_list_view.dart @@ -1,3 +1,4 @@ +import 'package:fluffychat/pangea/enum/time_span.dart'; import 'package:fluffychat/pangea/pages/analytics/analytics_language_button.dart'; import 'package:fluffychat/pangea/pages/analytics/analytics_list_tile.dart'; import 'package:fluffychat/pangea/pages/analytics/time_span_menu_button.dart'; @@ -5,7 +6,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; -import '../../../enum/time_span.dart'; import '../base_analytics.dart'; import 'space_list.dart'; @@ -32,27 +32,29 @@ class AnalyticsSpaceListView extends StatelessWidget { icon: const Icon(Icons.close_outlined), onPressed: () => context.pop(), ), - actions: [ - TimeSpanMenuButton( - value: - controller.pangeaController.analytics.currentAnalyticsTimeSpan, - onChange: (TimeSpan value) => controller.toggleTimeSpan( - context, - value, - ), - ), - AnalyticsLanguageButton( - value: - controller.pangeaController.analytics.currentAnalyticsSpaceLang, - onChange: (lang) => controller.toggleSpaceLang(lang), - languages: controller.targetLanguages.isEmpty - ? controller.pangeaController.pLanguageStore.targetOptions - : controller.targetLanguages, - ), - ], ), body: Column( children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TimeSpanMenuButton( + value: controller + .pangeaController.analytics.currentAnalyticsTimeSpan, + onChange: (TimeSpan value) => controller.toggleTimeSpan( + context, + value, + ), + ), + AnalyticsLanguageButton( + value: + controller.pangeaController.analytics.currentAnalyticsLang, + onChange: (lang) => controller.toggleSpaceLang(lang), + languages: + controller.pangeaController.pLanguageStore.targetOptions, + ), + ], + ), Flexible( child: ListView.builder( itemCount: controller.spaces.length, diff --git a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart index 65bd533e8..d6bc9d766 100644 --- a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart @@ -1,7 +1,12 @@ import 'dart:async'; import 'dart:developer'; +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/controllers/language_list_controller.dart'; import 'package:fluffychat/pangea/enum/bar_chart_view_enum.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/widgets/common/list_placeholder.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -75,6 +80,24 @@ class StudentAnalyticsController extends State { return id; } + List get targetLanguages { + final LanguageModel? l2 = + _pangeaController.languageController.activeL2Model(); + final List analyticsRoomLangs = + _pangeaController.matrixState.client.allMyAnalyticsRooms + .map((analyticsRoom) => analyticsRoom.madeForLang) + .where((langCode) => langCode != null) + .map((langCode) => PangeaLanguage.byLangCode(langCode!)) + .where( + (langModel) => langModel.langCode != LanguageKeys.unknownLanguage, + ) + .toList(); + if (l2 != null) { + analyticsRoomLangs.add(l2); + } + return analyticsRoomLangs.toSet().toList(); + } + @override Widget build(BuildContext context) { return PLoadingStatusV2( diff --git a/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart b/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart index 5b8924581..6ea754891 100644 --- a/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart @@ -59,6 +59,7 @@ class StudentAnalyticsView extends StatelessWidget { AnalyticsEntryType.student, L10n.of(context)!.allChatsAndClasses, ), + targetLanguages: controller.targetLanguages, ) : const SizedBox(); } diff --git a/lib/pangea/pages/analytics/time_span_menu_button.dart b/lib/pangea/pages/analytics/time_span_menu_button.dart index 23d2ad0c8..32f6668bc 100644 --- a/lib/pangea/pages/analytics/time_span_menu_button.dart +++ b/lib/pangea/pages/analytics/time_span_menu_button.dart @@ -15,7 +15,6 @@ class TimeSpanMenuButton extends StatelessWidget { @override Widget build(BuildContext context) { return PopupMenuButton( - icon: const Icon(Icons.calendar_month_outlined), tooltip: L10n.of(context)!.changeDateRange, initialValue: value, onSelected: (TimeSpan? timeSpan) { @@ -32,6 +31,19 @@ class TimeSpanMenuButton extends StatelessWidget { child: Text(timeSpan.string(context)), ); }).toList(), + child: TextButton.icon( + label: Text( + value.string(context), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + ), + ), + icon: Icon( + Icons.calendar_month_outlined, + color: Theme.of(context).colorScheme.onSurface, + ), + onPressed: null, + ), ); } } diff --git a/needed-translations.txt b/needed-translations.txt index 1355bb368..d577d89d9 100644 --- a/needed-translations.txt +++ b/needed-translations.txt @@ -863,7 +863,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "be": [ @@ -2363,7 +2364,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "bn": [ @@ -3859,7 +3861,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "bo": [ @@ -5359,7 +5362,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ca": [ @@ -6261,7 +6265,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "cs": [ @@ -7245,7 +7250,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "de": [ @@ -8112,7 +8118,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "el": [ @@ -9563,7 +9570,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "eo": [ @@ -10712,7 +10720,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "es": [ @@ -10727,7 +10736,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "et": [ @@ -11594,7 +11604,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "eu": [ @@ -12463,7 +12474,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "fa": [ @@ -13469,7 +13481,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "fi": [ @@ -14439,7 +14452,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "fil": [ @@ -15765,7 +15779,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "fr": [ @@ -16770,7 +16785,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ga": [ @@ -17904,7 +17920,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "gl": [ @@ -18771,7 +18788,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "he": [ @@ -20024,7 +20042,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "hi": [ @@ -21517,7 +21536,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "hr": [ @@ -22463,7 +22483,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "hu": [ @@ -23346,7 +23367,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ia": [ @@ -24832,7 +24854,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "id": [ @@ -25705,7 +25728,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ie": [ @@ -26962,7 +26986,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "it": [ @@ -27886,7 +27911,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ja": [ @@ -28921,7 +28947,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ka": [ @@ -30275,7 +30302,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ko": [ @@ -31144,7 +31172,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "lt": [ @@ -32179,7 +32208,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "lv": [ @@ -33054,7 +33084,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "nb": [ @@ -34253,7 +34284,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "nl": [ @@ -35216,7 +35248,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "pl": [ @@ -36188,7 +36221,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "pt": [ @@ -37666,7 +37700,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "pt_BR": [ @@ -38539,7 +38574,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "pt_PT": [ @@ -39739,7 +39775,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ro": [ @@ -40746,7 +40783,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ru": [ @@ -41619,7 +41657,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "sk": [ @@ -42885,7 +42924,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "sl": [ @@ -44281,7 +44321,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "sr": [ @@ -45451,7 +45492,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "sv": [ @@ -46355,7 +46397,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "ta": [ @@ -47852,7 +47895,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "th": [ @@ -49303,7 +49347,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "tr": [ @@ -50170,7 +50215,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "uk": [ @@ -51074,7 +51120,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "vi": [ @@ -52426,7 +52473,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "zh": [ @@ -53293,7 +53341,8 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ], "zh_Hant": [ @@ -54441,6 +54490,7 @@ "suggestToSpaceDesc", "practice", "noLanguagesSet", - "noActivitiesFound" + "noActivitiesFound", + "languageButtonLabel" ] }