fixed subject rename at homeworks

This commit is contained in:
Kima 2023-06-08 20:38:10 +02:00
parent 50e24bde17
commit 4e659308e5
6 changed files with 148 additions and 52 deletions

View File

@ -15,7 +15,8 @@ import 'package:provider/provider.dart';
import 'lesson_tile.i18n.dart'; import 'lesson_tile.i18n.dart';
class LessonTile extends StatelessWidget { 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 Lesson lesson;
final bool swapDesc; final bool swapDesc;
@ -34,7 +35,9 @@ class LessonTile extends StatelessWidget {
if (RegExp(r'\d').hasMatch(lesson.lessonIndex)) lessonIndexTrailing = "."; if (RegExp(r'\d').hasMatch(lesson.lessonIndex)) lessonIndexTrailing = ".";
var now = DateTime.now(); 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; fillLeading = true;
} }
@ -62,7 +65,8 @@ class LessonTile extends StatelessWidget {
if (lesson.homeworkId != "") { if (lesson.homeworkId != "") {
Homework homework = Provider.of<HomeworkProvider>(context, listen: false) Homework homework = Provider.of<HomeworkProvider>(context, listen: false)
.homework .homework
.firstWhere((h) => h.id == lesson.homeworkId, orElse: () => Homework.fromJson({})); .firstWhere((h) => h.id == lesson.homeworkId,
orElse: () => Homework.fromJson({}));
if (homework.id != "") { if (homework.id != "") {
subtiles.add(LessonSubtile( subtiles.add(LessonSubtile(
@ -74,11 +78,16 @@ class LessonTile extends StatelessWidget {
} }
if (lesson.exam != "") { if (lesson.exam != "") {
Exam exam = Provider.of<ExamProvider>(context, listen: false).exams.firstWhere((t) => t.id == lesson.exam, orElse: () => Exam.fromJson({})); Exam exam = Provider.of<ExamProvider>(context, listen: false)
.exams
.firstWhere((t) => t.id == lesson.exam,
orElse: () => Exam.fromJson({}));
if (exam.id != "") { if (exam.id != "") {
subtiles.add(LessonSubtile( subtiles.add(LessonSubtile(
type: LessonSubtileType.exam, 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), onPressed: () => ExamView.show(exam, context: context),
)); ));
} }
@ -87,7 +96,10 @@ class LessonTile extends StatelessWidget {
String description = ''; String description = '';
String room = ''; 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 (!swapDesc) {
if (cleanDesc != "") { if (cleanDesc != "") {
@ -131,16 +143,23 @@ class LessonTile extends StatelessWidget {
// onLongPress: kDebugMode ? () => log(jsonEncode(lesson.json)) : null, // onLongPress: kDebugMode ? () => log(jsonEncode(lesson.json)) : null,
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
contentPadding: const EdgeInsets.symmetric(horizontal: 4.0), contentPadding: const EdgeInsets.symmetric(horizontal: 4.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0)),
title: Text( 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, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 15.5, fontSize: 15.5,
color: AppColors.of(context).text.withOpacity(!lesson.isEmpty ? 1.0 : 0.5), color: AppColors.of(context)
fontStyle: lesson.subject.isRenamed ? FontStyle.italic : null), .text
.withOpacity(!lesson.isEmpty ? 1.0 : 0.5),
fontStyle:
lesson.subject.isRenamed ? FontStyle.italic : null),
), ),
subtitle: description != "" subtitle: description != ""
? Text( ? Text(
@ -175,12 +194,20 @@ class LessonTile extends StatelessWidget {
offset: const Offset(-12.0, -2.0), offset: const Offset(-12.0, -2.0),
child: Container( child: Container(
decoration: BoxDecoration( 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), borderRadius: BorderRadius.circular(12.0),
boxShadow: [ boxShadow: [
if (fillLeading) if (fillLeading)
BoxShadow( BoxShadow(
color: Theme.of(context).colorScheme.secondary.withOpacity(.25), color: Theme.of(context)
.colorScheme
.secondary
.withOpacity(.25),
blurRadius: 6.0, blurRadius: 6.0,
) )
], ],
@ -210,7 +237,9 @@ class LessonTile extends StatelessWidget {
maxLines: 2, maxLines: 2,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w500, 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, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w500, 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 } enum LessonSubtileType { homework, exam, absence }
class LessonSubtile extends StatelessWidget { 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 Function()? onPressed;
final String title; final String title;
@ -285,7 +318,8 @@ class LessonSubtile extends StatelessWidget {
Center( Center(
child: SizedBox( child: SizedBox(
width: 30.0, width: 30.0,
child: Icon(icon, color: iconColor.withOpacity(.75), size: 20.0), child:
Icon(icon, color: iconColor.withOpacity(.75), size: 20.0),
), ),
), ),
Expanded( Expanded(
@ -295,7 +329,9 @@ class LessonSubtile extends StatelessWidget {
title.escapeHtml(), title.escapeHtml(),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, 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)),
), ),
), ),
), ),

View File

@ -1,5 +1,7 @@
import 'package:filcnaplo_kreta_api/client/api.dart'; import 'package:filcnaplo_kreta_api/client/api.dart';
import 'subject.dart';
class Homework { class Homework {
Map? json; Map? json;
DateTime date; DateTime date;
@ -9,7 +11,7 @@ class Homework {
bool homeworkEnabled; bool homeworkEnabled;
String teacher; String teacher;
String content; String content;
String subjectName; Subject subject;
String group; String group;
List<HomeworkAttachment> attachments; List<HomeworkAttachment> attachments;
String id; String id;
@ -22,7 +24,7 @@ class Homework {
required this.homeworkEnabled, required this.homeworkEnabled,
required this.teacher, required this.teacher,
required this.content, required this.content,
required this.subjectName, required this.subject,
required this.group, required this.group,
required this.attachments, required this.attachments,
required this.id, required this.id,
@ -32,16 +34,27 @@ class Homework {
factory Homework.fromJson(Map json) { factory Homework.fromJson(Map json) {
return Homework( return Homework(
id: json["Uid"] ?? "", id: json["Uid"] ?? "",
date: json["RogzitesIdopontja"] != null ? DateTime.parse(json["RogzitesIdopontja"]).toLocal() : DateTime(0), date: json["RogzitesIdopontja"] != null
lessonDate: json["FeladasDatuma"] != null ? DateTime.parse(json["FeladasDatuma"]).toLocal() : DateTime(0), ? DateTime.parse(json["RogzitesIdopontja"]).toLocal()
deadline: json["HataridoDatuma"] != null ? DateTime.parse(json["HataridoDatuma"]).toLocal() : DateTime(0), : 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, byTeacher: json["IsTanarRogzitette"] ?? true,
homeworkEnabled: json["IsTanuloHaziFeladatEnabled"] ?? false, homeworkEnabled: json["IsTanuloHaziFeladatEnabled"] ?? false,
teacher: (json["RogzitoTanarNeve"] ?? "").trim(), teacher: (json["RogzitoTanarNeve"] ?? "").trim(),
content: (json["Szoveg"] ?? "").trim(), content: (json["Szoveg"] ?? "").trim(),
subjectName: json["TantargyNeve"] ?? "", subject: Subject.fromJson(json["Tantargy"] ?? {}),
group: json["OsztalyCsoport"] != null ? json["OsztalyCsoport"]["Uid"] ?? "" : "", group: json["OsztalyCsoport"] != null
attachments: ((json["Csatolmanyok"] ?? []) as List).cast<Map>().map((Map json) => HomeworkAttachment.fromJson(json)).toList(), ? json["OsztalyCsoport"]["Uid"] ?? ""
: "",
attachments: ((json["Csatolmanyok"] ?? []) as List)
.cast<Map>()
.map((Map json) => HomeworkAttachment.fromJson(json))
.toList(),
json: json, json: json,
); );
} }
@ -53,7 +66,8 @@ class HomeworkAttachment {
String name; String name;
String type; 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) { factory HomeworkAttachment.fromJson(Map json) {
return HomeworkAttachment( return HomeworkAttachment(
@ -64,6 +78,8 @@ class HomeworkAttachment {
); );
} }
String downloadUrl(String iss) => KretaAPI.downloadHomeworkAttachments(iss, id, type); String downloadUrl(String iss) =>
bool get isImage => name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png"); KretaAPI.downloadHomeworkAttachments(iss, id, type);
bool get isImage =>
name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png");
} }

View File

@ -22,7 +22,8 @@ class GradeProvider with ChangeNotifier {
// Public // Public
List<Grade> get grades => _grades; List<Grade> get grades => _grades;
DateTime get lastSeenDate => _settings.gradeOpeningFun ? _lastSeen : DateTime(3000); DateTime get lastSeenDate =>
_settings.gradeOpeningFun ? _lastSeen : DateTime(3000);
String get groups => _groups; String get groups => _groups;
List<GroupAverage> get groupAverages => _groupAvg; List<GroupAverage> get groupAverages => _groupAvg;
@ -66,7 +67,9 @@ class GradeProvider with ChangeNotifier {
_groupAvg = await userQuery.getGroupAverages(userId: userId); _groupAvg = await userQuery.getGroupAverages(userId: userId);
notifyListeners(); notifyListeners();
DateTime lastSeenDB = await userQuery.lastSeenGrade(userId: userId); 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(); _lastSeen = DateTime.now();
await seenAll(); await seenAll();
} else { } else {
@ -78,13 +81,22 @@ class GradeProvider with ChangeNotifier {
// good student mode, renamed subjects // good student mode, renamed subjects
Future<void> convertBySettings() async { Future<void> convertBySettings() async {
Map<String, String> renamedSubjects = _settings.renamedSubjectsEnabled ? await _database.userQuery.renamedSubjects(userId: _user.user!.id) : {}; Map<String, String> renamedSubjects = _settings.renamedSubjectsEnabled
? await _database.userQuery.renamedSubjects(userId: _user.user!.id)
: {};
for (Grade grade in _grades) { for (Grade grade in _grades) {
// grade.subject.renamedTo = renamedSubjects.isNotEmpty ? renamedSubjects[grade.subject.id] : null; grade.subject.renamedTo =
grade.value.value = _settings.goodStudent ? 5 : grade.json!["SzamErtek"] ?? 0; renamedSubjects.isNotEmpty ? renamedSubjects[grade.subject.id] : null;
grade.value.valueName = _settings.goodStudent ? "Jeles".i18n : grade.json!["SzovegesErtek"] ?? "";
grade.value.shortName = _settings.goodStudent ? "Jeles".i18n : grade.json!["SzovegesErtekelesRovidNev"] ?? ""; 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(); notifyListeners();
@ -103,12 +115,16 @@ class GradeProvider with ChangeNotifier {
if (grades.isNotEmpty || _grades.isNotEmpty) await store(grades); if (grades.isNotEmpty || _grades.isNotEmpty) await store(grades);
List? groupsJson = await _kreta.getAPI(KretaAPI.groups(iss)); 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"] ?? ""; _groups = (groupsJson[0]["OktatasNevelesiFeladat"] ?? {})["Uid"] ?? "";
List? groupAvgJson = await _kreta.getAPI(KretaAPI.groupAverages(iss, _groups)); List? groupAvgJson =
if (groupAvgJson == null) throw "Cannot fetch Class Averages for User ${user.id}"; await _kreta.getAPI(KretaAPI.groupAverages(iss, _groups));
final groupAvgs = groupAvgJson.map((e) => GroupAverage.fromJson(e)).toList(); if (groupAvgJson == null)
throw "Cannot fetch Class Averages for User ${user.id}";
final groupAvgs =
groupAvgJson.map((e) => GroupAverage.fromJson(e)).toList();
await storeGroupAvg(groupAvgs); await storeGroupAvg(groupAvgs);
} }

View File

@ -1,5 +1,6 @@
import 'package:filcnaplo/api/providers/user_provider.dart'; import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo/api/providers/database_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/models/user.dart';
import 'package:filcnaplo_kreta_api/client/api.dart'; import 'package:filcnaplo_kreta_api/client/api.dart';
import 'package:filcnaplo_kreta_api/client/client.dart'; import 'package:filcnaplo_kreta_api/client/client.dart';
@ -8,6 +9,12 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class HomeworkProvider with ChangeNotifier { class HomeworkProvider with ChangeNotifier {
// Private
late final SettingsProvider _settings;
late final UserProvider _user;
late final DatabaseProvider _database;
// Public
late List<Homework> _homework; late List<Homework> _homework;
late BuildContext _context; late BuildContext _context;
List<Homework> get homework => _homework; List<Homework> get homework => _homework;
@ -27,7 +34,10 @@ class HomeworkProvider with ChangeNotifier {
// Load homework from the database // Load homework from the database
if (userId != null) { if (userId != null) {
var dbHomework = await Provider.of<DatabaseProvider>(_context, listen: false).userQuery.getHomework(userId: userId); var dbHomework =
await Provider.of<DatabaseProvider>(_context, listen: false)
.userQuery
.getHomework(userId: userId);
_homework = dbHomework; _homework = dbHomework;
notifyListeners(); notifyListeners();
} }
@ -39,13 +49,24 @@ class HomeworkProvider with ChangeNotifier {
if (user == null) throw "Cannot fetch Homework for User null"; if (user == null) throw "Cannot fetch Homework for User null";
String iss = user.instituteCode; String iss = user.instituteCode;
List? homeworkJson = await Provider.of<KretaClient>(_context, listen: false).getAPI(KretaAPI.homework(iss, start: from)); List? homeworkJson = await Provider.of<KretaClient>(_context, listen: false)
.getAPI(KretaAPI.homework(iss, start: from));
if (homeworkJson == null) throw "Cannot fetch Homework for User ${user.id}"; if (homeworkJson == null) throw "Cannot fetch Homework for User ${user.id}";
List<Homework> homework = []; List<Homework> homework = [];
await Future.forEach(homeworkJson.cast<Map>(), (Map hw) async { await Future.forEach(homeworkJson.cast<Map>(), (Map hw) async {
Map? e = await Provider.of<KretaClient>(_context, listen: false).getAPI(KretaAPI.homework(iss, id: hw["Uid"])); Map? e = await Provider.of<KretaClient>(_context, listen: false)
if (e != null) homework.add(Homework.fromJson(e)); .getAPI(KretaAPI.homework(iss, id: hw["Uid"]));
Map<String, String> 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 (homework.isEmpty && _homework.isEmpty) return;
@ -60,6 +81,8 @@ class HomeworkProvider with ChangeNotifier {
User? user = Provider.of<UserProvider>(_context, listen: false).user; User? user = Provider.of<UserProvider>(_context, listen: false).user;
if (user == null) throw "Cannot store Homework for User null"; if (user == null) throw "Cannot store Homework for User null";
String userId = user.id; String userId = user.id;
await Provider.of<DatabaseProvider>(_context, listen: false).userStore.storeHomework(homework, userId: userId); await Provider.of<DatabaseProvider>(_context, listen: false)
.userStore
.storeHomework(homework, userId: userId);
} }
} }

View File

@ -42,7 +42,7 @@ class HomeworkTile extends StatelessWidget {
padding: const EdgeInsets.only(top: 2.0), padding: const EdgeInsets.only(top: 2.0),
child: Icon( child: Icon(
SubjectIcon.resolveVariant( SubjectIcon.resolveVariant(
subjectName: homework.subjectName, context: context), subjectName: homework.subject.name, context: context),
size: 28.0, size: 28.0,
color: AppColors.of(context).text.withOpacity(.75), color: AppColors.of(context).text.withOpacity(.75),
), ),
@ -62,7 +62,7 @@ class HomeworkTile extends StatelessWidget {
], ],
) )
: Text( : Text(
homework.subjectName.capital(), homework.subject.renamedTo ?? homework.subject.name.capital(),
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w600), style: const TextStyle(fontWeight: FontWeight.w600),

View File

@ -40,11 +40,12 @@ class HomeworkView extends StatelessWidget {
// Header // Header
ListTile( ListTile(
leading: Icon( leading: Icon(
SubjectIcon.resolveVariant(subjectName: homework.subjectName, context: context), SubjectIcon.resolveVariant(
subjectName: homework.subject.name, context: context),
size: 36.0, size: 36.0,
), ),
title: Text( title: Text(
homework.subjectName.capital(), homework.subject.renamedTo ?? homework.subject.name.capital(),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w600), style: const TextStyle(fontWeight: FontWeight.w600),
@ -62,9 +63,13 @@ class HomeworkView extends StatelessWidget {
), ),
// Details // 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(
padding: const EdgeInsets.symmetric(horizontal: 18.0, vertical: 6.0), padding:
const EdgeInsets.symmetric(horizontal: 18.0, vertical: 6.0),
child: SelectableLinkify( child: SelectableLinkify(
text: homework.content.escapeHtml(), text: homework.content.escapeHtml(),
options: const LinkifyOptions(looseUrl: true, removeWww: true), options: const LinkifyOptions(looseUrl: true, removeWww: true),