Skip to content
11 changes: 10 additions & 1 deletion lib/datatypes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class Tournament {
? _name
: "${date?.year ?? ''} $_name".trim();

static Tournament? _currentCache;

@override
String toString() => localized;

Expand All @@ -34,9 +36,14 @@ class Tournament {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('tournament', key);
await prefs.setString('tournament_localized', localized);
_currentCache = this;
}

static Tournament? get currentSync => _currentCache;

static Future<Tournament?> getCurrent() async {
if (_currentCache != null) return _currentCache;

final prefs = await SharedPreferences.getInstance();
final key = prefs.getString('tournament');
final name = prefs.getString('tournament_localized');
Expand All @@ -45,13 +52,15 @@ class Tournament {
return null;
}

return Tournament(key, name);
_currentCache = Tournament(key, name);
return _currentCache;
}

static Future<void> clearCurrent() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('tournament');
await prefs.remove('tournament_localized');
_currentCache = null;
}

Future<List<MatchScheduleMatch>> getMatches() async {
Expand Down
27 changes: 14 additions & 13 deletions lib/metrics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,24 @@ String numToStringRounded(num? num) {
final List<MetricCategoryData> metricCategories = [
MetricCategoryData("Score", [
CategoryMetric(
localizedName: "Total",
localizedName: "Total score in a match",
abbreviatedLocalizedName: "Total",
path: "totalPoints",
),
CategoryMetric(
localizedName: "Auto",
localizedName: "Total score during autonomous",
abbreviatedLocalizedName: "Auto",
path: "autoPoints",
),
CategoryMetric(
localizedName: "Teleop",
localizedName: "Total score during teleop",
abbreviatedLocalizedName: "Teleop",
path: "teleopPoints",
),
]),
MetricCategoryData("Hub", [
CategoryMetric(
localizedName: "Scoring Rate (Fuel / Second)",
localizedName: "Fuel scored per second",
abbreviatedLocalizedName: "Scoring Rate",
units: " bps",
path: "fuelPerSecond",
Expand All @@ -133,54 +133,54 @@ final List<MetricCategoryData> metricCategories = [
]),
MetricCategoryData("Feeding", [
CategoryMetric(
localizedName: "Time Spent Feeding",
localizedName: "Time spent feeding in a match",
abbreviatedLocalizedName: "Time Feeding",
units: "s",
path: "timeFeeding",
),
CategoryMetric(
localizedName: "Feeding Rate (Fuel / Second)",
localizedName: "Fuel fed per second",
abbreviatedLocalizedName: "Feeding Rate",
units: " bps",
path: "feedingRate",
),
CategoryMetric(
localizedName: "Feeds per match",
localizedName: "Feeing volleys/dumps per match",
abbreviatedLocalizedName: "Feeds/Match",
path: "feedsPerMatch",
)
]),
MetricCategoryData("Driving & Defense", [
CategoryMetric(
localizedName: "Driver Ability",
localizedName: "Manually scored driving rating",
abbreviatedLocalizedName: "Driver Ability",
max: 5,
units: "1-5",
valueToString: (val) => "$val/5",
path: "driverAbility",
),
CategoryMetric(
localizedName: "Contact Defense Time",
localizedName: "Time spent doing contact defense in a match",
abbreviatedLocalizedName: "Contact Defense Time",
units: "s",
path: "contactDefenseTime",
),
CategoryMetric(
localizedName: "Defense effectiveness",
localizedName: "Manually scored defense rating",
abbreviatedLocalizedName: "Defense effectiveness",
units: "1-5",
valueToString: (val) => "$val/5",
max: 5,
path: "defenseEffectiveness",
),
CategoryMetric(
localizedName: "Camping Defense Time",
localizedName: "Time spent doing camping defense in a match",
abbreviatedLocalizedName: "Camping Defense Time",
units: "s",
path: "campingDefenseTime",
),
CategoryMetric(
localizedName: "Total Defense Time (Camping + Contact)",
localizedName: "Total defense time (camping + contact)",
abbreviatedLocalizedName: "Total Defense Time",
units: "s",
path: "totalDefenseTime",
Expand Down Expand Up @@ -219,7 +219,8 @@ final List<MetricCategoryData> metricCategories = [
path: "totalFuelOutputted",
),
CategoryMetric(
localizedName: "Outpost Intakes",
localizedName:
"Number of times outpost was used to intake during a match",
abbreviatedLocalizedName: "Outpost Intakes",
path: "outpostIntakes",
)
Expand Down
95 changes: 36 additions & 59 deletions lib/pages/alliance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import 'package:scouting_dashboard_app/reusable/lovat_api/get_alliance_analysis.
import 'package:scouting_dashboard_app/reusable/lovat_api/lovat_api.dart';
import 'package:scouting_dashboard_app/reusable/models/robot_roles.dart';
import 'package:scouting_dashboard_app/reusable/scrollable_page_body.dart';
import 'package:scouting_dashboard_app/reusable/stale_refresh_builder.dart';
import 'package:scouting_dashboard_app/reusable/stale_refresh_indicator.dart';
import 'package:scouting_dashboard_app/reusable/team_auto_paths.dart';
import 'package:scouting_dashboard_app/reusable/value_tile.dart';

Expand All @@ -17,61 +19,39 @@ class AlliancePage extends StatefulWidget {
}

class _AlliancePageState extends State<AlliancePage> {
AllianceAnalysis? data;
String? error;
late List<int> teams;

Future<void> fetchData() async {
setState(() {
data = null;
error = null;
});

try {
final result = await lovatAPI.getAllianceAnalysis(teams);
setState(() => data = result);
} on LovatAPIException catch (e) {
setState(() => error = e.message);
} catch (_) {
setState(() => error = "Failed to load alliance data");
}
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
teams = (ModalRoute.of(context)!.settings.arguments
as Map<String, dynamic>)['teams'];
if (data == null && error == null) fetchData();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Alliance"),
actions: [
if (error != null || data != null)
IconButton(
icon: const Icon(Icons.refresh),
onPressed: fetchData,
),
],
),
body: _buildBody(),
);
}
return StaleRefreshBuilder(
query: lovatAPI.allianceAnalysisQuery(teams),
builder: (context, result) {
final data = result.data;
Widget body;
if (result.hasError && data == null) {
body = FriendlyErrorView.result(result);
} else if (data == null) {
body = const Center(child: CircularProgressIndicator());
} else {
body = ScrollablePageBody(children: [_AllianceContent(data: data)]);
}

Widget _buildBody() {
if (error != null) {
return FriendlyErrorView(errorMessage: error, onRetry: fetchData);
}

if (data == null) {
return const Center(child: CircularProgressIndicator());
}

return ScrollablePageBody(children: [_AllianceContent(data: data!)]);
return Scaffold(
appBar: AppBar(
title: const Text("Alliance"),
bottom: StaleRefreshIndicator.result(result),
),
body: body,
);
},
);
}
}

Expand Down Expand Up @@ -108,9 +88,7 @@ class _AllianceContentState extends State<_AllianceContent> {
InkWell(
onTap: () => {
Navigator.of(context).pushNamed("/team_lookup",
arguments: <String, dynamic>{
'team': teamData.team
})
arguments: <String, dynamic>{'team': teamData.team})
},
child: Text(
teamData.team.toString(),
Expand Down Expand Up @@ -156,16 +134,14 @@ class _AllianceContentState extends State<_AllianceContent> {
Flexible(
fit: FlexFit.tight,
child: ValueTile(
value:
Text(numToStringRounded(analysis.totalBallThroughput)),
value: Text(numToStringRounded(analysis.totalBallThroughput)),
label: const Text('Total output'),
),
),
Flexible(
fit: FlexFit.tight,
child: ValueTile(
value:
Text(numToStringRounded(analysis.totalFuelOutputted)),
value: Text(numToStringRounded(analysis.totalFuelOutputted)),
label: const Text('Hub shots'),
),
),
Expand Down Expand Up @@ -267,9 +243,8 @@ class _AlllianceAutoPathsState extends State<AlllianceAutoPaths>
borderRadius:
const BorderRadius.all(
Radius.circular(10)),
color: autoPathColors[widget
.data.teams
.indexOf(e)],
color: autoPathColors[
widget.data.teams.indexOf(e)],
),
),
),
Expand Down Expand Up @@ -306,8 +281,7 @@ class _AlllianceAutoPathsState extends State<AlllianceAutoPaths>
null
? "--"
: numToStringRounded(selectedPaths[
widget.data.teams
.indexOf(e)]!
widget.data.teams.indexOf(e)]!
.scores
.cast<num>()
.average()),
Expand Down Expand Up @@ -427,7 +401,11 @@ Container reefStack(
Color? backgroundColor,
Color? foregroundColor,
}) {
final startTimeLists = [analysis.l1StartTime, analysis.l2StartTime, analysis.l3StartTime];
final startTimeLists = [
analysis.l1StartTime,
analysis.l2StartTime,
analysis.l3StartTime
];

return Container(
decoration: BoxDecoration(
Expand Down Expand Up @@ -499,8 +477,7 @@ Container reefStack(
child: Text(
(() {
final list = startTimeLists[row];
if (list.length <= col ||
list[col] == null) {
if (list.length <= col || list[col] == null) {
return '--';
}
return '${numToStringRounded(list[col])}s';
Expand All @@ -522,4 +499,4 @@ Container reefStack(
],
),
);
}
}
Loading
Loading