| // Copyright 2019 The Flutter 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 'dart:html'; |
| |
| import 'package:intl/intl.dart'; |
| import 'package:flutter_web/material.dart'; |
| |
| import '../models/providers.dart'; |
| import '../models/roll_history.dart'; |
| import '../models/roll_sheriff.dart'; |
| import '../models/skia_autoroll.dart'; |
| |
| enum RollUnits { hour, day } |
| |
| class RollDetails extends StatelessWidget { |
| const RollDetails(); |
| |
| @override |
| Widget build(BuildContext context) { |
| final ThemeData theme = Theme.of(context); |
| final TextStyle headerStyle = theme.textTheme.headline |
| .copyWith(color: Theme.of(context).primaryColor) |
| .apply(fontSizeFactor: 1.3); |
| |
| return Theme( |
| data: Theme.of(context).copyWith( |
| textTheme: Theme.of(context).textTheme.apply(fontSizeFactor: 1.3), |
| ), |
| child: |
| Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ |
| ModelBinding<RollHistory>( |
| initialModel: RollHistory(), |
| child: RefreshRollHistory( |
| child: Expanded( |
| child: Column(children: <Widget>[ |
| ListTile( |
| title: Text('Roll Commits', style: headerStyle), |
| ), |
| ListTile( |
| title: const Text('Skia → Engine'), |
| subtitle: _DetailItem( |
| value: (RollHistory history) => |
| history.lastSkiaAutoRoll, |
| unit: RollUnits.hour), |
| onTap: () => window.open( |
| 'https://autoroll.skia.org/r/skia-flutter-autoroll', |
| '_blank')), |
| ListTile( |
| title: const Text('Engine → Framework'), |
| subtitle: _DetailItem( |
| value: (RollHistory history) => |
| history.lastEngineRoll, |
| unit: RollUnits.hour), |
| onTap: () => window.open( |
| 'https://autoroll.skia.org/r/flutter-engine-flutter-autoroll', |
| '_blank')), |
| ListTile( |
| title: const Text('master → dev channel'), |
| subtitle: _DetailItem( |
| value: (RollHistory history) => |
| history.lastDevBranchRoll), |
| onTap: () => window.open( |
| 'https://github.com/flutter/flutter/commits/dev', |
| '_blank')), |
| ListTile( |
| title: const Text('dev → beta channel'), |
| subtitle: _DetailItem( |
| value: (RollHistory history) => |
| history.lastBetaBranchRoll), |
| onTap: () => window.open( |
| 'https://github.com/flutter/flutter/commits/beta', |
| '_blank')), |
| ListTile( |
| title: const Text('beta → stable channel'), |
| subtitle: _DetailItem( |
| value: (RollHistory history) => |
| history.lastStableBranchRoll), |
| onTap: () => window.open( |
| 'https://github.com/flutter/flutter/commits/stable', |
| '_blank')), |
| ListTile( |
| title: const Text('flutter_web'), |
| subtitle: _DetailItem( |
| value: (RollHistory history) => |
| history.lastFlutterWebCommit), |
| onTap: () => window.open( |
| 'https://github.com/flutter/flutter_web/commits/master', |
| '_blank')), |
| ]), |
| ), |
| ), |
| ), |
| Expanded( |
| child: Column(children: <Widget>[ |
| ListTile( |
| title: Text('Auto Rollers', style: headerStyle), |
| ), |
| const ModelBinding<RollSheriff>( |
| initialModel: RollSheriff(), |
| child: RefreshSheriffRotation(child: RollSheriffWidget())), |
| const ModelBinding<SkiaAutoRoll>( |
| initialModel: SkiaAutoRoll(), |
| child: RefreshEngineFrameworkRoll( |
| child: AutoRollWidget( |
| name: 'Engine → Framework', |
| url: |
| 'https://autoroll.skia.org/r/flutter-engine-flutter-autoroll', |
| ))), |
| const ModelBinding<SkiaAutoRoll>( |
| initialModel: SkiaAutoRoll(), |
| child: RefreshSkiaFlutterRoll( |
| child: AutoRollWidget( |
| name: 'Skia → Engine', |
| url: 'https://autoroll.skia.org/r/skia-flutter-autoroll', |
| ))) |
| ]), |
| ) |
| ])); |
| } |
| } |
| |
| class RollSheriffWidget extends StatelessWidget { |
| const RollSheriffWidget(); |
| |
| @override |
| Widget build(BuildContext context) { |
| final RollSheriff sheriff = ModelBinding.of<RollSheriff>(context); |
| if (sheriff?.currentSheriff != null) { |
| return ListTile( |
| leading: const CircleAvatar( |
| child: Icon(Icons.security), |
| ), |
| title: Text('${sheriff.currentSheriff} 🤠'), |
| onTap: () => window.open( |
| 'http://chromium-build.appspot.com/static/rotations.html', |
| '_blank')); |
| } |
| return const SizedBox(); |
| } |
| } |
| |
| class AutoRollWidget extends StatelessWidget { |
| const AutoRollWidget({@required this.name, @required this.url}); |
| |
| final String name; |
| final String url; |
| |
| @override |
| Widget build(BuildContext context) { |
| final SkiaAutoRoll autoRoll = ModelBinding.of<SkiaAutoRoll>(context); |
| IconData icon; |
| Color backgroundColor; |
| if (autoRoll.mode == 'running') { |
| if (autoRoll.lastRollResult == 'succeeded') { |
| icon = Icons.check; |
| backgroundColor = Colors.green; |
| } else if (autoRoll.lastRollResult == 'failed') { |
| icon = Icons.error; |
| backgroundColor = Colors.redAccent; |
| } |
| } else if (autoRoll.mode == 'stopped') { |
| icon = Icons.pause_circle_filled; |
| backgroundColor = Colors.amberAccent; |
| } |
| if (icon == null || backgroundColor == null) { |
| icon = Icons.report_problem; |
| backgroundColor = Colors.grey; |
| } |
| return ListTile( |
| title: Text(name), |
| leading: CircleAvatar( |
| child: Icon(icon), |
| backgroundColor: backgroundColor, |
| ), |
| subtitle: Text( |
| '${autoRoll.mode ?? 'Unknown'}\nLast roll: ${autoRoll.lastRollResult}'), |
| isThreeLine: true, |
| onTap: () => window.open(url, '_blank')); |
| } |
| } |
| |
| class _DetailItem extends StatelessWidget { |
| const _DetailItem({@required this.value, this.unit = RollUnits.day}); |
| |
| final DateTime Function(RollHistory history) value; |
| final RollUnits unit; |
| |
| @override |
| Widget build(BuildContext context) { |
| DateFormat dateFormat; |
| String parenthesis; |
| DateTime valueDate; |
| final RollHistory history = ModelBinding.of<RollHistory>(context); |
| if (value != null) { |
| valueDate = value(history); |
| if (valueDate != null) { |
| if (unit == RollUnits.hour) { |
| final int hours = DateTime.now().difference(valueDate).inHours; |
| // Ignoring Russian, etc pluralization problems. |
| parenthesis = Intl.plural(hours, |
| zero: '<1 hour ago', |
| one: '1 hour ago', |
| other: '$hours hours ago'); |
| dateFormat = DateFormat.jm(); |
| } else { |
| // RollUnits.day |
| final int days = DateTime.now().difference(valueDate).inDays; |
| parenthesis = Intl.plural(days, |
| zero: 'today', one: '1 day ago', other: '$days days ago'); |
| dateFormat = DateFormat.MMMMd(); |
| } |
| } |
| } |
| return Text( |
| (valueDate != null) |
| ? '${dateFormat.format(valueDate.toLocal())} ($parenthesis)' |
| : 'Unknown', |
| style: Theme.of(context).textTheme.body1); |
| } |
| } |