diff --git a/filcnaplo/lib/ui/widgets/lesson/lesson_tile.dart b/filcnaplo/lib/ui/widgets/lesson/lesson_tile.dart index 5fb368b..0e259c5 100644 --- a/filcnaplo/lib/ui/widgets/lesson/lesson_tile.dart +++ b/filcnaplo/lib/ui/widgets/lesson/lesson_tile.dart @@ -15,7 +15,8 @@ import 'package:provider/provider.dart'; import 'lesson_tile.i18n.dart'; class LessonTile extends StatelessWidget { - const LessonTile(this.lesson, {Key? key, this.onTap, this.swapDesc = false}) : super(key: key); + const LessonTile(this.lesson, {Key? key, this.onTap, this.swapDesc = false}) + : super(key: key); final Lesson lesson; final bool swapDesc; @@ -34,7 +35,9 @@ class LessonTile extends StatelessWidget { if (RegExp(r'\d').hasMatch(lesson.lessonIndex)) lessonIndexTrailing = "."; var now = DateTime.now(); - if (lesson.start.isBefore(now) && lesson.end.isAfter(now) && lesson.status?.name != "Elmaradt") { + if (lesson.start.isBefore(now) && + lesson.end.isAfter(now) && + lesson.status?.name != "Elmaradt") { fillLeading = true; } @@ -62,7 +65,8 @@ class LessonTile extends StatelessWidget { if (lesson.homeworkId != "") { Homework homework = Provider.of(context, listen: false) .homework - .firstWhere((h) => h.id == lesson.homeworkId, orElse: () => Homework.fromJson({})); + .firstWhere((h) => h.id == lesson.homeworkId, + orElse: () => Homework.fromJson({})); if (homework.id != "") { subtiles.add(LessonSubtile( @@ -74,11 +78,16 @@ class LessonTile extends StatelessWidget { } if (lesson.exam != "") { - Exam exam = Provider.of(context, listen: false).exams.firstWhere((t) => t.id == lesson.exam, orElse: () => Exam.fromJson({})); + Exam exam = Provider.of(context, listen: false) + .exams + .firstWhere((t) => t.id == lesson.exam, + orElse: () => Exam.fromJson({})); if (exam.id != "") { subtiles.add(LessonSubtile( type: LessonSubtileType.exam, - title: exam.description != "" ? exam.description : exam.mode?.description ?? "exam".i18n, + title: exam.description != "" + ? exam.description + : exam.mode?.description ?? "exam".i18n, onPressed: () => ExamView.show(exam, context: context), )); } @@ -87,7 +96,10 @@ class LessonTile extends StatelessWidget { String description = ''; String room = ''; - final cleanDesc = lesson.description.specialChars().toLowerCase().replaceAll(lesson.subject.name.specialChars().toLowerCase(), ''); + final cleanDesc = lesson.description + .specialChars() + .toLowerCase() + .replaceAll(lesson.subject.name.specialChars().toLowerCase(), ''); if (!swapDesc) { if (cleanDesc != "") { @@ -131,16 +143,23 @@ class LessonTile extends StatelessWidget { // onLongPress: kDebugMode ? () => log(jsonEncode(lesson.json)) : null, visualDensity: VisualDensity.compact, contentPadding: const EdgeInsets.symmetric(horizontal: 4.0), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12.0)), title: Text( - !lesson.isEmpty ? lesson.subject.renamedTo ?? lesson.subject.name.capital() : "empty".i18n, + !lesson.isEmpty + ? lesson.subject.renamedTo ?? + lesson.subject.name.capital() + : "empty".i18n, maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 15.5, - color: AppColors.of(context).text.withOpacity(!lesson.isEmpty ? 1.0 : 0.5), - fontStyle: lesson.subject.isRenamed ? FontStyle.italic : null), + color: AppColors.of(context) + .text + .withOpacity(!lesson.isEmpty ? 1.0 : 0.5), + fontStyle: + lesson.subject.isRenamed ? FontStyle.italic : null), ), subtitle: description != "" ? Text( @@ -175,12 +194,20 @@ class LessonTile extends StatelessWidget { offset: const Offset(-12.0, -2.0), child: Container( decoration: BoxDecoration( - color: fillLeading ? Theme.of(context).colorScheme.secondary.withOpacity(.3) : const Color(0x00000000), + color: fillLeading + ? Theme.of(context) + .colorScheme + .secondary + .withOpacity(.3) + : const Color(0x00000000), borderRadius: BorderRadius.circular(12.0), boxShadow: [ if (fillLeading) BoxShadow( - color: Theme.of(context).colorScheme.secondary.withOpacity(.25), + color: Theme.of(context) + .colorScheme + .secondary + .withOpacity(.25), blurRadius: 6.0, ) ], @@ -210,7 +237,9 @@ class LessonTile extends StatelessWidget { maxLines: 2, style: TextStyle( fontWeight: FontWeight.w500, - color: AppColors.of(context).text.withOpacity(.75), + color: AppColors.of(context) + .text + .withOpacity(.75), ), ), ), @@ -225,7 +254,9 @@ class LessonTile extends StatelessWidget { textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.w500, - color: AppColors.of(context).text.withOpacity(.9), + color: AppColors.of(context) + .text + .withOpacity(.9), ), ), ], @@ -249,7 +280,9 @@ class LessonTile extends StatelessWidget { enum LessonSubtileType { homework, exam, absence } class LessonSubtile extends StatelessWidget { - const LessonSubtile({Key? key, this.onPressed, required this.title, required this.type}) : super(key: key); + const LessonSubtile( + {Key? key, this.onPressed, required this.title, required this.type}) + : super(key: key); final Function()? onPressed; final String title; @@ -285,7 +318,8 @@ class LessonSubtile extends StatelessWidget { Center( child: SizedBox( width: 30.0, - child: Icon(icon, color: iconColor.withOpacity(.75), size: 20.0), + child: + Icon(icon, color: iconColor.withOpacity(.75), size: 20.0), ), ), Expanded( @@ -295,7 +329,9 @@ class LessonSubtile extends StatelessWidget { title.escapeHtml(), maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(fontWeight: FontWeight.w500, color: AppColors.of(context).text.withOpacity(.65)), + style: TextStyle( + fontWeight: FontWeight.w500, + color: AppColors.of(context).text.withOpacity(.65)), ), ), ), diff --git a/filcnaplo_kreta_api/lib/models/homework.dart b/filcnaplo_kreta_api/lib/models/homework.dart index 7645817..b233a3c 100644 --- a/filcnaplo_kreta_api/lib/models/homework.dart +++ b/filcnaplo_kreta_api/lib/models/homework.dart @@ -1,5 +1,7 @@ import 'package:filcnaplo_kreta_api/client/api.dart'; +import 'subject.dart'; + class Homework { Map? json; DateTime date; @@ -9,7 +11,7 @@ class Homework { bool homeworkEnabled; String teacher; String content; - String subjectName; + Subject subject; String group; List attachments; String id; @@ -22,7 +24,7 @@ class Homework { required this.homeworkEnabled, required this.teacher, required this.content, - required this.subjectName, + required this.subject, required this.group, required this.attachments, required this.id, @@ -32,16 +34,27 @@ class Homework { factory Homework.fromJson(Map json) { return Homework( id: json["Uid"] ?? "", - date: json["RogzitesIdopontja"] != null ? DateTime.parse(json["RogzitesIdopontja"]).toLocal() : DateTime(0), - lessonDate: json["FeladasDatuma"] != null ? DateTime.parse(json["FeladasDatuma"]).toLocal() : DateTime(0), - deadline: json["HataridoDatuma"] != null ? DateTime.parse(json["HataridoDatuma"]).toLocal() : DateTime(0), + date: json["RogzitesIdopontja"] != null + ? DateTime.parse(json["RogzitesIdopontja"]).toLocal() + : DateTime(0), + lessonDate: json["FeladasDatuma"] != null + ? DateTime.parse(json["FeladasDatuma"]).toLocal() + : DateTime(0), + deadline: json["HataridoDatuma"] != null + ? DateTime.parse(json["HataridoDatuma"]).toLocal() + : DateTime(0), byTeacher: json["IsTanarRogzitette"] ?? true, homeworkEnabled: json["IsTanuloHaziFeladatEnabled"] ?? false, teacher: (json["RogzitoTanarNeve"] ?? "").trim(), content: (json["Szoveg"] ?? "").trim(), - subjectName: json["TantargyNeve"] ?? "", - group: json["OsztalyCsoport"] != null ? json["OsztalyCsoport"]["Uid"] ?? "" : "", - attachments: ((json["Csatolmanyok"] ?? []) as List).cast().map((Map json) => HomeworkAttachment.fromJson(json)).toList(), + subject: Subject.fromJson(json["Tantargy"] ?? {}), + group: json["OsztalyCsoport"] != null + ? json["OsztalyCsoport"]["Uid"] ?? "" + : "", + attachments: ((json["Csatolmanyok"] ?? []) as List) + .cast() + .map((Map json) => HomeworkAttachment.fromJson(json)) + .toList(), json: json, ); } @@ -53,7 +66,8 @@ class HomeworkAttachment { String name; String type; - HomeworkAttachment({required this.id, this.name = "", this.type = "", this.json}); + HomeworkAttachment( + {required this.id, this.name = "", this.type = "", this.json}); factory HomeworkAttachment.fromJson(Map json) { return HomeworkAttachment( @@ -64,6 +78,8 @@ class HomeworkAttachment { ); } - String downloadUrl(String iss) => KretaAPI.downloadHomeworkAttachments(iss, id, type); - bool get isImage => name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png"); + String downloadUrl(String iss) => + KretaAPI.downloadHomeworkAttachments(iss, id, type); + bool get isImage => + name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png"); } diff --git a/filcnaplo_kreta_api/lib/providers/grade_provider.dart b/filcnaplo_kreta_api/lib/providers/grade_provider.dart index 2eb320c..a6fbd4c 100644 --- a/filcnaplo_kreta_api/lib/providers/grade_provider.dart +++ b/filcnaplo_kreta_api/lib/providers/grade_provider.dart @@ -22,7 +22,8 @@ class GradeProvider with ChangeNotifier { // Public List get grades => _grades; - DateTime get lastSeenDate => _settings.gradeOpeningFun ? _lastSeen : DateTime(3000); + DateTime get lastSeenDate => + _settings.gradeOpeningFun ? _lastSeen : DateTime(3000); String get groups => _groups; List get groupAverages => _groupAvg; @@ -66,7 +67,9 @@ class GradeProvider with ChangeNotifier { _groupAvg = await userQuery.getGroupAverages(userId: userId); notifyListeners(); DateTime lastSeenDB = await userQuery.lastSeenGrade(userId: userId); - if (lastSeenDB.millisecondsSinceEpoch == 0 || lastSeenDB.year == 0 || !_settings.gradeOpeningFun) { + if (lastSeenDB.millisecondsSinceEpoch == 0 || + lastSeenDB.year == 0 || + !_settings.gradeOpeningFun) { _lastSeen = DateTime.now(); await seenAll(); } else { @@ -78,13 +81,22 @@ class GradeProvider with ChangeNotifier { // good student mode, renamed subjects Future convertBySettings() async { - Map renamedSubjects = _settings.renamedSubjectsEnabled ? await _database.userQuery.renamedSubjects(userId: _user.user!.id) : {}; + Map renamedSubjects = _settings.renamedSubjectsEnabled + ? await _database.userQuery.renamedSubjects(userId: _user.user!.id) + : {}; for (Grade grade in _grades) { - // grade.subject.renamedTo = renamedSubjects.isNotEmpty ? renamedSubjects[grade.subject.id] : null; - grade.value.value = _settings.goodStudent ? 5 : grade.json!["SzamErtek"] ?? 0; - grade.value.valueName = _settings.goodStudent ? "Jeles".i18n : grade.json!["SzovegesErtek"] ?? ""; - grade.value.shortName = _settings.goodStudent ? "Jeles".i18n : grade.json!["SzovegesErtekelesRovidNev"] ?? ""; + grade.subject.renamedTo = + renamedSubjects.isNotEmpty ? renamedSubjects[grade.subject.id] : null; + + grade.value.value = + _settings.goodStudent ? 5 : grade.json!["SzamErtek"] ?? 0; + grade.value.valueName = _settings.goodStudent + ? "Jeles".i18n + : '${grade.json!["SzovegesErtek"]}'.i18n; + grade.value.shortName = _settings.goodStudent + ? "Jeles".i18n + : '${grade.json!["SzovegesErtekelesRovidNev"]}'.i18n; } notifyListeners(); @@ -103,12 +115,16 @@ class GradeProvider with ChangeNotifier { if (grades.isNotEmpty || _grades.isNotEmpty) await store(grades); List? groupsJson = await _kreta.getAPI(KretaAPI.groups(iss)); - if (groupsJson == null || groupsJson.isEmpty) throw "Cannot fetch Groups for User ${user.id}"; + if (groupsJson == null || groupsJson.isEmpty) + throw "Cannot fetch Groups for User ${user.id}"; _groups = (groupsJson[0]["OktatasNevelesiFeladat"] ?? {})["Uid"] ?? ""; - List? groupAvgJson = await _kreta.getAPI(KretaAPI.groupAverages(iss, _groups)); - if (groupAvgJson == null) throw "Cannot fetch Class Averages for User ${user.id}"; - final groupAvgs = groupAvgJson.map((e) => GroupAverage.fromJson(e)).toList(); + List? groupAvgJson = + await _kreta.getAPI(KretaAPI.groupAverages(iss, _groups)); + if (groupAvgJson == null) + throw "Cannot fetch Class Averages for User ${user.id}"; + final groupAvgs = + groupAvgJson.map((e) => GroupAverage.fromJson(e)).toList(); await storeGroupAvg(groupAvgs); } @@ -132,4 +148,4 @@ class GradeProvider with ChangeNotifier { await _database.userStore.storeGroupAverages(groupAvgs, userId: userId); notifyListeners(); } -} \ No newline at end of file +} diff --git a/filcnaplo_kreta_api/lib/providers/homework_provider.dart b/filcnaplo_kreta_api/lib/providers/homework_provider.dart index 8d10cb9..5fd9981 100644 --- a/filcnaplo_kreta_api/lib/providers/homework_provider.dart +++ b/filcnaplo_kreta_api/lib/providers/homework_provider.dart @@ -1,5 +1,6 @@ import 'package:filcnaplo/api/providers/user_provider.dart'; import 'package:filcnaplo/api/providers/database_provider.dart'; +import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/models/user.dart'; import 'package:filcnaplo_kreta_api/client/api.dart'; import 'package:filcnaplo_kreta_api/client/client.dart'; @@ -8,6 +9,12 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class HomeworkProvider with ChangeNotifier { + // Private + late final SettingsProvider _settings; + late final UserProvider _user; + late final DatabaseProvider _database; + + // Public late List _homework; late BuildContext _context; List get homework => _homework; @@ -27,7 +34,10 @@ class HomeworkProvider with ChangeNotifier { // Load homework from the database if (userId != null) { - var dbHomework = await Provider.of(_context, listen: false).userQuery.getHomework(userId: userId); + var dbHomework = + await Provider.of(_context, listen: false) + .userQuery + .getHomework(userId: userId); _homework = dbHomework; notifyListeners(); } @@ -39,15 +49,26 @@ class HomeworkProvider with ChangeNotifier { if (user == null) throw "Cannot fetch Homework for User null"; String iss = user.instituteCode; - List? homeworkJson = await Provider.of(_context, listen: false).getAPI(KretaAPI.homework(iss, start: from)); + List? homeworkJson = await Provider.of(_context, listen: false) + .getAPI(KretaAPI.homework(iss, start: from)); if (homeworkJson == null) throw "Cannot fetch Homework for User ${user.id}"; List homework = []; await Future.forEach(homeworkJson.cast(), (Map hw) async { - Map? e = await Provider.of(_context, listen: false).getAPI(KretaAPI.homework(iss, id: hw["Uid"])); - if (e != null) homework.add(Homework.fromJson(e)); + Map? e = await Provider.of(_context, listen: false) + .getAPI(KretaAPI.homework(iss, id: hw["Uid"])); + Map renamedSubjects = _settings.renamedSubjectsEnabled + ? await _database.userQuery.renamedSubjects(userId: _user.user!.id) + : {}; + + if (e != null) { + Homework hw = Homework.fromJson(e); + hw.subject.renamedTo = + renamedSubjects.isNotEmpty ? renamedSubjects[hw.subject.id] : null; + homework.add(hw); + } }); - + if (homework.isEmpty && _homework.isEmpty) return; if (db) await store(homework); @@ -60,6 +81,8 @@ class HomeworkProvider with ChangeNotifier { User? user = Provider.of(_context, listen: false).user; if (user == null) throw "Cannot store Homework for User null"; String userId = user.id; - await Provider.of(_context, listen: false).userStore.storeHomework(homework, userId: userId); + await Provider.of(_context, listen: false) + .userStore + .storeHomework(homework, userId: userId); } } diff --git a/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_tile.dart b/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_tile.dart index ef5ae89..057f14e 100755 --- a/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_tile.dart +++ b/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_tile.dart @@ -42,7 +42,7 @@ class HomeworkTile extends StatelessWidget { padding: const EdgeInsets.only(top: 2.0), child: Icon( SubjectIcon.resolveVariant( - subjectName: homework.subjectName, context: context), + subjectName: homework.subject.name, context: context), size: 28.0, color: AppColors.of(context).text.withOpacity(.75), ), @@ -62,7 +62,7 @@ class HomeworkTile extends StatelessWidget { ], ) : Text( - homework.subjectName.capital(), + homework.subject.renamedTo ?? homework.subject.name.capital(), maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle(fontWeight: FontWeight.w600), diff --git a/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_view.dart b/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_view.dart index 1aef7cb..3399ce8 100755 --- a/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_view.dart +++ b/filcnaplo_mobile_ui/lib/common/widgets/homework/homework_view.dart @@ -40,11 +40,12 @@ class HomeworkView extends StatelessWidget { // Header ListTile( leading: Icon( - SubjectIcon.resolveVariant(subjectName: homework.subjectName, context: context), + SubjectIcon.resolveVariant( + subjectName: homework.subject.name, context: context), size: 36.0, ), title: Text( - homework.subjectName.capital(), + homework.subject.renamedTo ?? homework.subject.name.capital(), maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle(fontWeight: FontWeight.w600), @@ -62,9 +63,13 @@ class HomeworkView extends StatelessWidget { ), // Details - if (homework.deadline.year != 0) Detail(title: "deadline".i18n, description: homework.deadline.format(context)), + if (homework.deadline.year != 0) + Detail( + title: "deadline".i18n, + description: homework.deadline.format(context)), Padding( - padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 6.0), + padding: + const EdgeInsets.symmetric(horizontal: 18.0, vertical: 6.0), child: SelectableLinkify( text: homework.content.escapeHtml(), options: const LinkifyOptions(looseUrl: true, removeWww: true),