From 4a43f1607c34a05c200138f46f90e40ff5280bdc Mon Sep 17 00:00:00 2001
From: Kima <kimavideos97@gmail.com>
Date: Sat, 2 Sep 2023 15:37:49 +0200
Subject: [PATCH] added goal provider thing

---
 filcnaplo/lib/app.dart                        |  9 ++++-
 .../screens/navigation/navigation_screen.dart | 14 ++++++-
 .../screens/navigation/navigation_screen.dart | 26 +++++++++++--
 .../lib/providers/goal_provider.dart          | 39 +++++++++++++++----
 4 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/filcnaplo/lib/app.dart b/filcnaplo/lib/app.dart
index 15a410c..d6bbcea 100644
--- a/filcnaplo/lib/app.dart
+++ b/filcnaplo/lib/app.dart
@@ -12,6 +12,7 @@ import 'package:filcnaplo/theme/observer.dart';
 import 'package:filcnaplo/theme/theme.dart';
 import 'package:filcnaplo_kreta_api/client/client.dart';
 import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
+import 'package:filcnaplo_premium/providers/goal_provider.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
@@ -89,6 +90,7 @@ class App extends StatelessWidget {
 
     return MultiProvider(
       providers: [
+        // refilc providers
         ChangeNotifierProvider<PremiumProvider>(create: (_) => premium),
         ChangeNotifierProvider<SettingsProvider>(create: (_) => settings),
         ChangeNotifierProvider<UserProvider>(create: (_) => user),
@@ -103,7 +105,7 @@ class App extends StatelessWidget {
         ChangeNotifierProvider<UpdateProvider>(
             create: (context) => UpdateProvider(context: context)),
 
-        // User data providers
+        // user data (kreten) providers
         ChangeNotifierProvider<GradeProvider>(
             create: (_) => GradeProvider(
                 settings: settings,
@@ -125,6 +127,7 @@ class App extends StatelessWidget {
         ChangeNotifierProvider<AbsenceProvider>(
             create: (context) => AbsenceProvider(context: context)),
 
+        // other providers
         ChangeNotifierProvider<GradeCalculatorProvider>(
             create: (_) => GradeCalculatorProvider(
                 settings: settings,
@@ -133,7 +136,9 @@ class App extends StatelessWidget {
                 kreta: kreta)),
         ChangeNotifierProvider<LiveCardProvider>(
             create: (context) =>
-                LiveCardProvider(timetable: timetable, settings: settings))
+                LiveCardProvider(timetable: timetable, settings: settings)),
+        ChangeNotifierProvider<GoalProvider>(
+            create: (context) => GoalProvider(database: database, user: user)),
       ],
       child: Consumer<ThemeModeObserver>(
         builder: (context, themeMode, child) {
diff --git a/filcnaplo_desktop_ui/lib/screens/navigation/navigation_screen.dart b/filcnaplo_desktop_ui/lib/screens/navigation/navigation_screen.dart
index 12a3ccd..58bd949 100644
--- a/filcnaplo_desktop_ui/lib/screens/navigation/navigation_screen.dart
+++ b/filcnaplo_desktop_ui/lib/screens/navigation/navigation_screen.dart
@@ -12,6 +12,7 @@ import 'package:flutter_acrylic/flutter_acrylic.dart';
 import 'package:provider/provider.dart';
 import 'package:filcnaplo/models/settings.dart';
 import 'package:filcnaplo_kreta_api/client/client.dart';
+import 'package:filcnaplo_premium/providers/goal_provider.dart';
 
 class NavigationScreen extends StatefulWidget {
   const NavigationScreen({Key? key}) : super(key: key);
@@ -29,6 +30,7 @@ class NavigationScreenState extends State<NavigationScreen>
   late NavigationRoute selected;
   late SettingsProvider settings;
   late NewsProvider newsProvider;
+  late GoalProvider goalProvider;
   double topInset = 0.0;
 
   @override
@@ -45,10 +47,14 @@ class NavigationScreenState extends State<NavigationScreen>
     Provider.of<KretaClient>(context, listen: false).userAgent =
         settings.config.userAgent;
 
-    // Get news
+    // get news
     newsProvider = Provider.of<NewsProvider>(context, listen: false);
     newsProvider.restore().then((value) => newsProvider.fetch());
 
+    // get goals
+    // goalProvider = Provider.of<GoalProvider>(context, listen: false);
+    // goalProvider.fetchDone();
+
     // Initial sync
     syncAll(context);
 
@@ -98,13 +104,17 @@ class NavigationScreenState extends State<NavigationScreen>
   Widget build(BuildContext context) {
     settings = Provider.of<SettingsProvider>(context);
     newsProvider = Provider.of<NewsProvider>(context);
+    goalProvider = Provider.of<GoalProvider>(context);
 
-    // Show news
+    // show news / complete goals
     WidgetsBinding.instance.addPostFrameCallback((_) {
       if (newsProvider.show) {
         newsProvider.lock();
         // NewsView.show(newsProvider.news[newsProvider.state], context: context).then((value) => newsProvider.release());
       }
+      if (goalProvider.hasDoneGoals) {
+        // to-do
+      }
     });
 
     return Scaffold(
diff --git a/filcnaplo_mobile_ui/lib/screens/navigation/navigation_screen.dart b/filcnaplo_mobile_ui/lib/screens/navigation/navigation_screen.dart
index b661047..4c2ca14 100755
--- a/filcnaplo_mobile_ui/lib/screens/navigation/navigation_screen.dart
+++ b/filcnaplo_mobile_ui/lib/screens/navigation/navigation_screen.dart
@@ -3,6 +3,7 @@ import 'package:filcnaplo/helpers/quick_actions.dart';
 import 'package:filcnaplo/models/settings.dart';
 import 'package:filcnaplo/theme/observer.dart';
 import 'package:filcnaplo_kreta_api/client/client.dart';
+import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
 import 'package:filcnaplo_mobile_ui/common/system_chrome.dart';
 import 'package:filcnaplo_mobile_ui/screens/navigation/nabar.dart';
 import 'package:filcnaplo_mobile_ui/screens/navigation/navbar_item.dart';
@@ -12,6 +13,7 @@ import 'package:filcnaplo/icons/filc_icons.dart';
 import 'package:filcnaplo_mobile_ui/screens/navigation/status_bar.dart';
 import 'package:filcnaplo_mobile_ui/screens/news/news_view.dart';
 import 'package:filcnaplo_mobile_ui/screens/settings/settings_screen.dart';
+import 'package:filcnaplo_premium/ui/mobile/goal_planner/goal_complete_modal.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
@@ -23,6 +25,7 @@ import 'package:filcnaplo/api/providers/sync.dart';
 import 'package:home_widget/home_widget.dart';
 import 'package:wtf_sliding_sheet/wtf_sliding_sheet.dart';
 import 'package:background_fetch/background_fetch.dart';
+import 'package:filcnaplo_premium/providers/goal_provider.dart';
 
 class NavigationScreen extends StatefulWidget {
   const NavigationScreen({Key? key}) : super(key: key);
@@ -42,7 +45,9 @@ class NavigationScreenState extends State<NavigationScreen>
 
   late SettingsProvider settings;
   late NewsProvider newsProvider;
+  late GoalProvider goalProvider;
   late UpdateProvider updateProvider;
+  late GradeProvider gradeProvicer;
 
   NavigatorState? get navigator => _navigatorState.currentState;
 
@@ -156,15 +161,22 @@ class NavigationScreenState extends State<NavigationScreen>
     Provider.of<KretaClient>(context, listen: false).userAgent =
         settings.config.userAgent;
 
-    // Get news
+    // get news
     newsProvider = Provider.of<NewsProvider>(context, listen: false);
     newsProvider.restore().then((value) => newsProvider.fetch());
 
-    // Get releases
+    // init grade provider (for goals)
+    gradeProvicer = Provider.of<GradeProvider>(context, listen: false);
+
+    // get goals
+    goalProvider = Provider.of<GoalProvider>(context, listen: false);
+    goalProvider.fetchDone(gradeProvider: gradeProvicer);
+
+    // get releases
     updateProvider = Provider.of<UpdateProvider>(context, listen: false);
     updateProvider.fetch();
 
-    // Initial sync
+    // initial sync
     syncAll(context);
     setupQuickActions();
   }
@@ -195,14 +207,20 @@ class NavigationScreenState extends State<NavigationScreen>
     setSystemChrome(context);
     settings = Provider.of<SettingsProvider>(context);
     newsProvider = Provider.of<NewsProvider>(context);
+    goalProvider = Provider.of<GoalProvider>(context);
 
-    // Show news
+    // show news and complete goals
     WidgetsBinding.instance.addPostFrameCallback((_) {
       if (newsProvider.show) {
         NewsView.show(newsProvider.news[0], context: context)
             .then((value) => newsProvider.release());
         newsProvider.lock();
       }
+
+      if (goalProvider.hasDoneGoals) {
+        GoalCompleteModal.show(goalProvider.doneSubject!, context: context);
+        goalProvider.lock();
+      }
     });
 
     handleQuickActions(context, (page) {
diff --git a/filcnaplo_premium/lib/providers/goal_provider.dart b/filcnaplo_premium/lib/providers/goal_provider.dart
index ce73a96..86b981d 100644
--- a/filcnaplo_premium/lib/providers/goal_provider.dart
+++ b/filcnaplo_premium/lib/providers/goal_provider.dart
@@ -7,27 +7,24 @@ import 'package:flutter/widgets.dart';
 class GoalProvider extends ChangeNotifier {
   final DatabaseProvider _db;
   final UserProvider _user;
-  final GradeProvider _gradeProvider;
 
   late bool _done = false;
-  late Subject _doneSubject;
+  late Subject? _doneSubject;
 
   bool get hasDoneGoals => _done;
-  Subject get doneSubject => _doneSubject;
+  Subject? get doneSubject => _doneSubject;
 
   GoalProvider({
     required DatabaseProvider database,
     required UserProvider user,
-    required GradeProvider gradeProvider,
   })  : _db = database,
-        _user = user,
-        _gradeProvider = gradeProvider;
+        _user = user;
 
-  Future<void> fetchDone() async {
+  Future<void> fetchDone({required GradeProvider gradeProvider}) async {
     var goalAvgs = await _db.userQuery.subjectGoalAverages(userId: _user.id!);
     var beforeAvgs = await _db.userQuery.subjectGoalAverages(userId: _user.id!);
 
-    List<Subject> subjects = _gradeProvider.grades
+    List<Subject> subjects = gradeProvider.grades
         .map((e) => e.subject)
         .toSet()
         .toList()
@@ -42,4 +39,30 @@ class GoalProvider extends ChangeNotifier {
       }
     });
   }
+
+  void lock() {
+    _done = false;
+    _doneSubject = null;
+  }
+
+  Future<void> clearGoal(Subject subject) async {
+    final goalPlans = await _db.userQuery.subjectGoalPlans(userId: _user.id!);
+    final goalAvgs = await _db.userQuery.subjectGoalAverages(userId: _user.id!);
+    final goalBeforeGrades =
+        await _db.userQuery.subjectGoalBefores(userId: _user.id!);
+    final goalPinDates =
+        await _db.userQuery.subjectGoalPinDates(userId: _user.id!);
+
+    goalPlans.remove(subject.id);
+    goalAvgs.remove(subject.id);
+    goalBeforeGrades.remove(subject.id);
+    goalPinDates.remove(subject.id);
+
+    await _db.userStore.storeSubjectGoalPlans(goalPlans, userId: _user.id!);
+    await _db.userStore.storeSubjectGoalAverages(goalAvgs, userId: _user.id!);
+    await _db.userStore
+        .storeSubjectGoalBefores(goalBeforeGrades, userId: _user.id!);
+    await _db.userStore
+        .storeSubjectGoalPinDates(goalPinDates, userId: _user.id!);
+  }
 }