From 9d145da9bb3a404ed86843e1d9388ef8a06cdcd0 Mon Sep 17 00:00:00 2001 From: Bruno Mendes Date: Thu, 28 Sep 2023 20:39:33 +0100 Subject: [PATCH] Improve course units loading behavior --- .../pages_layouts/general/general.dart | 42 ++++++++++- .../course_unit_info/course_unit_info.dart | 73 ++++++++----------- uni/lib/view/lazy_consumer.dart | 4 +- 3 files changed, 70 insertions(+), 49 deletions(-) diff --git a/uni/lib/view/common_widgets/pages_layouts/general/general.dart b/uni/lib/view/common_widgets/pages_layouts/general/general.dart index ef5753178..116f830be 100644 --- a/uni/lib/view/common_widgets/pages_layouts/general/general.dart +++ b/uni/lib/view/common_widgets/pages_layouts/general/general.dart @@ -3,7 +3,9 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:logger/logger.dart'; import 'package:provider/provider.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:uni/model/providers/startup/profile_provider.dart'; import 'package:uni/model/providers/startup/session_provider.dart'; import 'package:uni/utils/drawer_items.dart'; @@ -13,6 +15,8 @@ import 'package:uni/view/profile/profile.dart'; /// Page with a hamburger menu and the user profile picture abstract class GeneralPageViewState extends State { final double borderMargin = 18; + bool _loadedOnce = false; + bool _loading = true; Future onRefresh(BuildContext context); @@ -20,8 +24,42 @@ abstract class GeneralPageViewState extends State { @override Widget build(BuildContext context) { - WidgetsBinding.instance.addPostFrameCallback((_) => onLoad(context)); - return getScaffold(context, getBody(context)); + WidgetsBinding.instance.addPostFrameCallback((_) async { + if (_loadedOnce) { + return; + } + _loadedOnce = true; + setState(() { + _loading = true; + }); + + try { + await onLoad(context); + } catch (e, stackTrace) { + Logger().e('Failed to load page info: $e\n$stackTrace'); + await Sentry.captureException(e, stackTrace: stackTrace); + } + + setState(() { + _loading = false; + }); + }); + + return getScaffold( + context, + _loading + ? const Flex( + direction: Axis.vertical, + children: [ + Expanded( + child: Center( + child: CircularProgressIndicator(), + ), + ) + ], + ) + : getBody(context), + ); } Widget getBody(BuildContext context) { diff --git a/uni/lib/view/course_unit_info/course_unit_info.dart b/uni/lib/view/course_unit_info/course_unit_info.dart index ade00b29d..dd858d9dd 100644 --- a/uni/lib/view/course_unit_info/course_unit_info.dart +++ b/uni/lib/view/course_unit_info/course_unit_info.dart @@ -6,13 +6,12 @@ import 'package:uni/model/providers/lazy/course_units_info_provider.dart'; import 'package:uni/model/providers/startup/session_provider.dart'; import 'package:uni/view/common_widgets/page_title.dart'; import 'package:uni/view/common_widgets/pages_layouts/secondary/secondary.dart'; -import 'package:uni/view/common_widgets/request_dependent_widget_builder.dart'; import 'package:uni/view/course_unit_info/widgets/course_unit_classes.dart'; import 'package:uni/view/course_unit_info/widgets/course_unit_sheet.dart'; -import 'package:uni/view/lazy_consumer.dart'; class CourseUnitDetailPageView extends StatefulWidget { const CourseUnitDetailPageView(this.courseUnit, {super.key}); + final CourseUnit courseUnit; @override @@ -91,50 +90,36 @@ class CourseUnitDetailPageViewState } Widget _courseUnitSheetView(BuildContext context) { - return LazyConsumer( - builder: (context, courseUnitsInfoProvider) { - return RequestDependentWidgetBuilder( - onNullContent: Center( - child: Text( - S.of(context).no_info, - textAlign: TextAlign.center, - ), - ), - status: courseUnitsInfoProvider.status, - builder: () => CourseUnitSheetView( - courseUnitsInfoProvider.courseUnitsSheets[widget.courseUnit]!, - ), - hasContentPredicate: - courseUnitsInfoProvider.courseUnitsSheets[widget.courseUnit] != - null && - courseUnitsInfoProvider.courseUnitsSheets[widget.courseUnit]! - .sections.isNotEmpty, - ); - }, - ); + final sheet = context + .read() + .courseUnitsSheets[widget.courseUnit]; + + if (sheet == null || sheet.sections.isEmpty) { + return Center( + child: Text( + S.of(context).no_info, + textAlign: TextAlign.center, + ), + ); + } + + return CourseUnitSheetView(sheet); } Widget _courseUnitClassesView(BuildContext context) { - return LazyConsumer( - builder: (context, courseUnitsInfoProvider) { - return RequestDependentWidgetBuilder( - onNullContent: Center( - child: Text( - S.of(context).no_class, - textAlign: TextAlign.center, - ), - ), - status: courseUnitsInfoProvider.status, - builder: () => CourseUnitClassesView( - courseUnitsInfoProvider.courseUnitsClasses[widget.courseUnit]!, - ), - hasContentPredicate: - courseUnitsInfoProvider.courseUnitsClasses[widget.courseUnit] != - null && - courseUnitsInfoProvider - .courseUnitsClasses[widget.courseUnit]!.isNotEmpty, - ); - }, - ); + final classes = context + .read() + .courseUnitsClasses[widget.courseUnit]; + + if (classes == null || classes.isEmpty) { + return Center( + child: Text( + S.of(context).no_class, + textAlign: TextAlign.center, + ), + ); + } + + return CourseUnitClassesView(classes); } } diff --git a/uni/lib/view/lazy_consumer.dart b/uni/lib/view/lazy_consumer.dart index 49b19d748..ccb2b0305 100644 --- a/uni/lib/view/lazy_consumer.dart +++ b/uni/lib/view/lazy_consumer.dart @@ -69,9 +69,7 @@ class LazyConsumer extends StatelessWidget { // Finally, complete provider initialization if (context.mounted) { - // This will fail if the session initialization failed. - // That is the expected behavior. - await sessionFuture!.then((_) async { + await sessionFuture?.then((_) async { await provider!.ensureInitializedFromRemote(context); }); }