fix for construct caching issues with other user's analytics showing up in the logged in user's analytics
This commit is contained in:
parent
c64829cd3c
commit
c8b38ab073
5 changed files with 97 additions and 80 deletions
|
|
@ -514,11 +514,6 @@ class AnalyticsController extends BaseController {
|
|||
|
||||
//////////////////////////// CONSTRUCTS ////////////////////////////
|
||||
|
||||
List<ConstructAnalyticsEvent>? _constructs;
|
||||
bool settingConstructs = false;
|
||||
|
||||
List<ConstructAnalyticsEvent>? get constructs => _constructs;
|
||||
|
||||
Future<List<ConstructAnalyticsEvent>> allMyConstructs() async {
|
||||
final List<Room> analyticsRooms =
|
||||
_pangeaController.matrixState.client.allMyAnalyticsRooms;
|
||||
|
|
@ -782,15 +777,13 @@ class AnalyticsController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
Future<List<ConstructAnalyticsEvent>?> setConstructs({
|
||||
Future<List<ConstructAnalyticsEvent>?> getConstructs({
|
||||
required ConstructType constructType,
|
||||
required AnalyticsSelected defaultSelected,
|
||||
AnalyticsSelected? selected,
|
||||
bool removeIT = true,
|
||||
bool forceUpdate = false,
|
||||
}) async {
|
||||
if (settingConstructs) return _constructs;
|
||||
settingConstructs = true;
|
||||
await _pangeaController.matrixState.client.roomsLoading;
|
||||
|
||||
Room? space;
|
||||
|
|
@ -807,8 +800,7 @@ class AnalyticsController extends BaseController {
|
|||
"selected": selected,
|
||||
},
|
||||
);
|
||||
settingConstructs = false;
|
||||
return _constructs;
|
||||
return [];
|
||||
}
|
||||
await space.postLoad();
|
||||
langCode = _pangeaController.languageController.activeL2Code(
|
||||
|
|
@ -821,8 +813,7 @@ class AnalyticsController extends BaseController {
|
|||
"space": space,
|
||||
},
|
||||
);
|
||||
settingConstructs = false;
|
||||
return _constructs;
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -852,8 +843,6 @@ class AnalyticsController extends BaseController {
|
|||
lastUpdated: lastUpdated,
|
||||
);
|
||||
if (local != null && !forceUpdate) {
|
||||
_constructs = local;
|
||||
settingConstructs = false;
|
||||
return local;
|
||||
}
|
||||
|
||||
|
|
@ -881,19 +870,16 @@ class AnalyticsController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
_constructs = filteredConstructs;
|
||||
|
||||
if (local == null) {
|
||||
cacheConstructs(
|
||||
constructType: constructType,
|
||||
events: _constructs!,
|
||||
events: filteredConstructs,
|
||||
defaultSelected: defaultSelected,
|
||||
selected: selected,
|
||||
);
|
||||
}
|
||||
|
||||
settingConstructs = false;
|
||||
return _constructs;
|
||||
return filteredConstructs;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/models/analytics/analytics_model.dart';
|
||||
import 'package:fluffychat/pangea/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
|
|
@ -16,11 +17,48 @@ class ConstructAnalyticsModel extends AnalyticsModel {
|
|||
static const _usesKey = "uses";
|
||||
|
||||
factory ConstructAnalyticsModel.fromJson(Map<String, dynamic> json) {
|
||||
final List<OneConstructUse> uses = [];
|
||||
if (json[_usesKey] is List) {
|
||||
// This is the new format
|
||||
uses.addAll(
|
||||
json[_usesKey]
|
||||
.map((use) => OneConstructUse.fromJson(use))
|
||||
.cast<OneConstructUse>()
|
||||
.toList(),
|
||||
);
|
||||
} else {
|
||||
// This is the old format. No data on production should be
|
||||
// structured this way, but it's useful for testing.
|
||||
try {
|
||||
final useValues = (json[_usesKey] as Map<String, dynamic>).values;
|
||||
for (final useValue in useValues) {
|
||||
final lemma = useValue['lemma'];
|
||||
final lemmaUses = useValue[_usesKey];
|
||||
for (final useData in lemmaUses) {
|
||||
final use = OneConstructUse(
|
||||
useType: ConstructUseType.ga,
|
||||
chatId: useData["chatId"],
|
||||
timeStamp: DateTime.parse(useData["timeStamp"]),
|
||||
lemma: lemma,
|
||||
form: useData["form"],
|
||||
msgId: useData["msgId"],
|
||||
constructType: ConstructType.grammar,
|
||||
);
|
||||
uses.add(use);
|
||||
}
|
||||
}
|
||||
} catch (err, s) {
|
||||
debugPrint("Error parsing ConstructAnalyticsModel");
|
||||
ErrorHandler.logError(
|
||||
e: err,
|
||||
s: s,
|
||||
m: "Error parsing ConstructAnalyticsModel",
|
||||
);
|
||||
// debugger(when: kDebugMode);
|
||||
}
|
||||
}
|
||||
return ConstructAnalyticsModel(
|
||||
uses: json[_usesKey]
|
||||
.map((use) => OneConstructUse.fromJson(use))
|
||||
.cast<OneConstructUse>()
|
||||
.toList(),
|
||||
uses: uses,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/pangea_event_types.dart';
|
||||
import 'package:fluffychat/pangea/enum/construct_type_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/analytics/analytics_event.dart';
|
||||
|
|
@ -147,26 +146,13 @@ class BaseAnalyticsController extends State<BaseAnalyticsPage> {
|
|||
currentLemma = null;
|
||||
selected = isSelected(selectedParam.id) ? null : selectedParam;
|
||||
});
|
||||
|
||||
await pangeaController.analytics.setConstructs(
|
||||
constructType: ConstructType.grammar,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: selected,
|
||||
removeIT: true,
|
||||
);
|
||||
await setChartData();
|
||||
|
||||
refreshStream.add(false);
|
||||
Future.delayed(Duration.zero, () => setState(() {}));
|
||||
}
|
||||
|
||||
Future<void> toggleTimeSpan(BuildContext context, TimeSpan timeSpan) async {
|
||||
await pangeaController.analytics.setCurrentAnalyticsTimeSpan(timeSpan);
|
||||
await pangeaController.analytics.setConstructs(
|
||||
constructType: ConstructType.grammar,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: selected,
|
||||
removeIT: true,
|
||||
);
|
||||
await setChartData();
|
||||
refreshStream.add(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ class ClassAnalyticsV2Controller extends State<ClassAnalyticsPage> {
|
|||
|
||||
Future<void> getChatAndStudents() async {
|
||||
try {
|
||||
await classRoom?.postLoad();
|
||||
await classRoom?.requestParticipants();
|
||||
|
||||
if (classRoom != null) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
|||
import 'package:fluffychat/pangea/enum/construct_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_representation_event.dart';
|
||||
import 'package:fluffychat/pangea/models/analytics/constructs_event.dart';
|
||||
import 'package:fluffychat/pangea/models/analytics/constructs_model.dart';
|
||||
import 'package:fluffychat/pangea/models/pangea_match_model.dart';
|
||||
import 'package:fluffychat/pangea/pages/analytics/base_analytics.dart';
|
||||
|
|
@ -40,29 +41,9 @@ class ConstructList extends StatefulWidget {
|
|||
}
|
||||
|
||||
class ConstructListState extends State<ConstructList> {
|
||||
bool initialized = false;
|
||||
String? langCode;
|
||||
String? error;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
widget.pangeaController.analytics
|
||||
.setConstructs(
|
||||
constructType: widget.constructType,
|
||||
removeIT: true,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: widget.selected,
|
||||
forceUpdate: true,
|
||||
)
|
||||
.whenComplete(() => setState(() => initialized = true));
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return error != null
|
||||
|
|
@ -72,7 +53,6 @@ class ConstructListState extends State<ConstructList> {
|
|||
: Column(
|
||||
children: [
|
||||
ConstructListView(
|
||||
init: initialized,
|
||||
controller: widget.controller,
|
||||
pangeaController: widget.pangeaController,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
|
|
@ -94,7 +74,6 @@ class ConstructListState extends State<ConstructList> {
|
|||
// subtitle = total uses, equal to construct.content.uses.length
|
||||
// list has a fixed height of 400 and is scrollable
|
||||
class ConstructListView extends StatefulWidget {
|
||||
final bool init;
|
||||
final BaseAnalyticsController controller;
|
||||
final PangeaController pangeaController;
|
||||
final AnalyticsSelected defaultSelected;
|
||||
|
|
@ -103,7 +82,6 @@ class ConstructListView extends StatefulWidget {
|
|||
|
||||
const ConstructListView({
|
||||
super.key,
|
||||
required this.init,
|
||||
required this.controller,
|
||||
required this.pangeaController,
|
||||
required this.defaultSelected,
|
||||
|
|
@ -120,22 +98,46 @@ class ConstructListViewState extends State<ConstructListView> {
|
|||
final Map<String, Timeline> _timelinesCache = {};
|
||||
final Map<String, PangeaMessageEvent> _msgEventCache = {};
|
||||
final List<PangeaMessageEvent> _msgEvents = [];
|
||||
bool fetchingConstructs = true;
|
||||
bool fetchingUses = false;
|
||||
StreamSubscription? refreshSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
widget.pangeaController.analytics
|
||||
.getConstructs(
|
||||
constructType: constructType,
|
||||
removeIT: true,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: widget.selected,
|
||||
forceUpdate: true,
|
||||
)
|
||||
.whenComplete(() => setState(() => fetchingConstructs = false))
|
||||
.then((value) => setState(() => _constructs = value));
|
||||
|
||||
refreshSubscription = widget.refreshStream.stream.listen((forceUpdate) {
|
||||
widget.pangeaController.analytics
|
||||
.setConstructs(
|
||||
constructType: constructType,
|
||||
removeIT: true,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: widget.selected,
|
||||
forceUpdate: true,
|
||||
)
|
||||
.then((_) => setState(() {}));
|
||||
debugPrint("updating constructs");
|
||||
// postframe callback to let widget rebuild with the new selected parameter
|
||||
// before sending selected to getConstructs function
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
widget.pangeaController.analytics
|
||||
.getConstructs(
|
||||
constructType: constructType,
|
||||
removeIT: true,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: widget.selected,
|
||||
forceUpdate: true,
|
||||
)
|
||||
.then(
|
||||
(value) => setState(() {
|
||||
_constructs = value;
|
||||
debugPrint(
|
||||
"constructs is now: ${constructs?.map((event) => event.uses.map((use) => use.lemma)).toList()}",
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -219,18 +221,19 @@ class ConstructListViewState extends State<ConstructListView> {
|
|||
}
|
||||
}
|
||||
|
||||
List<ConstructAnalyticsEvent>? _constructs;
|
||||
|
||||
List<ConstructUses>? get constructs {
|
||||
if (widget.pangeaController.analytics.constructs == null) {
|
||||
if (_constructs == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<OneConstructUse> filtered =
|
||||
List.from(widget.pangeaController.analytics.constructs!)
|
||||
.map((event) => event.content.uses)
|
||||
.expand((uses) => uses)
|
||||
.cast<OneConstructUse>()
|
||||
.where((use) => use.constructType == constructType)
|
||||
.toList();
|
||||
final List<OneConstructUse> filtered = List.from(_constructs!)
|
||||
.map((event) => event.content.uses)
|
||||
.expand((uses) => uses)
|
||||
.cast<OneConstructUse>()
|
||||
.where((use) => use.constructType == constructType)
|
||||
.toList();
|
||||
|
||||
final Map<String, List<OneConstructUse>> lemmaToUses = {};
|
||||
for (final use in filtered) {
|
||||
|
|
@ -303,7 +306,7 @@ class ConstructListViewState extends State<ConstructListView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!widget.init || fetchingUses) {
|
||||
if (fetchingConstructs || fetchingUses) {
|
||||
return const Expanded(
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
|
|
@ -347,7 +350,10 @@ class ConstructMessagesDialog extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (controller.widget.controller.currentLemma == null) {
|
||||
if (controller.widget.controller.currentLemma == null ||
|
||||
controller.constructs == null ||
|
||||
controller.lemmaIndex < 0 ||
|
||||
controller.lemmaIndex >= controller.constructs!.length) {
|
||||
return const AlertDialog(content: CircularProgressIndicator.adaptive());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue