blob: 34b9bd6c99d0ee8c2954af36550bb5fb57505147 [file] [log] [blame]
// 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,
),
),
);
}
}