`veggieseasons`: Migrate to null safety (#922)

pull/929/head
Brett Morgan 4 years ago committed by GitHub
parent 994cdb4afa
commit ac2bef7d83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,8 +15,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d shared_preferences: 5033afbb22d372e15aff8ff766df9021b845f273
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
COCOAPODS: 1.10.1 COCOAPODS: 1.11.0

@ -26,22 +26,22 @@ class AppState extends ChangeNotifier {
return _veggies.where((v) => !v.seasons.contains(currentSeason)).toList(); return _veggies.where((v) => !v.seasons.contains(currentSeason)).toList();
} }
Veggie getVeggie(int id) => _veggies.singleWhere((v) => v.id == id); Veggie getVeggie(int? id) => _veggies.singleWhere((v) => v.id == id);
List<Veggie> searchVeggies(String terms) => _veggies List<Veggie> searchVeggies(String? terms) => _veggies
.where((v) => v.name.toLowerCase().contains(terms.toLowerCase())) .where((v) => v.name.toLowerCase().contains(terms!.toLowerCase()))
.toList(); .toList();
void setFavorite(int id, bool isFavorite) { void setFavorite(int? id, bool isFavorite) {
var veggie = getVeggie(id); var veggie = getVeggie(id);
veggie.isFavorite = isFavorite; veggie.isFavorite = isFavorite;
notifyListeners(); notifyListeners();
} }
/// Used in tests to set the season independent of the current date. /// Used in tests to set the season independent of the current date.
static Season debugCurrentSeason; static Season? debugCurrentSeason;
static Season _getSeasonForDate(DateTime date) { static Season? _getSeasonForDate(DateTime date) {
if (debugCurrentSeason != null) { if (debugCurrentSeason != null) {
return debugCurrentSeason; return debugCurrentSeason;
} }

@ -16,7 +16,7 @@ class Preferences extends ChangeNotifier {
static const _preferredCategoriesKey = 'preferredCategories'; static const _preferredCategoriesKey = 'preferredCategories';
// Indicates whether a call to [_loadFromSharedPrefs] is in progress; // Indicates whether a call to [_loadFromSharedPrefs] is in progress;
Future<void> _loading; Future<void>? _loading;
int _desiredCalories = 2000; int _desiredCalories = 2000;
@ -79,9 +79,7 @@ class Preferences extends ChangeNotifier {
if (names != null && names.isNotEmpty) { if (names != null && names.isNotEmpty) {
for (final name in names.split(',')) { for (final name in names.split(',')) {
final index = int.tryParse(name) ?? -1; final index = int.tryParse(name) ?? -1;
if (VeggieCategory.values[index] != null) { _preferredCategories.add(VeggieCategory.values[index]);
_preferredCategories.add(VeggieCategory.values[index]);
}
} }
} }

@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:meta/meta.dart';
enum VeggieCategory { enum VeggieCategory {
allium, allium,
@ -71,18 +70,18 @@ const Map<Season, String> seasonNames = {
class Veggie { class Veggie {
Veggie({ Veggie({
@required this.id, required this.id,
@required this.name, required this.name,
@required this.imageAssetPath, required this.imageAssetPath,
@required this.category, required this.category,
@required this.shortDescription, required this.shortDescription,
@required this.accentColor, required this.accentColor,
@required this.seasons, required this.seasons,
@required this.vitaminAPercentage, required this.vitaminAPercentage,
@required this.vitaminCPercentage, required this.vitaminCPercentage,
@required this.servingSize, required this.servingSize,
@required this.caloriesPerServing, required this.caloriesPerServing,
@required this.trivia, required this.trivia,
this.isFavorite = false, this.isFavorite = false,
}); });
@ -127,5 +126,5 @@ class Veggie {
/// A set of trivia questions and answers related to the veggie. /// A set of trivia questions and answers related to the veggie.
final List<Trivia> trivia; final List<Trivia> trivia;
String get categoryName => veggieCategoryNames[category]; String? get categoryName => veggieCategoryNames[category];
} }

@ -26,7 +26,7 @@ void main() {
} }
class VeggieApp extends StatefulWidget { class VeggieApp extends StatefulWidget {
const VeggieApp({Key key}) : super(key: key); const VeggieApp({Key? key}) : super(key: key);
@override @override
State<StatefulWidget> createState() => _VeggieAppState(); State<StatefulWidget> createState() => _VeggieAppState();
@ -39,7 +39,7 @@ class _VeggieAppState extends State<VeggieApp> with RestorationMixin {
String get restorationId => 'wrapper'; String get restorationId => 'wrapper';
@override @override
void restoreState(RestorationBucket oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_appState, 'state'); registerForRestoration(_appState, 'state');
} }
@ -77,7 +77,7 @@ class _RestorableAppState extends RestorableListenable<AppState> {
} }
@override @override
AppState fromPrimitives(Object data) { AppState fromPrimitives(Object? data) {
final appState = AppState(); final appState = AppState();
final favorites = (data as List<dynamic>).cast<int>(); final favorites = (data as List<dynamic>).cast<int>();
for (var id in favorites) { for (var id in favorites) {

@ -13,7 +13,7 @@ import 'package:veggieseasons/widgets/close_button.dart';
import 'package:veggieseasons/widgets/trivia.dart'; import 'package:veggieseasons/widgets/trivia.dart';
class ServingInfoChart extends StatelessWidget { class ServingInfoChart extends StatelessWidget {
const ServingInfoChart(this.veggie, this.prefs, {Key key}) : super(key: key); const ServingInfoChart(this.veggie, this.prefs, {Key? key}) : super(key: key);
final Veggie veggie; final Veggie veggie;
@ -26,7 +26,7 @@ class ServingInfoChart extends StatelessWidget {
return FutureBuilder<int>( return FutureBuilder<int>(
future: targetCalories, future: targetCalories,
builder: (context, snapshot) { builder: (context, snapshot) {
final target = snapshot?.data ?? 2000; final target = snapshot.data ?? 2000;
final percent = standardPercentage * 2000 ~/ target; final percent = standardPercentage * 2000 ~/ target;
return Text( return Text(
@ -141,7 +141,7 @@ class ServingInfoChart extends StatelessWidget {
builder: (context, snapshot) { builder: (context, snapshot) {
return Text( return Text(
'Percent daily values based on a diet of ' 'Percent daily values based on a diet of '
'${snapshot?.data ?? '2,000'} calories.', '${snapshot.data ?? '2,000'} calories.',
style: Styles.detailsServingNoteText(themeData), style: Styles.detailsServingNoteText(themeData),
); );
}, },
@ -156,9 +156,9 @@ class ServingInfoChart extends StatelessWidget {
} }
class InfoView extends StatelessWidget { class InfoView extends StatelessWidget {
final int id; final int? id;
const InfoView(this.id, {Key key}) : super(key: key); const InfoView(this.id, {Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -179,9 +179,9 @@ class InfoView extends StatelessWidget {
future: prefs.preferredCategories, future: prefs.preferredCategories,
builder: (context, snapshot) { builder: (context, snapshot) {
return Text( return Text(
veggie.categoryName.toUpperCase(), veggie.categoryName!.toUpperCase(),
style: (snapshot.hasData && style: (snapshot.hasData &&
snapshot.data.contains(veggie.category)) snapshot.data!.contains(veggie.category))
? Styles.detailsPreferredCategoryText(themeData) ? Styles.detailsPreferredCategoryText(themeData)
: themeData.textTheme.textStyle, : themeData.textTheme.textStyle,
); );
@ -191,7 +191,7 @@ class InfoView extends StatelessWidget {
for (Season season in veggie.seasons) ...[ for (Season season in veggie.seasons) ...[
const SizedBox(width: 12), const SizedBox(width: 12),
Padding( Padding(
padding: Styles.seasonIconPadding[season], padding: Styles.seasonIconPadding[season]!,
child: Icon( child: Icon(
Styles.seasonIconData[season], Styles.seasonIconData[season],
semanticLabel: seasonNames[season], semanticLabel: seasonNames[season],
@ -236,17 +236,18 @@ class InfoView extends StatelessWidget {
} }
class DetailsScreen extends StatefulWidget { class DetailsScreen extends StatefulWidget {
final int id; final int? id;
final String restorationId; final String? restorationId;
const DetailsScreen({this.id, this.restorationId, Key key}) : super(key: key); const DetailsScreen({this.id, this.restorationId, Key? key})
: super(key: key);
static String show(NavigatorState navigator, int veggieId) { static String show(NavigatorState navigator, int veggieId) {
return navigator.restorablePush<void>(_routeBuilder, arguments: veggieId); return navigator.restorablePush<void>(_routeBuilder, arguments: veggieId);
} }
static Route<void> _routeBuilder(BuildContext context, Object arguments) { static Route<void> _routeBuilder(BuildContext context, Object? arguments) {
final veggieId = arguments as int; final veggieId = arguments as int?;
return CupertinoPageRoute( return CupertinoPageRoute(
builder: (context) => builder: (context) =>
DetailsScreen(id: veggieId, restorationId: 'details'), DetailsScreen(id: veggieId, restorationId: 'details'),
@ -262,10 +263,10 @@ class _DetailsScreenState extends State<DetailsScreen> with RestorationMixin {
final RestorableInt _selectedViewIndex = RestorableInt(0); final RestorableInt _selectedViewIndex = RestorableInt(0);
@override @override
String get restorationId => widget.restorationId; String? get restorationId => widget.restorationId;
@override @override
void restoreState(RestorationBucket oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_selectedViewIndex, 'tab'); registerForRestoration(_selectedViewIndex, 'tab');
} }

@ -10,9 +10,9 @@ import 'package:veggieseasons/data/veggie.dart';
import 'package:veggieseasons/widgets/veggie_headline.dart'; import 'package:veggieseasons/widgets/veggie_headline.dart';
class FavoritesScreen extends StatelessWidget { class FavoritesScreen extends StatelessWidget {
const FavoritesScreen({this.restorationId, Key key}) : super(key: key); const FavoritesScreen({this.restorationId, Key? key}) : super(key: key);
final String restorationId; final String? restorationId;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -10,9 +10,9 @@ import 'package:veggieseasons/screens/search.dart';
import 'package:veggieseasons/screens/settings.dart'; import 'package:veggieseasons/screens/settings.dart';
class HomeScreen extends StatelessWidget { class HomeScreen extends StatelessWidget {
const HomeScreen({Key key, this.restorationId}) : super(key: key); const HomeScreen({Key? key, this.restorationId}) : super(key: key);
final String restorationId; final String? restorationId;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -14,9 +14,9 @@ import 'package:veggieseasons/styles.dart';
import 'package:veggieseasons/widgets/veggie_card.dart'; import 'package:veggieseasons/widgets/veggie_card.dart';
class ListScreen extends StatelessWidget { class ListScreen extends StatelessWidget {
const ListScreen({this.restorationId, Key key}) : super(key: key); const ListScreen({this.restorationId, Key? key}) : super(key: key);
final String restorationId; final String? restorationId;
Widget _generateVeggieRow(Veggie veggie, Preferences prefs, Widget _generateVeggieRow(Veggie veggie, Preferences prefs,
{bool inSeason = true}) { {bool inSeason = true}) {

@ -11,9 +11,9 @@ import 'package:veggieseasons/data/veggie.dart';
import 'package:veggieseasons/widgets/veggie_headline.dart'; import 'package:veggieseasons/widgets/veggie_headline.dart';
class SearchScreen extends StatefulWidget { class SearchScreen extends StatefulWidget {
const SearchScreen({this.restorationId, Key key}) : super(key: key); const SearchScreen({this.restorationId, Key? key}) : super(key: key);
final String restorationId; final String? restorationId;
@override @override
_SearchScreenState createState() => _SearchScreenState(); _SearchScreenState createState() => _SearchScreenState();
@ -22,13 +22,13 @@ class SearchScreen extends StatefulWidget {
class _SearchScreenState extends State<SearchScreen> with RestorationMixin { class _SearchScreenState extends State<SearchScreen> with RestorationMixin {
final controller = RestorableTextEditingController(); final controller = RestorableTextEditingController();
final focusNode = FocusNode(); final focusNode = FocusNode();
String terms; String? terms;
@override @override
String get restorationId => widget.restorationId; String? get restorationId => widget.restorationId;
@override @override
void restoreState(RestorationBucket oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(controller, 'text'); registerForRestoration(controller, 'text');
controller.addListener(_onTextChanged); controller.addListener(_onTextChanged);
terms = controller.value.text; terms = controller.value.text;

@ -13,16 +13,16 @@ import 'package:veggieseasons/widgets/settings_group.dart';
import 'package:veggieseasons/widgets/settings_item.dart'; import 'package:veggieseasons/widgets/settings_item.dart';
class VeggieCategorySettingsScreen extends StatelessWidget { class VeggieCategorySettingsScreen extends StatelessWidget {
const VeggieCategorySettingsScreen({Key key, this.restorationId}) const VeggieCategorySettingsScreen({Key? key, this.restorationId})
: super(key: key); : super(key: key);
final String restorationId; final String? restorationId;
static String show(NavigatorState navigator) { static String show(NavigatorState navigator) {
return navigator.restorablePush(_routeBuilder); return navigator.restorablePush(_routeBuilder);
} }
static Route<void> _routeBuilder(BuildContext context, Object argument) { static Route<void> _routeBuilder(BuildContext context, Object? argument) {
return CupertinoPageRoute( return CupertinoPageRoute(
builder: (context) => builder: (context) =>
const VeggieCategorySettingsScreen(restorationId: 'category'), const VeggieCategorySettingsScreen(restorationId: 'category'),
@ -56,7 +56,7 @@ class VeggieCategorySettingsScreen extends StatelessWidget {
// otherwise. // otherwise.
if (snapshot.hasData) { if (snapshot.hasData) {
toggle = CupertinoSwitch( toggle = CupertinoSwitch(
value: snapshot.data.contains(category), value: snapshot.data!.contains(category),
onChanged: (value) { onChanged: (value) {
if (value) { if (value) {
model.addPreferredCategory(category); model.addPreferredCategory(category);
@ -73,7 +73,7 @@ class VeggieCategorySettingsScreen extends StatelessWidget {
} }
items.add(SettingsItem( items.add(SettingsItem(
label: veggieCategoryNames[category], label: veggieCategoryNames[category]!,
content: toggle, content: toggle,
)); ));
} }
@ -94,9 +94,9 @@ class VeggieCategorySettingsScreen extends StatelessWidget {
} }
class CalorieSettingsScreen extends StatelessWidget { class CalorieSettingsScreen extends StatelessWidget {
const CalorieSettingsScreen({Key key, this.restorationId}) : super(key: key); const CalorieSettingsScreen({Key? key, this.restorationId}) : super(key: key);
final String restorationId; final String? restorationId;
static const max = 1000; static const max = 1000;
static const min = 2600; static const min = 2600;
@ -106,7 +106,7 @@ class CalorieSettingsScreen extends StatelessWidget {
return navigator.restorablePush(_routeBuilder); return navigator.restorablePush(_routeBuilder);
} }
static Route<void> _routeBuilder(BuildContext context, Object argument) { static Route<void> _routeBuilder(BuildContext context, Object? argument) {
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (context) => builder: (context) =>
const CalorieSettingsScreen(restorationId: 'calorie'), const CalorieSettingsScreen(restorationId: 'calorie'),
@ -169,9 +169,9 @@ class CalorieSettingsScreen extends StatelessWidget {
} }
class SettingsScreen extends StatelessWidget { class SettingsScreen extends StatelessWidget {
const SettingsScreen({this.restorationId, Key key}) : super(key: key); const SettingsScreen({this.restorationId, Key? key}) : super(key: key);
final String restorationId; final String? restorationId;
SettingsItem _buildCaloriesItem(BuildContext context, Preferences prefs) { SettingsItem _buildCaloriesItem(BuildContext context, Preferences prefs) {
return SettingsItem( return SettingsItem(

@ -115,7 +115,7 @@ abstract class Styles {
static const appBackground = Color(0xffd0d0d0); static const appBackground = Color(0xffd0d0d0);
static Color scaffoldBackground(Brightness brightness) => static Color? scaffoldBackground(Brightness brightness) =>
brightness == Brightness.light brightness == Brightness.light
? CupertinoColors.lightBackgroundGray ? CupertinoColors.lightBackgroundGray
: null; : null;

@ -12,10 +12,10 @@ import 'package:veggieseasons/styles.dart';
class FrostedBox extends StatelessWidget { class FrostedBox extends StatelessWidget {
const FrostedBox({ const FrostedBox({
this.child, this.child,
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
final Widget child; final Widget? child;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -37,18 +37,15 @@ class ColorChangingIcon extends ImplicitlyAnimatedWidget {
this.icon, { this.icon, {
this.color = CupertinoColors.black, this.color = CupertinoColors.black,
this.size, this.size,
@required Duration duration, required Duration duration,
Key key, Key? key,
}) : assert(icon != null), }) : super(key: key, duration: duration);
assert(color != null),
assert(duration != null),
super(key: key, duration: duration);
final Color color; final Color color;
final IconData icon; final IconData icon;
final double size; final double? size;
@override @override
_ColorChangingIconState createState() => _ColorChangingIconState(); _ColorChangingIconState createState() => _ColorChangingIconState();
@ -56,7 +53,7 @@ class ColorChangingIcon extends ImplicitlyAnimatedWidget {
class _ColorChangingIconState class _ColorChangingIconState
extends AnimatedWidgetBaseState<ColorChangingIcon> { extends AnimatedWidgetBaseState<ColorChangingIcon> {
ColorTween _colorTween; ColorTween? _colorTween;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -73,14 +70,14 @@ class _ColorChangingIconState
_colorTween = visitor( _colorTween = visitor(
_colorTween, _colorTween,
widget.color, widget.color,
(dynamic value) => ColorTween(begin: value as Color), (dynamic value) => ColorTween(begin: value as Color?),
) as ColorTween; ) as ColorTween?;
} }
} }
/// A simple "close this modal" button that invokes a callback when pressed. /// A simple "close this modal" button that invokes a callback when pressed.
class CloseButton extends StatefulWidget { class CloseButton extends StatefulWidget {
const CloseButton(this.onPressed, {Key key}) : super(key: key); const CloseButton(this.onPressed, {Key? key}) : super(key: key);
final VoidCallback onPressed; final VoidCallback onPressed;

@ -14,7 +14,7 @@ import 'settings_item.dart';
// See https://github.com/flutter/flutter/projects/29 for more info. // See https://github.com/flutter/flutter/projects/29 for more info.
class SettingsGroupHeader extends StatelessWidget { class SettingsGroupHeader extends StatelessWidget {
const SettingsGroupHeader(this.title, {Key key}) : super(key: key); const SettingsGroupHeader(this.title, {Key? key}) : super(key: key);
final String title; final String title;
@ -35,7 +35,7 @@ class SettingsGroupHeader extends StatelessWidget {
} }
class SettingsGroupFooter extends StatelessWidget { class SettingsGroupFooter extends StatelessWidget {
const SettingsGroupFooter(this.title, {Key key}) : super(key: key); const SettingsGroupFooter(this.title, {Key? key}) : super(key: key);
final String title; final String title;
@ -55,17 +55,16 @@ class SettingsGroupFooter extends StatelessWidget {
class SettingsGroup extends StatelessWidget { class SettingsGroup extends StatelessWidget {
SettingsGroup({ SettingsGroup({
@required this.items, required this.items,
this.header, this.header,
this.footer, this.footer,
Key key, Key? key,
}) : assert(items != null), }) : assert(items.isNotEmpty),
assert(items.isNotEmpty),
super(key: key); super(key: key);
final List<SettingsItem> items; final List<SettingsItem> items;
final Widget header; final Widget? header;
final Widget footer; final Widget? footer;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var brightness = CupertinoTheme.brightnessOf(context); var brightness = CupertinoTheme.brightnessOf(context);
@ -85,7 +84,7 @@ class SettingsGroup extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (header != null) header, if (header != null) header!,
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: CupertinoColors.white, color: CupertinoColors.white,
@ -105,7 +104,7 @@ class SettingsGroup extends StatelessWidget {
children: dividedItems, children: dividedItems,
), ),
), ),
if (footer != null) footer, if (footer != null) footer!,
], ],
), ),
); );

@ -16,7 +16,7 @@ import 'package:veggieseasons/styles.dart';
typedef SettingsItemCallback = FutureOr<void> Function(); typedef SettingsItemCallback = FutureOr<void> Function();
class SettingsNavigationIndicator extends StatelessWidget { class SettingsNavigationIndicator extends StatelessWidget {
const SettingsNavigationIndicator({Key key}) : super(key: key); const SettingsNavigationIndicator({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -30,12 +30,11 @@ class SettingsNavigationIndicator extends StatelessWidget {
class SettingsIcon extends StatelessWidget { class SettingsIcon extends StatelessWidget {
const SettingsIcon({ const SettingsIcon({
@required this.icon, required this.icon,
this.foregroundColor = CupertinoColors.white, this.foregroundColor = CupertinoColors.white,
this.backgroundColor = CupertinoColors.black, this.backgroundColor = CupertinoColors.black,
Key key, Key? key,
}) : assert(icon != null), }) : super(key: key);
super(key: key);
final Color backgroundColor; final Color backgroundColor;
final Color foregroundColor; final Color foregroundColor;
@ -61,20 +60,19 @@ class SettingsIcon extends StatelessWidget {
class SettingsItem extends StatefulWidget { class SettingsItem extends StatefulWidget {
const SettingsItem({ const SettingsItem({
@required this.label, required this.label,
this.icon, this.icon,
this.content, this.content,
this.subtitle, this.subtitle,
this.onPress, this.onPress,
Key key, Key? key,
}) : assert(label != null), }) : super(key: key);
super(key: key);
final String label; final String label;
final Widget icon; final Widget? icon;
final Widget content; final Widget? content;
final String subtitle; final String? subtitle;
final SettingsItemCallback onPress; final SettingsItemCallback? onPress;
@override @override
State<StatefulWidget> createState() => SettingsItemState(); State<StatefulWidget> createState() => SettingsItemState();
@ -97,7 +95,7 @@ class SettingsItemState extends State<SettingsItem> {
setState(() { setState(() {
pressed = true; pressed = true;
}); });
await widget.onPress(); await widget.onPress!();
Future.delayed( Future.delayed(
const Duration(milliseconds: 150), const Duration(milliseconds: 150),
() { () {
@ -138,7 +136,7 @@ class SettingsItemState extends State<SettingsItem> {
style: themeData.textTheme.textStyle), style: themeData.textTheme.textStyle),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
widget.subtitle, widget.subtitle!,
style: Styles.settingsItemSubtitleText(themeData), style: Styles.settingsItemSubtitleText(themeData),
), ),
], ],

@ -8,10 +8,10 @@ import 'package:veggieseasons/styles.dart';
/// Presents a series of trivia questions about a particular widget, and tracks /// Presents a series of trivia questions about a particular widget, and tracks
/// the user's score. /// the user's score.
class TriviaView extends StatefulWidget { class TriviaView extends StatefulWidget {
final int id; final int? id;
final String restorationId; final String? restorationId;
const TriviaView({this.id, this.restorationId, Key key}) : super(key: key); const TriviaView({this.id, this.restorationId, Key? key}) : super(key: key);
@override @override
_TriviaViewState createState() => _TriviaViewState(); _TriviaViewState createState() => _TriviaViewState();
@ -26,10 +26,10 @@ enum PlayerStatus {
class _TriviaViewState extends State<TriviaView> with RestorationMixin { class _TriviaViewState extends State<TriviaView> with RestorationMixin {
/// Current app state. This is used to fetch veggie data. /// Current app state. This is used to fetch veggie data.
AppState appState; late AppState appState;
/// The veggie trivia about which to show. /// The veggie trivia about which to show.
Veggie veggie; late Veggie veggie;
/// Index of the current trivia question. /// Index of the current trivia question.
RestorableInt triviaIndex = RestorableInt(0); RestorableInt triviaIndex = RestorableInt(0);
@ -45,10 +45,10 @@ class _TriviaViewState extends State<TriviaView> with RestorationMixin {
_RestorablePlayerStatus(PlayerStatus.readyToAnswer); _RestorablePlayerStatus(PlayerStatus.readyToAnswer);
@override @override
String get restorationId => widget.restorationId; String? get restorationId => widget.restorationId;
@override @override
void restoreState(RestorationBucket oldBucket, bool initialRestore) { void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(triviaIndex, 'index'); registerForRestoration(triviaIndex, 'index');
registerForRestoration(score, 'score'); registerForRestoration(score, 'score');
registerForRestoration(status, 'status'); registerForRestoration(status, 'status');
@ -234,7 +234,7 @@ class _RestorablePlayerStatus extends RestorableValue<PlayerStatus> {
} }
@override @override
PlayerStatus fromPrimitives(Object data) { PlayerStatus fromPrimitives(Object? data) {
return PlayerStatus.values[data as int]; return PlayerStatus.values[data as int];
} }
@ -244,7 +244,7 @@ class _RestorablePlayerStatus extends RestorableValue<PlayerStatus> {
} }
@override @override
void didUpdateValue(PlayerStatus oldValue) { void didUpdateValue(PlayerStatus? oldValue) {
notifyListeners(); notifyListeners();
} }
} }

@ -14,12 +14,12 @@ class FrostyBackground extends StatelessWidget {
this.color, this.color,
this.intensity = 25, this.intensity = 25,
this.child, this.child,
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
final Color color; final Color? color;
final double intensity; final double intensity;
final Widget child; final Widget? child;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -41,23 +41,17 @@ class FrostyBackground extends StatelessWidget {
/// elevation and invoking an optional [onPressed] callback. /// elevation and invoking an optional [onPressed] callback.
class PressableCard extends StatefulWidget { class PressableCard extends StatefulWidget {
const PressableCard({ const PressableCard({
@required this.child, required this.child,
this.borderRadius = const BorderRadius.all(Radius.circular(5)), this.borderRadius = const BorderRadius.all(Radius.circular(5)),
this.upElevation = 2, this.upElevation = 2,
this.downElevation = 0, this.downElevation = 0,
this.shadowColor = CupertinoColors.black, this.shadowColor = CupertinoColors.black,
this.duration = const Duration(milliseconds: 100), this.duration = const Duration(milliseconds: 100),
this.onPressed, this.onPressed,
Key key, Key? key,
}) : assert(child != null), }) : super(key: key);
assert(borderRadius != null),
assert(upElevation != null),
assert(downElevation != null),
assert(shadowColor != null),
assert(duration != null),
super(key: key);
final VoidCallback onPressed; final VoidCallback? onPressed;
final Widget child; final Widget child;
@ -84,7 +78,7 @@ class _PressableCardState extends State<PressableCard> {
onTap: () { onTap: () {
setState(() => cardIsDown = false); setState(() => cardIsDown = false);
if (widget.onPressed != null) { if (widget.onPressed != null) {
widget.onPressed(); widget.onPressed!();
} }
}, },
onTapDown: (details) => setState(() => cardIsDown = true), onTapDown: (details) => setState(() => cardIsDown = true),
@ -107,7 +101,7 @@ class _PressableCardState extends State<PressableCard> {
class VeggieCard extends StatelessWidget { class VeggieCard extends StatelessWidget {
const VeggieCard(this.veggie, this.isInSeason, this.isPreferredCategory, const VeggieCard(this.veggie, this.isInSeason, this.isPreferredCategory,
{Key key}) {Key? key})
: super(key: key); : super(key: key);
/// Veggie to be displayed by the card. /// Veggie to be displayed by the card.

@ -8,17 +8,17 @@ import 'package:veggieseasons/screens/details.dart';
import 'package:veggieseasons/styles.dart'; import 'package:veggieseasons/styles.dart';
class ZoomClipAssetImage extends StatelessWidget { class ZoomClipAssetImage extends StatelessWidget {
const ZoomClipAssetImage( const ZoomClipAssetImage({
{@required this.zoom, required this.zoom,
this.height, this.height,
this.width, this.width,
@required this.imageAsset, required this.imageAsset,
Key key}) Key? key,
: super(key: key); }) : super(key: key);
final double zoom; final double zoom;
final double height; final double? height;
final double width; final double? width;
final String imageAsset; final String imageAsset;
@override @override
@ -30,8 +30,8 @@ class ZoomClipAssetImage extends StatelessWidget {
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
child: OverflowBox( child: OverflowBox(
maxHeight: height * zoom, maxHeight: height! * zoom,
maxWidth: width * zoom, maxWidth: width! * zoom,
child: Image.asset( child: Image.asset(
imageAsset, imageAsset,
fit: BoxFit.fill, fit: BoxFit.fill,
@ -45,7 +45,7 @@ class ZoomClipAssetImage extends StatelessWidget {
class VeggieHeadline extends StatelessWidget { class VeggieHeadline extends StatelessWidget {
final Veggie veggie; final Veggie veggie;
const VeggieHeadline(this.veggie, {Key key}) : super(key: key); const VeggieHeadline(this.veggie, {Key? key}) : super(key: key);
List<Widget> _buildSeasonDots(List<Season> seasons) { List<Widget> _buildSeasonDots(List<Season> seasons) {
var widgets = <Widget>[]; var widgets = <Widget>[];

@ -19,4 +19,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
COCOAPODS: 1.10.1 COCOAPODS: 1.11.0

@ -21,7 +21,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.1" version: "2.8.2"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -35,7 +35,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -162,7 +162,7 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.10" version: "0.12.11"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -239,7 +239,7 @@ packages:
name: provider name: provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.0" version: "6.0.1"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -328,7 +328,7 @@ packages:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.2" version: "0.4.3"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:

@ -4,7 +4,7 @@ description: An iOS app that shows the fruits and veggies currently in season.
version: 1.2.0 version: 1.2.0
environment: environment:
sdk: ">=2.5.0 <3.0.0" sdk: '>=2.12.0 <3.0.0'
dependencies: dependencies:
flutter: flutter:
@ -13,7 +13,7 @@ dependencies:
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
font_awesome_flutter: ^9.0.0 font_awesome_flutter: ^9.0.0
intl: ^0.17.0 intl: ^0.17.0
provider: ^5.0.0 provider: ^6.0.1
shared_preferences: ^2.0.5 shared_preferences: ^2.0.5
dev_dependencies: dev_dependencies:

Loading…
Cancel
Save