Skip to content

Commit

Permalink
Add provider caching
Browse files Browse the repository at this point in the history
  • Loading branch information
bdmendes committed Jul 10, 2023
1 parent 1d13aa3 commit a231d07
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 18 deletions.
2 changes: 1 addition & 1 deletion uni/lib/model/providers/lazy/bus_stop_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class BusStopProvider extends StateProviderNotifier {
Map<String, BusStopData> _configuredBusStops = Map.identity();
DateTime _timeStamp = DateTime.now();

BusStopProvider() : super(dependsOnSession: false);
BusStopProvider() : super(dependsOnSession: false, cacheDuration: null);

UnmodifiableMapView<String, BusStopData> get configuredBusStops =>
UnmodifiableMapView(_configuredBusStops);
Expand Down
3 changes: 2 additions & 1 deletion uni/lib/model/providers/lazy/calendar_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import 'package:uni/model/request_status.dart';
class CalendarProvider extends StateProviderNotifier {
List<CalendarEvent> _calendar = [];

CalendarProvider() : super(dependsOnSession: true);
CalendarProvider()
: super(dependsOnSession: true, cacheDuration: const Duration(days: 30));

UnmodifiableListView<CalendarEvent> get calendar =>
UnmodifiableListView(_calendar);
Expand Down
3 changes: 2 additions & 1 deletion uni/lib/model/providers/lazy/exam_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class ExamProvider extends StateProviderNotifier {
List<String> _hiddenExams = [];
Map<String, bool> _filteredExamsTypes = {};

ExamProvider() : super(dependsOnSession: true);
ExamProvider()
: super(dependsOnSession: true, cacheDuration: const Duration(days: 1));

UnmodifiableListView<Exam> get exams => UnmodifiableListView(_exams);

Expand Down
3 changes: 2 additions & 1 deletion uni/lib/model/providers/lazy/faculty_locations_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import 'package:uni/model/request_status.dart';
class FacultyLocationsProvider extends StateProviderNotifier {
List<LocationGroup> _locations = [];

FacultyLocationsProvider() : super(dependsOnSession: false);
FacultyLocationsProvider()
: super(dependsOnSession: false, cacheDuration: const Duration(days: 30));

UnmodifiableListView<LocationGroup> get locations =>
UnmodifiableListView(_locations);
Expand Down
2 changes: 1 addition & 1 deletion uni/lib/model/providers/lazy/home_page_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class HomePageProvider extends StateProviderNotifier {
List<FavoriteWidgetType> _favoriteCards = [];
bool _isEditing = false;

HomePageProvider() : super(dependsOnSession: false);
HomePageProvider() : super(dependsOnSession: false, cacheDuration: null);

List<FavoriteWidgetType> get favoriteCards => _favoriteCards.toList();

Expand Down
3 changes: 2 additions & 1 deletion uni/lib/model/providers/lazy/lecture_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import 'package:uni/model/request_status.dart';
class LectureProvider extends StateProviderNotifier {
List<Lecture> _lectures = [];

LectureProvider() : super(dependsOnSession: true);
LectureProvider()
: super(dependsOnSession: true, cacheDuration: const Duration(hours: 6));

UnmodifiableListView<Lecture> get lectures => UnmodifiableListView(_lectures);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import 'package:uni/model/request_status.dart';
class LibraryOccupationProvider extends StateProviderNotifier {
LibraryOccupation? _occupation;

LibraryOccupationProvider() : super(dependsOnSession: true);
LibraryOccupationProvider()
: super(dependsOnSession: true, cacheDuration: const Duration(hours: 1));

LibraryOccupation? get occupation => _occupation;

Expand Down
3 changes: 2 additions & 1 deletion uni/lib/model/providers/lazy/restaurant_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import 'package:uni/model/request_status.dart';
class RestaurantProvider extends StateProviderNotifier {
List<Restaurant> _restaurants = [];

RestaurantProvider() : super(dependsOnSession: false);
RestaurantProvider()
: super(dependsOnSession: false, cacheDuration: const Duration(days: 1));

UnmodifiableListView<Restaurant> get restaurants =>
UnmodifiableListView(_restaurants);
Expand Down
3 changes: 2 additions & 1 deletion uni/lib/model/providers/startup/profile_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class ProfileProvider extends StateProviderNotifier {
DateTime? _feesRefreshTime;
DateTime? _printRefreshTime;

ProfileProvider() : super(dependsOnSession: true);
ProfileProvider()
: super(dependsOnSession: true, cacheDuration: const Duration(days: 1));

String get feesRefreshTime => _feesRefreshTime.toString();

Expand Down
6 changes: 5 additions & 1 deletion uni/lib/model/providers/startup/session_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ class SessionProvider extends StateProviderNotifier {
Session _session = Session();
List<String> _faculties = [];

SessionProvider() : super(dependsOnSession: false);
SessionProvider()
: super(
dependsOnSession: false,
cacheDuration: null,
initialStatus: RequestStatus.none);

Session get session => _session;

Expand Down
45 changes: 37 additions & 8 deletions uni/lib/model/providers/state_provider_notifier.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';
import 'package:synchronized/synchronized.dart';
import 'package:uni/controller/local_storage/app_shared_preferences.dart';
Expand All @@ -11,16 +12,21 @@ import 'package:uni/model/request_status.dart';

abstract class StateProviderNotifier extends ChangeNotifier {
static final Lock _lock = Lock();
RequestStatus _status = RequestStatus.busy;
RequestStatus _status;
bool _initialized = false;
DateTime? _lastUpdateTime;
bool dependsOnSession;
Duration? cacheDuration;

RequestStatus get status => _status;

DateTime? get lastUpdateTime => _lastUpdateTime;

StateProviderNotifier({required this.dependsOnSession});
StateProviderNotifier(
{required this.dependsOnSession,
required this.cacheDuration,
RequestStatus? initialStatus})
: _status = initialStatus ?? RequestStatus.busy;

Future<void> _loadFromStorage() async {
_lastUpdateTime = await AppSharedPreferences.getLastDataClassUpdateTime(
Expand All @@ -30,20 +36,43 @@ abstract class StateProviderNotifier extends ChangeNotifier {
await AppSharedPreferences.getPersistentUserInfo();
final sessionIsPersistent =
userPersistentInfo.item1 != '' && userPersistentInfo.item2 != '';

if (sessionIsPersistent) {
await loadFromStorage();
Logger().i("Loaded $runtimeType info from storage");
} else {
Logger().i(
"Session is not persistent; skipping $runtimeType load from storage");
}
}

Future<void> _loadFromRemote(Session session, Profile profile) async {
Future<void> _loadFromRemote(Session session, Profile profile,
{bool force = false}) async {
final bool hasConnectivity =
await Connectivity().checkConnectivity() != ConnectivityResult.none;
if (hasConnectivity) {
updateStatus(RequestStatus.busy);
await loadFromRemote(session, profile);
final shouldReload = force ||
_lastUpdateTime == null ||
cacheDuration == null ||
DateTime.now().difference(_lastUpdateTime!) > cacheDuration!;

if (shouldReload) {
if (hasConnectivity) {
updateStatus(RequestStatus.busy);
await loadFromRemote(session, profile);
if (_status == RequestStatus.successful) {
Logger().i("Loaded $runtimeType info from remote");
} else if (_status == RequestStatus.failed) {
Logger().e("Failed to load $runtimeType info from remote");
}
} else {
Logger().i("No internet connection; skipping $runtimeType remote load");
}
} else {
Logger().i(
"Last info for $runtimeType is within cache period ($cacheDuration); skipping remote load");
}

if (!hasConnectivity || _status == RequestStatus.busy) {
if (!shouldReload || !hasConnectivity || _status == RequestStatus.busy) {
// No online activity from provider
updateStatus(RequestStatus.successful);
} else {
Expand All @@ -65,7 +94,7 @@ abstract class StateProviderNotifier extends ChangeNotifier {
final profile =
Provider.of<ProfileProvider>(context, listen: false).profile;

_loadFromRemote(session, profile);
_loadFromRemote(session, profile, force: true);
}

Future<void> ensureInitialized(Session session, Profile profile) async {
Expand Down

0 comments on commit a231d07

Please sign in to comment.