firka: show ghost grades on the chart and in the grades list

This commit is contained in:
2026-03-02 21:40:01 +01:00
parent 68ddffd808
commit d96c4b66bb
4 changed files with 93 additions and 11 deletions

View File

@@ -986,8 +986,9 @@ Future<void> showHomeworkBottomSheet(
Future<void> showGradeCalculatorBottomSheet(
BuildContext context,
AppInitialization data,
Subject subject,
) async {
Subject subject, {
void Function(int grade, int weight)? onAdd,
}) async {
showModalBottomSheet(
context: context,
elevation: 100,
@@ -1017,6 +1018,7 @@ Future<void> showGradeCalculatorBottomSheet(
child: _GradeCalculatorSheetContent(
data: data,
subject: subject,
onAdd: onAdd,
),
),
),
@@ -1030,10 +1032,12 @@ Future<void> showGradeCalculatorBottomSheet(
class _GradeCalculatorSheetContent extends StatefulWidget {
final AppInitialization data;
final Subject subject;
final void Function(int grade, int weight)? onAdd;
const _GradeCalculatorSheetContent({
required this.data,
required this.subject,
this.onAdd,
});
@override
@@ -1193,9 +1197,9 @@ class _GradeCalculatorSheetContentState
),
child: Slider(
value: weightPercent.toDouble(),
min: 0,
max: 100,
divisions: 100,
min: 1,
max: 500,
divisions: 499,
onChanged: (v) => setState(() => weightPercent = v.round()),
),
),
@@ -1203,7 +1207,7 @@ class _GradeCalculatorSheetContentState
),
SizedBox(width: 12),
SizedBox(
width: 48,
width: 56,
child: Text(
'$weightPercent%',
style: appStyle.fonts.B_16R.apply(
@@ -1231,6 +1235,7 @@ class _GradeCalculatorSheetContentState
setState(() {
entries.add((selectedGrade, weightPercent));
});
widget.onAdd?.call(selectedGrade, weightPercent);
},
child: Text(
widget.data.l10n.grade_calculator_add,
@@ -1257,8 +1262,9 @@ class _GradeCalculatorSheetContentState
Future<void> showSubjectBottomSheetSettings(
BuildContext context,
AppInitialization data,
Subject subject,
) async {
Subject subject, {
void Function(int grade, int weight)? onAddFromCalculator,
}) async {
final parentContext = context;
showModalBottomSheet(
context: context,
@@ -1315,6 +1321,7 @@ Future<void> showSubjectBottomSheetSettings(
parentContext,
data,
subject,
onAdd: onAddFromCalculator,
);
},
child: Container(

View File

@@ -29,6 +29,7 @@ class HomeGradesSubjectScreen extends StatefulWidget {
class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
Iterable<Grade>? grades;
final List<(int grade, int weight)> _ghostEntries = [];
void _onRefreshRequested(BuildContext context) async {
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
Widget build(BuildContext context) {
return BlocListener<HomeRefreshCubit, HomeRefreshState>(
@@ -72,7 +108,30 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
var aGrade = grades!.first;
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);
gradeWidgets.addAll(ghostGradeWidgets);
for (var group in groups.entries) {
gradeWidgets.add(SizedBox(height: 8));
@@ -190,6 +249,9 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
context,
widget.data,
aGrade.subject,
onAddFromCalculator: (g, w) {
setState(() => _ghostEntries.add((g, w)));
},
);
},
),
@@ -237,7 +299,9 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
SizedBox(height: 15),
],
),
GradeChartWithInteraction(grades: grades?.toList() ?? []),
GradeChartWithInteraction(
grades: _gradesWithGhosts(aGrade.subject),
),
SizedBox(height: 12),
Padding(
padding: EdgeInsets.only(left: 4),

View File

@@ -26,7 +26,7 @@ class _GradeChartState extends State<GradeChart> {
appStyle.colors.grade1,
];
late final List<FlSpot> spots;
late List<FlSpot> spots;
double? _subjectAverageInList(List<Grade> grades, String subjectUid) {
double weightedSum = 0;
@@ -67,7 +67,10 @@ class _GradeChartState extends State<GradeChart> {
@override
void initState() {
super.initState();
_computeSpots();
}
void _computeSpots() {
final sortedGrades = List<Grade>.from(widget.grades)
..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
Widget build(BuildContext context) {
return ClipRRect(