| // Copyright (c) 2019 The Chromium Authors. 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:flutter/material.dart'; |
| import 'package:provider/provider.dart'; |
| |
| import 'navigation_drawer.dart'; |
| import 'service/google_authentication.dart'; |
| import 'sign_in_button.dart'; |
| import 'state/flutter_build.dart'; |
| import 'status_grid.dart'; |
| |
| /// [BuildDashboard] parent widget that manages the state of the dashboard. |
| class BuildDashboardPage extends StatefulWidget { |
| BuildDashboardPage( |
| {FlutterBuildState buildState, GoogleSignInService signInService}) |
| : buildState = |
| buildState ?? FlutterBuildState(authServiceValue: signInService); |
| |
| static const String routeName = '/build'; |
| |
| final FlutterBuildState buildState; |
| |
| @visibleForTesting |
| static const Duration errorSnackbarDuration = Duration(seconds: 8); |
| @override |
| _BuildDashboardPageState createState() => _BuildDashboardPageState(); |
| } |
| |
| class _BuildDashboardPageState extends State<BuildDashboardPage> { |
| final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); |
| |
| FlutterBuildState buildState; |
| |
| @override |
| void initState() { |
| super.initState(); |
| |
| widget.buildState.startFetchingUpdates(); |
| |
| widget.buildState.errors.addListener(_showErrorSnackbar); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| buildState = widget.buildState; |
| |
| return ChangeNotifierProvider<FlutterBuildState>( |
| create: (_) => buildState, |
| child: BuildDashboard(scaffoldKey: _scaffoldKey), |
| ); |
| } |
| |
| void _showErrorSnackbar() { |
| final Row snackbarContent = Row( |
| children: <Widget>[ |
| const Icon(Icons.error), |
| const SizedBox(width: 10), |
| Text(buildState.errors.message) |
| ], |
| ); |
| _scaffoldKey.currentState.showSnackBar( |
| SnackBar( |
| content: snackbarContent, |
| backgroundColor: Theme.of(context).errorColor, |
| duration: BuildDashboardPage.errorSnackbarDuration, |
| ), |
| ); |
| } |
| |
| @override |
| void dispose() { |
| buildState.errors.removeListener(_showErrorSnackbar); |
| super.dispose(); |
| } |
| } |
| |
| /// Shows information about the current build status of flutter/flutter. |
| /// |
| /// The tree's current build status is reflected in [AppBar]. |
| /// The results from tasks run on individual commits is shown in [StatusGrid]. |
| class BuildDashboard extends StatelessWidget { |
| const BuildDashboard({this.scaffoldKey}); |
| |
| final GlobalKey<ScaffoldState> scaffoldKey; |
| |
| @override |
| Widget build(BuildContext context) { |
| final ThemeData theme = Theme.of(context); |
| |
| /// Color of [AppBar] based on [buildState.isTreeBuilding]. |
| final Map<bool, Color> colorTable = <bool, Color>{ |
| null: Colors.grey, |
| false: theme.errorColor, |
| true: theme.appBarTheme.color, |
| }; |
| |
| /// Message to show on [AppBar] based on [buildState.isTreeBuilding]. |
| const Map<bool, Text> statusTable = <bool, Text>{ |
| null: Text('Loading...'), |
| false: Text('Tree is Closed'), |
| true: Text('Tree is Open'), |
| }; |
| |
| return Consumer<FlutterBuildState>( |
| builder: (_, FlutterBuildState buildState, Widget child) => Scaffold( |
| key: scaffoldKey, |
| appBar: AppBar( |
| title: statusTable[buildState.isTreeBuilding], |
| backgroundColor: colorTable[buildState.isTreeBuilding], |
| actions: <Widget>[ |
| SignInButton(authService: buildState.authService), |
| ], |
| ), |
| body: Column( |
| children: const <Widget>[ |
| StatusGridContainer(), |
| ], |
| ), |
| drawer: const NavigationDrawer( |
| currentRoute: BuildDashboardPage.routeName, |
| ), |
| ), |
| ); |
| } |
| } |