From c0dd84c6652c2c6004da9ce15f5171885307f728 Mon Sep 17 00:00:00 2001 From: Kima Date: Sun, 16 Jun 2024 21:32:27 +0200 Subject: [PATCH] finished grade importing and exporting totally --- refilc_kreta_api/lib/models/grade.dart | 35 +++++ .../lib/pages/grades/grades_page.dart | 133 ++++++++++++++---- refilc_mobile_ui/pubspec.yaml | 1 + refilc_plus | 2 +- 4 files changed, 139 insertions(+), 32 deletions(-) diff --git a/refilc_kreta_api/lib/models/grade.dart b/refilc_kreta_api/lib/models/grade.dart index a7d595a..b12469d 100644 --- a/refilc_kreta_api/lib/models/grade.dart +++ b/refilc_kreta_api/lib/models/grade.dart @@ -1,6 +1,7 @@ // ignore_for_file: no_leading_underscores_for_local_identifiers import 'package:refilc/utils/format.dart'; +import 'package:uuid/uuid.dart'; import 'category.dart'; import 'subject.dart'; import 'teacher.dart'; @@ -75,6 +76,40 @@ class Grade { ); } + factory Grade.fromExportJson(Map json) { + return Grade( + id: const Uuid().v4(), + date: json["date"] != null ? DateTime.parse(json["date"]) : DateTime(0), + value: GradeValue( + json["value"] ?? 0, + json["value_name"] ?? "", + json["value_name"] ?? "", + json["weight"] ?? 0, + percentage: false, + ), + teacher: Teacher.fromString((json["teacher"] ?? "").trim()), + description: json["description"] ?? "", + type: json["type"] != null + ? Category.getGradeType(json["type"] + .replaceAll("midYear", "evkozi_jegy_ertekeles") + .replaceAll("halfYear", "felevi_jegy_ertekeles") + .replaceAll("endYear", "evvegi_jegy_ertekeles")) + : GradeType.unknown, + groupId: const Uuid().v4(), + subject: GradeSubject( + id: const Uuid().v4(), + category: Category.fromJson({}), + name: json["subject"] ?? ""), + mode: Category.fromJson({}), + writeDate: + json["date"] != null ? DateTime.parse(json["date"]) : DateTime(0), + seenDate: + json["date"] != null ? DateTime.parse(json["date"]) : DateTime(0), + form: "", + json: json, + ); + } + bool compareTo(dynamic other) { if (runtimeType != other.runtimeType) return false; diff --git a/refilc_mobile_ui/lib/pages/grades/grades_page.dart b/refilc_mobile_ui/lib/pages/grades/grades_page.dart index 4f33264..5992cc9 100644 --- a/refilc_mobile_ui/lib/pages/grades/grades_page.dart +++ b/refilc_mobile_ui/lib/pages/grades/grades_page.dart @@ -1,9 +1,12 @@ // ignore_for_file: no_leading_underscores_for_local_identifiers +import 'dart:convert'; +import 'dart:io'; import 'dart:math'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:collection/collection.dart'; +import 'package:file_picker/file_picker.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:refilc/api/providers/update_provider.dart'; import 'package:refilc/models/settings.dart'; @@ -89,19 +92,18 @@ class GradesPageState extends State { int avgDropValue = 0; bool gradeCalcMode = false; + bool importedViewMode = false; + + List jsonGrades = []; List getSubjectGrades(GradeSubject subject, {int days = 0}) => !gradeCalcMode - ? gradeProvider - .grades + ? (importedViewMode ? jsonGrades : gradeProvider.grades) .where((e) => - e - .subject == - subject && + e.subject == subject && e.type == GradeType.midYear && - (days == - 0 || + (days == 0 || e.date.isBefore( DateTime.now().subtract(Duration(days: days))))) .toList() @@ -110,18 +112,19 @@ class GradesPageState extends State { .toList(); void generateTiles() { - List subjects = gradeProvider.grades - .map((e) => GradeSubject( - category: e.subject.category, - id: e.subject.id, - name: e.subject.name, - renamedTo: e.subject.renamedTo, - customRounding: e.subject.customRounding, - teacher: e.teacher, - )) - .toSet() - .toList() - ..sort((a, b) => a.name.compareTo(b.name)); + List subjects = + (importedViewMode ? jsonGrades : gradeProvider.grades) + .map((e) => GradeSubject( + category: e.subject.category, + id: e.subject.id, + name: e.subject.name, + renamedTo: e.subject.renamedTo, + customRounding: e.subject.customRounding, + teacher: e.teacher, + )) + .toSet() + .toList() + ..sort((a, b) => a.name.compareTo(b.name)); List tiles = []; Map subjectAvgs = {}; @@ -165,7 +168,8 @@ class GradesPageState extends State { e.subject.id == subject.id && e.writeDate.isAfter(DateTime.now())); bool hasUnder = (hasHomework || nearestExam != null) && - Provider.of(context).qSubjectsSubTiles; + Provider.of(context, listen: false) + .qSubjectsSubTiles; return Padding( padding: i > 1 ? const EdgeInsets.only(top: 9.0) : EdgeInsets.zero, @@ -220,7 +224,8 @@ class GradesPageState extends State { height: 6.0, ), if (hasHomework && - Provider.of(context).qSubjectsSubTiles) + Provider.of(context, listen: false) + .qSubjectsSubTiles) Container( decoration: BoxDecoration( boxShadow: [ @@ -448,25 +453,28 @@ class GradesPageState extends State { .fold(0.0, (double a, double b) => a + b) / gradeProvider.groupAverages.length; - final now = gradeProvider.grades.isNotEmpty - ? gradeProvider.grades - .reduce((v, e) => e.date.isAfter(v.date) ? e : v) - .date - : DateTime.now(); + final now = + (importedViewMode ? jsonGrades : gradeProvider.grades).isNotEmpty + ? (importedViewMode ? jsonGrades : gradeProvider.grades) + .reduce((v, e) => e.date.isAfter(v.date) ? e : v) + .date + : DateTime.now(); final currentStudentAvg = AverageHelper.averageEvals(!gradeCalcMode - ? gradeProvider.grades + ? (importedViewMode ? jsonGrades : gradeProvider.grades) .where((e) => e.type == GradeType.midYear) .toList() : calculatorProvider.grades); - final prevStudentAvg = AverageHelper.averageEvals(gradeProvider.grades + final prevStudentAvg = AverageHelper.averageEvals((importedViewMode + ? jsonGrades + : gradeProvider.grades) .where((e) => e.type == GradeType.midYear) .where((e) => e.date.isBefore(now.subtract(const Duration(days: 30)))) .toList()); List graphGrades = !gradeCalcMode - ? gradeProvider.grades + ? (importedViewMode ? jsonGrades : gradeProvider.grades) .where((e) => e.type == GradeType.midYear && (avgDropValue == 0 || @@ -500,7 +508,7 @@ class GradesPageState extends State { // const SizedBox(width: 4.0), TrendDisplay( previous: prevStudentAvg, current: currentStudentAvg), - if (gradeProvider.grades + if ((importedViewMode ? jsonGrades : gradeProvider.grades) .where((e) => e.type == GradeType.midYear) .isNotEmpty) AverageDisplay(average: currentStudentAvg), @@ -632,7 +640,8 @@ class GradesPageState extends State { void gradeCalcTotal(BuildContext context) { calculatorProvider.clear(); - calculatorProvider.addAllGrades(gradeProvider.grades); + calculatorProvider + .addAllGrades((importedViewMode ? jsonGrades : gradeProvider.grades)); _sheetController = _scaffoldKey.currentState?.showBottomSheet( (context) => const RoundedBottomSheet( @@ -693,6 +702,68 @@ class GradesPageState extends State { const SizedBox( height: 10.0, ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: Theme.of(context).colorScheme.background), + child: ListTile( + title: Row( + children: [ + const Icon(Icons.toll_rounded), + const SizedBox( + width: 10.0, + ), + Text('import_grades'.i18n), + ], + ), + trailing: importedViewMode ? const Icon(FeatherIcons.x) : null, + onTap: () { + if (importedViewMode) { + importedViewMode = false; + + generateTiles(); + setState(() {}); + + Navigator.of(context, rootNavigator: true).pop(); + return; + } + + // if (!Provider.of(context, listen: false) + // .hasScope(PremiumScopes.gradeExporting)) { + // PlusLockedFeaturePopup.show( + // context: context, feature: PremiumFeature.gradeExporting); + // return; + // } + + // show file picker + FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['json'], + ).then((value) { + if (value != null) { + final File file = File(value.files.single.path!); + final String content = file.readAsStringSync(); + final List json = jsonDecode(content); + + jsonGrades = json.map((e) => Grade.fromJson(e)).toList(); + importedViewMode = true; + + generateTiles(); + setState(() {}); + + print(content); + print(json); + print(jsonGrades.map((e) => e.json)); + } + }); + + Navigator.of(context, rootNavigator: true).pop(); + }, + ), + ), + const SizedBox( + height: 10.0, + ), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), diff --git a/refilc_mobile_ui/pubspec.yaml b/refilc_mobile_ui/pubspec.yaml index 555383f..109ecc6 100644 --- a/refilc_mobile_ui/pubspec.yaml +++ b/refilc_mobile_ui/pubspec.yaml @@ -72,6 +72,7 @@ dependencies: carousel_slider: ^4.2.1 flutter_portal: ^1.1.4 webview_flutter: ^4.8.0 + file_picker: ^6.2.1 dev_dependencies: flutter_lints: ^3.0.1 diff --git a/refilc_plus b/refilc_plus index 9bd46b8..ac93b31 160000 --- a/refilc_plus +++ b/refilc_plus @@ -1 +1 @@ -Subproject commit 9bd46b81f230cd094787e1436cd5e8cdee7b5529 +Subproject commit ac93b31cbc8a3ce2a9e9e2036e2f2ae4ffbe51f3