add pageview to home pages

co-authored-by: Armand <4831c0@proton.me>
This commit is contained in:
2025-08-31 22:15:06 +02:00
committed by Armand
parent b9fd0846d2
commit 8857a1efd7
7 changed files with 524 additions and 486 deletions

View File

@@ -20,17 +20,18 @@ class HomeGradesScreen extends StatefulWidget {
final AppInitialization data;
final UpdateNotifier updateNotifier;
final UpdateNotifier finishNotifier;
final void Function(ActiveHomePage, bool) cb;
final void Function(int) pageController;
const HomeGradesScreen(
this.data, this.updateNotifier, this.finishNotifier, this.cb,
this.data, this.updateNotifier, this.finishNotifier, this.pageController,
{super.key});
@override
State<StatefulWidget> createState() => _HomeGradesScreen();
}
String activeSubjectUid = "";
class _HomeGradesScreen extends State<HomeGradesScreen> {
ApiResponse<List<Grade>>? grades;
ApiResponse<List<Lesson>>? week;
@@ -83,7 +84,7 @@ class _HomeGradesScreen extends State<HomeGradesScreen> {
@override
Widget build(BuildContext context) {
if (grades == null || week == null) {
return SizedBox(
return SizedBox(
height: MediaQuery.of(context).size.height / 1.35,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -128,9 +129,9 @@ class _HomeGradesScreen extends State<HomeGradesScreen> {
gradeCards.add(GestureDetector(
child: GradeSmallCard(grades!.response!, subject),
onTap: () {
widget.cb(
ActiveHomePage(HomePages.grades, subPageUid: subject.uid),
true);
activeSubjectUid = subject.uid;
widget.pageController(1);
},
));
}
@@ -144,129 +145,128 @@ class _HomeGradesScreen extends State<HomeGradesScreen> {
var subjectAvgColor = getGradeColor(subjectAvg);
return Flexible(
child: Padding(
padding: const EdgeInsets.only(
left: 20.0,
right: 20.0,
top: 12.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
return Scaffold(
backgroundColor: appStyle.colors.background, body: Padding(
padding: const EdgeInsets.only(
left: 20.0,
right: 20.0,
top: 12.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
widget.data.l10n.subjects,
style: appStyle.fonts.H_H2
.apply(color: appStyle.colors.textPrimary),
)
],
),
SizedBox(height: 16), // TODO: Add graphs here
// ...gradeCards,
SizedBox(
height: MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
240,
child: ListView(
children: [
Text(
widget.data.l10n.subjects,
style: appStyle.fonts.H_H2
.apply(color: appStyle.colors.textPrimary),
)
],
),
SizedBox(height: 16), // TODO: Add graphs here
// ...gradeCards,
SizedBox(
height: MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
240,
child: ListView(
children: [
Text(
widget.data.l10n.your_subjects,
style: appStyle.fonts.H_14px
.apply(color: appStyle.colors.textSecondary),
),
SizedBox(height: 16),
...gradeCards,
SizedBox(height: 16),
Text(
widget.data.l10n.data,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textSecondary),
),
SizedBox(height: 16),
FirkaCard(
left: [
Text(
widget.data.l10n.subject_avg,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textPrimary),
),
],
right: [
Card(
shadowColor: Colors.transparent,
color: subjectAvgColor.withAlpha(38),
child: Padding(
padding: EdgeInsets.only(
left: 8, right: 8, top: 4, bottom: 4),
child: Text(
subjectAvg.toStringAsFixed(2),
style: appStyle.fonts.B_16SB
.apply(color: subjectAvgColor),
),
),
),
],
),
FirkaCard(
left: [
Text(
widget.data.l10n.subject_avg_rounded,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textPrimary),
),
],
right: [
Card(
shadowColor: Colors.transparent,
color: subjectAvgColor.withAlpha(38),
child: Padding(
padding: EdgeInsets.only(
left: 8, right: 8, top: 4, bottom: 4),
child: Text(
subjectAvgRounded.toStringAsFixed(2),
style: appStyle.fonts.B_16SB
.apply(color: subjectAvgColor),
),
),
),
],
),
FirkaCard(left: [
widget.data.l10n.your_subjects,
style: appStyle.fonts.H_14px
.apply(color: appStyle.colors.textSecondary),
),
SizedBox(height: 16),
...gradeCards,
SizedBox(height: 16),
Text(
widget.data.l10n.data,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textSecondary),
),
SizedBox(height: 16),
FirkaCard(
left: [
Text(
widget.data.l10n.class_avg,
widget.data.l10n.subject_avg,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textPrimary),
),
]),
FirkaCard(
left: [
Text(
widget.data.l10n.class_n,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textPrimary),
],
right: [
Card(
shadowColor: Colors.transparent,
color: subjectAvgColor.withAlpha(38),
child: Padding(
padding: EdgeInsets.only(
left: 8, right: 8, top: 4, bottom: 4),
child: Text(
subjectAvg.toStringAsFixed(2),
style: appStyle.fonts.B_16SB
.apply(color: subjectAvgColor),
),
),
],
right: [
Text(
week!.response!
.where((lesson) =>
lesson.type.name != TimetableConsts.event)
.length
.toString(),
style: appStyle.fonts.B_14SB
.apply(color: appStyle.colors.textPrimary),
),
],
),
FirkaCard(
left: [
Text(
widget.data.l10n.subject_avg_rounded,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textPrimary),
),
],
right: [
Card(
shadowColor: Colors.transparent,
color: subjectAvgColor.withAlpha(38),
child: Padding(
padding: EdgeInsets.only(
left: 8, right: 8, top: 4, bottom: 4),
child: Text(
subjectAvgRounded.toStringAsFixed(2),
style: appStyle.fonts.B_16SB
.apply(color: subjectAvgColor),
),
),
],
),
],
),
FirkaCard(left: [
Text(
widget.data.l10n.class_avg,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textPrimary),
),
],
),
]),
FirkaCard(
left: [
Text(
widget.data.l10n.class_n,
style: appStyle.fonts.B_16SB
.apply(color: appStyle.colors.textPrimary),
),
],
right: [
Text(
week!.response!
.where((lesson) =>
lesson.type.name != TimetableConsts.event)
.length
.toString(),
style: appStyle.fonts.B_14SB
.apply(color: appStyle.colors.textPrimary),
),
],
),
],
),
],
),
),
],
),
);
));
}
}
}

