1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-10 23:08:59 +00:00

Add firebase support to web_dashboard (#421)

* add mock data, app state, model classes

* Set up app without ChangeNotifier

* refactor

* add experiments to experimental/

* Add project-agnostic Firebase authentication code

* add sign in button

* add stub firebase API

* add firestore

* refactor code for google_sign_in

* update pubspec.lock

* switch to mocks for non-firebase version

* Add firebase instructions to the README

* fix README

* sign in silently if the user is already signed in

* add json_serializable

* update README

* ignore 'id' field on types

* Implement FirebaseItemApi

* Add build_runner instructions to README

* remove experiments directory

* add EditItemForm

* move types.dart into api.dart

* move mock and firebase configuration into the constructor

* add main_mock entrypoint

* add copyright checks to grinder script

* fix fix-copyright task

* run grind fix-copyright

* add run and generate tasks

* add run tasks to grind script

* add fillWithMockData() fix delete() in mock API

* add edit / new form dialogs

* Add charts that display entries from Firebase

* Add Entries list without editing

* refactor home page

* format

* Add entries page functionality

* Show current day in charts

* cleanup: pubspec.lock, remove type annotation

* Remove _selectedItem from Home page

Add ItemsDropdown
Use ItemsDropdown in NewEntryDialog / NewEntryForm

* rename item-category

* don't wait to show snackbar on delete

* fix circular progress indicator

* Move dialogs into dialogs.dart

* run grind fix-copyright

* remove unused import

* Refactor entry total calculation, add chart_utils library

* fix bug in chart_utils.dart

* convert CategoryChart to a stateless widget

* use a const for number of days in chart

* code review updates

- rename stream -> subscribe
- timeStamp -> timestamp
- remove latest() from API
- use FutureBuilder and StreamBuilder instead of stateful widget
- rename variables in mock_service_test.dart

* use a single collection reference in firebase API

* remove reference to stream in mock API

* Use a new type,  _EntriesEvent to improve filtering in mock API

* add analysis_options.yaml and fix (most) issues

* fix avoid_types_on_closure_parameters lint warnings

* use spread operator in dashboard.dart

* handle case where selected item in the category dropdown goes away

* use StreamBuilder + FutureBuilder on Entries page

* rename method

* use fake firebase configuration

* update pubspec.lock

* update README

* Change categories_dropdown to FutureBuilder + StreamBuilder

* Update minSdkVersion in build.gradle

SDK version 16 was failing: "The number of method references in a .dex
file cannot exceed 64K."

* update README

* Use a collection reference in FirebaseEntryApi

Already added to FirebaseCategoryApi

* Invoke onSelected in CategoriesDropdown when necessary

Also, avoid calling onSelected during a build.

* fix misnamed var

* remove unused import

* Use relative imports

* Use extension methods for DateTime utilities

* remove forms.dart

* Make Firebase instructions specific for this sample

* add copyright headers

* fix grammar

* dartfmt

* avoid setState() during build phase in CategoryDropdown

* add empty test to material_theme_builder
This commit is contained in:
John Ryan
2020-05-26 13:14:21 -07:00
committed by GitHub
parent b518c322cc
commit 395ae8c0bb
39 changed files with 2730 additions and 220 deletions

View File

@@ -2,58 +2,102 @@
// 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 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'api/api.dart';
import 'api/firebase.dart';
import 'api/mock.dart';
import 'auth/auth.dart';
import 'auth/firebase.dart';
import 'auth/mock.dart';
import 'pages/home.dart';
import 'widgets/third_party/adaptive_scaffold.dart';
import 'pages/sign_in.dart';
/// An app that shows a responsive dashboard.
/// The global state the app.
class AppState {
final Auth auth;
DashboardApi api;
AppState(this.auth);
}
/// Creates a [DashboardApi] when the user is logged in.
typedef DashboardApi ApiBuilder(User user);
/// An app that displays a personalized dashboard.
class DashboardApp extends StatefulWidget {
static ApiBuilder _mockApiBuilder =
(user) => MockDashboardApi()..fillWithMockData();
static ApiBuilder _apiBuilder =
(user) => FirebaseDashboardApi(Firestore.instance, user.uid);
final Auth auth;
final ApiBuilder apiBuilder;
/// Runs the app using Firebase
DashboardApp()
: auth = FirebaseAuthService(),
apiBuilder = _apiBuilder;
/// Runs the app using mock data
DashboardApp.mock()
: auth = MockAuthService(),
apiBuilder = _mockApiBuilder;
@override
_DashboardAppState createState() => _DashboardAppState();
}
class _DashboardAppState extends State<DashboardApp> {
int _pageIndex = 0;
AppState _appState;
void initState() {
super.initState();
_appState = AppState(widget.auth);
}
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<DashboardApi>(create: (_) => MockDashboardApi()),
],
return Provider.value(
value: _appState,
child: MaterialApp(
home: AdaptiveScaffold(
currentIndex: _pageIndex,
destinations: [
AdaptiveScaffoldDestination(title: 'Home', icon: Icons.home),
AdaptiveScaffoldDestination(title: 'Entries', icon: Icons.list),
AdaptiveScaffoldDestination(
title: 'Settings', icon: Icons.settings),
],
body: _pageAtIndex(_pageIndex),
onNavigationIndexChange: (newIndex) {
setState(() {
_pageIndex = newIndex;
});
},
home: Builder(
builder: (context) => SignInPage(
auth: _appState.auth,
onSuccess: (user) => _handleSignIn(user, context, _appState),
),
),
),
);
}
static Widget _pageAtIndex(int index) {
switch (index) {
case 1:
return Center(child: Text('page 2'));
case 2:
return Center(child: Text('page 3'));
case 0:
default:
return HomePage();
}
/// Sets the DashboardApi on AppState and navigates to the home page.
void _handleSignIn(User user, BuildContext context, AppState appState) {
appState.api = widget.apiBuilder(user);
_showPage(HomePage(), context);
}
/// Navigates to the home page using a fade transition.
void _showPage(Widget page, BuildContext context) {
var route = _fadeRoute(page);
Navigator.of(context).pushReplacement(route);
}
/// Creates a [Route] that shows [newPage] using a fade transition.
Route<FadeTransition> _fadeRoute(Widget newPage) {
return PageRouteBuilder<FadeTransition>(
pageBuilder: (context, animation, secondaryAnimation) {
return newPage;
},
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(
opacity: animation.drive(CurveTween(curve: Curves.ease)),
child: child,
);
},
);
}
}