From 540e4d28122adeffe42dca3adfeab7ce96770ff1 Mon Sep 17 00:00:00 2001 From: Kima Date: Mon, 13 May 2024 22:35:20 +0200 Subject: [PATCH] started grade streak --- refilc/lib/api/providers/user_provider.dart | 1 + refilc/lib/database/init.dart | 10 ++++- refilc/lib/models/user.dart | 4 ++ .../lib/providers/grade_provider.dart | 35 ++++++++++++++++-- .../notes/submenu/create_image_note.dart | 37 ++++++++++++++++++- .../notes/submenu/notes_screen.i18n.dart | 3 ++ 6 files changed, 84 insertions(+), 6 deletions(-) diff --git a/refilc/lib/api/providers/user_provider.dart b/refilc/lib/api/providers/user_provider.dart index a71028c..8d4bc89 100644 --- a/refilc/lib/api/providers/user_provider.dart +++ b/refilc/lib/api/providers/user_provider.dart @@ -23,6 +23,7 @@ class UserProvider with ChangeNotifier { String? get nickname => user?.nickname; String get picture => user?.picture ?? ""; String? get displayName => user?.displayName; + int? get gradeStreak => user?.gradeStreak; final SettingsProvider _settings; diff --git a/refilc/lib/database/init.dart b/refilc/lib/database/init.dart index 0d2822a..bb1b5dc 100644 --- a/refilc/lib/database/init.dart +++ b/refilc/lib/database/init.dart @@ -61,7 +61,8 @@ const settingsDB = DatabaseStruct("settings", { const usersDB = DatabaseStruct("users", { "id": String, "name": String, "username": String, "password": String, "institute_code": String, "student": String, "role": int, - "nickname": String, "picture": String // premium only + "nickname": String, "picture": String, // premium only (it's now plus btw) + "grade_streak": int, }); const userDataDB = DatabaseStruct("user_data", { "id": String, "grades": String, "timetable": String, "exams": String, @@ -129,7 +130,12 @@ Future initDB(DatabaseProvider database) async { await migrateDB( db, struct: usersDB, - defaultValues: {"role": 0, "nickname": "", "picture": ""}, + defaultValues: { + "role": 0, + "nickname": "", + "picture": "", + "grade_streak": 0 + }, ); await migrateDB(db, struct: userDataDB, defaultValues: { "grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]", diff --git a/refilc/lib/models/user.dart b/refilc/lib/models/user.dart index 7f22018..83d15d3 100644 --- a/refilc/lib/models/user.dart +++ b/refilc/lib/models/user.dart @@ -16,8 +16,10 @@ class User { Role role; String nickname; String picture; + int gradeStreak; String get displayName => nickname != '' ? nickname : name; + bool get hasStreak => gradeStreak > 0; User({ String? id, @@ -29,6 +31,7 @@ class User { required this.role, this.nickname = "", this.picture = "", + this.gradeStreak = 0, }) { if (id != null) { this.id = id; @@ -57,6 +60,7 @@ class User { role: Role.values[map["role"] ?? 0], nickname: map["nickname"] ?? "", picture: map["picture"] ?? "", + gradeStreak: map["grade_streak"] ?? 0, ); } diff --git a/refilc_kreta_api/lib/providers/grade_provider.dart b/refilc_kreta_api/lib/providers/grade_provider.dart index 3ab9701..f0e07ba 100644 --- a/refilc_kreta_api/lib/providers/grade_provider.dart +++ b/refilc_kreta_api/lib/providers/grade_provider.dart @@ -50,7 +50,8 @@ class GradeProvider with ChangeNotifier { String? userId = _user.id; if (userId != null) { final userStore = _database.userStore; - userStore.storeLastSeen(DateTime.now(), userId: userId, category: LastSeenCategory.surprisegrade); + userStore.storeLastSeen(DateTime.now(), + userId: userId, category: LastSeenCategory.surprisegrade); _lastSeen = DateTime.now(); } } @@ -59,7 +60,8 @@ class GradeProvider with ChangeNotifier { String? userId = _user.id; if (userId != null) { final userStore = _database.userStore; - userStore.storeLastSeen(DateTime(1969), userId: userId, category: LastSeenCategory.surprisegrade); + userStore.storeLastSeen(DateTime(1969), + userId: userId, category: LastSeenCategory.surprisegrade); _lastSeen = DateTime(1969); } } @@ -73,9 +75,11 @@ class GradeProvider with ChangeNotifier { _grades = await userQuery.getGrades(userId: userId); await convertBySettings(); + await getGradeStreak(); _groupAvg = await userQuery.getGroupAverages(userId: userId); notifyListeners(); - DateTime lastSeenDB = await userQuery.lastSeen(userId: userId, category: LastSeenCategory.surprisegrade); + DateTime lastSeenDB = await userQuery.lastSeen( + userId: userId, category: LastSeenCategory.surprisegrade); if (lastSeenDB.millisecondsSinceEpoch == 0 || lastSeenDB.year == 0 || !_settings.gradeOpeningFun) { @@ -133,6 +137,30 @@ class GradeProvider with ChangeNotifier { notifyListeners(); } + // get current grade streak and set it to the user + Future getGradeStreak() async { + User? user = _user.user; + if (user == null) throw "Cannot get Grade Streak for User null"; + + // streak magic + int gradeStreak = 0; + List grs = _grades; + grs.sort((a, b) => -a.date.compareTo(b.date)); + + for (Grade grade in grs) { + if (grade.value.value == 5) { + gradeStreak++; + } else { + break; + } + } + + print(gradeStreak); + + user.gradeStreak = gradeStreak; + notifyListeners(); + } + // Fetches Grades from the Kreta API then stores them in the database Future fetch() async { // test cucc @@ -173,6 +201,7 @@ class GradeProvider with ChangeNotifier { await _database.userStore.storeGrades(grades, userId: userId); _grades = grades; await convertBySettings(); + await getGradeStreak(); } Future storeGroupAvg(List groupAvgs) async { diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart b/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart index 7168ada..765338b 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/create_image_note.dart @@ -6,6 +6,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:image_crop/image_crop.dart'; import 'package:image_picker/image_picker.dart'; import 'package:provider/provider.dart'; @@ -27,6 +28,8 @@ class ImageNoteEditor extends StatefulWidget { } class _ImageNoteEditorState extends State { + final _title = TextEditingController(); + final cropKey = GlobalKey(); File? _file; File? _sample; @@ -135,7 +138,8 @@ class _ImageNoteEditorState extends State { selfNotes.add(SelfNote.fromJson({ 'id': const Uuid().v4(), 'content': base64Image, - 'note_type': 'image' + 'note_type': 'image', + 'title': _title.text, })); await Provider.of(context, listen: false) @@ -171,6 +175,37 @@ class _ImageNoteEditorState extends State { const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0), child: _sample == null ? openImageWidget() : cropImageWidget(), ), + Padding( + padding: + const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0), + child: TextField( + controller: _title, + onEditingComplete: () async {}, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: const BorderSide(color: Colors.grey, width: 1.5), + borderRadius: BorderRadius.circular(12.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide(color: Colors.grey, width: 1.5), + borderRadius: BorderRadius.circular(12.0), + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 12.0), + hintText: 'title'.i18n, + suffixIcon: IconButton( + icon: const Icon( + FeatherIcons.x, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _title.text = ''; + }); + }, + ), + ), + ), + ), // if (widget.u.picture != "") // TextButton( // child: Text( diff --git a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart index 77d6128..f8e3ed2 100644 --- a/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart +++ b/refilc_mobile_ui/lib/pages/notes/submenu/notes_screen.i18n.dart @@ -19,6 +19,7 @@ extension SettingsLocalization on String { "select_image": "to select an image", "new_image": "New Image", "image_note": "Image", + "title": "Image title...", }, "hu_hu": { "notes": "Füzet", @@ -36,6 +37,7 @@ extension SettingsLocalization on String { "select_image": "kép kiválasztásához", "new_image": "Új kép", "image_note": "Kép", + "title": "Kép címe...", }, "de_de": { "notes": "Broschüre", @@ -53,6 +55,7 @@ extension SettingsLocalization on String { "select_image": "um ein Bild auszuwählen", "new_image": "Neues Bild", "image_note": "Bild", + "title": "Bildtitel...", }, };