View File

@@ -2,6 +2,7 @@ import 'package:firka/helpers/api/model/grade.dart';
import 'package:firka/helpers/extensions.dart';
import 'package:firka/helpers/ui/firka_card.dart';
import 'package:firka/helpers/ui/grade.dart';
import 'package:firka/ui/phone/pages/home/home_grades.dart';
import 'package:flutter/material.dart';
import '../../../../helpers/update_notifier.dart';
@@ -11,12 +12,11 @@ import '../../../widget/delayed_spinner.dart';
class HomeGradesSubjectScreen extends StatefulWidget {
final AppInitialization data;
final String subPageUid;
final UpdateNotifier updateNotifier;
final UpdateNotifier finishNotifier;
const HomeGradesSubjectScreen(
this.data, this.updateNotifier, this.finishNotifier, this.subPageUid,
this.data, this.updateNotifier, this.finishNotifier,
{super.key});
@override
@@ -37,7 +37,7 @@ class _HomeGradesSubjectScreen extends State<HomeGradesSubjectScreen> {
void updateListener() async {
grades = (await widget.data.client.getGrades(forceCache: false))
.response!
.where((grade) => grade.subject.uid == widget.subPageUid)
.where((grade) => grade.subject.uid == activeSubjectUid)
.where((grade) => grade.type.name != "felevi_jegy_ertekeles");
if (mounted) setState(() {});
@@ -54,7 +54,7 @@ class _HomeGradesSubjectScreen extends State<HomeGradesSubjectScreen> {
(() async {
grades = (await widget.data.client.getGrades())
.response!
.where((grade) => grade.subject.uid == widget.subPageUid)
.where((grade) => grade.subject.uid == activeSubjectUid)
.where((grade) => grade.type.name != "felevi_jegy_ertekeles");
if (mounted) setState(() {});
@@ -69,7 +69,7 @@ class _HomeGradesSubjectScreen extends State<HomeGradesSubjectScreen> {
@override
Widget build(BuildContext context) {
if (grades != null) {
if (grades != null && activeSubjectUid != "") {
var aGrade = grades!.first;
var groups = grades!.groupList((grade) => grade.recordDate);
@@ -119,72 +119,74 @@ class _HomeGradesSubjectScreen extends State<HomeGradesSubjectScreen> {
}
}
return Flexible(
child: Padding(
padding: const EdgeInsets.only(
left: 16.0,
right: 16.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
widget.data.l10n.subjects,
style: appStyle
.fonts.H_16px // TODO: Replace this with the proper font
.apply(color: appStyle.colors.textPrimary),
)
],
),
SizedBox(height: 16),
SizedBox(
height: MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
230,
child: ListView(
return Scaffold(
backgroundColor: appStyle.colors.background,
body: Padding(
padding: const EdgeInsets.only(
left: 16.0,
right: 16.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
FirkaCard(
left: [
Padding(
padding: EdgeInsets.only(left: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: MediaQuery.of(context).size.width / 1.45,
child: Text(
aGrade.subject.name,
style: appStyle.fonts.H_H2,
),
),
Text(
aGrade.teacher, // For some reason the teacher's
// name isn't stored in the subject, so we need
// to get *a* grade, and then get the teacher's
// name from there :3
style: appStyle.fonts.B_14R,
)
],
),
)
],
),
Padding(
padding: EdgeInsets.only(left: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: gradeWidgets,
),
Text(
widget.data.l10n.subjects,
style: appStyle.fonts
.H_16px // TODO: Replace this with the proper font
.apply(color: appStyle.colors.textPrimary),
)
],
),
),
],
),
),
);
SizedBox(height: 16),
SizedBox(
height: MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
230,
child: ListView(
children: [
FirkaCard(
left: [
Padding(
padding: EdgeInsets.only(left: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width:
MediaQuery.of(context).size.width / 1.45,
child: Text(
aGrade.subject.name,
style: appStyle.fonts.H_H2,
),
),
Text(
aGrade
.teacher, // For some reason the teacher's
// name isn't stored in the subject, so we need
// to get *a* grade, and then get the teacher's
// name from there :3
style: appStyle.fonts.B_14R,
)
],
),
)
],
),
Padding(
padding: EdgeInsets.only(left: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: gradeWidgets,
),
)
],
),
),
],
),
));
} else {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.35,

View File

@@ -142,8 +142,7 @@ class _HomeMainScreen extends State<HomeMainScreen> {
}
if (student != null && lessons != null) {
return Flexible(
child: Padding(
return Padding(
padding: const EdgeInsets.only(
left: 20.0,
top: 24.0,
@@ -159,8 +158,7 @@ class _HomeMainScreen extends State<HomeMainScreen> {
nextClass
],
),
),
);
);
} else {
return DelayedSpinnerWidget();
}

View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
class PageWithSubPages extends StatefulWidget {
final int pageIndex;
final List<Widget Function(void Function(int))> subPages;
const PageWithSubPages(this.subPages, {Key? key, required this.pageIndex}) : super(key: key);
@override
_PageWithSubPagesState createState() => _PageWithSubPagesState();
}
class _PageWithSubPagesState extends State<PageWithSubPages> {
int _currentSubPage = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: widget.subPages[_currentSubPage]((page) {
setState(() {
_currentSubPage = page;
});
}),
);
}
}

