diff --git a/lib/config/routes.dart b/lib/config/routes.dart index e6ab37967..8bf162372 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -24,6 +24,7 @@ import 'package:fluffychat/pages/settings_notifications/settings_notifications.d import 'package:fluffychat/pages/settings_password/settings_password.dart'; import 'package:fluffychat/pages/settings_security/settings_security.dart'; import 'package:fluffychat/pages/settings_style/settings_style.dart'; +import 'package:fluffychat/pangea/enum/bar_chart_view_enum.dart'; import 'package:fluffychat/pangea/guard/p_vguard.dart'; import 'package:fluffychat/pangea/pages/analytics/student_analytics/student_analytics.dart'; import 'package:fluffychat/pangea/pages/exchange/add_exchange_to_class.dart'; @@ -171,6 +172,28 @@ abstract class AppRoutes { const StudentAnalyticsPage(), ), redirect: loggedOutRedirect, + routes: [ + GoRoute( + path: 'messages', + pageBuilder: (context, state) => defaultPageBuilder( + context, + state, + const StudentAnalyticsPage( + selectedView: BarChartViewSelection.messages, + ), + ), + ), + GoRoute( + path: 'errors', + pageBuilder: (context, state) => defaultPageBuilder( + context, + state, + const StudentAnalyticsPage( + selectedView: BarChartViewSelection.grammar, + ), + ), + ), + ], ), GoRoute( path: 'analytics', @@ -189,6 +212,36 @@ abstract class AppRoutes { state, const ClassAnalyticsPage(), ), + routes: [ + GoRoute( + path: 'messages', + pageBuilder: (context, state) => defaultPageBuilder( + context, + state, + ClassAnalyticsPage( + // when going to sub-space from within a parent space's analytics, the + // analytics list tiles do not properly update. Adding a unique key to this page is the best fix + // I can find at the moment + key: UniqueKey(), + selectedView: BarChartViewSelection.messages, + ), + ), + ), + GoRoute( + path: 'errors', + pageBuilder: (context, state) => defaultPageBuilder( + context, + state, + ClassAnalyticsPage( + // when going to sub-space from within a parent space's analytics, the + // analytics list tiles do not properly update. Adding a unique key to this page is the best fix + // I can find at the moment + key: UniqueKey(), + selectedView: BarChartViewSelection.grammar, + ), + ), + ), + ], ), ], ), diff --git a/lib/pangea/enum/bar_chart_view_enum.dart b/lib/pangea/enum/bar_chart_view_enum.dart index d59f34d9a..3fe812634 100644 --- a/lib/pangea/enum/bar_chart_view_enum.dart +++ b/lib/pangea/enum/bar_chart_view_enum.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; - import 'package:flutter_gen/gen_l10n/l10n.dart'; enum BarChartViewSelection { @@ -30,4 +29,15 @@ extension BarChartViewSelectionExtension on BarChartViewSelection { return Icons.spellcheck_outlined; } } + + String get route { + switch (this) { + case BarChartViewSelection.messages: + return 'messages'; + // case BarChartViewSelection.vocab: + // return 'vocab'; + case BarChartViewSelection.grammar: + return 'errors'; + } + } } diff --git a/lib/pangea/pages/analytics/analytics_list_tile.dart b/lib/pangea/pages/analytics/analytics_list_tile.dart index 9580cc135..b5a2bd770 100644 --- a/lib/pangea/pages/analytics/analytics_list_tile.dart +++ b/lib/pangea/pages/analytics/analytics_list_tile.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:fluffychat/pangea/controllers/pangea_controller.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:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -24,6 +25,7 @@ class AnalyticsListTile extends StatefulWidget { required this.isSelected, required this.onTap, required this.pangeaController, + this.controller, // this.isEnabled = true, // this.showSpaceAnalytics = true, this.refreshStream, @@ -42,6 +44,7 @@ class AnalyticsListTile extends StatefulWidget { // final bool showSpaceAnalytics; final PangeaController pangeaController; + final BaseAnalyticsController? controller; final StreamController? refreshStream; @override @@ -133,11 +136,17 @@ class AnalyticsListTileState extends State { ), selected: widget.isSelected, onTap: () { - (room?.isSpace ?? false) && widget.allowNavigateOnSelect - ? context.go( - '/rooms/analytics/${room!.id}', - ) - : widget.onTap(widget.selected); + if (widget.controller?.widget.selectedView == null) { + widget.onTap(widget.selected); + return; + } + if ((room?.isSpace ?? false) && widget.allowNavigateOnSelect) { + final String selectedView = + widget.controller!.widget.selectedView!.route; + context.go('/rooms/analytics/${room!.id}/$selectedView'); + return; + } + widget.onTap(widget.selected); }, trailing: (room?.isSpace ?? false) && widget.selected.type != AnalyticsEntryType.privateChats && diff --git a/lib/pangea/pages/analytics/base_analytics.dart b/lib/pangea/pages/analytics/base_analytics.dart index 7a6e077b3..7829407ed 100644 --- a/lib/pangea/pages/analytics/base_analytics.dart +++ b/lib/pangea/pages/analytics/base_analytics.dart @@ -19,6 +19,7 @@ import '../../models/chart_analytics_model.dart'; class BaseAnalyticsPage extends StatefulWidget { final String pageTitle; final List tabs; + final BarChartViewSelection? selectedView; final AnalyticsSelected defaultSelected; final AnalyticsSelected? alwaysSelected; @@ -30,6 +31,7 @@ class BaseAnalyticsPage extends StatefulWidget { required this.tabs, required this.alwaysSelected, required this.defaultSelected, + this.selectedView, this.myAnalyticsController, }); @@ -39,7 +41,6 @@ class BaseAnalyticsPage extends StatefulWidget { class BaseAnalyticsController extends State { final PangeaController pangeaController = MatrixState.pangeaController; - BarChartViewSelection? selectedView; AnalyticsSelected? selected; String? currentLemma; ChartAnalyticsModel? chartData; @@ -125,14 +126,6 @@ class BaseAnalyticsController extends State { TimeSpan get currentTimeSpan => pangeaController.analytics.currentAnalyticsTimeSpan; - void navigate() { - if (selectedView != null) { - setSelectedView(null); - } else { - Navigator.of(context).pop(); - } - } - Future toggleSelection(AnalyticsSelected selectedParam) async { setState(() { debugPrint("selectedParam.id is ${selectedParam.id}"); @@ -163,13 +156,6 @@ class BaseAnalyticsController extends State { refreshStream.add(false); } - void setSelectedView(BarChartViewSelection? view) { - currentLemma = null; - selectedView = view; - setState(() {}); - refreshStream.add(false); - } - void setCurrentLemma(String? lemma) { currentLemma = lemma; setState(() {}); @@ -206,6 +192,19 @@ class TabItem { enum AnalyticsEntryType { student, room, space, privateChats } +extension AnalyticsEntryTypeExtension on AnalyticsEntryType { + String get route { + switch (this) { + case AnalyticsEntryType.student: + return 'mylearning'; + case AnalyticsEntryType.space: + return 'analytics'; + default: + throw Exception('No route for $this'); + } + } +} + class AnalyticsSelected { String id; AnalyticsEntryType type; diff --git a/lib/pangea/pages/analytics/base_analytics_view.dart b/lib/pangea/pages/analytics/base_analytics_view.dart index 1669cd534..151497063 100644 --- a/lib/pangea/pages/analytics/base_analytics_view.dart +++ b/lib/pangea/pages/analytics/base_analytics_view.dart @@ -12,6 +12,7 @@ import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; class BaseAnalyticsView extends StatelessWidget { const BaseAnalyticsView({ @@ -22,11 +23,11 @@ class BaseAnalyticsView extends StatelessWidget { final BaseAnalyticsController controller; Widget chartView(BuildContext context) { - if (controller.selectedView == null) { + if (controller.widget.selectedView == null) { return const SizedBox(); } - switch (controller.selectedView!) { + switch (controller.widget.selectedView!) { case BarChartViewSelection.messages: return MessagesBarChart( chartAnalytics: controller.chartData, @@ -60,36 +61,32 @@ class BaseAnalyticsView extends StatelessWidget { text: controller.widget.pageTitle, style: const TextStyle(decoration: TextDecoration.underline), recognizer: TapGestureRecognizer() - ..onTap = () => controller.selectedView != null - ? controller.setSelectedView(null) - : null, + ..onTap = () { + if (controller.widget.selectedView == null) return; + String route = + "/rooms/${controller.widget.defaultSelected.type.route}"; + if (controller.widget.defaultSelected.type == + AnalyticsEntryType.space) { + route += "/${controller.widget.defaultSelected.id}"; + } + context.go(route); + }, ), - if (controller.selectedView != null) + if (controller.widget.selectedView != null) const TextSpan( text: " > ", ), - if (controller.selectedView != null) - TextSpan( - style: const TextStyle(decoration: TextDecoration.underline), - text: controller.selectedView!.string(context), - recognizer: TapGestureRecognizer() - ..onTap = () => controller.currentLemma != null - ? controller.setCurrentLemma(null) - : null, - ), + if (controller.widget.selectedView != null) + TextSpan(text: controller.widget.selectedView!.string(context)), ], ), overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, ), - leading: IconButton( - icon: const Icon(Icons.arrow_back), - onPressed: controller.navigate, - ), ), body: MaxWidthBody( withScrolling: false, - child: controller.selectedView != null + child: controller.widget.selectedView != null ? Column( children: [ Row( @@ -177,6 +174,7 @@ class BaseAnalyticsView extends StatelessWidget { .allowNavigateOnSelect, pangeaController: controller.pangeaController, + controller: controller, ), ), if (controller @@ -202,6 +200,7 @@ class BaseAnalyticsView extends StatelessWidget { onTap: controller.toggleSelection, pangeaController: controller.pangeaController, + controller: controller, ), ], ), @@ -230,6 +229,7 @@ class BaseAnalyticsView extends StatelessWidget { .allowNavigateOnSelect, pangeaController: controller.pangeaController, + controller: controller, ), ) .toList(), @@ -249,7 +249,7 @@ class BaseAnalyticsView extends StatelessWidget { children: [ const Divider(height: 1), ListTile( - title: const Text("Error Analytics"), + title: Text(L10n.of(context)!.grammarAnalytics), leading: CircleAvatar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, @@ -258,13 +258,20 @@ class BaseAnalyticsView extends StatelessWidget { child: Icon(BarChartViewSelection.grammar.icon), ), trailing: const Icon(Icons.chevron_right), - onTap: () => controller.setSelectedView( - BarChartViewSelection.grammar, - ), + onTap: () { + String route = + "/rooms/${controller.widget.defaultSelected.type.route}"; + if (controller.widget.defaultSelected.type == + AnalyticsEntryType.space) { + route += "/${controller.widget.defaultSelected.id}"; + } + route += "/${BarChartViewSelection.grammar.route}"; + context.go(route); + }, ), const Divider(height: 1), ListTile( - title: const Text("Message Analytics"), + title: Text(L10n.of(context)!.messageAnalytics), leading: CircleAvatar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, @@ -273,9 +280,16 @@ class BaseAnalyticsView extends StatelessWidget { child: Icon(BarChartViewSelection.messages.icon), ), trailing: const Icon(Icons.chevron_right), - onTap: () => controller.setSelectedView( - BarChartViewSelection.messages, - ), + onTap: () { + String route = + "/rooms/${controller.widget.defaultSelected.type.route}"; + if (controller.widget.defaultSelected.type == + AnalyticsEntryType.space) { + route += "/${controller.widget.defaultSelected.id}"; + } + route += "/${BarChartViewSelection.messages.route}"; + context.go(route); + }, ), const Divider(height: 1), ], diff --git a/lib/pangea/pages/analytics/class_analytics/class_analytics.dart b/lib/pangea/pages/analytics/class_analytics/class_analytics.dart index 0d7402dc1..f271ba96d 100644 --- a/lib/pangea/pages/analytics/class_analytics/class_analytics.dart +++ b/lib/pangea/pages/analytics/class_analytics/class_analytics.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:developer'; import 'package:fluffychat/pangea/constants/pangea_room_types.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/utils/error_handler.dart'; import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; @@ -18,7 +19,8 @@ import 'class_analytics_view.dart'; enum AnalyticsPageType { classList, student, classDetails } class ClassAnalyticsPage extends StatefulWidget { - const ClassAnalyticsPage({super.key}); + final BarChartViewSelection? selectedView; + const ClassAnalyticsPage({super.key, this.selectedView}); @override State createState() => ClassAnalyticsV2Controller(); @@ -40,6 +42,9 @@ class ClassAnalyticsV2Controller extends State { _classRoom = classId != null ? Matrix.of(context).client.getRoomById(classId!) : null; + if (_classRoom == null) { + context.go('/rooms/analytics'); + } getChatAndStudents(); } return _classRoom; diff --git a/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart b/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart index 537903025..5f609437b 100644 --- a/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart +++ b/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart @@ -48,6 +48,7 @@ class ClassAnalyticsView extends StatelessWidget { return controller.classId != null ? BaseAnalyticsPage( + selectedView: controller.widget.selectedView, pageTitle: pageTitle, tabs: [tab1, tab2], alwaysSelected: AnalyticsSelected( diff --git a/lib/pangea/pages/analytics/class_list/class_list_view.dart b/lib/pangea/pages/analytics/class_list/class_list_view.dart index 8d4bc6a5a..d8cafcf8e 100644 --- a/lib/pangea/pages/analytics/class_list/class_list_view.dart +++ b/lib/pangea/pages/analytics/class_list/class_list_view.dart @@ -61,9 +61,11 @@ class AnalyticsClassListView extends StatelessWidget { AnalyticsEntryType.space, snapshot.data![i].name, ), - onTap: (selected) => context.go( - '/rooms/analytics/${selected.id}', - ), + onTap: (selected) { + context.go( + '/rooms/analytics/${selected.id}', + ); + }, allowNavigateOnSelect: true, isSelected: false, pangeaController: controller.pangeaController, diff --git a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart index 9e51087a6..65bd533e8 100644 --- a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:developer'; +import 'package:fluffychat/pangea/enum/bar_chart_view_enum.dart'; import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -13,7 +14,8 @@ import '../base_analytics.dart'; import 'student_analytics_view.dart'; class StudentAnalyticsPage extends StatefulWidget { - const StudentAnalyticsPage({super.key}); + final BarChartViewSelection? selectedView; + const StudentAnalyticsPage({super.key, this.selectedView}); @override State createState() => StudentAnalyticsController(); 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 a4ae454ca..5b8924581 100644 --- a/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart @@ -45,6 +45,7 @@ class StudentAnalyticsView extends StatelessWidget { return controller.userId != null ? BaseAnalyticsPage( + selectedView: controller.widget.selectedView, pageTitle: pageTitle, tabs: [chatTabData, classTabData], alwaysSelected: AnalyticsSelected(