Skip to content

Commit

Permalink
Refactor student homework logic (#1650)
Browse files Browse the repository at this point in the history
I made the code less complex and changed `List` to `IList` everywhere.
This is a step to using (parts of) the logic for parents and teachers.
  • Loading branch information
Jonas-Sander authored May 28, 2024
1 parent 7495cab commit d82db13
Show file tree
Hide file tree
Showing 73 changed files with 582 additions and 1,322 deletions.
5 changes: 1 addition & 4 deletions app/lib/homework/student/src/open_homework_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class OpenHomeworkList extends StatelessWidget {
Widget build(BuildContext context) {
final bloc = BlocProvider.of<HomeworkPageBloc>(context);

if (_nullOrEmpty(homeworkListView.sections)) return Container();
if (homeworkListView.sections.isEmpty) return Container();
return GlowingOverscrollColorChanger(
color: overscrollColor,
child: AnimatedStaggeredScrollView(
Expand Down Expand Up @@ -72,7 +72,4 @@ class OpenHomeworkList extends StatelessWidget {
),
);
}

bool _nullOrEmpty(List<HomeworkSectionView> homeworkSections) =>
homeworkSections.isEmpty;
}
5 changes: 1 addition & 4 deletions app/lib/homework/teacher/src/teacher_open_homework_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class TeacherOpenHomeworkList extends StatelessWidget {

@override
Widget build(BuildContext context) {
if (_nullOrEmpty(homeworkListView.sections)) return Container();
if (homeworkListView.sections.isEmpty) return Container();
return GlowingOverscrollColorChanger(
color: overscrollColor,
child: AnimatedStaggeredScrollView(
Expand All @@ -48,7 +48,4 @@ class TeacherOpenHomeworkList extends StatelessWidget {
],
));
}

bool _nullOrEmpty(List<TeacherHomeworkSectionView> homeworkSections) =>
homeworkSections.isEmpty;
}
74 changes: 43 additions & 31 deletions app/test/homework/teacher/teacher_homework_page_widget_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:analytics/null_analytics_backend.dart';
import 'package:bloc_provider/bloc_provider.dart';
import 'package:bloc_provider/multi_bloc_provider.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart' as flutter show Color;
import 'package:flutter/material.dart' hide Color;
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -161,16 +162,22 @@ void main() {
bloc: homeworkPageBloc, initialTab: HomeworkTab.open);

homeworkPageBloc.emitNewState(Success(
TeacherOpenHomeworkListView([
TeacherHomeworkSectionView('Section 1', [
randomHomeworkViewWith(title: 'HW in first Section'),
]),
TeacherHomeworkSectionView('Section 2', [
randomHomeworkViewWith(title: 'HW in second Section'),
]),
], sorting: HomeworkSort.subjectSmallestDateAndTitleSort),
TeacherOpenHomeworkListView(
IList([
TeacherHomeworkSectionView(
'Section 1',
IListConst([
randomHomeworkViewWith(title: 'HW in first Section'),
])),
TeacherHomeworkSectionView(
'Section 2',
IList([
randomHomeworkViewWith(title: 'HW in second Section'),
])),
]),
sorting: HomeworkSort.subjectSmallestDateAndTitleSort),
TeacherArchivedHomeworkListView(
[],
const IListConst([]),
loadedAllArchivedHomeworks: true,
),
));
Expand Down Expand Up @@ -242,7 +249,7 @@ void main() {
await pumpHomeworkPage(tester,
bloc: homeworkPageBloc, initialTab: HomeworkTab.archived);

final firstHomeworkBatch = generateRandomHomeworks(count: 30);
final firstHomeworkBatch = generateRandomHomeworks(count: 30).toIList();

homeworkPageBloc.emitNewState(
Success(
Expand Down Expand Up @@ -274,10 +281,8 @@ void main() {
reason:
"After scrolling down to near the last loaded homework the bloc should've received the event to load the next archived homeworks (as there are more to load in this test).");

final allLoadedHomeworks = [
...firstHomeworkBatch,
...generateRandomHomeworks(count: 10)
];
final allLoadedHomeworks =
IList([...firstHomeworkBatch, ...generateRandomHomeworks(count: 10)]);

homeworkPageBloc.emitNewState(
Success(
Expand Down Expand Up @@ -362,11 +367,13 @@ void main() {
bloc: homeworkPageBloc, initialTab: HomeworkTab.open);

homeworkPageBloc.emitNewState(Success(
TeacherOpenHomeworkListView([
TeacherHomeworkSectionView('Section 1', views),
], sorting: HomeworkSort.subjectSmallestDateAndTitleSort),
TeacherOpenHomeworkListView(
IList([
TeacherHomeworkSectionView('Section 1', views.toIList()),
]),
sorting: HomeworkSort.subjectSmallestDateAndTitleSort),
TeacherArchivedHomeworkListView(
[],
const IListConst([]),
loadedAllArchivedHomeworks: true,
),
));
Expand Down Expand Up @@ -416,7 +423,7 @@ void main() {
_noOpenHomeworks,
TeacherArchivedHomeworkListView(
// No homeworks loaded already
[],
const IListConst([]),
// but there are homeworks to load
loadedAllArchivedHomeworks: false,
),
Expand Down Expand Up @@ -489,32 +496,37 @@ TeacherHomeworkView randomHomeworkViewWith({

Success _openHomeworksWith(HomeworkSort sort) {
return Success(
TeacherOpenHomeworkListView([
TeacherHomeworkSectionView('Heute', [
randomHomeworkViewWith(title: 'S. 32'),
randomHomeworkViewWith(title: 'S. 34'),
randomHomeworkViewWith(title: 'S. 31'),
])
], sorting: sort),
TeacherOpenHomeworkListView(
IList([
TeacherHomeworkSectionView(
'Heute',
IList([
randomHomeworkViewWith(title: 'S. 32'),
randomHomeworkViewWith(title: 'S. 34'),
randomHomeworkViewWith(title: 'S. 31'),
])),
]),
sorting: sort),
_noArchivedHomeworks,
);
}

final _noHomeworks = Success(
TeacherOpenHomeworkListView(
[],
const IListConst([]),
sorting: HomeworkSort.smallestDateSubjectAndTitle,
),
TeacherArchivedHomeworkListView(
[],
const IListConst([]),
loadedAllArchivedHomeworks: true,
),
);

final _noOpenHomeworks = TeacherOpenHomeworkListView([],
final _noOpenHomeworks = TeacherOpenHomeworkListView(const IListConst([]),
sorting: HomeworkSort.smallestDateSubjectAndTitle);
final _noArchivedHomeworks =
TeacherArchivedHomeworkListView([], loadedAllArchivedHomeworks: true);
final _noArchivedHomeworks = TeacherArchivedHomeworkListView(
const IListConst([]),
loadedAllArchivedHomeworks: true);

Future<void> _pumpHomeworkPageWithNoHomeworks(
WidgetTester tester, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:hausaufgabenheft_logik/hausaufgabenheft_logik.dart';
import 'homework_transformation.dart';

Expand All @@ -24,7 +25,7 @@ class FirestoreHomeworkDataSource extends HomeworkDataSource {
this.createLazyLoadingController, this._homeworkTransformer);

@override
Stream<List<HomeworkReadModel>> get openHomeworks {
Stream<IList<HomeworkReadModel>> get openHomeworks {
return _homeworkCollection
.where("assignedUserArrays.openStudentUids", arrayContains: uid)
.snapshots()
Expand All @@ -37,12 +38,12 @@ class FirestoreHomeworkDataSource extends HomeworkDataSource {
return homework;
}

Future<List<HomeworkId>> getCurrentOpenOverdueHomeworkIds() async {
Future<IList<HomeworkId>> getCurrentOpenOverdueHomeworkIds() async {
final open = await openHomeworks.first;
final overdue = open
.where((homeworks) => homeworks.isOverdueRelativeTo(Date.now()))
.toList();
final overdueIds = overdue.map((hws) => hws.id).toList();
final overdueIds = overdue.map((hws) => hws.id).toIList();
return overdueIds;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// SPDX-License-Identifier: EUPL-1.2

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:hausaufgabenheft_logik/hausaufgabenheft_logik.dart';

import 'homework_transformation.dart';
Expand All @@ -22,7 +23,7 @@ class FirestoreRealtimeCompletedHomeworkLoader
this._homeworkCollection, this._userId, this._homeworkTransformer);

@override
Stream<List<HomeworkReadModel>> loadMostRecentHomeworks(
Stream<IList<HomeworkReadModel>> loadMostRecentHomeworks(
int numberOfHomeworks) {
return _homeworkCollection
.where('assignedUserArrays.completedStudentUids',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'dart:developer';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:hausaufgabenheft_logik/color.dart';
import 'package:hausaufgabenheft_logik/hausaufgabenheft_logik.dart';

Expand All @@ -19,25 +20,25 @@ import 'homework_dto.dart';
typedef CourseColorRetriever = FutureOr<int> Function(String courseId);

class HomeworkTransformer extends StreamTransformerBase<
QuerySnapshot<Map<String, dynamic>>, List<HomeworkReadModel>> {
QuerySnapshot<Map<String, dynamic>>, IList<HomeworkReadModel>> {
final String userId;
final CourseColorRetriever getCourseColorHexValue;

HomeworkTransformer(this.userId, {required this.getCourseColorHexValue});

@override
Stream<List<HomeworkReadModel>> bind(Stream<QuerySnapshot> stream) {
Stream<IList<HomeworkReadModel>> bind(Stream<QuerySnapshot> stream) {
return stream.asyncMap(querySnapshotToHomeworks);
}

Future<List<HomeworkReadModel>> querySnapshotToHomeworks(
Future<IList<HomeworkReadModel>> querySnapshotToHomeworks(
QuerySnapshot querySnapshot) async {
final homeworks = <HomeworkReadModel>[];
IList<HomeworkReadModel> homeworks = const IListConst([]);
for (final document in querySnapshot.docs) {
final homework = await tryToConvertToHomework(document, userId,
getCourseColorHexValue: getCourseColorHexValue);
if (homework != null) {
homeworks.add(homework);
homeworks = homeworks.add(homework);
}
}
return homeworks;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
//
// SPDX-License-Identifier: EUPL-1.2

import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:hausaufgabenheft_logik/hausaufgabenheft_logik.dart';

abstract class RealtimeCompletedHomeworkLoader {
Stream<List<HomeworkReadModel>> loadMostRecentHomeworks(
Stream<IList<HomeworkReadModel>> loadMostRecentHomeworks(
int numberOfHomeworks);
}
8 changes: 8 additions & 0 deletions lib/firebase_hausaufgabenheft_logik/pubspec.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/firebase_hausaufgabenheft_logik/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dependencies:
time:
path: ../time
cloud_firestore: ^4.17.2
fast_immutable_collections: ^9.1.5
flutter:
sdk: flutter
clock: ^1.1.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
//
// SPDX-License-Identifier: EUPL-1.2

import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:firebase_hausaufgabenheft_logik/src/realtime_completed_homework_loader.dart';
import 'package:hausaufgabenheft_logik/hausaufgabenheft_logik.dart';
import 'package:rxdart/subjects.dart';

class InMemoryHomeworkLoader extends RealtimeCompletedHomeworkLoader {
final BehaviorSubject<List<HomeworkReadModel>> _completedHomeworksSubject;
final BehaviorSubject<IList<HomeworkReadModel>> _completedHomeworksSubject;

InMemoryHomeworkLoader(this._completedHomeworksSubject);

@override
Stream<List<HomeworkReadModel>> loadMostRecentHomeworks(
Stream<IList<HomeworkReadModel>> loadMostRecentHomeworks(
int numberOfHomeworks) {
return _completedHomeworksSubject.map((homeworks) {
if (homeworks.length < numberOfHomeworks) return homeworks;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'dart:async';

import 'package:clock/clock.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:firebase_hausaufgabenheft_logik/src/realtime_updating_lazy_loading_controller.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hausaufgabenheft_logik/hausaufgabenheft_logik.dart';
Expand All @@ -22,14 +23,14 @@ class ReportingInMemoryHomeworkLoader extends InMemoryHomeworkLoader {

bool wasInvoked = false;
@override
Stream<List<HomeworkReadModel>> loadMostRecentHomeworks(
Stream<IList<HomeworkReadModel>> loadMostRecentHomeworks(
int numberOfHomeworks) {
wasInvoked = true;
return super.loadMostRecentHomeworks(numberOfHomeworks);
}
}

List<HomeworkReadModel> listOfHomeworksWithLength(int length) => List.generate(
IList<HomeworkReadModel> listOfHomeworksWithLength(int length) => List.generate(
length,
(index) => HomeworkReadModel(
id: HomeworkId("$index"),
Expand All @@ -38,29 +39,29 @@ List<HomeworkReadModel> listOfHomeworksWithLength(int length) => List.generate(
subject: Subject("Mathe", abbreviation: 'Ma'),
title: const Title("ABC"),
withSubmissions: false),
);
).toIList();

Stream<List<HomeworkReadModel>> getHomeworkResultsAsStream(
Stream<IList<HomeworkReadModel>> getHomeworkResultsAsStream(
Stream<LazyLoadingResult> resultStream) =>
resultStream.map((res) => res.homeworks);

void main() {
group('LazyLoadingController', () {
late ReportingInMemoryHomeworkLoader homeworkLoader;
late rx.BehaviorSubject<List<HomeworkReadModel>> homeworkSubject;
late rx.BehaviorSubject<IList<HomeworkReadModel>> homeworkSubject;

void addToDataSource(List<HomeworkReadModel> homeworks) {
final hws = homeworkSubject.valueOrNull;
void addToDataSource(IList<HomeworkReadModel> homeworks) {
var hws = homeworkSubject.valueOrNull;
if (hws != null) {
hws.addAll(homeworks);
hws = hws.addAll(homeworks);
homeworkSubject.add(hws);
} else {
homeworkSubject.add(homeworks);
}
}

setUp(() {
homeworkSubject = rx.BehaviorSubject<List<HomeworkReadModel>>();
homeworkSubject = rx.BehaviorSubject<IList<HomeworkReadModel>>();
homeworkLoader = ReportingInMemoryHomeworkLoader(homeworkSubject);
});

Expand Down
Loading

0 comments on commit d82db13

Please sign in to comment.