View File

@@ -23,11 +23,10 @@ class HomeTimetableScreen extends StatefulWidget {
final AppInitialization data;
final UpdateNotifier updateNotifier;
final UpdateNotifier finishNotifier;
final void Function(ActiveHomePage, bool) cb;
final void Function(int) pageController;
const HomeTimetableScreen(
this.data, this.updateNotifier, this.finishNotifier, this.cb,
this.data, this.updateNotifier, this.finishNotifier, this.pageController,
{super.key});
@override
@@ -171,7 +170,9 @@ class _HomeTimetableScreen extends State<HomeTimetableScreen> {
widget.data, date, lessonsOnDate, eventsOnDate, testsOnDate));
}
return Stack(children: [
return Scaffold(
backgroundColor: appStyle.colors.background, body:
Stack(children: [
SizedBox(
width: MediaQuery.of(context).size.width,
height: 74 + 16,
@@ -189,6 +190,7 @@ class _HomeTimetableScreen extends State<HomeTimetableScreen> {
),
Row(
children: [
/* TODO: 1.1.0
GestureDetector(
child: Card(
color: appStyle.colors.buttonSecondaryFill,
@@ -203,11 +205,9 @@ class _HomeTimetableScreen extends State<HomeTimetableScreen> {
),
),
onTap: () {
widget.cb(
ActiveHomePage(HomePages.timetableMo), false);
widget.pageController(1);
},
),
/* TODO: 1.1.0
Card(
color: appStyle.colors.buttonSecondaryFill,
child: Padding( TO
@@ -338,11 +338,12 @@ class _HomeTimetableScreen extends State<HomeTimetableScreen> {
))),
TransparentPointer(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: ttWidgets,
)),
],
)
]);
]));
} else {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.35,

View File

@@ -21,10 +21,10 @@ class HomeTimetableMonthlyScreen extends StatefulWidget {
final AppInitialization data;
final UpdateNotifier updateNotifier;
final UpdateNotifier finishNotifier;
final void Function(ActiveHomePage, bool) cb;
final void Function(int) pageController;
const HomeTimetableMonthlyScreen(
this.data, this.updateNotifier, this.finishNotifier, this.cb,
this.data, this.updateNotifier, this.finishNotifier, this.pageController,
{super.key});
@override
@@ -141,7 +141,6 @@ class _HomeTimetableMonthlyScreen extends State<HomeTimetableMonthlyScreen> {
d.weekday == DateTime.sunday)
? appStyle.colors.errorText
: appStyle.colors.textTertiary)),
SizedBox(height: 12),
],
));
} else {
@@ -258,229 +257,239 @@ class _HomeTimetableMonthlyScreen extends State<HomeTimetableMonthlyScreen> {
}
}
return Stack(children: [
SizedBox(
width: MediaQuery.of(context).size.width,
height: 74 + 16,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
return Scaffold(
backgroundColor: appStyle.colors.background,
body: Stack(children: [
SizedBox(
width: MediaQuery.of(context).size.width,
height: 74 + 16,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Text(
widget.data.l10n.timetable,
style: appStyle.fonts.H_H2
.apply(color: appStyle.colors.textPrimary),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: Card(
color: appStyle.colors.buttonSecondaryFill,
child: Padding(
padding: const EdgeInsets.all(8),
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.tableSolid,
size: 26.0,
color: appStyle.colors.accent,
Text(
widget.data.l10n.timetable,
style: appStyle.fonts.H_H2
.apply(color: appStyle.colors.textPrimary),
),
Row(
children: [
GestureDetector(
child: Card(
color: appStyle.colors.buttonSecondaryFill,
child: Padding(
padding: const EdgeInsets.all(8),
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.tableSolid,
size: 26.0,
color: appStyle.colors.accent,
),
),
),
onTap: () {
widget.pageController(0);
},
),
Card(
color: appStyle.colors.buttonSecondaryFill,
child: Padding(
padding: const EdgeInsets.all(4),
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.plusLine,
size: 32.0,
color: appStyle.colors.accent,
),
),
),
),
onTap: () {
widget.cb(
ActiveHomePage(HomePages.timetable), false);
},
GestureDetector(
child: Card(
color: appStyle.colors.buttonSecondaryFill,
child: Padding(
padding: const EdgeInsets.all(8),
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.settingsCogSolid,
size: 26.0,
color: appStyle.colors.accent,
),
),
),
onTap: () {
showSettingsSheet(
context,
MediaQuery.of(context).size.height * 0.4,
widget.data,
widget.data.settings
.group("settings")
.subGroup("timetable_toast"));
},
),
],
),
Card(
color: appStyle.colors.buttonSecondaryFill,
child: Padding(
padding: const EdgeInsets.all(4),
],
),
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
child: SizedBox(
width: 24,
height: 24,
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.plusLine,
size: 32.0,
FirkaIconType.icons,
"dropdownLeft",
size: 24,
color: appStyle.colors.accent,
),
),
onTap: () async {
var newNow = DateTime(now!.year, now!.month - 1);
setState(() {
now = newNow;
lessons = null;
dates = null;
});
await initForMonth(newNow);
setState(() {
now = newNow;
});
},
),
Text(
now!
.format(widget.data.l10n, FormatMode.yyyymmmm)
.toLowerCase(),
style: appStyle.fonts.B_14R),
GestureDetector(
child: Card(
color: appStyle.colors.buttonSecondaryFill,
child: Padding(
padding: const EdgeInsets.all(8),
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.settingsCogSolid,
size: 26.0,
color: appStyle.colors.accent,
),
),
child: FirkaIconWidget(
FirkaIconType.icons,
"dropdownRight",
size: 24,
color: appStyle.colors.accent,
),
onTap: () {
showSettingsSheet(
context,
MediaQuery.of(context).size.height * 0.4,
widget.data,
widget.data.settings
.group("settings")
.subGroup("timetable_toast"));
onTap: () async {
var newNow = DateTime(now!.year, now!.month + 1);
setState(() {
now = newNow;
lessons = null;
dates = null;
});
await initForMonth(newNow);
setState(() {
now = newNow;
});
},
),
],
),
)
],
),
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
child: SizedBox(
width: 24,
height: 24,
child: FirkaIconWidget(
FirkaIconType.icons,
"dropdownLeft",
size: 24,
color: appStyle.colors.accent,
),
),
onTap: () async {
var newNow = DateTime(now!.year, now!.month - 1);
setState(() {
now = newNow;
lessons = null;
dates = null;
});
await initForMonth(newNow);
setState(() {
now = newNow;
});
},
),
Text(
now!
.format(widget.data.l10n, FormatMode.yyyymmmm)
.toLowerCase(),
style: appStyle.fonts.B_14R),
GestureDetector(
child: FirkaIconWidget(
FirkaIconType.icons,
"dropdownRight",
size: 24,
color: appStyle.colors.accent,
),
onTap: () async {
var newNow = DateTime(now!.year, now!.month + 1);
setState(() {
now = newNow;
lessons = null;
dates = null;
});
await initForMonth(newNow);
setState(() {
now = newNow;
});
},
),
],
)
],
),
),
),
TransparentPointer(
child: Padding(
padding: const EdgeInsets.only(top: 74 + 16 + 12),
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 1.45,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: StaggeredGrid.count(
crossAxisCount: 7,
children: ttDays,
),
)),
)),
TransparentPointer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height / 1.3,
),
SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(),
Row(
),
TransparentPointer(
child: Padding(
padding: const EdgeInsets.only(top: 74 + 16 + 12),
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 1.45,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_StatusToast(
FirkaIconWidget(FirkaIconType.majesticons,
Majesticon.clockSolid,
color: appStyle.colors.accent, size: 16),
lessons!
.where((lesson) =>
lesson.start.isAfter(currentMonthStart) &&
lesson.end.isBefore(currentMonthEnd))
.length,
activeFilter == ActiveFilter.lessonNo, () {
setState(() {
activeFilter = ActiveFilter.lessonNo;
});
}),
_StatusToast(
FirkaIconWidget(FirkaIconType.majesticons,
Majesticon.editPen4Solid,
color: appStyle.colors.accent, size: 16),
lessons!
.where((lesson) => tests!.any((test) =>
test.lessonNumber == lesson.lessonNumber &&
lesson.start
.isAfter(test.date.getMidnight()) &&
lesson.end.isBefore(test.date
.getMidnight()
.add(
Duration(hours: 23, minutes: 59)))))
.length,
activeFilter == ActiveFilter.tests, () {
setState(() {
activeFilter = ActiveFilter.tests;
});
}),
_StatusToast(
FirkaIconWidget(
FirkaIconType.majesticons, Majesticon.timerLine,
color: appStyle.colors.accent, size: 16),
lessons!
.where((lesson) =>
lesson.start.isAfter(currentMonthStart) &&
lesson.end.isBefore(currentMonthEnd) &&
lesson.studentPresence != null &&
lesson.studentPresence?.name !=
OmissionConsts.present)
.length,
activeFilter == ActiveFilter.omissions, () {
setState(() {
activeFilter = ActiveFilter.omissions;
});
}),
StaggeredGrid.count(
crossAxisCount: 7,
mainAxisSpacing: 8,
children: ttDays,
)
],
),
SizedBox()
],
),
)
],
),
),
]);
)),
)),
TransparentPointer(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height / 1.3,
),
SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(),
Row(
children: [
_StatusToast(
FirkaIconWidget(FirkaIconType.majesticons,
Majesticon.clockSolid,
color: appStyle.colors.accent, size: 16),
lessons!
.where((lesson) =>
lesson.start
.isAfter(currentMonthStart) &&
lesson.end.isBefore(currentMonthEnd))
.length,
activeFilter == ActiveFilter.lessonNo, () {
setState(() {
activeFilter = ActiveFilter.lessonNo;
});
}),
_StatusToast(
FirkaIconWidget(FirkaIconType.majesticons,
Majesticon.editPen4Solid,
color: appStyle.colors.accent, size: 16),
lessons!
.where((lesson) => tests!.any((test) =>
test.lessonNumber ==
lesson.lessonNumber &&
lesson.start
.isAfter(test.date.getMidnight()) &&
lesson.end.isBefore(test.date
.getMidnight()
.add(Duration(
hours: 23, minutes: 59)))))
.length,
activeFilter == ActiveFilter.tests, () {
setState(() {
activeFilter = ActiveFilter.tests;
});
}),
_StatusToast(
FirkaIconWidget(FirkaIconType.majesticons,
Majesticon.timerLine,
color: appStyle.colors.accent, size: 16),
lessons!
.where((lesson) =>
lesson.start
.isAfter(currentMonthStart) &&
lesson.end.isBefore(currentMonthEnd) &&
lesson.studentPresence != null &&
lesson.studentPresence?.name !=
OmissionConsts.present)
.length,
activeFilter == ActiveFilter.omissions, () {
setState(() {
activeFilter = ActiveFilter.omissions;
});
}),
],
),
SizedBox()
],
),
)
],
),
),
]));
} else {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.35,

View File

@@ -11,6 +11,7 @@ import 'package:firka/ui/model/style.dart';
import 'package:firka/ui/phone/pages/extras/main_wear_pair.dart';
import 'package:firka/ui/phone/pages/home/home_grades.dart';
import 'package:firka/ui/phone/pages/home/home_main.dart';
import 'package:firka/ui/phone/pages/home/home_subpage.dart';
import 'package:firka/ui/phone/pages/home/home_timetable_mo.dart';
import 'package:firka/ui/phone/screens/home/beta_screen.dart';
import 'package:firka/ui/phone/widgets/bottom_nav_icon.dart';
@@ -46,25 +47,10 @@ class HomeScreen extends StatefulWidget {
State<HomeScreen> createState() => _HomeScreenState();
}
enum HomePages { home, grades, timetable, timetableMo }
enum HomePage { home, grades, timetable }
enum ActiveToastType { fetching, error, reauth, none }
class ActiveHomePage {
final HomePages page;
final String? subPageUid;
ActiveHomePage(this.page, {this.subPageUid});
@override
int get hashCode => (page.hashCode ^ subPageUid.hashCode);
@override
bool operator ==(Object other) {
return (other is ActiveHomePage) && hashCode == other.hashCode;
}
}
bool _fetching = true;
bool _prefetched = false;
bool canPop = true;
@@ -72,8 +58,9 @@ bool canPop = true;
class _HomeScreenState extends State<HomeScreen> {
_HomeScreenState();
ActiveHomePage page = ActiveHomePage(HomePages.home);
List<ActiveHomePage> previousPages = List.empty(growable: true);
HomePage page = HomePage.home;
List<HomePage> previousPages = List.empty(growable: true);
final PageController _pageController = PageController();
Widget? toast;
bool pairingDone = false;
@@ -84,7 +71,7 @@ class _HomeScreenState extends State<HomeScreen> {
ActiveToastType activeToast = ActiveToastType.none;
void setPageCB(ActiveHomePage newPage, bool setPrev) {
void setPageCB(HomePage newPage, bool setPrev) {
if (_disposed) return;
setState(() {
if (setPrev) previousPages.add(page);
@@ -413,7 +400,7 @@ class _HomeScreenState extends State<HomeScreen> {
),
physics: ClampingScrollPhysics(),
child: PopScope(
canPop: canPop,
canPop: false,
child: Scaffold(
backgroundColor: appStyle.colors.background,
body: SafeArea(
@@ -424,16 +411,39 @@ class _HomeScreenState extends State<HomeScreen> {
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
HomeSubPage(
page,
setPageCB,
widget.data,
widget.updateNotifier,
widget.updateFinishedNotifier)
],
Expanded(
child: PageView(
controller: _pageController,
onPageChanged: (index) {
HapticFeedback.heavyImpact();
setState(() {
previousPages.add(page);
canPop = false;
page = HomePage.values[index];
});
},
children: [
HomeSubPage(
HomePage.home,
widget.data,
widget.updateNotifier,
widget.updateFinishedNotifier,
_pageController),
HomeSubPage(
HomePage.grades,
widget.data,
widget.updateNotifier,
widget.updateFinishedNotifier,
_pageController),
HomeSubPage(
HomePage.timetable,
widget.data,
widget.updateNotifier,
widget.updateFinishedNotifier,
_pageController),
],
),
),
Container(
decoration: BoxDecoration(
@@ -457,65 +467,58 @@ class _HomeScreenState extends State<HomeScreen> {
children: [
// Home Button
BottomNavIconWidget(() {
if (page.page != HomePages.home) {
HapticFeedback.lightImpact();
setState(() {
previousPages.add(page);
canPop = false;
page = ActiveHomePage(HomePages.home);
});
if (page != HomePage.home) {
_pageController.animateToPage(
HomePage.home.index,
duration: Duration(milliseconds: 175),
curve: Curves.easeInOut,
);
}
},
page.page == HomePages.home,
page.page == HomePages.home
page == HomePage.home,
page == HomePage.home
? Majesticon.homeSolid
: Majesticon.homeLine,
widget.data.l10n.home,
page.page == HomePages.home
page == HomePage.home
? appStyle.colors.accent
: appStyle.colors.secondary,
appStyle.colors.textPrimary),
// Grades Button
BottomNavIconWidget(() {
if (page.page != HomePages.grades) {
HapticFeedback.lightImpact();
setState(() {
previousPages.add(page);
canPop = false;
page = ActiveHomePage(HomePages.grades);
});
if (page != HomePage.grades) {
_pageController.animateToPage(
HomePage.grades.index,
duration: Duration(milliseconds: 175),
curve: Curves.easeInOut,
);
}
},
page.page == HomePages.grades,
page.page == HomePages.grades
page == HomePage.grades,
page == HomePage.grades
? Majesticon.bookmarkSolid
: Majesticon.bookmarkLine,
widget.data.l10n.grades,
page.page == HomePages.grades
page == HomePage.grades
? appStyle.colors.accent
: appStyle.colors.secondary,
appStyle.colors.textPrimary),
// Timetable Button
BottomNavIconWidget(() {
if (page.page != HomePages.timetable) {
HapticFeedback.lightImpact();
setState(() {
previousPages.add(page);
canPop = false;
page =
ActiveHomePage(HomePages.timetable);
});
if (page != HomePage.timetable) {
_pageController.animateToPage(
HomePage.timetable.index,
duration: Duration(milliseconds: 175),
curve: Curves.easeInOut,
);
}
},
page.page == HomePages.timetable,
page.page == HomePages.timetable
page == HomePage.timetable,
page == HomePage.timetable
? Majesticon.calendarSolid
: Majesticon.calendarLine,
widget.data.l10n.timetable,
page.page == HomePages.timetable
page == HomePage.timetable
? appStyle.colors.accent
: appStyle.colors.secondary,
appStyle.colors.textPrimary),
@@ -557,6 +560,7 @@ class _HomeScreenState extends State<HomeScreen> {
@override
void dispose() {
_pageController.dispose();
super.dispose();
widget.data.settingsUpdateNotifier.removeListener(settingsUpdateListener);
@@ -569,35 +573,31 @@ class _HomeScreenState extends State<HomeScreen> {
}
class HomeSubPage extends StatelessWidget {
final ActiveHomePage page;
final void Function(ActiveHomePage, bool) cb;
final HomePage page;
final AppInitialization data;
final UpdateNotifier _updateNotifier;
final UpdateNotifier _updateFinishNotifier;
final PageController _pageController;
const HomeSubPage(this.page, this.cb, this.data, this._updateNotifier,
this._updateFinishNotifier,
const HomeSubPage(this.page, this.data, this._updateNotifier,
this._updateFinishNotifier, this._pageController,
{super.key});
@override
Widget build(BuildContext context) {
switch (page.page) {
case HomePages.home:
switch (page) {
case HomePage.home:
return HomeMainScreen(data, _updateNotifier, _updateFinishNotifier);
case HomePages.grades:
if (page.subPageUid != null) {
return HomeGradesSubjectScreen(
data, _updateNotifier, _updateFinishNotifier, page.subPageUid!);
} else {
return HomeGradesScreen(
data, _updateNotifier, _updateFinishNotifier, cb);
}
case HomePages.timetable:
return HomeTimetableScreen(
data, _updateNotifier, _updateFinishNotifier, cb);
case HomePages.timetableMo:
return HomeTimetableMonthlyScreen(
data, _updateNotifier, _updateFinishNotifier, cb);
case HomePage.grades:
return PageWithSubPages([
(cb) => HomeGradesScreen(data, _updateNotifier, _updateFinishNotifier, cb),
(cb) => HomeGradesSubjectScreen(data, _updateNotifier, _updateFinishNotifier)
], pageIndex: 0);
case HomePage.timetable:
return PageWithSubPages([
(cb) => HomeTimetableScreen(data, _updateNotifier, _updateFinishNotifier, cb),
(cb) => HomeTimetableMonthlyScreen(data, _updateNotifier, _updateFinishNotifier, cb)
], pageIndex: 0);
}
}
}