From a56453ab9d613f92d21977d796e57d6e9d4bc1b1 Mon Sep 17 00:00:00 2001 From: unknown <55nknown@pm.me> Date: Sat, 2 Oct 2021 21:47:41 +0200 Subject: [PATCH] status --- .../lib/api/providers/status_provider.dart | 69 +++++++++++++++++++ filcnaplo/lib/api/providers/sync.dart | 68 ++++++++++++++++++ filcnaplo/lib/app.dart | 2 + filcnaplo_kreta_api | 2 +- 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 filcnaplo/lib/api/providers/status_provider.dart create mode 100644 filcnaplo/lib/api/providers/sync.dart diff --git a/filcnaplo/lib/api/providers/status_provider.dart b/filcnaplo/lib/api/providers/status_provider.dart new file mode 100644 index 0000000..9029581 --- /dev/null +++ b/filcnaplo/lib/api/providers/status_provider.dart @@ -0,0 +1,69 @@ +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; + +enum Status { network, maintenance, syncing } + +class StatusProvider extends ChangeNotifier { + List _stack = []; + double _progress = 0.0; + + StatusProvider() { + _handleNetworkChanges(); + } + + Status? getStatus() => _stack.length > 0 ? _stack[0] : null; + // Status progress from 0.0 to 1.0 + double get progress => _progress; + + void _handleNetworkChanges() { + Connectivity().onConnectivityChanged.listen((event) { + if (event == ConnectivityResult.none) { + if (!_stack.contains(Status.network)) { + _stack.insert(0, Status.network); + notifyListeners(); + } + } else { + if (_stack.contains(Status.network)) { + _stack.remove(Status.network); + notifyListeners(); + } + } + }); + } + + void triggerRequest(http.Response res) { + if (res.headers.containsKey("x-maintenance-mode") || res.statusCode == 503) { + if (!_stack.contains(Status.maintenance)) { + _stack.insert(0, Status.maintenance); + notifyListeners(); + } + } else { + if (_stack.contains(Status.maintenance)) { + _stack.remove(Status.maintenance); + notifyListeners(); + } + } + } + + void triggerSync({required int current, required int max}) { + double prev = _progress; + + if (!_stack.contains(Status.syncing)) { + _stack.add(Status.syncing); + notifyListeners(); + } + + if (max == 0) { + _progress = 0.0; + } else { + _progress = current / max; + } + + if (_progress == 1.0) { + _stack.remove(Status.syncing); + _progress = 0.0; + notifyListeners(); + } else if (progress != prev) notifyListeners(); + } +} diff --git a/filcnaplo/lib/api/providers/sync.dart b/filcnaplo/lib/api/providers/sync.dart new file mode 100644 index 0000000..6705f7b --- /dev/null +++ b/filcnaplo/lib/api/providers/sync.dart @@ -0,0 +1,68 @@ +import 'package:filcnaplo/api/providers/database_provider.dart'; +import 'package:filcnaplo/api/providers/status_provider.dart'; +import 'package:filcnaplo/api/providers/user_provider.dart'; +import 'package:filcnaplo_kreta_api/client/api.dart'; +import 'package:filcnaplo_kreta_api/client/client.dart'; +import 'package:filcnaplo_kreta_api/models/student.dart'; +import 'package:filcnaplo_kreta_api/models/week.dart'; +import 'package:filcnaplo_kreta_api/providers/absence_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/event_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/exam_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/grade_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/homework_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/message_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/note_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart'; +import 'package:flutter/widgets.dart'; +import 'package:provider/provider.dart'; + +// Mutex +bool lock = false; + +Future syncAll(BuildContext context) { + if (lock) return Future.value(); + // Lock + lock = true; + + print("INFO Syncing all"); + + UserProvider user = Provider.of(context, listen: false); + StatusProvider statusProvider = Provider.of(context, listen: false); + + List> tasks = []; + int taski = 0; + + Future _syncStatus(Future future) async { + await future.onError((error, stackTrace) => null); + taski++; + statusProvider.triggerSync(current: taski, max: tasks.length); + } + + tasks = [ + _syncStatus(Provider.of(context, listen: false).fetch()), + _syncStatus(Provider.of(context, listen: false).fetch(week: Week.current())), + _syncStatus(Provider.of(context, listen: false).fetch()), + _syncStatus(Provider.of(context, listen: false).fetch(from: DateTime.now().subtract(Duration(days: 30)))), + _syncStatus(Provider.of(context, listen: false).fetchAll()), + _syncStatus(Provider.of(context, listen: false).fetch()), + _syncStatus(Provider.of(context, listen: false).fetch()), + _syncStatus(Provider.of(context, listen: false).fetch()), + + // Sync student + _syncStatus(() async { + if (user.user == null) return; + Map? studentJson = await Provider.of(context, listen: false).getAPI(KretaAPI.student(user.instituteCode!)); + if (studentJson == null) return; + Student student = Student.fromJson(studentJson); + + user.user?.name = student.name; + + // Store user + await Provider.of(context, listen: false).store.storeUser(user.user!); + }()), + ]; + + return Future.wait(tasks) + // Unlock + .then((value) => lock = false); +} diff --git a/filcnaplo/lib/app.dart b/filcnaplo/lib/app.dart index 3b1fa49..d3df993 100644 --- a/filcnaplo/lib/app.dart +++ b/filcnaplo/lib/app.dart @@ -4,6 +4,7 @@ import 'dart:math'; import 'package:filcnaplo/api/client.dart'; import 'package:filcnaplo/api/providers/news_provider.dart'; import 'package:filcnaplo/api/providers/database_provider.dart'; +import 'package:filcnaplo/api/providers/status_provider.dart'; import 'package:filcnaplo/models/config.dart'; import 'package:filcnaplo/theme.dart'; import 'package:filcnaplo_kreta_api/client/client.dart'; @@ -62,6 +63,7 @@ class App extends StatelessWidget { providers: [ ChangeNotifierProvider(create: (_) => settings), ChangeNotifierProvider(create: (_) => user), + ChangeNotifierProvider(create: (context) => StatusProvider()), Provider(create: (context) => KretaClient(context: context, userAgent: settings.config.userAgent)), Provider(create: (context) => database), ChangeNotifierProvider(create: (context) => ThemeModeObserver(initialTheme: settings.theme)), diff --git a/filcnaplo_kreta_api b/filcnaplo_kreta_api index 54f93dd..10d259e 160000 --- a/filcnaplo_kreta_api +++ b/filcnaplo_kreta_api @@ -1 +1 @@ -Subproject commit 54f93dd273491071451a6e684a1d241a4875f8c4 +Subproject commit 10d259ebc983960d5872c9ee743676ecbb3c7022