fix for out-of-date cached analytics not updating
This commit is contained in:
parent
98778abc51
commit
91f5fab0ea
5 changed files with 75 additions and 36 deletions
|
|
@ -117,6 +117,7 @@ class AnalyticsController extends BaseController {
|
|||
ChartAnalyticsModel? getAnalyticsLocal({
|
||||
TimeSpan? timeSpan,
|
||||
required AnalyticsSelected defaultSelected,
|
||||
required DateTime? analyticsLastUpdated,
|
||||
AnalyticsSelected? selected,
|
||||
bool forceUpdate = false,
|
||||
bool updateExpired = false,
|
||||
|
|
@ -132,8 +133,11 @@ class AnalyticsController extends BaseController {
|
|||
);
|
||||
|
||||
if (index != -1) {
|
||||
final DateTime? cachedLastUpdate =
|
||||
_cachedAnalyticsModels[index].summaryLastUpdated;
|
||||
if ((updateExpired && _cachedAnalyticsModels[index].isExpired) ||
|
||||
forceUpdate) {
|
||||
forceUpdate ||
|
||||
cachedLastUpdate != analyticsLastUpdated) {
|
||||
_cachedAnalyticsModels.removeAt(index);
|
||||
} else {
|
||||
return _cachedAnalyticsModels[index].chartAnalyticsModel;
|
||||
|
|
@ -146,6 +150,7 @@ class AnalyticsController extends BaseController {
|
|||
void cacheAnalytics({
|
||||
required ChartAnalyticsModel chartAnalyticsModel,
|
||||
required AnalyticsSelected defaultSelected,
|
||||
required DateTime? summaryLastUpdated,
|
||||
AnalyticsSelected? selected,
|
||||
TimeSpan? timeSpan,
|
||||
}) {
|
||||
|
|
@ -155,6 +160,7 @@ class AnalyticsController extends BaseController {
|
|||
chartAnalyticsModel: chartAnalyticsModel,
|
||||
defaultSelected: defaultSelected,
|
||||
selected: selected,
|
||||
summaryLastUpdated: summaryLastUpdated,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -273,10 +279,13 @@ class AnalyticsController extends BaseController {
|
|||
bool forceUpdate = false,
|
||||
}) async {
|
||||
try {
|
||||
final DateTime? analyticsLastUpdated = await _pangeaController.myAnalytics
|
||||
.analyticsLastUpdated(PangeaEventTypes.summaryAnalytics);
|
||||
final local = getAnalyticsLocal(
|
||||
defaultSelected: defaultSelected,
|
||||
selected: selected,
|
||||
forceUpdate: forceUpdate,
|
||||
analyticsLastUpdated: analyticsLastUpdated,
|
||||
);
|
||||
if (local != null && !forceUpdate) {
|
||||
return local;
|
||||
|
|
@ -330,6 +339,7 @@ class AnalyticsController extends BaseController {
|
|||
defaultSelected: defaultSelected,
|
||||
selected: selected,
|
||||
timeSpan: currentAnalyticsTimeSpan,
|
||||
summaryLastUpdated: analyticsLastUpdated,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -510,26 +520,36 @@ class AnalyticsController extends BaseController {
|
|||
required TimeSpan timeSpan,
|
||||
required ConstructType constructType,
|
||||
required AnalyticsSelected defaultSelected,
|
||||
required DateTime? constructsLastUpdated,
|
||||
AnalyticsSelected? selected,
|
||||
}) {
|
||||
final cachedEntry = _cachedConstructs
|
||||
.firstWhereOrNull(
|
||||
(e) =>
|
||||
e.timeSpan == timeSpan &&
|
||||
e.type == constructType &&
|
||||
e.defaultSelected.id == defaultSelected.id &&
|
||||
e.defaultSelected.type == defaultSelected.type &&
|
||||
e.selected?.id == selected?.id &&
|
||||
e.selected?.type == selected?.type,
|
||||
)
|
||||
?.events;
|
||||
return cachedEntry;
|
||||
final index = _cachedConstructs.indexWhere(
|
||||
(e) =>
|
||||
e.timeSpan == timeSpan &&
|
||||
e.type == constructType &&
|
||||
e.defaultSelected.id == defaultSelected.id &&
|
||||
e.defaultSelected.type == defaultSelected.type &&
|
||||
e.selected?.id == selected?.id &&
|
||||
e.selected?.type == selected?.type,
|
||||
);
|
||||
|
||||
if (index > -1) {
|
||||
if (_cachedConstructs[index].constructsLastUpdated !=
|
||||
constructsLastUpdated) {
|
||||
_cachedConstructs.removeAt(index);
|
||||
return null;
|
||||
}
|
||||
return _cachedConstructs[index].events;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void cacheConstructs({
|
||||
required ConstructType constructType,
|
||||
required List<ConstructAnalyticsEvent> events,
|
||||
required AnalyticsSelected defaultSelected,
|
||||
required DateTime? constructsLastUpdated,
|
||||
AnalyticsSelected? selected,
|
||||
}) {
|
||||
_cachedConstructs.add(
|
||||
|
|
@ -539,6 +559,7 @@ class AnalyticsController extends BaseController {
|
|||
events: events,
|
||||
defaultSelected: defaultSelected,
|
||||
selected: selected,
|
||||
constructsLastUpdated: constructsLastUpdated,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -638,11 +659,14 @@ class AnalyticsController extends BaseController {
|
|||
bool removeIT = false,
|
||||
bool forceUpdate = false,
|
||||
}) async {
|
||||
final DateTime? constructsLastUpdated = await _pangeaController.myAnalytics
|
||||
.analyticsLastUpdated(PangeaEventTypes.construct);
|
||||
final List<ConstructAnalyticsEvent>? local = getConstructsLocal(
|
||||
timeSpan: currentAnalyticsTimeSpan,
|
||||
constructType: constructType,
|
||||
defaultSelected: defaultSelected,
|
||||
selected: selected,
|
||||
constructsLastUpdated: constructsLastUpdated,
|
||||
);
|
||||
if (local != null && !forceUpdate) {
|
||||
_constructs = local;
|
||||
|
|
@ -691,6 +715,7 @@ class AnalyticsController extends BaseController {
|
|||
events: _constructs!,
|
||||
defaultSelected: defaultSelected,
|
||||
selected: selected,
|
||||
constructsLastUpdated: constructsLastUpdated,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -705,12 +730,14 @@ class ConstructCacheEntry {
|
|||
final List<ConstructAnalyticsEvent> events;
|
||||
final AnalyticsSelected defaultSelected;
|
||||
AnalyticsSelected? selected;
|
||||
final DateTime? constructsLastUpdated;
|
||||
|
||||
ConstructCacheEntry({
|
||||
required this.timeSpan,
|
||||
required this.type,
|
||||
required this.events,
|
||||
required this.defaultSelected,
|
||||
required this.constructsLastUpdated,
|
||||
this.selected,
|
||||
});
|
||||
}
|
||||
|
|
@ -721,11 +748,13 @@ class AnalyticsCacheModel {
|
|||
final AnalyticsSelected defaultSelected;
|
||||
AnalyticsSelected? selected;
|
||||
late DateTime _createdAt;
|
||||
final DateTime? summaryLastUpdated;
|
||||
|
||||
AnalyticsCacheModel({
|
||||
required this.timeSpan,
|
||||
required this.chartAnalyticsModel,
|
||||
required this.defaultSelected,
|
||||
required this.summaryLastUpdated,
|
||||
this.selected,
|
||||
}) {
|
||||
_createdAt = DateTime.now();
|
||||
|
|
|
|||
|
|
@ -316,6 +316,25 @@ class MyAnalyticsController extends BaseController {
|
|||
}
|
||||
return aggregatedConstructs;
|
||||
}
|
||||
|
||||
Future<DateTime?> analyticsLastUpdated(String type) async {
|
||||
final List<Room> analyticsRooms =
|
||||
_pangeaController.matrixState.client.allMyAnalyticsRooms;
|
||||
if (analyticsRooms.isEmpty) return null;
|
||||
final List<DateTime> lastUpdates = [];
|
||||
for (final analyticsRoom in analyticsRooms) {
|
||||
final AnalyticsEvent? lastEvent =
|
||||
await analyticsRoom.getLastAnalyticsEvent(
|
||||
type,
|
||||
);
|
||||
if (lastEvent?.content.lastUpdated != null) {
|
||||
lastUpdates.add(lastEvent!.content.lastUpdated!);
|
||||
}
|
||||
}
|
||||
return lastUpdates.reduce(
|
||||
(value, element) => value.isAfter(element) ? value : element,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AggregateConstructUses {
|
||||
|
|
|
|||
|
|
@ -65,14 +65,8 @@ class BaseAnalyticsController extends State<BaseAnalyticsPage> {
|
|||
AnalyticsSelected? params, {
|
||||
forceUpdate = false,
|
||||
}) async {
|
||||
ChartAnalyticsModel? data = pangeaController.analytics.getAnalyticsLocal(
|
||||
timeSpan: currentTimeSpan,
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: params,
|
||||
forceUpdate: forceUpdate,
|
||||
);
|
||||
|
||||
data ??= await pangeaController.analytics.getAnalytics(
|
||||
final ChartAnalyticsModel data =
|
||||
await pangeaController.analytics.getAnalytics(
|
||||
defaultSelected: widget.defaultSelected,
|
||||
selected: params,
|
||||
forceUpdate: forceUpdate,
|
||||
|
|
|
|||
|
|
@ -95,11 +95,13 @@ class BaseAnalyticsView extends StatelessWidget {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
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) =>
|
||||
|
|
|
|||
|
|
@ -278,14 +278,16 @@ class ConstructListViewState extends State<ConstructListView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
debugPrint(
|
||||
"constructs lengths: ${constructs?.map((x) => '${x.lemma}: ${x.uses.length}').toList()}",
|
||||
);
|
||||
if (!widget.init || fetchingUses) {
|
||||
return const Expanded(
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
|
||||
if ((constructs?.isEmpty ?? true) ||
|
||||
(widget.controller.currentLemma != null && currentConstruct == null)) {
|
||||
if (constructs?.isEmpty ?? true) {
|
||||
return Expanded(
|
||||
child: Center(child: Text(L10n.of(context)!.noDataFound)),
|
||||
);
|
||||
|
|
@ -551,14 +553,7 @@ class ConstructMessageMetadata extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final String roomName = msgEvent.event.room.name.isEmpty
|
||||
? Matrix.of(context)
|
||||
.client
|
||||
.getRoomById(msgEvent.event.room.id)
|
||||
?.getLocalizedDisplayname() ??
|
||||
""
|
||||
: msgEvent.event.room.name;
|
||||
|
||||
final String roomName = msgEvent.event.room.getLocalizedDisplayname();
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(10, 0, 30, 0),
|
||||
child: Column(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue