1
0
mirror of https://github.com/flutter/samples.git synced 2026-04-29 19:16:54 +00:00

Migrate web dashboard to null safety (#928)

* update dependencies

* Update to cloud_firestore 2.x.x

* run dart migrate

* Fix analyzer warnings from null safety migration

* Fix errors resulting from null safety migration

* Fix info level warnings

* run flutter format

* fix tests

* remove unused import, format
This commit is contained in:
John Ryan
2021-10-12 14:38:34 -07:00
committed by GitHub
parent 0061b0d70d
commit 4893a24625
20 changed files with 277 additions and 301 deletions

View File

@@ -10,13 +10,13 @@ import '../app.dart';
import '../widgets/category_chart.dart';
class DashboardPage extends StatelessWidget {
const DashboardPage({Key key}) : super(key: key);
const DashboardPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var appState = Provider.of<AppState>(context);
return FutureBuilder<List<Category>>(
future: appState.api.categories.list(),
future: appState.api!.categories.list(),
builder: (context, futureSnapshot) {
if (!futureSnapshot.hasData) {
return const Center(
@@ -25,7 +25,7 @@ class DashboardPage extends StatelessWidget {
}
return StreamBuilder<List<Category>>(
initialData: futureSnapshot.data,
stream: appState.api.categories.subscribe(),
stream: appState.api!.categories.subscribe(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return const Center(
@@ -41,9 +41,9 @@ class DashboardPage extends StatelessWidget {
}
class Dashboard extends StatelessWidget {
final List<Category> categories;
final List<Category>? categories;
const Dashboard(this.categories, {Key key}) : super(key: key);
const Dashboard(this.categories, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@@ -55,7 +55,7 @@ class Dashboard extends StatelessWidget {
maxCrossAxisExtent: 500,
),
children: [
...categories.map(
...categories!.map(
(category) => Card(
child: CategoryChart(
category: category,

View File

@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;
import 'package:provider/provider.dart';
@@ -12,14 +14,14 @@ import '../widgets/categories_dropdown.dart';
import '../widgets/dialogs.dart';
class EntriesPage extends StatefulWidget {
const EntriesPage({Key key}) : super(key: key);
const EntriesPage({Key? key}) : super(key: key);
@override
_EntriesPageState createState() => _EntriesPageState();
}
class _EntriesPageState extends State<EntriesPage> {
Category _selected;
Category? _selected;
@override
Widget build(BuildContext context) {
@@ -27,14 +29,14 @@ class _EntriesPageState extends State<EntriesPage> {
return Column(
children: [
CategoryDropdown(
api: appState.api.categories,
api: appState.api!.categories,
onSelected: (category) => setState(() => _selected = category)),
Expanded(
child: _selected == null
? const Center(child: CircularProgressIndicator())
: EntriesList(
category: _selected,
api: appState.api.entries,
api: appState.api!.entries,
),
),
],
@@ -43,13 +45,13 @@ class _EntriesPageState extends State<EntriesPage> {
}
class EntriesList extends StatefulWidget {
final Category category;
final Category? category;
final EntryApi api;
EntriesList({
@required this.category,
@required this.api,
}) : super(key: ValueKey(category.id));
this.category,
required this.api,
}) : super(key: ValueKey(category?.id));
@override
_EntriesListState createState() => _EntriesListState();
@@ -63,14 +65,14 @@ class _EntriesListState extends State<EntriesList> {
}
return FutureBuilder<List<Entry>>(
future: widget.api.list(widget.category.id),
future: widget.api.list(widget.category!.id!),
builder: (context, futureSnapshot) {
if (!futureSnapshot.hasData) {
return _buildLoadingIndicator();
}
return StreamBuilder<List<Entry>>(
initialData: futureSnapshot.data,
stream: widget.api.subscribe(widget.category.id),
stream: widget.api.subscribe(widget.category!.id!),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return _buildLoadingIndicator();
@@ -79,10 +81,10 @@ class _EntriesListState extends State<EntriesList> {
itemBuilder: (context, index) {
return EntryTile(
category: widget.category,
entry: snapshot.data[index],
entry: snapshot.data![index],
);
},
itemCount: snapshot.data.length,
itemCount: snapshot.data!.length,
);
},
);
@@ -96,20 +98,20 @@ class _EntriesListState extends State<EntriesList> {
}
class EntryTile extends StatelessWidget {
final Category category;
final Entry entry;
final Category? category;
final Entry? entry;
const EntryTile({
this.category,
this.entry,
Key key,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(entry.value.toString()),
subtitle: Text(intl.DateFormat('MM/dd/yy h:mm a').format(entry.time)),
title: Text(entry!.value.toString()),
subtitle: Text(intl.DateFormat('MM/dd/yy h:mm a').format(entry!.time)),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
@@ -127,7 +129,7 @@ class EntryTile extends StatelessWidget {
TextButton(
child: const Text('Delete'),
onPressed: () async {
var shouldDelete = await showDialog<bool>(
var shouldDelete = await (showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Delete entry?'),
@@ -142,12 +144,12 @@ class EntryTile extends StatelessWidget {
),
],
),
);
) as FutureOr<bool>);
if (shouldDelete) {
await Provider.of<AppState>(context, listen: false)
.api
.api!
.entries
.delete(category.id, entry.id);
.delete(category!.id!, entry!.id!);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(

View File

@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:flutter/material.dart';
import '../widgets/dialogs.dart';
@@ -13,8 +15,8 @@ class HomePage extends StatefulWidget {
final VoidCallback onSignOut;
const HomePage({
@required this.onSignOut,
Key key,
required this.onSignOut,
Key? key,
}) : super(key: key);
@override
@@ -86,7 +88,7 @@ class _HomePageState extends State<HomePage> {
}
Future<void> _handleSignOut() async {
var shouldSignOut = await showDialog<bool>(
var shouldSignOut = await (showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Are you sure you want to sign out?'),
@@ -105,9 +107,9 @@ class _HomePageState extends State<HomePage> {
),
],
),
);
));
if (!shouldSignOut) {
if (shouldSignOut == null || !shouldSignOut) {
return;
}

View File

@@ -11,9 +11,9 @@ class SignInPage extends StatelessWidget {
final ValueChanged<User> onSuccess;
const SignInPage({
@required this.auth,
@required this.onSuccess,
Key key,
required this.auth,
required this.onSuccess,
Key? key,
}) : super(key: key);
@override
@@ -31,9 +31,9 @@ class SignInButton extends StatefulWidget {
final ValueChanged<User> onSuccess;
const SignInButton({
@required this.auth,
@required this.onSuccess,
Key key,
required this.auth,
required this.onSuccess,
Key? key,
}) : super(key: key);
@override
@@ -41,7 +41,7 @@ class SignInButton extends StatefulWidget {
}
class _SignInButtonState extends State<SignInButton> {
Future<bool> _checkSignInFuture;
Future<bool>? _checkSignInFuture;
@override
void initState() {