improved performance and battery usage on older devices
This commit is contained in:
@@ -7,6 +7,7 @@ import '../../../api/marianumconnect/queries/timetable_get_element_week/timetabl
|
||||
import '../../../api/marianumconnect/queries/timetable_get_rooms/timetable_get_rooms.dart';
|
||||
import '../../../api/marianumconnect/queries/timetable_get_students/timetable_get_students.dart';
|
||||
import '../../../api/marianumconnect/queries/timetable_get_teachers/timetable_get_teachers.dart';
|
||||
import '../../../model/account_data.dart';
|
||||
import '../../../state/app/modules/settings/bloc/settings_cubit.dart';
|
||||
import '../../../storage/timetable_favorites_settings.dart';
|
||||
import '../../../utils/haptics.dart';
|
||||
@@ -31,7 +32,14 @@ class _ElementPickerPageState extends State<ElementPickerPage> {
|
||||
|
||||
// One in-flight/resolved future per type so switching tabs (or rebuilds)
|
||||
// never re-fetches a list that's already loaded.
|
||||
final Map<TimetableElementType, Future<List<_PickerItem>>> _futures = {};
|
||||
// Session-wide (per account): the student list alone has 1000+ entries and
|
||||
// used to be downloaded again every time the picker opened.
|
||||
static final Map<
|
||||
TimetableElementType,
|
||||
({int epoch, DateTime at, Future<List<_PickerItem>> items})
|
||||
>
|
||||
_futures = {};
|
||||
static const Duration _listMaxAge = Duration(minutes: 15);
|
||||
// Memoised combined future for the "Alle" tab; rebuilt on retry.
|
||||
Future<List<_PickerItem>>? _allFuture;
|
||||
|
||||
@@ -47,8 +55,25 @@ class _ElementPickerPageState extends State<ElementPickerPage> {
|
||||
return _allFuture ??= _loadAll();
|
||||
}
|
||||
|
||||
Future<List<_PickerItem>> _loadFor(TimetableElementType type) =>
|
||||
_futures.putIfAbsent(type, () => _fetch(type));
|
||||
Future<List<_PickerItem>> _loadFor(TimetableElementType type) {
|
||||
final epoch = AccountData().sessionEpoch;
|
||||
final cached = _futures[type];
|
||||
if (cached != null &&
|
||||
cached.epoch == epoch &&
|
||||
DateTime.now().difference(cached.at) < _listMaxAge) {
|
||||
return cached.items;
|
||||
}
|
||||
final items = _fetch(type);
|
||||
_futures[type] = (epoch: epoch, at: DateTime.now(), items: items);
|
||||
// A failed load must not stick for the rest of the session.
|
||||
items.then(
|
||||
(_) {},
|
||||
onError: (Object _) {
|
||||
if (identical(_futures[type]?.items, items)) _futures.remove(type);
|
||||
},
|
||||
);
|
||||
return items;
|
||||
}
|
||||
|
||||
Future<List<_PickerItem>> _loadAll() async {
|
||||
final lists = await Future.wait(TimetableElementType.values.map(_loadFor));
|
||||
@@ -117,20 +142,16 @@ class _ElementPickerPageState extends State<ElementPickerPage> {
|
||||
Haptics.selection();
|
||||
// Hand the selection back to the timetable view, which renders the foreign
|
||||
// plan inline. We do not navigate to a new page.
|
||||
Navigator.of(context).pop((
|
||||
type: item.type,
|
||||
id: item.id,
|
||||
label: item.primary,
|
||||
));
|
||||
Navigator.of(
|
||||
context,
|
||||
).pop((type: item.type, id: item.id, label: item.primary));
|
||||
}
|
||||
|
||||
void _openFavorite(FavoriteTimetableElement favorite) {
|
||||
Haptics.selection();
|
||||
Navigator.of(context).pop((
|
||||
type: favorite.type,
|
||||
id: favorite.id,
|
||||
label: favorite.label,
|
||||
));
|
||||
Navigator.of(
|
||||
context,
|
||||
).pop((type: favorite.type, id: favorite.id, label: favorite.label));
|
||||
}
|
||||
|
||||
void _toggleFavorite(TimetableElementType type, int id, String label) {
|
||||
@@ -325,9 +346,7 @@ class _ElementPickerPageState extends State<ElementPickerPage> {
|
||||
return ListTile(
|
||||
leading: Icon(_iconFor(item.type)),
|
||||
title: Text(item.primary),
|
||||
subtitle: subtitleParts.isEmpty
|
||||
? null
|
||||
: Text(subtitleParts.join(' · ')),
|
||||
subtitle: subtitleParts.isEmpty ? null : Text(subtitleParts.join(' · ')),
|
||||
trailing: IconButton(
|
||||
icon: Icon(isFavorite ? Icons.star : Icons.star_border),
|
||||
tooltip: isFavorite ? 'Favorit entfernen' : 'Als Favorit markieren',
|
||||
|
||||
Reference in New Issue
Block a user