You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fluffychat/lib/pangea/pages/analytics/base_analytics_view.dart

325 lines
15 KiB
Dart

import 'dart:math';
import 'package:fluffychat/pangea/enum/bar_chart_view_enum.dart';
import 'package:fluffychat/pangea/enum/construct_type_enum.dart';
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/base_analytics.dart';
import 'package:fluffychat/pangea/pages/analytics/construct_list.dart';
import 'package:fluffychat/pangea/pages/analytics/messages_bar_chart.dart';
import 'package:fluffychat/pangea/pages/analytics/time_span_menu_button.dart';
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({
super.key,
required this.controller,
});
final BaseAnalyticsController controller;
Widget chartView(BuildContext context) {
if (controller.widget.selectedView == null) {
return const SizedBox();
}
switch (controller.widget.selectedView!) {
case BarChartViewSelection.messages:
return MessagesBarChart(
chartAnalytics: controller.chartData,
);
case BarChartViewSelection.grammar:
return ConstructList(
constructType: ConstructType.grammar,
defaultSelected: controller.widget.defaultSelected,
selected: controller.selected,
controller: controller,
pangeaController: controller.pangeaController,
refreshStream: controller.refreshStream,
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: RichText(
text: TextSpan(
style: TextStyle(
color: Theme.of(context).textTheme.bodyLarge!.color,
fontSize: 18,
fontWeight: FontWeight.w700,
),
children: [
TextSpan(
text: controller.widget.pageTitle,
style: const TextStyle(decoration: TextDecoration.underline),
recognizer: TapGestureRecognizer()
..onTap = () {
final String route =
"/rooms/${controller.widget.defaultSelected.type.route}";
context.go(route);
},
),
if (controller.activeSpace != null)
const TextSpan(
text: " > ",
),
if (controller.activeSpace != null)
TextSpan(
text: controller.activeSpace!.getLocalizedDisplayname(),
style: const TextStyle(decoration: TextDecoration.underline),
recognizer: TapGestureRecognizer()
..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.widget.selectedView != null)
const TextSpan(
text: " > ",
),
if (controller.widget.selectedView != null)
TextSpan(
text: controller.widget.selectedView!.string(context),
),
],
),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
),
),
body: MaxWidthBody(
withScrolling: false,
child: controller.widget.selectedView != null
? Column(
children: [
Row(
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,
// ),
TimeSpanMenuButton(
value: controller.currentTimeSpan,
onChange: (TimeSpan value) =>
controller.toggleTimeSpan(context, value),
),
AnalyticsLanguageButton(
value: controller
.pangeaController.analytics.currentAnalyticsLang,
onChange: (lang) => controller.toggleSpaceLang(lang),
languages: controller.widget.targetLanguages,
),
],
),
Expanded(
flex: 1,
child: chartView(context),
),
Expanded(
flex: 1,
child: DefaultTabController(
length: 2,
child: Column(
children: [
TabBar(
tabs: [
...controller.widget.tabs.map(
(tab) => Tab(
icon: Icon(
tab.icon,
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
),
),
),
],
),
Expanded(
child: SingleChildScrollView(
child: SizedBox(
height: max(
controller.widget.tabs[0].items.length +
1,
controller.widget.tabs[1].items.length,
) *
72,
child: TabBarView(
physics: const NeverScrollableScrollPhysics(),
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
...controller.widget.tabs[0].items.map(
(item) => AnalyticsListTile(
refreshStream:
controller.refreshStream,
avatar: item.avatar,
defaultSelected: controller
.widget.defaultSelected,
selected: AnalyticsSelected(
item.id,
controller.widget.tabs[0].type,
item.displayName,
),
isSelected:
controller.isSelected(item.id),
onTap: (_) =>
controller.toggleSelection(
AnalyticsSelected(
item.id,
controller.widget.tabs[0].type,
item.displayName,
),
),
allowNavigateOnSelect: controller
.widget
.tabs[0]
.allowNavigateOnSelect,
pangeaController:
controller.pangeaController,
controller: controller,
),
),
if (controller
.widget.defaultSelected.type ==
AnalyticsEntryType.space)
AnalyticsListTile(
refreshStream:
controller.refreshStream,
defaultSelected: controller
.widget.defaultSelected,
avatar: null,
selected: AnalyticsSelected(
controller
.widget.defaultSelected.id,
AnalyticsEntryType.privateChats,
L10n.of(context)!.allPrivateChats,
),
allowNavigateOnSelect: false,
isSelected: controller.isSelected(
controller
.widget.defaultSelected.id,
),
onTap: controller.toggleSelection,
pangeaController:
controller.pangeaController,
controller: controller,
),
],
),
Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: controller.widget.tabs[1].items
.map(
(item) => AnalyticsListTile(
refreshStream:
controller.refreshStream,
avatar: item.avatar,
defaultSelected: controller
.widget.defaultSelected,
selected: AnalyticsSelected(
item.id,
controller.widget.tabs[1].type,
item.displayName,
),
isSelected: controller
.isSelected(item.id),
onTap: controller.toggleSelection,
allowNavigateOnSelect: controller
.widget
.tabs[1]
.allowNavigateOnSelect,
pangeaController:
controller.pangeaController,
controller: controller,
),
)
.toList(),
),
],
),
),
),
),
],
),
),
),
],
)
: Column(
children: [
const Divider(height: 1),
ListTile(
title: Text(L10n.of(context)!.grammarAnalytics),
leading: CircleAvatar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor,
foregroundColor:
Theme.of(context).textTheme.bodyLarge!.color,
child: Icon(BarChartViewSelection.grammar.icon),
),
trailing: const Icon(Icons.chevron_right),
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: Text(L10n.of(context)!.messageAnalytics),
leading: CircleAvatar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor,
foregroundColor:
Theme.of(context).textTheme.bodyLarge!.color,
child: Icon(BarChartViewSelection.messages.icon),
),
trailing: const Icon(Icons.chevron_right),
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),
],
),
),
);
}
}