Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalize onNullContent #1406

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 50 additions & 61 deletions packages/uni_app/lib/view/lazy_consumer.dart
Original file line number Diff line number Diff line change
@@ -1,40 +1,18 @@
import 'dart:async';
import 'dart:io';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:shimmer/shimmer.dart';
import 'package:uni/generated/l10n.dart';
import 'package:uni/model/providers/startup/profile_provider.dart';
import 'package:uni/model/providers/startup/session_provider.dart';
import 'package:uni/model/providers/state_provider_notifier.dart';
import 'package:uni/model/request_status.dart';
import 'package:uni/view/bug_report/bug_report.dart';

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restore the imports to ensure that the code compiles and works as intended.

/// Wrapper around Consumer that ensures that the provider is initialized,
/// meaning that it has loaded its data from storage and/or remote.
/// The provider will not reload its data if it has already been loaded before.
/// If the provider depends on the session, it will ensure that SessionProvider
/// and ProfileProvider are initialized before initializing itself.
/// This widget also falls back to loading or error widgets if
/// the provider data is not ready or has thrown an error, respectively.
class LazyConsumer<T1 extends StateProviderNotifier<T2>, T2>
extends StatelessWidget {
class LazyConsumer<T1 extends StateProviderNotifier<T2>, T2> extends StatelessWidget {
const LazyConsumer({
required this.builder,
required this.hasContent,
required this.onNullContent,
required this.onNullContentText,
this.optionalImage,
this.contentLoadingWidget,
this.mapper,
super.key,
});

final Widget Function(BuildContext, T2) builder;
final bool Function(T2) hasContent;
final Widget onNullContent;
final String onNullContentText;
final Widget? optionalImage;
final Widget? contentLoadingWidget;
final T2 Function(T2)? mapper;

Expand All @@ -47,32 +25,25 @@ class LazyConsumer<T1 extends StateProviderNotifier<T2>, T2>
try {
provider = Provider.of<T1>(context, listen: false);
} catch (_) {
// The provider was not found. This should only happen in tests.
Logger().e('LazyConsumer: ${T1.runtimeType} not found');
return;
}

// If the provider fetchers depend on the session, make sure that
// SessionProvider and ProfileProvider are initialized
Future<void>? sessionFuture;
try {
sessionFuture = provider.dependsOnSession
? Provider.of<SessionProvider>(context, listen: false)
.ensureInitialized(context)
.then((_) async {
if (context.mounted) {
await Provider.of<ProfileProvider>(context, listen: false)
.ensureInitialized(context);
}
})
.ensureInitialized(context)
.then((_) async {
if (context.mounted) {
await Provider.of<ProfileProvider>(context, listen: false)
.ensureInitialized(context);
}
})
: Future(() {});
} catch (err, st) {
// In tests, it is ok to not find the startup providers:
// all provider data should be mocked by the test itself.
if (!Platform.environment.containsKey('FLUTTER_TEST')) {
Logger().e(
'Failed to initialize startup providers: $err',
);
Logger().e('Failed to initialize startup providers: $err');
await Sentry.captureException(err, stackTrace: st);
}
}
Expand Down Expand Up @@ -108,28 +79,48 @@ class LazyConsumer<T1 extends StateProviderNotifier<T2>, T2>
return showContent
? builder(context, mappedState)
: Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: onNullContent,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: onNullContent(context),
),
);
}

Widget onNullContent(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
onNullContentText,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Theme.of(context).textTheme.bodyText1?.color,
),
);
),
),
if (optionalImage != null) optionalImage!,
],
);
}

Widget loadingWidget(BuildContext context) {
return contentLoadingWidget == null
? const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: CircularProgressIndicator(),
),
)
child: Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: CircularProgressIndicator(),
),
)
: Center(
child: Shimmer.fromColors(
baseColor: Theme.of(context).highlightColor,
highlightColor: Theme.of(context).colorScheme.onPrimary,
child: contentLoadingWidget!,
),
);
child: Shimmer.fromColors(
baseColor: Theme.of(context).highlightColor,
highlightColor: Theme.of(context).colorScheme.onPrimary,
child: contentLoadingWidget!,
),
);
}

Widget requestFailedMessage() {
Expand Down Expand Up @@ -172,9 +163,7 @@ class LazyConsumer<T1 extends StateProviderNotifier<T2>, T2>
.forceRefresh(context),
child: Text(S.of(context).try_again),
),
const SizedBox(
width: 10,
),
const SizedBox(width: 10),
OutlinedButton(
onPressed: () => Navigator.push(
context,
Expand All @@ -189,6 +178,6 @@ class LazyConsumer<T1 extends StateProviderNotifier<T2>, T2>
],
);
},
);
)
}
}
Loading