forked from firka/firka
firka: show ghost grades on the chart and in the grades list
This commit is contained in:
Submodule firka/lib/l10n updated: a52a907c9f...fa3a97f2d4
@@ -986,8 +986,9 @@ Future<void> showHomeworkBottomSheet(
|
|||||||
Future<void> showGradeCalculatorBottomSheet(
|
Future<void> showGradeCalculatorBottomSheet(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
AppInitialization data,
|
AppInitialization data,
|
||||||
Subject subject,
|
Subject subject, {
|
||||||
) async {
|
void Function(int grade, int weight)? onAdd,
|
||||||
|
}) async {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
elevation: 100,
|
elevation: 100,
|
||||||
@@ -1017,6 +1018,7 @@ Future<void> showGradeCalculatorBottomSheet(
|
|||||||
child: _GradeCalculatorSheetContent(
|
child: _GradeCalculatorSheetContent(
|
||||||
data: data,
|
data: data,
|
||||||
subject: subject,
|
subject: subject,
|
||||||
|
onAdd: onAdd,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1030,10 +1032,12 @@ Future<void> showGradeCalculatorBottomSheet(
|
|||||||
class _GradeCalculatorSheetContent extends StatefulWidget {
|
class _GradeCalculatorSheetContent extends StatefulWidget {
|
||||||
final AppInitialization data;
|
final AppInitialization data;
|
||||||
final Subject subject;
|
final Subject subject;
|
||||||
|
final void Function(int grade, int weight)? onAdd;
|
||||||
|
|
||||||
const _GradeCalculatorSheetContent({
|
const _GradeCalculatorSheetContent({
|
||||||
required this.data,
|
required this.data,
|
||||||
required this.subject,
|
required this.subject,
|
||||||
|
this.onAdd,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1193,9 +1197,9 @@ class _GradeCalculatorSheetContentState
|
|||||||
),
|
),
|
||||||
child: Slider(
|
child: Slider(
|
||||||
value: weightPercent.toDouble(),
|
value: weightPercent.toDouble(),
|
||||||
min: 0,
|
min: 1,
|
||||||
max: 100,
|
max: 500,
|
||||||
divisions: 100,
|
divisions: 499,
|
||||||
onChanged: (v) => setState(() => weightPercent = v.round()),
|
onChanged: (v) => setState(() => weightPercent = v.round()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1203,7 +1207,7 @@ class _GradeCalculatorSheetContentState
|
|||||||
),
|
),
|
||||||
SizedBox(width: 12),
|
SizedBox(width: 12),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 48,
|
width: 56,
|
||||||
child: Text(
|
child: Text(
|
||||||
'$weightPercent%',
|
'$weightPercent%',
|
||||||
style: appStyle.fonts.B_16R.apply(
|
style: appStyle.fonts.B_16R.apply(
|
||||||
@@ -1231,6 +1235,7 @@ class _GradeCalculatorSheetContentState
|
|||||||
setState(() {
|
setState(() {
|
||||||
entries.add((selectedGrade, weightPercent));
|
entries.add((selectedGrade, weightPercent));
|
||||||
});
|
});
|
||||||
|
widget.onAdd?.call(selectedGrade, weightPercent);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.data.l10n.grade_calculator_add,
|
widget.data.l10n.grade_calculator_add,
|
||||||
@@ -1257,8 +1262,9 @@ class _GradeCalculatorSheetContentState
|
|||||||
Future<void> showSubjectBottomSheetSettings(
|
Future<void> showSubjectBottomSheetSettings(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
AppInitialization data,
|
AppInitialization data,
|
||||||
Subject subject,
|
Subject subject, {
|
||||||
) async {
|
void Function(int grade, int weight)? onAddFromCalculator,
|
||||||
|
}) async {
|
||||||
final parentContext = context;
|
final parentContext = context;
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -1315,6 +1321,7 @@ Future<void> showSubjectBottomSheetSettings(
|
|||||||
parentContext,
|
parentContext,
|
||||||
data,
|
data,
|
||||||
subject,
|
subject,
|
||||||
|
onAdd: onAddFromCalculator,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class HomeGradesSubjectScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
|
class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
|
||||||
Iterable<Grade>? grades;
|
Iterable<Grade>? grades;
|
||||||
|
final List<(int grade, int weight)> _ghostEntries = [];
|
||||||
|
|
||||||
void _onRefreshRequested(BuildContext context) async {
|
void _onRefreshRequested(BuildContext context) async {
|
||||||
final cubit = context.read<HomeRefreshCubit>();
|
final cubit = context.read<HomeRefreshCubit>();
|
||||||
@@ -55,6 +56,41 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Grade> _gradesWithGhosts(Subject subject) {
|
||||||
|
final real = grades?.toList() ?? [];
|
||||||
|
if (_ghostEntries.isEmpty) return real;
|
||||||
|
final baseDate = real.isEmpty
|
||||||
|
? DateTime.now()
|
||||||
|
: real
|
||||||
|
.map((g) => g.creationDate)
|
||||||
|
.reduce((a, b) => a.isAfter(b) ? a : b);
|
||||||
|
final osztalyzat = NameUidDesc(
|
||||||
|
uid: '1,Osztalyzat',
|
||||||
|
name: 'Osztalyzat',
|
||||||
|
description: '',
|
||||||
|
);
|
||||||
|
final ghostGrades = <Grade>[];
|
||||||
|
for (var i = 0; i < _ghostEntries.length; i++) {
|
||||||
|
final e = _ghostEntries[i];
|
||||||
|
ghostGrades.add(
|
||||||
|
Grade(
|
||||||
|
uid: 'ghost-$i-${e.$1}-${e.$2}',
|
||||||
|
recordDate: baseDate.add(Duration(seconds: i)),
|
||||||
|
creationDate: baseDate.add(Duration(seconds: i)),
|
||||||
|
subject: subject,
|
||||||
|
type: osztalyzat,
|
||||||
|
valueType: osztalyzat,
|
||||||
|
teacher: '',
|
||||||
|
strValue: '${e.$1}',
|
||||||
|
sortIndex: 0,
|
||||||
|
numericValue: e.$1,
|
||||||
|
weightPercentage: e.$2,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return [...real, ...ghostGrades];
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocListener<HomeRefreshCubit, HomeRefreshState>(
|
return BlocListener<HomeRefreshCubit, HomeRefreshState>(
|
||||||
@@ -72,7 +108,30 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
|
|||||||
var aGrade = grades!.first;
|
var aGrade = grades!.first;
|
||||||
var groups = grades!.groupList((grade) => grade.recordDate);
|
var groups = grades!.groupList((grade) => grade.recordDate);
|
||||||
|
|
||||||
|
final ghostGradeWidgets = _ghostEntries.reversed.map((e) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: FirkaCard(
|
||||||
|
left: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
GradeWidget.gradeValue(e.$1),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'${widget.data.l10n.ghost_grade} ${e.$2}%',
|
||||||
|
style: appStyle.fonts.B_16SB.apply(
|
||||||
|
color: appStyle.colors.textPrimary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () {},
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
var gradeWidgets = List<Widget>.empty(growable: true);
|
var gradeWidgets = List<Widget>.empty(growable: true);
|
||||||
|
gradeWidgets.addAll(ghostGradeWidgets);
|
||||||
|
|
||||||
for (var group in groups.entries) {
|
for (var group in groups.entries) {
|
||||||
gradeWidgets.add(SizedBox(height: 8));
|
gradeWidgets.add(SizedBox(height: 8));
|
||||||
@@ -190,6 +249,9 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
|
|||||||
context,
|
context,
|
||||||
widget.data,
|
widget.data,
|
||||||
aGrade.subject,
|
aGrade.subject,
|
||||||
|
onAddFromCalculator: (g, w) {
|
||||||
|
setState(() => _ghostEntries.add((g, w)));
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -237,7 +299,9 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
|
|||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
GradeChartWithInteraction(grades: grades?.toList() ?? []),
|
GradeChartWithInteraction(
|
||||||
|
grades: _gradesWithGhosts(aGrade.subject),
|
||||||
|
),
|
||||||
SizedBox(height: 12),
|
SizedBox(height: 12),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(left: 4),
|
padding: EdgeInsets.only(left: 4),
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class _GradeChartState extends State<GradeChart> {
|
|||||||
appStyle.colors.grade1,
|
appStyle.colors.grade1,
|
||||||
];
|
];
|
||||||
|
|
||||||
late final List<FlSpot> spots;
|
late List<FlSpot> spots;
|
||||||
|
|
||||||
double? _subjectAverageInList(List<Grade> grades, String subjectUid) {
|
double? _subjectAverageInList(List<Grade> grades, String subjectUid) {
|
||||||
double weightedSum = 0;
|
double weightedSum = 0;
|
||||||
@@ -67,7 +67,10 @@ class _GradeChartState extends State<GradeChart> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_computeSpots();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _computeSpots() {
|
||||||
final sortedGrades = List<Grade>.from(widget.grades)
|
final sortedGrades = List<Grade>.from(widget.grades)
|
||||||
..sort((a, b) => a.creationDate.compareTo(b.creationDate));
|
..sort((a, b) => a.creationDate.compareTo(b.creationDate));
|
||||||
|
|
||||||
@@ -90,6 +93,14 @@ class _GradeChartState extends State<GradeChart> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant GradeChart oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (oldWidget.grades.length != widget.grades.length) {
|
||||||
|
_computeSpots();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
|
|||||||
Reference in New Issue
Block a user