diff --git a/lib/core/providers/classes.dart b/lib/core/providers/classes.dart index 864571d78..715cb9d2c 100644 --- a/lib/core/providers/classes.dart +++ b/lib/core/providers/classes.dart @@ -163,7 +163,6 @@ class ClassScheduleDataProvider extends ChangeNotifier { _isLoading = false; notifyListeners(); } - for (ClassData classData in enrolledCourses) { for (SectionData sectionData in classData.sectionData!) { /// copy over info from [ClassData] object and put into [SectionData] object @@ -193,11 +192,9 @@ class ClassScheduleDataProvider extends ChangeNotifier { for (List listOfClasses in _enrolledClasses!.values.toList()) { listOfClasses.sort((a, b) => _compare(a, b)); } - for (List listOfFinals in _finals!.values.toList()) { listOfFinals.sort((a, b) => _compare(a, b)); } - for (List listOfMidterms in _midterms!.values.toList()) { listOfMidterms.sort((a, b) => _compare(a, b)); listOfMidterms.sort((a, b) => _compareMidterms(a, b)); @@ -267,29 +264,40 @@ class ClassScheduleDataProvider extends ChangeNotifier { } List get upcomingCourses { - /// get weekday and return [List] associated with current weekday - List listToReturn = []; - String today = DateFormat('EEEE') - .format(DateTime.now()) - .toString() - .toUpperCase() - .substring(0, 2); - nextDayWithClass = DateFormat('EEEE').format(DateTime.now()).toString(); - - /// if no classes are scheduled for today then find the next day with classes - int daysToAdd = 1; - while (_enrolledClasses![today]!.isEmpty) { - today = DateFormat('EEEE') - .format(DateTime.now().add(Duration(days: daysToAdd))) + try { + /// get weekday and return [List] associated with current weekday + List listToReturn = []; + String today = DateFormat('EEEE') + .format(DateTime.now()) .toString() .toUpperCase() .substring(0, 2); - nextDayWithClass = DateFormat('EEEE') - .format(DateTime.now().add(Duration(days: daysToAdd))); - daysToAdd += 1; + nextDayWithClass = DateFormat('EEEE').format(DateTime.now()).toString(); + + /// if no classes are scheduled for today then find the next day with classes + int daysToAdd = 1; + + while (_enrolledClasses![today]!.isEmpty && daysToAdd <= 7) { + today = DateFormat('EEEE') + .format(DateTime.now().add(Duration(days: daysToAdd))) + .toString() + .toUpperCase() + .substring(0, 2); + nextDayWithClass = DateFormat('EEEE') + .format(DateTime.now().add(Duration(days: daysToAdd))); + daysToAdd += 1; + } + + if (_enrolledClasses![today]!.isNotEmpty) { + listToReturn.addAll(_enrolledClasses![today]!); + } else { + listToReturn.addAll([]); + } + return listToReturn; + } catch (err) { + print(err); + return []; } - listToReturn.addAll(_enrolledClasses![today]!); - return listToReturn; } set userDataProvider(UserDataProvider value) { diff --git a/lib/ui/classes/classes_card.dart b/lib/ui/classes/classes_card.dart index 82014d70f..a79ee2551 100644 --- a/lib/ui/classes/classes_card.dart +++ b/lib/ui/classes/classes_card.dart @@ -7,6 +7,7 @@ import 'package:campus_mobile_experimental/ui/classes/upcoming_classes.dart'; import 'package:campus_mobile_experimental/ui/common/card_container.dart'; import 'package:campus_mobile_experimental/ui/common/last_updated_widget.dart'; import 'package:campus_mobile_experimental/ui/common/time_range_widget.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -59,48 +60,66 @@ class ClassScheduleCard extends StatelessWidget { Widget buildClassScheduleCard(List courseData, int selectedCourse, DateTime? lastUpdated, String nextDayWithClasses) { - return Padding( - padding: const EdgeInsets.only(left: 4.0, top: 4.0), - child: Row( - children: [ - Flexible( - flex: 5, - child: Padding( - padding: const EdgeInsets.only(left: 8.0), - child: IntrinsicHeight( - child: Column( - children: [ - buildWeekdayText(nextDayWithClasses), - buildClassTitle(courseData[selectedCourse].subjectCode! + - ' ' + - courseData[selectedCourse].courseCode!), - buildClassType(courseData[selectedCourse].meetingType!), - buildTimeRow(courseData[selectedCourse].time), - buildLocationRow(courseData[selectedCourse].building! + - ' ' + - courseData[selectedCourse].room!), - buildGradeEvaluationRow( - courseData[selectedCourse].gradeOption), - Flexible( - flex: 2, - child: Padding( - padding: const EdgeInsets.only(left: 4.0, top: 24.0), - child: LastUpdatedWidget(time: lastUpdated), + try { + return Padding( + padding: const EdgeInsets.only(left: 4.0, top: 4.0), + child: Row( + children: [ + Flexible( + flex: 5, + child: Padding( + padding: const EdgeInsets.only(left: 8.0), + child: IntrinsicHeight( + child: Column( + children: [ + buildWeekdayText(nextDayWithClasses), + buildClassTitle(courseData[selectedCourse].subjectCode! + + ' ' + + courseData[selectedCourse].courseCode!), + buildClassType(courseData[selectedCourse].meetingType!), + buildTimeRow(courseData[selectedCourse].time), + buildLocationRow(courseData[selectedCourse].building! + + ' ' + + courseData[selectedCourse].room!), + buildGradeEvaluationRow( + courseData[selectedCourse].gradeOption), + Flexible( + flex: 2, + child: Padding( + padding: const EdgeInsets.only(left: 4.0, top: 24.0), + child: LastUpdatedWidget(time: lastUpdated), + ), ), - ), - ], - crossAxisAlignment: CrossAxisAlignment.start, + ], + crossAxisAlignment: CrossAxisAlignment.start, + ), ), ), ), + Flexible( + flex: 2, + child: UpcomingCoursesList(), + ), + ], + ), + ); + } catch (e) { + FirebaseCrashlytics.instance.recordError( + e, StackTrace.fromString(e.toString()), + reason: "Classes Card: Failed to build card content.", fatal: false); + return Container( + width: double.infinity, + child: Center( + child: Padding( + padding: EdgeInsets.only(top: 32, bottom: 48), + child: Container( + child: Text( + "Your classes could not be displayed.\n\nIf the problem persists contact mobile@ucsd.edu"), + ), ), - Flexible( - flex: 2, - child: UpcomingCoursesList(), - ), - ], - ), - ); + ), + ); + } } Widget buildWeekdayText(String nextDayWithClasses) { diff --git a/lib/ui/common/card_container.dart b/lib/ui/common/card_container.dart index b04852a37..0b8789717 100644 --- a/lib/ui/common/card_container.dart +++ b/lib/ui/common/card_container.dart @@ -83,13 +83,26 @@ class CardContainer extends StatelessWidget { child: Text('An error occurred, please try again.'), ); } else if (titleText == 'Finals') { - // TODO: Resolve alignment issues on cards without action buttons + var customErrorText = ''; + if (errorText!.contains('Exception')) { + customErrorText = + 'Your finals could not be displayed.\n\nIf the problem persists contact mobile@ucsd.edu'; + } else { + customErrorText = 'No finals found.'; + } return Padding( padding: const EdgeInsets.only(bottom: 42.0), - child: Text('No finals found.'), + child: Text(customErrorText), ); } else if (titleText == 'Classes') { - return Text('No classes found.'); + var customErrorText = ''; + if (errorText!.contains('Exception')) { + customErrorText = + 'Your classes could not be displayed.\n\nIf the problem persists contact mobile@ucsd.edu'; + } else { + customErrorText = 'No finals found.'; + } + return Text(customErrorText); } else { return Text('An error occurred, please try again.'); } diff --git a/lib/ui/finals/finals_card.dart b/lib/ui/finals/finals_card.dart index c653ca40b..1fc5905a3 100644 --- a/lib/ui/finals/finals_card.dart +++ b/lib/ui/finals/finals_card.dart @@ -5,6 +5,7 @@ import 'package:campus_mobile_experimental/core/providers/classes.dart'; import 'package:campus_mobile_experimental/ui/common/card_container.dart'; import 'package:campus_mobile_experimental/ui/common/last_updated_widget.dart'; import 'package:campus_mobile_experimental/ui/common/time_range_widget.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -62,36 +63,54 @@ class FinalsCard extends StatelessWidget { Widget buildFinalsCard(Map> finalsData, DateTime? lastUpdated, String? nextDayWithClasses, BuildContext context) { - List listToReturn = []; - finalsData.forEach((key, value) { - for (SectionData data in value) { - listToReturn.add(ListTile( - title: buildWeekdayText(abbrevToFullWeekday(data.days)), - subtitle: Column( - children: [ - buildClassTitle(data.subjectCode! + ' ' + data.courseCode!), - buildTimeRow(data.time), - buildClassTitle(data.courseTitle!), - buildLocationRow(data.building! + ' ' + data.room!), - ], - crossAxisAlignment: CrossAxisAlignment.start, + try { + List listToReturn = []; + finalsData.forEach((key, value) { + for (SectionData data in value) { + listToReturn.add(ListTile( + title: buildWeekdayText(abbrevToFullWeekday(data.days)), + subtitle: Column( + children: [ + buildClassTitle(data.subjectCode! + ' ' + data.courseCode!), + buildTimeRow(data.time), + buildClassTitle(data.courseTitle!), + buildLocationRow(data.building! + ' ' + data.room!), + ], + crossAxisAlignment: CrossAxisAlignment.start, + ), + )); + } + }); + listToReturn = + ListTile.divideTiles(tiles: listToReturn, context: context).toList(); + listToReturn.add( + Padding( + padding: const EdgeInsets.only(left: 16.0, bottom: 8.0), + child: LastUpdatedWidget(time: lastUpdated), + ), + ); + return ListView( + physics: NeverScrollableScrollPhysics(), + children: listToReturn, + shrinkWrap: true, + ); + } catch (e) { + FirebaseCrashlytics.instance.recordError( + e, StackTrace.fromString(e.toString()), + reason: "Finals Card: Failed to build card content.", fatal: false); + return Container( + width: double.infinity, + child: Center( + child: Padding( + padding: EdgeInsets.only(top: 32, bottom: 48), + child: Container( + child: Text( + "Your finals could not be displayed.\n\nIf the problem persists contact mobile@ucsd.edu"), + ), ), - )); - } - }); - listToReturn = - ListTile.divideTiles(tiles: listToReturn, context: context).toList(); - listToReturn.add( - Padding( - padding: const EdgeInsets.only(left: 16.0, bottom: 8.0), - child: LastUpdatedWidget(time: lastUpdated), - ), - ); - return ListView( - physics: NeverScrollableScrollPhysics(), - children: listToReturn, - shrinkWrap: true, - ); + ), + ); + } } Widget buildClassTitle(String title) {