maybe finished teacher rename

This commit is contained in:
Kima 2023-08-26 15:15:56 +02:00
parent e64ab75753
commit ded029e4cb
15 changed files with 246 additions and 92 deletions

View File

@ -1,6 +1,4 @@
import 'package:filcnaplo/api/providers/update_provider.dart'; import 'package:filcnaplo/api/providers/update_provider.dart';
import 'package:filcnaplo/theme/colors/accent.dart';
import 'package:filcnaplo/theme/observer.dart';
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart'; import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
import 'package:filcnaplo_kreta_api/providers/event_provider.dart'; import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
import 'package:filcnaplo_kreta_api/providers/exam_provider.dart'; import 'package:filcnaplo_kreta_api/providers/exam_provider.dart';

View File

@ -1,4 +1,5 @@
import 'category.dart'; import 'category.dart';
import 'teacher.dart';
class Exam { class Exam {
Map? json; Map? json;
@ -7,7 +8,7 @@ class Exam {
Category? mode; Category? mode;
int? subjectIndex; int? subjectIndex;
String subjectName; String subjectName;
String teacher; Teacher teacher;
String description; String description;
String group; String group;
String id; String id;
@ -28,14 +29,20 @@ class Exam {
factory Exam.fromJson(Map json) { factory Exam.fromJson(Map json) {
return Exam( return Exam(
id: json["Uid"] ?? "", id: json["Uid"] ?? "",
date: json["BejelentesDatuma"] != null ? DateTime.parse(json["BejelentesDatuma"]).toLocal() : DateTime(0), date: json["BejelentesDatuma"] != null
writeDate: json["Datum"] != null ? DateTime.parse(json["Datum"]).toLocal() : DateTime(0), ? DateTime.parse(json["BejelentesDatuma"]).toLocal()
: DateTime(0),
writeDate: json["Datum"] != null
? DateTime.parse(json["Datum"]).toLocal()
: DateTime(0),
mode: json["Modja"] != null ? Category.fromJson(json["Modja"]) : null, mode: json["Modja"] != null ? Category.fromJson(json["Modja"]) : null,
subjectIndex: json["OrarendiOraOraszama"], subjectIndex: json["OrarendiOraOraszama"],
subjectName: json["TantargyNeve"] ?? "", subjectName: json["TantargyNeve"] ?? "",
teacher: (json["RogzitoTanarNeve"] ?? "").trim(), teacher: Teacher.fromString((json["RogzitoTanarNeve"] ?? "").trim()),
description: (json["Temaja"] ?? "").trim(), description: (json["Temaja"] ?? "").trim(),
group: json["OsztalyCsoport"] != null ? json["OsztalyCsoport"]["Uid"] ?? "" : "", group: json["OsztalyCsoport"] != null
? json["OsztalyCsoport"]["Uid"] ?? ""
: "",
json: json, json: json,
); );
} }

View File

@ -1,13 +1,14 @@
import 'package:filcnaplo/utils/format.dart'; import 'package:filcnaplo/utils/format.dart';
import 'category.dart'; import 'category.dart';
import 'subject.dart'; import 'subject.dart';
import 'teacher.dart';
class Grade { class Grade {
Map? json; Map? json;
String id; String id;
DateTime date; DateTime date;
GradeValue value; GradeValue value;
String teacher; Teacher teacher;
String description; String description;
GradeType type; GradeType type;
String groupId; String groupId;
@ -38,23 +39,35 @@ class Grade {
factory Grade.fromJson(Map json) { factory Grade.fromJson(Map json) {
return Grade( return Grade(
id: json["Uid"] ?? "", id: json["Uid"] ?? "",
date: json["KeszitesDatuma"] != null ? DateTime.parse(json["KeszitesDatuma"]).toLocal() : DateTime(0), date: json["KeszitesDatuma"] != null
? DateTime.parse(json["KeszitesDatuma"]).toLocal()
: DateTime(0),
value: GradeValue( value: GradeValue(
json["SzamErtek"] ?? 0, json["SzamErtek"] ?? 0,
json["SzovegesErtek"] ?? "", json["SzovegesErtek"] ?? "",
json["SzovegesErtekelesRovidNev"] ?? "", json["SzovegesErtekelesRovidNev"] ?? "",
json["SulySzazalekErteke"] ?? 0, json["SulySzazalekErteke"] ?? 0,
percentage: json["ErtekFajta"] != null ? json["ErtekFajta"]["Uid"] == "3,Szazalekos" : false, percentage: json["ErtekFajta"] != null
? json["ErtekFajta"]["Uid"] == "3,Szazalekos"
: false,
), ),
teacher: (json["ErtekeloTanarNeve"] ?? "").trim(), teacher: Teacher.fromString((json["ErtekeloTanarNeve"] ?? "").trim()),
description: json["Tema"] ?? "", description: json["Tema"] ?? "",
type: json["Tipus"] != null ? Category.getGradeType(json["Tipus"]["Nev"]) : GradeType.unknown, type: json["Tipus"] != null
? Category.getGradeType(json["Tipus"]["Nev"])
: GradeType.unknown,
groupId: (json["OsztalyCsoport"] ?? {})["Uid"] ?? "", groupId: (json["OsztalyCsoport"] ?? {})["Uid"] ?? "",
subject: Subject.fromJson(json["Tantargy"] ?? {}), subject: Subject.fromJson(json["Tantargy"] ?? {}),
gradeType: json["ErtekFajta"] != null ? Category.fromJson(json["ErtekFajta"]) : null, gradeType: json["ErtekFajta"] != null
? Category.fromJson(json["ErtekFajta"])
: null,
mode: Category.fromJson(json["Mod"] ?? {}), mode: Category.fromJson(json["Mod"] ?? {}),
writeDate: json["RogzitesDatuma"] != null ? DateTime.parse(json["RogzitesDatuma"]).toLocal() : DateTime(0), writeDate: json["RogzitesDatuma"] != null
seenDate: json["LattamozasDatuma"] != null ? DateTime.parse(json["LattamozasDatuma"]).toLocal() : DateTime(0), ? DateTime.parse(json["RogzitesDatuma"]).toLocal()
: DateTime(0),
seenDate: json["LattamozasDatuma"] != null
? DateTime.parse(json["LattamozasDatuma"]).toLocal()
: DateTime(0),
form: (json["Jelleg"] ?? "Na") != "Na" ? json["Jelleg"] : "", form: (json["Jelleg"] ?? "Na") != "Na" ? json["Jelleg"] : "",
json: json, json: json,
); );
@ -76,7 +89,8 @@ class GradeValue {
set value(int v) => _value = v; set value(int v) => _value = v;
int get value { int get value {
String _valueName = valueName.toLowerCase().specialChars(); String _valueName = valueName.toLowerCase().specialChars();
if (_value == 0 && ["peldas", "jo", "valtozo", "rossz", "hanyag"].contains(_valueName)) { if (_value == 0 &&
["peldas", "jo", "valtozo", "rossz", "hanyag"].contains(_valueName)) {
switch (_valueName) { switch (_valueName) {
case "peldas": case "peldas":
return 5; return 5;
@ -101,7 +115,8 @@ class GradeValue {
set weight(int v) => _weight = v; set weight(int v) => _weight = v;
int get weight { int get weight {
String _valueName = valueName.toLowerCase().specialChars(); String _valueName = valueName.toLowerCase().specialChars();
if (_value == 0 && ["peldas", "jo", "valtozo", "rossz", "hanyag"].contains(_valueName)) { if (_value == 0 &&
["peldas", "jo", "valtozo", "rossz", "hanyag"].contains(_valueName)) {
return 0; return 0;
} }
return _weight; return _weight;
@ -110,11 +125,23 @@ class GradeValue {
final bool _percentage; final bool _percentage;
bool get percentage => _percentage; bool get percentage => _percentage;
GradeValue(int value, String valueName, this.shortName, int weight, {bool percentage = false}) GradeValue(int value, String valueName, this.shortName, int weight,
{bool percentage = false})
: _value = value, : _value = value,
_valueName = valueName, _valueName = valueName,
_weight = weight, _weight = weight,
_percentage = percentage; _percentage = percentage;
} }
enum GradeType { midYear, firstQ, secondQ, halfYear, thirdQ, fourthQ, endYear, levelExam, ghost, unknown } enum GradeType {
midYear,
firstQ,
secondQ,
halfYear,
thirdQ,
fourthQ,
endYear,
levelExam,
ghost,
unknown
}

View File

@ -1,6 +1,7 @@
import 'package:filcnaplo_kreta_api/client/api.dart'; import 'package:filcnaplo_kreta_api/client/api.dart';
import 'subject.dart'; import 'subject.dart';
import 'teacher.dart';
class Homework { class Homework {
Map? json; Map? json;
@ -9,7 +10,7 @@ class Homework {
DateTime deadline; DateTime deadline;
bool byTeacher; bool byTeacher;
bool homeworkEnabled; bool homeworkEnabled;
String teacher; Teacher teacher;
String content; String content;
Subject subject; Subject subject;
String group; String group;
@ -45,7 +46,7 @@ class Homework {
: DateTime(0), : DateTime(0),
byTeacher: json["IsTanarRogzitette"] ?? true, byTeacher: json["IsTanarRogzitette"] ?? true,
homeworkEnabled: json["IsTanuloHaziFeladatEnabled"] ?? false, homeworkEnabled: json["IsTanuloHaziFeladatEnabled"] ?? false,
teacher: (json["RogzitoTanarNeve"] ?? "").trim(), teacher: Teacher.fromString((json["RogzitoTanarNeve"] ?? "").trim()),
content: (json["Szoveg"] ?? "").trim(), content: (json["Szoveg"] ?? "").trim(),
subject: Subject.fromJson(json["Tantargy"] ?? {}), subject: Subject.fromJson(json["Tantargy"] ?? {}),
group: json["OsztalyCsoport"] != null group: json["OsztalyCsoport"] != null

View File

@ -1,5 +1,6 @@
import 'subject.dart'; import 'subject.dart';
import 'category.dart'; import 'category.dart';
import 'teacher.dart';
class Lesson { class Lesson {
Map? json; Map? json;
@ -8,8 +9,8 @@ class Lesson {
Subject subject; Subject subject;
String lessonIndex; String lessonIndex;
int? lessonYearIndex; int? lessonYearIndex;
String substituteTeacher; Teacher? substituteTeacher;
String teacher; Teacher teacher;
bool homeworkEnabled; bool homeworkEnabled;
DateTime start; DateTime start;
DateTime end; DateTime end;
@ -31,7 +32,7 @@ class Lesson {
required this.subject, required this.subject,
required this.lessonIndex, required this.lessonIndex,
this.lessonYearIndex, this.lessonYearIndex,
this.substituteTeacher = "", this.substituteTeacher,
required this.teacher, required this.teacher,
this.homeworkEnabled = false, this.homeworkEnabled = false,
required this.start, required this.start,
@ -53,27 +54,38 @@ class Lesson {
factory Lesson.fromJson(Map json) { factory Lesson.fromJson(Map json) {
return Lesson( return Lesson(
id: json["Uid"] ?? "", id: json["Uid"] ?? "",
status: json["Allapot"] != null ? Category.fromJson(json["Allapot"]) : null, status:
date: json["Datum"] != null ? DateTime.parse(json["Datum"]).toLocal() : DateTime(0), json["Allapot"] != null ? Category.fromJson(json["Allapot"]) : null,
date: json["Datum"] != null
? DateTime.parse(json["Datum"]).toLocal()
: DateTime(0),
subject: Subject.fromJson(json["Tantargy"] ?? {}), subject: Subject.fromJson(json["Tantargy"] ?? {}),
lessonIndex: json["Oraszam"] != null ? json["Oraszam"].toString() : "+", lessonIndex: json["Oraszam"] != null ? json["Oraszam"].toString() : "+",
lessonYearIndex: json["OraEvesSorszama"], lessonYearIndex: json["OraEvesSorszama"],
substituteTeacher: (json["HelyettesTanarNeve"] ?? "").trim(), substituteTeacher:
teacher: (json["TanarNeve"] ?? "").trim(), Teacher.fromString((json["HelyettesTanarNeve"] ?? "").trim()),
teacher: Teacher.fromString((json["TanarNeve"] ?? "").trim()),
homeworkEnabled: json["IsTanuloHaziFeladatEnabled"] ?? false, homeworkEnabled: json["IsTanuloHaziFeladatEnabled"] ?? false,
start: json["KezdetIdopont"] != null ? DateTime.parse(json["KezdetIdopont"]).toLocal() : DateTime(0), start: json["KezdetIdopont"] != null
? DateTime.parse(json["KezdetIdopont"]).toLocal()
: DateTime(0),
studentPresence: json["TanuloJelenlet"] != null studentPresence: json["TanuloJelenlet"] != null
? (json["TanuloJelenlet"]["Nev"] ?? "") == "Hianyzas" ? (json["TanuloJelenlet"]["Nev"] ?? "") == "Hianyzas"
? false ? false
: true : true
: true, : true,
end: json["VegIdopont"] != null ? DateTime.parse(json["VegIdopont"]).toLocal() : DateTime(0), end: json["VegIdopont"] != null
? DateTime.parse(json["VegIdopont"]).toLocal()
: DateTime(0),
homeworkId: json["HaziFeladatUid"] ?? "", homeworkId: json["HaziFeladatUid"] ?? "",
exam: json["BejelentettSzamonkeresUid"] ?? "", exam: json["BejelentettSzamonkeresUid"] ?? "",
type: json["Tipus"] != null ? Category.fromJson(json["Tipus"]) : null, type: json["Tipus"] != null ? Category.fromJson(json["Tipus"]) : null,
description: json["Tema"] ?? "", description: json["Tema"] ?? "",
room: ((json["TeremNeve"] ?? "").split("_").join(" ") as String).replaceAll(RegExp(r" ?terem ?", caseSensitive: false), ""), room: ((json["TeremNeve"] ?? "").split("_").join(" ") as String)
groupName: json["OsztalyCsoport"] != null ? json["OsztalyCsoport"]["Nev"] ?? "" : "", .replaceAll(RegExp(r" ?terem ?", caseSensitive: false), ""),
groupName: json["OsztalyCsoport"] != null
? json["OsztalyCsoport"]["Nev"] ?? ""
: "",
name: json["Nev"] ?? "", name: json["Nev"] ?? "",
online: json["IsDigitalisOra"] ?? false, online: json["IsDigitalisOra"] ?? false,
isEmpty: json['isEmpty'] ?? false, isEmpty: json['isEmpty'] ?? false,
@ -92,6 +104,6 @@ class Lesson {
return null; return null;
} }
bool get isChanged => status?.name == "Elmaradt" || substituteTeacher != ""; bool get isChanged => status?.name == "Elmaradt" || substituteTeacher != null;
bool get swapDesc => room.length > 8; bool get swapDesc => room.length > 8;
} }

View File

@ -1,4 +1,5 @@
import 'category.dart'; import 'category.dart';
import 'teacher.dart';
class Note { class Note {
Map? json; Map? json;
@ -6,7 +7,7 @@ class Note {
String title; String title;
DateTime date; DateTime date;
DateTime submitDate; DateTime submitDate;
String teacher; Teacher teacher;
DateTime seenDate; DateTime seenDate;
String groupId; String groupId;
String content; String content;
@ -29,11 +30,19 @@ class Note {
return Note( return Note(
id: json["Uid"] ?? "", id: json["Uid"] ?? "",
title: json["Cim"] ?? "", title: json["Cim"] ?? "",
date: json["Datum"] != null ? DateTime.parse(json["Datum"]).toLocal() : DateTime(0), date: json["Datum"] != null
submitDate: json["KeszitesDatuma"] != null ? DateTime.parse(json["KeszitesDatuma"]).toLocal() : DateTime(0), ? DateTime.parse(json["Datum"]).toLocal()
teacher: (json["KeszitoTanarNeve"] ?? "").trim(), : DateTime(0),
seenDate: json["LattamozasDatuma"] != null ? DateTime.parse(json["LattamozasDatuma"]).toLocal() : DateTime(0), submitDate: json["KeszitesDatuma"] != null
groupId: json["OsztalyCsoport"] != null ? json["OsztalyCsoport"]["Uid"] ?? "" : "", ? DateTime.parse(json["KeszitesDatuma"]).toLocal()
: DateTime(0),
teacher: Teacher.fromString((json["KeszitoTanarNeve"] ?? "").trim()),
seenDate: json["LattamozasDatuma"] != null
? DateTime.parse(json["LattamozasDatuma"]).toLocal()
: DateTime(0),
groupId: json["OsztalyCsoport"] != null
? json["OsztalyCsoport"]["Uid"] ?? ""
: "",
content: json["Tartalom"].replaceAll("\r", "") ?? "", content: json["Tartalom"].replaceAll("\r", "") ?? "",
type: json["Tipus"] != null ? Category.fromJson(json["Tipus"]) : null, type: json["Tipus"] != null ? Category.fromJson(json["Tipus"]) : null,
json: json, json: json,

View File

@ -12,7 +12,8 @@ class ExamView extends StatelessWidget {
final Exam exam; final Exam exam;
static show(Exam exam, {required BuildContext context}) => showBottomCard(context: context, child: ExamView(exam)); static show(Exam exam, {required BuildContext context}) =>
showBottomCard(context: context, child: ExamView(exam));
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,7 +28,8 @@ class ExamView extends StatelessWidget {
leading: Padding( leading: Padding(
padding: const EdgeInsets.only(left: 6.0), padding: const EdgeInsets.only(left: 6.0),
child: Icon( child: Icon(
SubjectIcon.resolveVariant(subjectName: exam.subjectName, context: context), SubjectIcon.resolveVariant(
subjectName: exam.subjectName, context: context),
size: 36.0, size: 36.0,
color: AppColors.of(context).text.withOpacity(.75), color: AppColors.of(context).text.withOpacity(.75),
), ),
@ -39,7 +41,10 @@ class ExamView extends StatelessWidget {
style: const TextStyle(fontWeight: FontWeight.w600), style: const TextStyle(fontWeight: FontWeight.w600),
), ),
subtitle: Text( subtitle: Text(
exam.teacher, (exam.teacher.isRenamed
? exam.teacher.renamedTo
: exam.teacher.name) ??
'',
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w500), style: const TextStyle(fontWeight: FontWeight.w500),
@ -51,9 +56,14 @@ class ExamView extends StatelessWidget {
), ),
// Details // Details
if (exam.writeDate.year != 0) Detail(title: "date".i18n, description: exam.writeDate.format(context)), if (exam.writeDate.year != 0)
if (exam.description != "") Detail(title: "description".i18n, description: exam.description), Detail(
if (exam.mode != null) Detail(title: "mode".i18n, description: exam.mode!.description), title: "date".i18n,
description: exam.writeDate.format(context)),
if (exam.description != "")
Detail(title: "description".i18n, description: exam.description),
if (exam.mode != null)
Detail(title: "mode".i18n, description: exam.mode!.description),
], ],
), ),
); );

View File

@ -11,7 +11,8 @@ import 'grade_view.i18n.dart';
class GradeView extends StatelessWidget { class GradeView extends StatelessWidget {
const GradeView(this.grade, {Key? key}) : super(key: key); const GradeView(this.grade, {Key? key}) : super(key: key);
static show(Grade grade, {required BuildContext context}) => showBottomCard(context: context, child: GradeView(grade)); static show(Grade grade, {required BuildContext context}) =>
showBottomCard(context: context, child: GradeView(grade));
final Grade grade; final Grade grade;
@ -30,10 +31,21 @@ class GradeView extends StatelessWidget {
grade.subject.renamedTo ?? grade.subject.name.capital(), grade.subject.renamedTo ?? grade.subject.name.capital(),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: grade.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null), style: TextStyle(
fontWeight: FontWeight.w600,
fontStyle: grade.subject.isRenamed &&
settingsProvider.renamedSubjectsItalics
? FontStyle.italic
: null),
), ),
subtitle: Text( subtitle: Text(
!Provider.of<SettingsProvider>(context, listen: false).presentationMode ? grade.teacher : "Tanár", !Provider.of<SettingsProvider>(context, listen: false)
.presentationMode
? (grade.teacher.isRenamed
? grade.teacher.renamedTo
: grade.teacher.name) ??
''
: "Tanár",
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w500), style: const TextStyle(fontWeight: FontWeight.w500),
@ -49,13 +61,20 @@ class GradeView extends StatelessWidget {
title: "value".i18n, title: "value".i18n,
description: "${grade.value.valueName} " + percentText(), description: "${grade.value.valueName} " + percentText(),
), ),
if (grade.description != "") Detail(title: "description".i18n, description: grade.description), if (grade.description != "")
if (grade.mode.description != "") Detail(title: "mode".i18n, description: grade.mode.description), Detail(title: "description".i18n, description: grade.description),
if (grade.writeDate.year != 0) Detail(title: "date".i18n, description: grade.writeDate.format(context)), if (grade.mode.description != "")
Detail(title: "mode".i18n, description: grade.mode.description),
if (grade.writeDate.year != 0)
Detail(
title: "date".i18n,
description: grade.writeDate.format(context)),
], ],
), ),
); );
} }
String percentText() => grade.value.weight != 100 && grade.value.weight > 0 ? "${grade.value.weight}%" : ""; String percentText() => grade.value.weight != 100 && grade.value.weight > 0
? "${grade.value.weight}%"
: "";
} }

View File

@ -51,10 +51,18 @@ class HomeworkView extends StatelessWidget {
homework.subject.renamedTo ?? homework.subject.name.capital(), homework.subject.renamedTo ?? homework.subject.name.capital(),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: homework.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null), style: TextStyle(
fontWeight: FontWeight.w600,
fontStyle: homework.subject.isRenamed &&
settingsProvider.renamedSubjectsItalics
? FontStyle.italic
: null),
), ),
subtitle: Text( subtitle: Text(
homework.teacher, (homework.teacher.isRenamed
? homework.teacher.renamedTo
: homework.teacher.name) ??
'',
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w500), style: const TextStyle(fontWeight: FontWeight.w500),

View File

@ -54,10 +54,23 @@ class LessonView extends StatelessWidget {
lesson.subject.renamedTo ?? lesson.subject.name.capital(), lesson.subject.renamedTo ?? lesson.subject.name.capital(),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: lesson.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null), style: TextStyle(
fontWeight: FontWeight.w600,
fontStyle: lesson.subject.isRenamed &&
settingsProvider.renamedSubjectsItalics
? FontStyle.italic
: null),
), ),
subtitle: Text( subtitle: Text(
lesson.substituteTeacher == "" ? lesson.teacher : lesson.substituteTeacher, ((lesson.substituteTeacher == null ||
lesson.substituteTeacher!.name == "")
? (lesson.teacher.isRenamed
? lesson.teacher.renamedTo
: lesson.teacher.name)
: (lesson.substituteTeacher!.isRenamed
? lesson.substituteTeacher!.renamedTo
: lesson.substituteTeacher!.name)) ??
'',
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w500), style: const TextStyle(fontWeight: FontWeight.w500),
@ -69,10 +82,18 @@ class LessonView extends StatelessWidget {
), ),
// Details // Details
if (lesson.room != "") Detail(title: "Room".i18n, description: lesson.room.replaceAll("_", " ")), if (lesson.room != "")
if (lesson.description != "") Detail(title: "Description".i18n, description: lesson.description), Detail(
if (lesson.lessonYearIndex != null) Detail(title: "Lesson Number".i18n, description: "${lesson.lessonYearIndex}."), title: "Room".i18n,
if (lesson.groupName != "") Detail(title: "Group".i18n, description: lesson.groupName), description: lesson.room.replaceAll("_", " ")),
if (lesson.description != "")
Detail(title: "Description".i18n, description: lesson.description),
if (lesson.lessonYearIndex != null)
Detail(
title: "Lesson Number".i18n,
description: "${lesson.lessonYearIndex}."),
if (lesson.groupName != "")
Detail(title: "Group".i18n, description: lesson.groupName),
], ],
), ),
); );

View File

@ -4,7 +4,8 @@ import 'package:filcnaplo_mobile_ui/common/profile_image/profile_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class NoteTile extends StatelessWidget { class NoteTile extends StatelessWidget {
const NoteTile(this.note, {Key? key, this.onTap, this.padding}) : super(key: key); const NoteTile(this.note, {Key? key, this.onTap, this.padding})
: super(key: key);
final Note note; final Note note;
final void Function()? onTap; final void Function()? onTap;
@ -20,11 +21,20 @@ class NoteTile extends StatelessWidget {
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
contentPadding: const EdgeInsets.only(left: 8.0, right: 12.0), contentPadding: const EdgeInsets.only(left: 8.0, right: 12.0),
onTap: onTap, onTap: onTap,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)), shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
leading: ProfileImage( leading: ProfileImage(
name: note.teacher, name: (note.teacher.isRenamed
? note.teacher.renamedTo
: note.teacher.name) ??
'',
radius: 22.0, radius: 22.0,
backgroundColor: ColorUtils.stringToColor(note.teacher), backgroundColor: ColorUtils.stringToColor(
(note.teacher.isRenamed
? note.teacher.renamedTo
: note.teacher.name) ??
'',
),
), ),
title: Text( title: Text(
note.title, note.title,

View File

@ -12,7 +12,8 @@ class NoteView extends StatelessWidget {
final Note note; final Note note;
static void show(Note note, {required BuildContext context}) => showSlidingBottomSheet(context: context, child: NoteView(note)); static void show(Note note, {required BuildContext context}) =>
showSlidingBottomSheet(context: context, child: NoteView(note));
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -25,9 +26,17 @@ class NoteView extends StatelessWidget {
// Header // Header
ListTile( ListTile(
leading: ProfileImage( leading: ProfileImage(
name: note.teacher, name: (note.teacher.isRenamed
? note.teacher.renamedTo
: note.teacher.name) ??
'',
radius: 22.0, radius: 22.0,
backgroundColor: ColorUtils.stringToColor(note.teacher), backgroundColor: ColorUtils.stringToColor(
(note.teacher.isRenamed
? note.teacher.renamedTo
: note.teacher.name) ??
'',
),
), ),
title: Text( title: Text(
note.title, note.title,
@ -36,7 +45,10 @@ class NoteView extends StatelessWidget {
style: const TextStyle(fontWeight: FontWeight.w600), style: const TextStyle(fontWeight: FontWeight.w600),
), ),
subtitle: Text( subtitle: Text(
note.teacher, (note.teacher.isRenamed
? note.teacher.renamedTo
: note.teacher.name) ??
'',
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w500), style: const TextStyle(fontWeight: FontWeight.w500),

View File

@ -3,6 +3,7 @@ import 'dart:math';
import 'package:filcnaplo_kreta_api/models/category.dart'; import 'package:filcnaplo_kreta_api/models/category.dart';
import 'package:filcnaplo_kreta_api/models/grade.dart'; import 'package:filcnaplo_kreta_api/models/grade.dart';
import 'package:filcnaplo_kreta_api/models/subject.dart'; import 'package:filcnaplo_kreta_api/models/subject.dart';
import 'package:filcnaplo_kreta_api/models/teacher.dart';
import 'package:filcnaplo_mobile_ui/common/custom_snack_bar.dart'; import 'package:filcnaplo_mobile_ui/common/custom_snack_bar.dart';
import 'package:filcnaplo_mobile_ui/common/material_action_button.dart'; import 'package:filcnaplo_mobile_ui/common/material_action_button.dart';
import 'package:filcnaplo/ui/widgets/grade/grade_tile.dart'; import 'package:filcnaplo/ui/widgets/grade/grade_tile.dart';
@ -42,7 +43,8 @@ class _GradeCalculatorState extends State<GradeCalculator> {
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
child: Text( child: Text(
"Grade Calculator".i18n, "Grade Calculator".i18n,
style: const TextStyle(fontSize: 20.0, fontWeight: FontWeight.w600), style:
const TextStyle(fontSize: 20.0, fontWeight: FontWeight.w600),
), ),
), ),
@ -63,7 +65,9 @@ class _GradeCalculatorState extends State<GradeCalculator> {
Container( Container(
width: 80.0, width: 80.0,
padding: const EdgeInsets.only(right: 12.0), padding: const EdgeInsets.only(right: 12.0),
child: Center(child: GradeValueWidget(GradeValue(newValue.toInt(), "", "", 0))), child: Center(
child: GradeValueWidget(
GradeValue(newValue.toInt(), "", "", 0))),
), ),
]), ]),
@ -90,7 +94,8 @@ class _GradeCalculatorState extends State<GradeCalculator> {
child: Center( child: Center(
child: TextField( child: TextField(
controller: _weightController, controller: _weightController,
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 22.0), style: const TextStyle(
fontWeight: FontWeight.w600, fontSize: 22.0),
autocorrect: false, autocorrect: false,
textAlign: TextAlign.right, textAlign: TextAlign.right,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
@ -122,7 +127,8 @@ class _GradeCalculatorState extends State<GradeCalculator> {
child: Text("Add Grade".i18n), child: Text("Add Grade".i18n),
onPressed: () { onPressed: () {
if (calculatorProvider.ghosts.length >= 50) { if (calculatorProvider.ghosts.length >= 50) {
ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(content: Text("limit_reached".i18n), context: context)); ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(
content: Text("limit_reached".i18n), context: context));
return; return;
} }
@ -133,7 +139,11 @@ class _GradeCalculatorState extends State<GradeCalculator> {
grades.sort((a, b) => -a.writeDate.compareTo(b.writeDate)); grades.sort((a, b) => -a.writeDate.compareTo(b.writeDate));
date = grades.first.date.add(const Duration(days: 7)); date = grades.first.date.add(const Duration(days: 7));
} else { } else {
List<Grade> grades = calculatorProvider.grades.where((e) => e.type == GradeType.midYear && e.subject == widget.subject).toList(); List<Grade> grades = calculatorProvider.grades
.where((e) =>
e.type == GradeType.midYear &&
e.subject == widget.subject)
.toList();
grades.sort((a, b) => -a.writeDate.compareTo(b.writeDate)); grades.sort((a, b) => -a.writeDate.compareTo(b.writeDate));
date = grades.first.date; date = grades.first.date;
} }
@ -143,8 +153,9 @@ class _GradeCalculatorState extends State<GradeCalculator> {
date: date, date: date,
writeDate: date, writeDate: date,
description: "Ghost Grade".i18n, description: "Ghost Grade".i18n,
value: GradeValue(newValue.toInt(), "", "", newWeight.toInt()), value:
teacher: "Ghost", GradeValue(newValue.toInt(), "", "", newWeight.toInt()),
teacher: Teacher.fromString("Ghost"),
type: GradeType.ghost, type: GradeType.ghost,
form: "", form: "",
subject: widget.subject, subject: widget.subject,

View File

@ -13,6 +13,7 @@ import 'dart:math';
import 'package:filcnaplo_kreta_api/models/category.dart'; import 'package:filcnaplo_kreta_api/models/category.dart';
import 'package:filcnaplo_kreta_api/models/grade.dart'; import 'package:filcnaplo_kreta_api/models/grade.dart';
import 'package:filcnaplo_kreta_api/models/subject.dart'; import 'package:filcnaplo_kreta_api/models/subject.dart';
import 'package:filcnaplo_kreta_api/models/teacher.dart';
import 'package:flutter/foundation.dart' show listEquals; import 'package:flutter/foundation.dart' show listEquals;
/// Generate list of grades that achieve the wanted goal. /// Generate list of grades that achieve the wanted goal.
@ -46,7 +47,8 @@ class GoalPlanner {
for (int i = g.max; i >= 0; i--) { for (int i = g.max; i >= 0; i--) {
int newGradeToAdd = g.gradeToAdd - 1; int newGradeToAdd = g.gradeToAdd - 1;
List<int> newPlan = GoalPlannerHelper._addToList<int>(g.plan, g.gradeToAdd, i); List<int> newPlan =
GoalPlannerHelper._addToList<int>(g.plan, g.gradeToAdd, i);
Avg newAvg = GoalPlannerHelper._addToAvg(g.currentAvg, g.gradeToAdd, i); Avg newAvg = GoalPlannerHelper._addToAvg(g.currentAvg, g.gradeToAdd, i);
int newN = GoalPlannerHelper.howManyNeeded( int newN = GoalPlannerHelper.howManyNeeded(
@ -57,7 +59,7 @@ class GoalPlanner {
id: '', id: '',
date: DateTime(0), date: DateTime(0),
value: GradeValue(e, '', '', 100), value: GradeValue(e, '', '', 100),
teacher: '', teacher: Teacher.fromString(''),
description: '', description: '',
form: '', form: '',
groupId: '', groupId: '',
@ -83,7 +85,8 @@ class GoalPlanner {
grades, grades,
goal, goal,
), ),
Avg(GoalPlannerHelper.averageEvals(grades), GoalPlannerHelper.weightSum(grades)), Avg(GoalPlannerHelper.averageEvals(grades),
GoalPlannerHelper.weightSum(grades)),
[], [],
), ),
); );
@ -92,7 +95,9 @@ class GoalPlanner {
for (var e in plans) { for (var e in plans) {
e.sum = e.plan.fold(0, (int a, b) => a + b); e.sum = e.plan.fold(0, (int a, b) => a + b);
e.avg = e.sum / e.plan.length; e.avg = e.sum / e.plan.length;
e.sigma = sqrt(e.plan.map((i) => pow(i - e.avg, 2)).fold(0, (num a, b) => a + b) / e.plan.length); e.sigma = sqrt(
e.plan.map((i) => pow(i - e.avg, 2)).fold(0, (num a, b) => a + b) /
e.plan.length);
} }
// filter without aggression // filter without aggression
@ -141,7 +146,8 @@ class Plan {
} }
class GoalPlannerHelper { class GoalPlannerHelper {
static Avg _addToAvg(Avg base, int grade, int n) => Avg((base.avg * base.n + grade * n) / (base.n + n), base.n + n); static Avg _addToAvg(Avg base, int grade, int n) =>
Avg((base.avg * base.n + grade * n) / (base.n + n), base.n + n);
static List<T> _addToList<T>(List<T> l, T e, int n) { static List<T> _addToList<T>(List<T> l, T e, int n) {
if (n == 0) return l; if (n == 0) return l;
@ -158,15 +164,20 @@ class GoalPlannerHelper {
if (avg >= goal) return 0; if (avg >= goal) return 0;
if (grade * 1.0 == goal) return -1; if (grade * 1.0 == goal) return -1;
int candidate = (wsum * (avg - goal) / (goal - grade)).floor(); int candidate = (wsum * (avg - goal) / (goal - grade)).floor();
return (candidate * grade + avg * wsum) / (candidate + wsum) < goal ? candidate + 1 : candidate; return (candidate * grade + avg * wsum) / (candidate + wsum) < goal
? candidate + 1
: candidate;
} }
static double averageEvals(List<Grade> grades, {bool finalAvg = false}) { static double averageEvals(List<Grade> grades, {bool finalAvg = false}) {
double average = double average = grades
grades.map((e) => e.value.value * e.value.weight / 100.0).fold(0.0, (double a, double b) => a + b) / weightSum(grades, finalAvg: finalAvg); .map((e) => e.value.value * e.value.weight / 100.0)
.fold(0.0, (double a, double b) => a + b) /
weightSum(grades, finalAvg: finalAvg);
return average.isNaN ? 0.0 : average; return average.isNaN ? 0.0 : average;
} }
static double weightSum(List<Grade> grades, {bool finalAvg = false}) => static double weightSum(List<Grade> grades, {bool finalAvg = false}) => grades
grades.map((e) => finalAvg ? 1 : e.value.weight / 100).fold(0, (a, b) => a + b); .map((e) => finalAvg ? 1 : e.value.weight / 100)
.fold(0, (a, b) => a + b);
} }

View File

@ -103,9 +103,7 @@ class _ModifyTeacherNamesState extends State<ModifyTeacherNames> {
.map((e) => e.teacher) .map((e) => e.teacher)
.toSet() .toSet()
.toList() .toList()
..sort((a, b) => a.compareTo(b))) ..sort((a, b) => a.name.compareTo(b.name)));
.map((e) => Teacher.fromString(e))
.toList();
print(teachers.map((e) => e.name)); print(teachers.map((e) => e.name));
user = Provider.of<UserProvider>(context, listen: false); user = Provider.of<UserProvider>(context, listen: false);
dbProvider = Provider.of<DatabaseProvider>(context, listen: false); dbProvider = Provider.of<DatabaseProvider>(context, listen: false);