Smooth graph + unfinished reimplementation of tl progress bar
Also small UI changes
This commit is contained in:
parent
3b16822c1f
commit
5c6c502a57
|
@ -17,6 +17,9 @@ const double appdspWeight = 140;
|
||||||
const double vsapmWeight = 60;
|
const double vsapmWeight = 60;
|
||||||
const double cheeseWeight = 1.25;
|
const double cheeseWeight = 1.25;
|
||||||
const double gbeWeight = 315;
|
const double gbeWeight = 315;
|
||||||
|
const List<String> ranks = [
|
||||||
|
"d", "d+", "c-", "c", "c+", "b-", "b", "b+", "a-", "a", "a+", "s-", "s", "s+", "ss", "u", "x"
|
||||||
|
];
|
||||||
const Map<String, double> rankCutoffs = {
|
const Map<String, double> rankCutoffs = {
|
||||||
"x": 0.01,
|
"x": 0.01,
|
||||||
"u": 0.05,
|
"u": 0.05,
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
/// To regenerate, run: `dart run slang`
|
/// To regenerate, run: `dart run slang`
|
||||||
///
|
///
|
||||||
/// Locales: 2
|
/// Locales: 2
|
||||||
/// Strings: 1120 (560 per locale)
|
/// Strings: 1122 (561 per locale)
|
||||||
///
|
///
|
||||||
/// Built on 2024-03-24 at 14:28 UTC
|
/// Built on 2024-04-11 at 22:23 UTC
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
|
@ -216,6 +216,7 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
|
||||||
String verdictGeneral({required Object n, required Object verdict, required Object rank}) => '${n} ${verdict} than ${rank} rank average';
|
String verdictGeneral({required Object n, required Object verdict, required Object rank}) => '${n} ${verdict} than ${rank} rank average';
|
||||||
String get verdictBetter => 'better';
|
String get verdictBetter => 'better';
|
||||||
String get verdictWorse => 'worse';
|
String get verdictWorse => 'worse';
|
||||||
|
String get smooth => 'Smooth';
|
||||||
String gamesUntilRanked({required Object left}) => '${left} games until being ranked';
|
String gamesUntilRanked({required Object left}) => '${left} games until being ranked';
|
||||||
String get nerdStats => 'Nerd Stats';
|
String get nerdStats => 'Nerd Stats';
|
||||||
String get playersYouTrack => 'Players you track';
|
String get playersYouTrack => 'Players you track';
|
||||||
|
@ -870,6 +871,7 @@ class _StringsRu implements Translations {
|
||||||
@override String verdictGeneral({required Object verdict, required Object rank, required Object n}) => '${verdict} среднего ${rank} ранга на ${n}';
|
@override String verdictGeneral({required Object verdict, required Object rank, required Object n}) => '${verdict} среднего ${rank} ранга на ${n}';
|
||||||
@override String get verdictBetter => 'Лучше';
|
@override String get verdictBetter => 'Лучше';
|
||||||
@override String get verdictWorse => 'Хуже';
|
@override String get verdictWorse => 'Хуже';
|
||||||
|
@override String get smooth => 'Гладкий';
|
||||||
@override String gamesUntilRanked({required Object left}) => '${left} матчей до получения рейтинга';
|
@override String gamesUntilRanked({required Object left}) => '${left} матчей до получения рейтинга';
|
||||||
@override String get nerdStats => 'Для задротов';
|
@override String get nerdStats => 'Для задротов';
|
||||||
@override String get playersYouTrack => 'Отслеживаемые игроки';
|
@override String get playersYouTrack => 'Отслеживаемые игроки';
|
||||||
|
@ -1516,6 +1518,7 @@ extension on Translations {
|
||||||
case 'verdictGeneral': return ({required Object n, required Object verdict, required Object rank}) => '${n} ${verdict} than ${rank} rank average';
|
case 'verdictGeneral': return ({required Object n, required Object verdict, required Object rank}) => '${n} ${verdict} than ${rank} rank average';
|
||||||
case 'verdictBetter': return 'better';
|
case 'verdictBetter': return 'better';
|
||||||
case 'verdictWorse': return 'worse';
|
case 'verdictWorse': return 'worse';
|
||||||
|
case 'smooth': return 'Smooth';
|
||||||
case 'gamesUntilRanked': return ({required Object left}) => '${left} games until being ranked';
|
case 'gamesUntilRanked': return ({required Object left}) => '${left} games until being ranked';
|
||||||
case 'nerdStats': return 'Nerd Stats';
|
case 'nerdStats': return 'Nerd Stats';
|
||||||
case 'playersYouTrack': return 'Players you track';
|
case 'playersYouTrack': return 'Players you track';
|
||||||
|
@ -2096,6 +2099,7 @@ extension on _StringsRu {
|
||||||
case 'verdictGeneral': return ({required Object verdict, required Object rank, required Object n}) => '${verdict} среднего ${rank} ранга на ${n}';
|
case 'verdictGeneral': return ({required Object verdict, required Object rank, required Object n}) => '${verdict} среднего ${rank} ранга на ${n}';
|
||||||
case 'verdictBetter': return 'Лучше';
|
case 'verdictBetter': return 'Лучше';
|
||||||
case 'verdictWorse': return 'Хуже';
|
case 'verdictWorse': return 'Хуже';
|
||||||
|
case 'smooth': return 'Гладкий';
|
||||||
case 'gamesUntilRanked': return ({required Object left}) => '${left} матчей до получения рейтинга';
|
case 'gamesUntilRanked': return ({required Object left}) => '${left} матчей до получения рейтинга';
|
||||||
case 'nerdStats': return 'Для задротов';
|
case 'nerdStats': return 'Для задротов';
|
||||||
case 'playersYouTrack': return 'Отслеживаемые игроки';
|
case 'playersYouTrack': return 'Отслеживаемые игроки';
|
||||||
|
|
|
@ -816,21 +816,23 @@ class CompareThingy extends StatelessWidget {
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: const [Colors.green, Colors.transparent],
|
colors: const [Colors.green, Colors.transparent],
|
||||||
begin: Alignment.centerLeft,
|
begin: Alignment.centerLeft,
|
||||||
end: Alignment.centerRight,
|
end: Alignment.centerRight,
|
||||||
stops: [
|
transform: GradientRotation(0.6),
|
||||||
0.0,
|
stops: [
|
||||||
higherIsBetter
|
0.0,
|
||||||
? greenSide > redSide
|
higherIsBetter
|
||||||
? 0.6
|
? greenSide > redSide
|
||||||
: 0
|
? 0.6
|
||||||
: greenSide < redSide
|
: 0
|
||||||
? 0.6
|
: greenSide < redSide
|
||||||
: 0
|
? 0.6
|
||||||
],
|
: 0
|
||||||
)),
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
(prefix ?? "") + f.format(greenSide) + (postfix ?? ""),
|
(prefix ?? "") + f.format(greenSide) + (postfix ?? ""),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
@ -838,7 +840,12 @@ class CompareThingy extends StatelessWidget {
|
||||||
shadows: <Shadow>[
|
shadows: <Shadow>[
|
||||||
Shadow(
|
Shadow(
|
||||||
offset: Offset(0.0, 0.0),
|
offset: Offset(0.0, 0.0),
|
||||||
blurRadius: 3.0,
|
blurRadius: 1.0,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Shadow(
|
||||||
|
offset: Offset(0.0, 0.0),
|
||||||
|
blurRadius: 2.0,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
Shadow(
|
Shadow(
|
||||||
|
@ -874,6 +881,7 @@ class CompareThingy extends StatelessWidget {
|
||||||
colors: const [Colors.red, Colors.transparent],
|
colors: const [Colors.red, Colors.transparent],
|
||||||
begin: Alignment.centerRight,
|
begin: Alignment.centerRight,
|
||||||
end: Alignment.centerLeft,
|
end: Alignment.centerLeft,
|
||||||
|
transform: GradientRotation(-0.6),
|
||||||
stops: [
|
stops: [
|
||||||
0.0,
|
0.0,
|
||||||
higherIsBetter
|
higherIsBetter
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// ignore_for_file: type_literal_in_constant_pattern
|
// ignore_for_file: type_literal_in_constant_pattern
|
||||||
|
|
||||||
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
|
@ -35,6 +36,7 @@ import 'package:go_router/go_router.dart';
|
||||||
final TetrioService teto = TetrioService(); // thing, that manadge our local DB
|
final TetrioService teto = TetrioService(); // thing, that manadge our local DB
|
||||||
int _chartsIndex = 0;
|
int _chartsIndex = 0;
|
||||||
bool _gamesPlayedInsteadOfDateAndTime = false;
|
bool _gamesPlayedInsteadOfDateAndTime = false;
|
||||||
|
bool _smooth = false;
|
||||||
List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS/S", "DS/P", "APP + DS/P", "VS/APM", "Cheese", "GbE", "wAPP", "Area", "eTR", "±eTR", "Opener", "Plonk", "Inf. DS", "Stride"];
|
List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS/S", "DS/P", "APP + DS/P", "VS/APM", "Cheese", "GbE", "wAPP", "Area", "eTR", "±eTR", "Opener", "Plonk", "Inf. DS", "Stride"];
|
||||||
late ScrollController _scrollController;
|
late ScrollController _scrollController;
|
||||||
final NumberFormat _timeInSec = NumberFormat("#,###.###s.", LocaleSettings.currentLocale.languageCode);
|
final NumberFormat _timeInSec = NumberFormat("#,###.###s.", LocaleSettings.currentLocale.languageCode);
|
||||||
|
@ -81,11 +83,15 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
TetrioPlayersLeaderboard? everyone;
|
TetrioPlayersLeaderboard? everyone;
|
||||||
PlayerLeaderboardPosition? meAmongEveryone;
|
PlayerLeaderboardPosition? meAmongEveryone;
|
||||||
TetraLeagueAlpha? rankAverages;
|
TetraLeagueAlpha? rankAverages;
|
||||||
|
double? thatRankCutoff;
|
||||||
|
double? nextRankCutoff;
|
||||||
String _searchFor = "6098518e3d5155e6ec429cdc"; // who we looking for
|
String _searchFor = "6098518e3d5155e6ec429cdc"; // who we looking for
|
||||||
String _titleNickname = "dan63047";
|
String _titleNickname = "";
|
||||||
/// Each dropdown menu item contains list of dots for the graph
|
/// Each dropdown menu item contains list of dots for the graph
|
||||||
var chartsData = <DropdownMenuItem<List<FlSpot>>>[];
|
List<DropdownMenuItem<List<FlSpot>>> chartsData = [];
|
||||||
var chartsDataGamesPlayed = <DropdownMenuItem<List<FlSpot>>>[];
|
List<DropdownMenuItem<List<FlSpot>>>? smoothChartsData;
|
||||||
|
List<DropdownMenuItem<List<FlSpot>>> chartsDataGamesPlayed = [];
|
||||||
|
List<DropdownMenuItem<List<FlSpot>>>? smoothChartsDataGamesPlayed;
|
||||||
//var tableData = <TableRow>[];
|
//var tableData = <TableRow>[];
|
||||||
final bodyGlobalKey = GlobalKey();
|
final bodyGlobalKey = GlobalKey();
|
||||||
bool _showSearchBar = false;
|
bool _showSearchBar = false;
|
||||||
|
@ -108,7 +114,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
changePlayer(widget.player!); // it's gonna be user input
|
changePlayer(widget.player!); // it's gonna be user input
|
||||||
}else{
|
}else{
|
||||||
_getPreferences() // otherwise, checking for preferences
|
_getPreferences() // otherwise, checking for preferences
|
||||||
.then((value) => changePlayer(prefs.getString("player") ?? "dan63047")); // no preferences - loading me
|
.then((value) => changePlayer(prefs.getString("player") ?? "6098518e3d5155e6ec429cdc")); // no preferences - loading me
|
||||||
}
|
}
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
@ -185,6 +191,11 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
everyone ??= await teto.fetchTLLeaderboard();
|
everyone ??= await teto.fetchTLLeaderboard();
|
||||||
meAmongEveryone = await compute(everyone!.getLeaderboardPosition, me);
|
meAmongEveryone = await compute(everyone!.getLeaderboardPosition, me);
|
||||||
if (meAmongEveryone != null) teto.cacheLeaderboardPositions(me.userId, meAmongEveryone!);
|
if (meAmongEveryone != null) teto.cacheLeaderboardPositions(me.userId, meAmongEveryone!);
|
||||||
|
if (me.tlSeason1.rank != "z") {
|
||||||
|
thatRankCutoff = everyone!.cutoffs[me.tlSeason1.rank];
|
||||||
|
nextRankCutoff = everyone!.cutoffs[ranks.indexOf(me.tlSeason1.rank)+1];
|
||||||
|
nextRankCutoff = nextRankCutoff??25000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (everyone != null && me.tlSeason1.gamesPlayed > 9) rankAverages = everyone?.averages[me.tlSeason1.percentileRank]?[0];
|
if (everyone != null && me.tlSeason1.gamesPlayed > 9) rankAverages = everyone?.averages[me.tlSeason1.percentileRank]?[0];
|
||||||
|
@ -262,51 +273,87 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
if (uniqueTL.length >= 2){
|
if (uniqueTL.length >= 2){
|
||||||
compareWith = uniqueTL.toList().elementAtOrNull(uniqueTL.length - 2);
|
compareWith = uniqueTL.toList().elementAtOrNull(uniqueTL.length - 2);
|
||||||
chartsData = <DropdownMenuItem<List<FlSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid
|
chartsData = <DropdownMenuItem<List<FlSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rating)], child: Text(t.statCellNum.tr)),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rating)], child: Text(t.statCellNum.tr)),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.glicko!)], child: const Text("Glicko")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.glicko!)], child: const Text("Glicko")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rd!)], child: const Text("Rating Deviation")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rd!)], child: const Text("Rating Deviation")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.pps!)], child: Text(t.statCellNum.pps.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.pps!)], child: Text(t.statCellNum.pps.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.vs!)], child: Text(t.statCellNum.vs.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.vs!)], child: Text(t.statCellNum.vs.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.app)], child: Text(t.statCellNum.app.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.app)], child: Text(t.statCellNum.app.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dss)], child: Text(t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dss)], child: Text(t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dsp)], child: Text(t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dsp)], child: Text(t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.vsapm)], child: const Text("VS/APM")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.vsapm)], child: const Text("VS/APM")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.cheese)], child: Text(t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.cheese)], child: Text(t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.gbe)], child: Text(t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.gbe)], child: Text(t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.nyaapp)], child: Text(t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.nyaapp)], child: Text(t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.area)], child: Text(t.statCellNum.area.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.area)], child: Text(t.statCellNum.area.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.estTr!.esttr)], child: Text(t.statCellNum.estOfTR.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.estTr!.esttr)], child: Text(t.statCellNum.estOfTR.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.opener)], child: const Text("Opener")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.opener)], child: const Text("Opener")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.plonk)], child: const Text("Plonk")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.plonk)], child: const Text("Plonk")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.infds)], child: const Text("Inf. DS")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.infds)], child: const Text("Inf. DS")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.stride)], child: const Text("Stride")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.playstyle!.stride)], child: const Text("Stride")),
|
||||||
];
|
];
|
||||||
chartsDataGamesPlayed = <DropdownMenuItem<List<FlSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid
|
chartsDataGamesPlayed = <DropdownMenuItem<List<FlSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.rating)], child: Text(t.statCellNum.tr)),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.rating)], child: Text(t.statCellNum.tr)),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.glicko!)], child: const Text("Glicko")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.glicko!)], child: const Text("Glicko")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.rd!)], child: const Text("Rating Deviation")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.gamesPlayed.toDouble(), tl.rd!)], child: const Text("Rating Deviation")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) FlSpot(tl.gamesPlayed.toDouble(), tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) FlSpot(tl.gamesPlayed.toDouble(), tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) FlSpot(tl.gamesPlayed.toDouble(), tl.pps!)], child: Text(t.statCellNum.pps.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) FlSpot(tl.gamesPlayed.toDouble(), tl.pps!)], child: Text(t.statCellNum.pps.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) FlSpot(tl.gamesPlayed.toDouble(), tl.vs!)], child: Text(t.statCellNum.vs.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) FlSpot(tl.gamesPlayed.toDouble(), tl.vs!)], child: Text(t.statCellNum.vs.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.app)], child: Text(t.statCellNum.app.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.app)], child: Text(t.statCellNum.app.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.dss)], child: Text(t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.dss)], child: Text(t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.dsp)], child: Text(t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.dsp)], child: Text(t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.vsapm)], child: const Text("VS/APM")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.vsapm)], child: const Text("VS/APM")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.cheese)], child: Text(t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.cheese)], child: Text(t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.gbe)], child: Text(t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.gbe)], child: Text(t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.nyaapp)], child: Text(t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.nyaapp)], child: Text(t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.area)], child: Text(t.statCellNum.area.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.gamesPlayed.toDouble(), tl.nerdStats!.area)], child: Text(t.statCellNum.area.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.gamesPlayed.toDouble(), tl.estTr!.esttr)], child: Text(t.statCellNum.estOfTR.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.gamesPlayed.toDouble(), tl.estTr!.esttr)], child: Text(t.statCellNum.estOfTR.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) FlSpot(tl.gamesPlayed.toDouble(), tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) FlSpot(tl.gamesPlayed.toDouble(), tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.opener)], child: const Text("Opener")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.opener)], child: const Text("Opener")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.plonk)], child: const Text("Plonk")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.plonk)], child: const Text("Plonk")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.infds)], child: const Text("Inf. DS")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.infds)], child: const Text("Inf. DS")),
|
||||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.stride)], child: const Text("Stride")),
|
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) FlSpot(tl.gamesPlayed.toDouble(), tl.playstyle!.stride)], child: const Text("Stride")),
|
||||||
];
|
];
|
||||||
|
if (chartsData[0].value!.length > 200){
|
||||||
|
smoothChartsData = [];
|
||||||
|
smoothChartsDataGamesPlayed = [];
|
||||||
|
for (var chart in chartsData) {
|
||||||
|
int valuesPerDot = (chart.value!.length / 200).floor();
|
||||||
|
int lastDotEntries = chart.value!.length - (valuesPerDot * 199);
|
||||||
|
List<FlSpot> spots = [];
|
||||||
|
for (int i=0; i < 200; i++){
|
||||||
|
double avgX = 0, avgY = 0;
|
||||||
|
for (int k = i * valuesPerDot; k < (i == 199 ? chart.value!.length : i * valuesPerDot + valuesPerDot); k++) {
|
||||||
|
avgX += chart.value![k].x;
|
||||||
|
avgY += chart.value![k].y;
|
||||||
|
}
|
||||||
|
avgX /= i == 199 ? lastDotEntries : valuesPerDot;
|
||||||
|
avgY /= i == 199 ? lastDotEntries : valuesPerDot;
|
||||||
|
spots.add(FlSpot(avgX, avgY));
|
||||||
|
}
|
||||||
|
smoothChartsData!.add(DropdownMenuItem(value: spots, child: chart.child));
|
||||||
|
}
|
||||||
|
for (var chart in chartsDataGamesPlayed) {
|
||||||
|
int valuesPerDot = (chart.value!.length / 200).floor();
|
||||||
|
int lastDotEntries = chart.value!.length - (valuesPerDot * 199);
|
||||||
|
List<FlSpot> spots = [];
|
||||||
|
for (int i=0; i < 200; i++){
|
||||||
|
double avgX = 0, avgY = 0;
|
||||||
|
for (int k = i * valuesPerDot; k < (i == 199 ? chart.value!.length : i * valuesPerDot + valuesPerDot); k++) {
|
||||||
|
avgX += chart.value![k].x;
|
||||||
|
avgY += chart.value![k].y;
|
||||||
|
}
|
||||||
|
avgX /= i == 199 ? lastDotEntries : valuesPerDot;
|
||||||
|
avgY /= i == 199 ? lastDotEntries : valuesPerDot;
|
||||||
|
spots.add(FlSpot(avgX, avgY));
|
||||||
|
}
|
||||||
|
smoothChartsDataGamesPlayed!.add(DropdownMenuItem(value: spots, child: chart.child));
|
||||||
|
}
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
compareWith = null;
|
compareWith = null;
|
||||||
chartsData = [];
|
chartsData = [];
|
||||||
|
@ -465,6 +512,10 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
topTR: snapshot.data![7],
|
topTR: snapshot.data![7],
|
||||||
bot: snapshot.data![0].role == "bot",
|
bot: snapshot.data![0].role == "bot",
|
||||||
guest: snapshot.data![0].role == "anon",
|
guest: snapshot.data![0].role == "anon",
|
||||||
|
thatRankCutoff: thatRankCutoff,
|
||||||
|
thatRankTarget: snapshot.data![0].tlSeason1.rank != "z" ? rankTargets[snapshot.data![0].tlSeason1.rank] : null,
|
||||||
|
nextRankCutoff: nextRankCutoff,
|
||||||
|
nextRankTarget: snapshot.data![0].tlSeason1.rank != "z" || snapshot.data![0].tlSeason1.rank != "x" ? rankTargets[ranks.indexOf(snapshot.data![0].tlSeason1.rank)+1] : null,
|
||||||
averages: rankAverages,
|
averages: rankAverages,
|
||||||
lbPositions: meAmongEveryone
|
lbPositions: meAmongEveryone
|
||||||
),
|
),
|
||||||
|
@ -474,7 +525,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
child: _TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, oldMathcesHere: _TLHistoryWasFetched, separateScrollController: true,)
|
child: _TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, oldMathcesHere: _TLHistoryWasFetched, separateScrollController: true,)
|
||||||
),
|
),
|
||||||
],),
|
],),
|
||||||
_History(chartsData: chartsData, chartsDataGamesPlayed: chartsDataGamesPlayed, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
_History(chartsData: chartsData, chartsDataGamesPlayed: chartsDataGamesPlayed, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, smoothChartsData: smoothChartsData, smoothChartsDataGamesPlayed: smoothChartsDataGamesPlayed),
|
||||||
_TwoRecordsThingy(sprint: snapshot.data![1]['sprint'], blitz: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank,),
|
_TwoRecordsThingy(sprint: snapshot.data![1]['sprint'], blitz: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank,),
|
||||||
_OtherThingy(zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![6],)
|
_OtherThingy(zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![6],)
|
||||||
] : [
|
] : [
|
||||||
|
@ -489,7 +540,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
lbPositions: meAmongEveryone
|
lbPositions: meAmongEveryone
|
||||||
),
|
),
|
||||||
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, oldMathcesHere: _TLHistoryWasFetched),
|
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3], wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, oldMathcesHere: _TLHistoryWasFetched),
|
||||||
_History(chartsData: chartsData, chartsDataGamesPlayed: chartsDataGamesPlayed, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0),
|
_History(chartsData: chartsData, chartsDataGamesPlayed: chartsDataGamesPlayed, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![0].tlSeason1.gamesPlayed > 0, smoothChartsData: smoothChartsData, smoothChartsDataGamesPlayed: smoothChartsDataGamesPlayed),
|
||||||
_RecordThingy(record: snapshot.data![1]['sprint'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
_RecordThingy(record: snapshot.data![1]['sprint'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
||||||
_RecordThingy(record: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
_RecordThingy(record: snapshot.data![1]['blitz'], rank: snapshot.data![0].tlSeason1.percentileRank),
|
||||||
_OtherThingy(zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![6],)
|
_OtherThingy(zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment, newsletter: snapshot.data![6],)
|
||||||
|
@ -592,7 +643,7 @@ class _NavDrawerState extends State<NavDrawer> {
|
||||||
homePlayerNickname = id;
|
homePlayerNickname = id;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
homePlayerNickname = "dan63047";
|
homePlayerNickname = "dan63";
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
@ -624,7 +675,7 @@ class _NavDrawerState extends State<NavDrawer> {
|
||||||
leading: const Icon(Icons.home),
|
leading: const Icon(Icons.home),
|
||||||
title: Text(homePlayerNickname),
|
title: Text(homePlayerNickname),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
widget.changePlayer(prefs.getString("player") ?? "dan63047"); // changes player on main view to the one from preferences
|
widget.changePlayer(prefs.getString("player") ?? "6098518e3d5155e6ec429cdc"); // changes player on main view to the one from preferences
|
||||||
Navigator.of(context).pop(); // and then NavDrawer closes itself.
|
Navigator.of(context).pop(); // and then NavDrawer closes itself.
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -753,7 +804,9 @@ class _TLRecords extends StatelessWidget {
|
||||||
|
|
||||||
class _History extends StatelessWidget{
|
class _History extends StatelessWidget{
|
||||||
final List<DropdownMenuItem<List<FlSpot>>> chartsData;
|
final List<DropdownMenuItem<List<FlSpot>>> chartsData;
|
||||||
|
final List<DropdownMenuItem<List<FlSpot>>>? smoothChartsData;
|
||||||
final List<DropdownMenuItem<List<FlSpot>>> chartsDataGamesPlayed;
|
final List<DropdownMenuItem<List<FlSpot>>> chartsDataGamesPlayed;
|
||||||
|
final List<DropdownMenuItem<List<FlSpot>>>? smoothChartsDataGamesPlayed;
|
||||||
final String userID;
|
final String userID;
|
||||||
final Function update;
|
final Function update;
|
||||||
final Function changePlayer;
|
final Function changePlayer;
|
||||||
|
@ -761,7 +814,7 @@ class _History extends StatelessWidget{
|
||||||
|
|
||||||
/// Widget, that can show history of some stat of the player on the graph.
|
/// Widget, that can show history of some stat of the player on the graph.
|
||||||
/// Requires player [states], which is list of states and function [update], which rebuild widgets
|
/// Requires player [states], which is list of states and function [update], which rebuild widgets
|
||||||
const _History({required this.chartsData, required this.chartsDataGamesPlayed, required this.userID, required this.changePlayer, required this.update, required this.wasActiveInTL});
|
const _History({required this.chartsData, required this.chartsDataGamesPlayed, required this.userID, required this.changePlayer, required this.update, required this.wasActiveInTL, this.smoothChartsData, this.smoothChartsDataGamesPlayed});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -776,6 +829,8 @@ class _History extends StatelessWidget{
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
||||||
|
var selectedGraph = _gamesPlayedInsteadOfDateAndTime ? chartsDataGamesPlayed[_chartsIndex].value! : chartsData[_chartsIndex].value!;
|
||||||
|
var smoothSelectedGraph = _gamesPlayedInsteadOfDateAndTime ? (smoothChartsDataGamesPlayed?[_chartsIndex].value) : (smoothChartsData?[_chartsIndex].value);
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
|
@ -786,6 +841,7 @@ class _History extends StatelessWidget{
|
||||||
children: [
|
children: [
|
||||||
Wrap(
|
Wrap(
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@ -815,9 +871,21 @@ class _History extends StatelessWidget{
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (smoothSelectedGraph != null) Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Checkbox(value: _smooth,
|
||||||
|
checkColor: Colors.black,
|
||||||
|
onChanged: ((value) {
|
||||||
|
_smooth = value!;
|
||||||
|
update();
|
||||||
|
})),
|
||||||
|
Text(t.smooth, style: const TextStyle(color: Colors.white, fontSize: 22))
|
||||||
|
],
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if(chartsData[_chartsIndex].value!.length > 1) _HistoryChartThigy(data: _gamesPlayedInsteadOfDateAndTime ? chartsDataGamesPlayed[_chartsIndex].value! : chartsData[_chartsIndex].value!, yAxisTitle: _historyShortTitles[_chartsIndex], bigScreen: bigScreen, leftSpace: bigScreen? 80 : 45, yFormat: bigScreen? f2 : NumberFormat.compact(), xFormat: NumberFormat.compact())
|
if(chartsData[_chartsIndex].value!.length > 1) _HistoryChartThigy(data: selectedGraph, smoothData: smoothSelectedGraph, smooth: _smooth, yAxisTitle: _historyShortTitles[_chartsIndex], bigScreen: bigScreen, leftSpace: bigScreen? 80 : 45, yFormat: bigScreen? f2 : NumberFormat.compact(), xFormat: NumberFormat.compact())
|
||||||
else if (chartsData[_chartsIndex].value!.length <= 1) Center(child: Column(
|
else if (chartsData[_chartsIndex].value!.length <= 1) Center(child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
@ -835,6 +903,8 @@ class _History extends StatelessWidget{
|
||||||
|
|
||||||
class _HistoryChartThigy extends StatefulWidget{
|
class _HistoryChartThigy extends StatefulWidget{
|
||||||
final List<FlSpot> data;
|
final List<FlSpot> data;
|
||||||
|
final List<FlSpot>? smoothData;
|
||||||
|
final bool smooth;
|
||||||
final String yAxisTitle;
|
final String yAxisTitle;
|
||||||
final bool bigScreen;
|
final bool bigScreen;
|
||||||
final double leftSpace;
|
final double leftSpace;
|
||||||
|
@ -844,7 +914,7 @@ class _HistoryChartThigy extends StatefulWidget{
|
||||||
/// Implements graph for the _History widget. Requires [data] which is a list of dots for the graph. [yAxisTitle] used to keep track of changes.
|
/// Implements graph for the _History widget. Requires [data] which is a list of dots for the graph. [yAxisTitle] used to keep track of changes.
|
||||||
/// [bigScreen] tells if screen wide enough, [leftSpace] sets size, reserved for titles on the left from the graph and [yFormat] sets number format
|
/// [bigScreen] tells if screen wide enough, [leftSpace] sets size, reserved for titles on the left from the graph and [yFormat] sets number format
|
||||||
/// for left titles
|
/// for left titles
|
||||||
const _HistoryChartThigy({required this.data, required this.yAxisTitle, required this.bigScreen, required this.leftSpace, required this.yFormat, this.xFormat});
|
const _HistoryChartThigy({required this.data, this.smoothData, required this.smooth, required this.yAxisTitle, required this.bigScreen, required this.leftSpace, required this.yFormat, this.xFormat});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_HistoryChartThigy> createState() => _HistoryChartThigyState();
|
State<_HistoryChartThigy> createState() => _HistoryChartThigyState();
|
||||||
|
@ -1050,8 +1120,26 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
||||||
children: [
|
children: [
|
||||||
LineChart(
|
LineChart(
|
||||||
key: graphKey,
|
key: graphKey,
|
||||||
|
curve: Curves.elasticInOut,
|
||||||
LineChartData(
|
LineChartData(
|
||||||
lineBarsData: [LineChartBarData(spots: widget.data)],
|
lineBarsData: [
|
||||||
|
LineChartBarData(
|
||||||
|
show: !_smooth,
|
||||||
|
spots: widget.data,
|
||||||
|
dotData: FlDotData(show: false),
|
||||||
|
isCurved: true,
|
||||||
|
curveSmoothness: 0.35,
|
||||||
|
preventCurveOverShooting: true
|
||||||
|
),
|
||||||
|
if (widget.smoothData != null) LineChartBarData(
|
||||||
|
show: _smooth,
|
||||||
|
spots: widget.smoothData!,
|
||||||
|
dotData: FlDotData(show: false),
|
||||||
|
isCurved: true,
|
||||||
|
curveSmoothness: 0.35,
|
||||||
|
preventCurveOverShooting: true,
|
||||||
|
)
|
||||||
|
],
|
||||||
clipData: const FlClipData.all(),
|
clipData: const FlClipData.all(),
|
||||||
borderData: FlBorderData(show: false),
|
borderData: FlBorderData(show: false),
|
||||||
gridData: FlGridData(verticalInterval: xInterval),
|
gridData: FlGridData(verticalInterval: xInterval),
|
||||||
|
@ -1116,29 +1204,6 @@ class _HistoryChartThigyState extends State<_HistoryChartThigy> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// class _HistoryTableThingy extends StatelessWidget{
|
|
||||||
// final List<TableRow> tableData;
|
|
||||||
|
|
||||||
// const _HistoryTableThingy(this.tableData);
|
|
||||||
// // :tf:
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// return LayoutBuilder(builder: (context, constraints){
|
|
||||||
// return Table(
|
|
||||||
// defaultColumnWidth: FixedColumnWidth(75),
|
|
||||||
// columnWidths: {
|
|
||||||
// 0: FixedColumnWidth(170),
|
|
||||||
// 1: FixedColumnWidth(100),
|
|
||||||
// 2: FixedColumnWidth(90),
|
|
||||||
// 18: FixedColumnWidth(100),
|
|
||||||
// 19: FixedColumnWidth(90),
|
|
||||||
// },
|
|
||||||
// children: tableData,
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
class _TwoRecordsThingy extends StatelessWidget {
|
class _TwoRecordsThingy extends StatelessWidget {
|
||||||
final RecordSingle? sprint;
|
final RecordSingle? sprint;
|
||||||
final RecordSingle? blitz;
|
final RecordSingle? blitz;
|
||||||
|
|
|
@ -15,6 +15,7 @@ var _chartsShortTitlesDropdowns = <DropdownMenuItem>[for (MapEntry e in chartsSh
|
||||||
Stats _chartsX = Stats.tr;
|
Stats _chartsX = Stats.tr;
|
||||||
Stats _chartsY = Stats.apm;
|
Stats _chartsY = Stats.apm;
|
||||||
List<DropdownMenuItem> _itemStats = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuItem(value: e.key, child: Text(e.value))];
|
List<DropdownMenuItem> _itemStats = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuItem(value: e.key, child: Text(e.value))];
|
||||||
|
List<_MyScatterSpot> _spots = [];
|
||||||
Stats _sortBy = Stats.tr;
|
Stats _sortBy = Stats.tr;
|
||||||
late List<TetrioPlayerFromLeaderboard> they;
|
late List<TetrioPlayerFromLeaderboard> they;
|
||||||
bool _reversed = false;
|
bool _reversed = false;
|
||||||
|
@ -63,6 +64,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
||||||
super.initState();
|
super.initState();
|
||||||
previousAxisTitles = _chartsX.toString()+_chartsY.toString();
|
previousAxisTitles = _chartsX.toString()+_chartsY.toString();
|
||||||
they = TetrioPlayersLeaderboard("lol", []).getStatRanking(widget.rank[1]["entries"]!, _sortBy, reversed: _reversed, country: _country);
|
they = TetrioPlayersLeaderboard("lol", []).getStatRanking(widget.rank[1]["entries"]!, _sortBy, reversed: _reversed, country: _country);
|
||||||
|
createSpots();
|
||||||
recalculateBoundaries();
|
recalculateBoundaries();
|
||||||
resetScale();
|
resetScale();
|
||||||
}
|
}
|
||||||
|
@ -101,6 +103,19 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
||||||
}
|
}
|
||||||
}).getStatByEnum(_chartsY).toDouble();
|
}).getStatByEnum(_chartsY).toDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createSpots(){
|
||||||
|
_spots = [
|
||||||
|
for (TetrioPlayerFromLeaderboard entry in widget.rank[1]["entries"])
|
||||||
|
if (entry.apm != 0.0 && entry.vs != 0.0) // prevents from ScatterChart "Offset argument contained a NaN value." exception
|
||||||
|
_MyScatterSpot(
|
||||||
|
entry.getStatByEnum(_chartsX).toDouble(),
|
||||||
|
entry.getStatByEnum(_chartsY).toDouble(),
|
||||||
|
entry.userId,
|
||||||
|
entry.username,
|
||||||
|
dotPainter: FlDotCirclePainter(color: rankColors[entry.rank]??Colors.white, radius: 3))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
void resetScale(){
|
void resetScale(){
|
||||||
maxX = actualMaxX;
|
maxX = actualMaxX;
|
||||||
|
@ -161,6 +176,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
||||||
double graphStartX = padding.left;
|
double graphStartX = padding.left;
|
||||||
double graphEndX = MediaQuery.sizeOf(context).width - padding.right;
|
double graphEndX = MediaQuery.sizeOf(context).width - padding.right;
|
||||||
if (previousAxisTitles != _chartsX.toString()+_chartsY.toString()){
|
if (previousAxisTitles != _chartsX.toString()+_chartsY.toString()){
|
||||||
|
createSpots();
|
||||||
recalculateBoundaries();
|
recalculateBoundaries();
|
||||||
resetScale();
|
resetScale();
|
||||||
previousAxisTitles = _chartsX.toString()+_chartsY.toString();
|
previousAxisTitles = _chartsX.toString()+_chartsY.toString();
|
||||||
|
@ -325,16 +341,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
||||||
minY: minY,
|
minY: minY,
|
||||||
maxY: maxY,
|
maxY: maxY,
|
||||||
clipData: const FlClipData.all(),
|
clipData: const FlClipData.all(),
|
||||||
scatterSpots: [
|
scatterSpots: _spots,
|
||||||
for (TetrioPlayerFromLeaderboard entry in widget.rank[1]["entries"])
|
|
||||||
if (entry.apm != 0.0 && entry.vs != 0.0) // prevents from ScatterChart "Offset argument contained a NaN value." exception
|
|
||||||
_MyScatterSpot(
|
|
||||||
entry.getStatByEnum(_chartsX).toDouble(),
|
|
||||||
entry.getStatByEnum(_chartsY).toDouble(),
|
|
||||||
entry.userId,
|
|
||||||
entry.username,
|
|
||||||
dotPainter: FlDotCirclePainter(color: rankColors[entry.rank]??Colors.white, radius: 3))
|
|
||||||
],
|
|
||||||
scatterTouchData: ScatterTouchData(
|
scatterTouchData: ScatterTouchData(
|
||||||
handleBuiltInTouches: false,
|
handleBuiltInTouches: false,
|
||||||
touchCallback:(touchEvent, touchResponse) {
|
touchCallback:(touchEvent, touchResponse) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ class SettingsState extends State<SettingsView> {
|
||||||
defaultNickname = n;
|
defaultNickname = n;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
defaultNickname = "dan63047";
|
defaultNickname = "6098518e3d5155e6ec429cdc";
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ class SettingsState extends State<SettingsView> {
|
||||||
|
|
||||||
Future<void> _removePlayer() async {
|
Future<void> _removePlayer() async {
|
||||||
await prefs.remove('player');
|
await prefs.remove('player');
|
||||||
await _setDefaultNickname("dan63047");
|
await _setDefaultNickname("6098518e3d5155e6ec429cdc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:tetra_stats/data_objects/tetrio_multiplayer_replay.dart';
|
import 'package:tetra_stats/data_objects/tetrio_multiplayer_replay.dart';
|
||||||
import 'package:tetra_stats/services/crud_exceptions.dart';
|
import 'package:tetra_stats/services/crud_exceptions.dart';
|
||||||
import 'package:tetra_stats/views/compare_view.dart' show CompareThingy, CompareBoolThingy;
|
import 'package:tetra_stats/views/compare_view.dart' show CompareThingy, CompareBoolThingy;
|
||||||
|
@ -62,422 +64,426 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildComparison(bool bigScreen, bool showMobileSelector){
|
Widget buildComparison(double width, bool showMobileSelector){
|
||||||
return FutureBuilder(future: replayData, builder: (context, snapshot){
|
bool bigScreen = width >= 768;
|
||||||
late Duration time;
|
return SizedBox(
|
||||||
late String readableTime;
|
width: width,
|
||||||
late String reason;
|
child: FutureBuilder(future: replayData, builder: (context, snapshot){
|
||||||
timeWeightedStatsAvaliable = true;
|
late Duration time;
|
||||||
if (snapshot.connectionState != ConnectionState.done) return const LinearProgressIndicator();
|
late String readableTime;
|
||||||
if (!snapshot.hasError){
|
late String reason;
|
||||||
if (rounds.indexWhere((element) => element.value == -2) == -1) rounds.insert(1, DropdownMenuItem(value: -2, child: Text(t.timeWeightedmatch)));
|
timeWeightedStatsAvaliable = true;
|
||||||
greenSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId == widget.initPlayerId);
|
if (snapshot.connectionState != ConnectionState.done) return const LinearProgressIndicator();
|
||||||
redSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId != widget.initPlayerId);
|
if (!snapshot.hasError){
|
||||||
if (roundSelector.isNegative){
|
if (rounds.indexWhere((element) => element.value == -2) == -1) rounds.insert(1, DropdownMenuItem(value: -2, child: Text(t.timeWeightedmatch)));
|
||||||
time = framesToTime(snapshot.data!.totalLength);
|
greenSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId == widget.initPlayerId);
|
||||||
readableTime = "${t.matchLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}";
|
redSidePlayer = snapshot.data!.endcontext.indexWhere((element) => element.userId != widget.initPlayerId);
|
||||||
|
if (roundSelector.isNegative){
|
||||||
|
time = framesToTime(snapshot.data!.totalLength);
|
||||||
|
readableTime = "${t.matchLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}";
|
||||||
|
}else{
|
||||||
|
time = framesToTime(snapshot.data!.roundLengths[roundSelector]);
|
||||||
|
readableTime = "${t.roundLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}\n${t.winner}: ${snapshot.data!.roundWinners[roundSelector][1]}";
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
time = framesToTime(snapshot.data!.roundLengths[roundSelector]);
|
switch (snapshot.error.runtimeType){
|
||||||
readableTime = "${t.roundLength}: ${time.inMinutes}:${secs.format(time.inMicroseconds /1000000 % 60)}\n${t.winner}: ${snapshot.data!.roundWinners[roundSelector][1]}";
|
case ReplayNotAvalable:
|
||||||
|
reason = t.matchIsTooOld;
|
||||||
|
break;
|
||||||
|
case SzyNotFound:
|
||||||
|
reason = t.matchIsTooOld;
|
||||||
|
break;
|
||||||
|
case SzyForbidden:
|
||||||
|
reason = t.errors.replayRejected;
|
||||||
|
break;
|
||||||
|
case SzyTooManyRequests:
|
||||||
|
reason = t.errors.tooManyRequests;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reason = snapshot.error.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else{
|
return NestedScrollView(
|
||||||
switch (snapshot.error.runtimeType){
|
headerSliverBuilder: (context, value) {
|
||||||
case ReplayNotAvalable:
|
return [
|
||||||
reason = t.matchIsTooOld;
|
SliverToBoxAdapter(
|
||||||
break;
|
child: Padding(
|
||||||
case SzyNotFound:
|
padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
|
||||||
reason = t.matchIsTooOld;
|
child: Row(
|
||||||
break;
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
case SzyForbidden:
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
reason = t.errors.replayRejected;
|
children: [
|
||||||
break;
|
Expanded(
|
||||||
case SzyTooManyRequests:
|
child: Container(
|
||||||
reason = t.errors.tooManyRequests;
|
decoration: BoxDecoration(
|
||||||
break;
|
gradient: LinearGradient(
|
||||||
default:
|
colors: const [Colors.green, Colors.transparent],
|
||||||
reason = snapshot.error.toString();
|
begin: Alignment.bottomCenter,
|
||||||
break;
|
end: Alignment.topCenter,
|
||||||
}
|
stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).success ? 0.4 : 0.0],
|
||||||
}
|
)),
|
||||||
return NestedScrollView(
|
child: Padding(
|
||||||
headerSliverBuilder: (context, value) {
|
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||||
return [
|
child: Column(children: [
|
||||||
SliverToBoxAdapter(
|
Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username, style: bigScreen ? const TextStyle(
|
||||||
child: Padding(
|
fontFamily: "Eurostile Round Extended",
|
||||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
|
fontSize: 28) : const TextStyle()),
|
||||||
child: Row(
|
Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).points.toString(), style: const TextStyle(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
fontFamily: "Eurostile Round Extended",
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
fontSize: 42))
|
||||||
children: [
|
]),
|
||||||
Expanded(
|
),
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: const [Colors.green, Colors.transparent],
|
|
||||||
begin: Alignment.bottomCenter,
|
|
||||||
end: Alignment.topCenter,
|
|
||||||
stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).success ? 0.4 : 0.0],
|
|
||||||
)),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
|
||||||
child: Column(children: [
|
|
||||||
Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).username, style: bigScreen ? const TextStyle(
|
|
||||||
fontFamily: "Eurostile Round Extended",
|
|
||||||
fontSize: 28) : const TextStyle()),
|
|
||||||
Text(widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).points.toString(), style: const TextStyle(
|
|
||||||
fontFamily: "Eurostile Round Extended",
|
|
||||||
fontSize: 42))
|
|
||||||
]),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const Padding(
|
||||||
const Padding(
|
padding: EdgeInsets.only(top: 16),
|
||||||
padding: EdgeInsets.only(top: 16),
|
child: Text("VS"),
|
||||||
child: Text("VS"),
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: Container(
|
||||||
child: Container(
|
decoration: BoxDecoration(
|
||||||
decoration: BoxDecoration(
|
gradient: LinearGradient(
|
||||||
gradient: LinearGradient(
|
colors: const [Colors.red, Colors.transparent],
|
||||||
colors: const [Colors.red, Colors.transparent],
|
begin: Alignment.bottomCenter,
|
||||||
begin: Alignment.bottomCenter,
|
end: Alignment.topCenter,
|
||||||
end: Alignment.topCenter,
|
stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).success ? 0.4 : 0.0],
|
||||||
stops: [0.0, widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).success ? 0.4 : 0.0],
|
)),
|
||||||
)),
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
||||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
child: Column(children: [
|
||||||
child: Column(children: [
|
Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username, style: bigScreen ? const TextStyle(
|
||||||
Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).username, style: bigScreen ? const TextStyle(
|
fontFamily: "Eurostile Round Extended",
|
||||||
fontFamily: "Eurostile Round Extended",
|
fontSize: 28) : const TextStyle()),
|
||||||
fontSize: 28) : const TextStyle()),
|
Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).points.toString(), style: const TextStyle(
|
||||||
Text(widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).points.toString(), style: const TextStyle(
|
fontFamily: "Eurostile Round Extended",
|
||||||
fontFamily: "Eurostile Round Extended",
|
fontSize: 42))
|
||||||
fontSize: 42))
|
]),
|
||||||
]),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (showMobileSelector) SliverToBoxAdapter(
|
||||||
if (showMobileSelector) SliverToBoxAdapter(
|
child: Center(
|
||||||
child: Center(
|
child: Row(
|
||||||
child: Row(
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisSize: MainAxisSize.min,
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
textBaseline: TextBaseline.alphabetic,
|
||||||
textBaseline: TextBaseline.alphabetic,
|
children: [
|
||||||
children: [
|
Text("${t.statsFor}: ",
|
||||||
Text("${t.statsFor}: ",
|
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
DropdownButton(items: rounds, value: roundSelector, onChanged: ((value) {
|
||||||
DropdownButton(items: rounds, value: roundSelector, onChanged: ((value) {
|
roundSelector = value;
|
||||||
roundSelector = value;
|
setState(() {});
|
||||||
setState(() {});
|
}),),
|
||||||
}),),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (widget.record.ownId == widget.record.replayId && showMobileSelector) SliverToBoxAdapter(
|
||||||
if (widget.record.ownId == widget.record.replayId && showMobileSelector) SliverToBoxAdapter(
|
child: Center(child: Text(t.p1nkl0bst3rAlert, textAlign: TextAlign.center)),
|
||||||
child: Center(child: Text(t.p1nkl0bst3rAlert, textAlign: TextAlign.center)),
|
),
|
||||||
),
|
if (showMobileSelector) SliverToBoxAdapter(child: Center(child: Text(snapshot.hasError ? reason : readableTime, textAlign: TextAlign.center))),
|
||||||
if (showMobileSelector) SliverToBoxAdapter(child: Center(child: Text(snapshot.hasError ? reason : readableTime, textAlign: TextAlign.center))),
|
const SliverToBoxAdapter(
|
||||||
const SliverToBoxAdapter(
|
child: Divider(),
|
||||||
child: Divider(),
|
|
||||||
)
|
|
||||||
];
|
|
||||||
},
|
|
||||||
body: ListView(
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
CompareThingy(
|
|
||||||
label: "APM",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].apm :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector],
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].apm :
|
|
||||||
roundSelector == -1 ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector],
|
|
||||||
fractionDigits: 2,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "PPS",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].pps:
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector],
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].pps :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector],
|
|
||||||
fractionDigits: 2,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "VS",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].vs :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector],
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].vs :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector],
|
|
||||||
fractionDigits: 2,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
if (snapshot.hasData) Column(children: [
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].inputs : snapshot.data!.stats[roundSelector][greenSidePlayer].inputs,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].inputs : snapshot.data!.stats[roundSelector][redSidePlayer].inputs,
|
|
||||||
label: "Inputs", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][greenSidePlayer].piecesPlaced,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][redSidePlayer].piecesPlaced,
|
|
||||||
label: "Pieces Placed", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].kpp :
|
|
||||||
roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kpp : snapshot.data!.stats[roundSelector][greenSidePlayer].kpp,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].kpp :
|
|
||||||
roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kpp : snapshot.data!.stats[roundSelector][redSidePlayer].kpp,
|
|
||||||
label: "KpP", higherIsBetter: false, fractionDigits: 2,),
|
|
||||||
CompareThingy(greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].kps :
|
|
||||||
roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kps : snapshot.data!.stats[roundSelector][greenSidePlayer].kps,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].kps :
|
|
||||||
roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kps : snapshot.data!.stats[roundSelector][redSidePlayer].kps,
|
|
||||||
label: "KpS", higherIsBetter: true, fractionDigits: 2,),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][greenSidePlayer].linesCleared,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][redSidePlayer].linesCleared,
|
|
||||||
label: "Lines Cleared", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].score : snapshot.data!.stats[roundSelector][greenSidePlayer].score,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].score : snapshot.data!.stats[roundSelector][redSidePlayer].score,
|
|
||||||
label: "Score", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].spp :
|
|
||||||
roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].spp : snapshot.data!.stats[roundSelector][greenSidePlayer].spp,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].spp :
|
|
||||||
roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].spp : snapshot.data!.stats[roundSelector][redSidePlayer].spp,
|
|
||||||
label: "SpP", higherIsBetter: true, fractionDigits: 2,),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][greenSidePlayer].finessePercentage * 100,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][redSidePlayer].finessePercentage * 100,
|
|
||||||
label: "Finnese", postfix: "%", fractionDigits: 2, higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topSpike : snapshot.data!.stats[roundSelector][greenSidePlayer].topSpike,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topSpike : snapshot.data!.stats[roundSelector][redSidePlayer].topSpike,
|
|
||||||
label: "Best Spike", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topCombo : snapshot.data!.stats[roundSelector][greenSidePlayer].topCombo,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topCombo : snapshot.data!.stats[roundSelector][redSidePlayer].topCombo,
|
|
||||||
label: "Best Combo", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topBtB : snapshot.data!.stats[roundSelector][greenSidePlayer].topBtB,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topBtB : snapshot.data!.stats[roundSelector][redSidePlayer].topBtB,
|
|
||||||
label: "Best BtB", higherIsBetter: true),
|
|
||||||
const Divider(),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 16),
|
|
||||||
child: Text("Garbage", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
|
||||||
),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.sent,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.sent,
|
|
||||||
label: "Sent", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.recived,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.recived,
|
|
||||||
label: "Recived", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.attack,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.attack,
|
|
||||||
label: "Attack", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.cleared,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.cleared,
|
|
||||||
label: "Cleared", higherIsBetter: true),
|
|
||||||
const Divider(),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 16),
|
|
||||||
child: Text("Line Clears", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
|
||||||
),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.allClears,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][redSidePlayer].clears.allClears,
|
|
||||||
label: "PC", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].tspins : snapshot.data!.stats[roundSelector][greenSidePlayer].tspins,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].tspins : snapshot.data!.stats[roundSelector][redSidePlayer].tspins,
|
|
||||||
label: "T-spins", higherIsBetter: true),
|
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.quads,
|
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][redSidePlayer].clears.quads,
|
|
||||||
label: "Quads", higherIsBetter: true),
|
|
||||||
],),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 16),
|
|
||||||
child: Text(t.nerdStats,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: "Eurostile Round Extended",
|
|
||||||
fontSize: bigScreen ? 42 : 28)),
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "APP",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.app :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].app,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.app :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].app,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "VS/APM",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.vsapm :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.vsapm :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "DS/S",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.dss :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dss,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.dss :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dss,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "DS/P",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.dsp :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dsp,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.dsp :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dsp,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "APP + DS/P",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.appdsp :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.appdsp :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "),
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.cheese :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].cheese,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.cheese :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].cheese,
|
|
||||||
fractionDigits: 2,
|
|
||||||
higherIsBetter: false,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "Gb Eff.",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.gbe :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].gbe,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.gbe :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].gbe,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "wAPP",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.nyaapp :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.nyaapp :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "Area",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.area :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].area,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.area :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].area,
|
|
||||||
fractionDigits: 2,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: t.statCellNum.estOfTRShort,
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].estTr.esttr :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTrTracking[roundSelector].esttr,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].estTr.esttr :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTrTracking[roundSelector].esttr,
|
|
||||||
fractionDigits: 2,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "Opener",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.opener :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].opener,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.opener :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].opener,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "Plonk",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.plonk :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].plonk,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.plonk :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].plonk,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "Stride",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.stride :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].stride,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.stride :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].stride,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
label: "Inf. DS",
|
|
||||||
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.infds :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].infds,
|
|
||||||
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.infds :
|
|
||||||
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].infds,
|
|
||||||
fractionDigits: 3,
|
|
||||||
higherIsBetter: true,
|
|
||||||
),
|
|
||||||
VsGraphs(
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].apm : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].pps : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].vs : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].apm : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].pps : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].vs : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector],
|
|
||||||
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector]
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (widget.record.ownId != widget.record.replayId) const Divider(),
|
|
||||||
if (widget.record.ownId != widget.record.replayId) Column(
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 16),
|
|
||||||
child: Text("Handling",
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: "Eurostile Round Extended",
|
|
||||||
fontSize: bigScreen ? 42 : 28)),
|
|
||||||
),
|
|
||||||
CompareThingy(
|
|
||||||
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.das,
|
|
||||||
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.das,
|
|
||||||
label: "DAS", fractionDigits: 1, postfix: "F",
|
|
||||||
higherIsBetter: false),
|
|
||||||
CompareThingy(
|
|
||||||
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.arr,
|
|
||||||
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.arr,
|
|
||||||
label: "ARR", fractionDigits: 1, postfix: "F",
|
|
||||||
higherIsBetter: false),
|
|
||||||
CompareThingy(
|
|
||||||
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.sdf,
|
|
||||||
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.sdf,
|
|
||||||
label: "SDF", prefix: "x",
|
|
||||||
higherIsBetter: true),
|
|
||||||
CompareBoolThingy(
|
|
||||||
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.safeLock,
|
|
||||||
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.safeLock,
|
|
||||||
label: "Safe HD",
|
|
||||||
trueIsBetter: true)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
);
|
];
|
||||||
});
|
},
|
||||||
|
body: ListView(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
CompareThingy(
|
||||||
|
label: "APM",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].apm :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector],
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].apm :
|
||||||
|
roundSelector == -1 ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector],
|
||||||
|
fractionDigits: 2,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "PPS",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].pps:
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector],
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].pps :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector],
|
||||||
|
fractionDigits: 2,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "VS",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].vs :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector],
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].vs :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector],
|
||||||
|
fractionDigits: 2,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
if (snapshot.hasData) Column(children: [
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].inputs : snapshot.data!.stats[roundSelector][greenSidePlayer].inputs,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].inputs : snapshot.data!.stats[roundSelector][redSidePlayer].inputs,
|
||||||
|
label: "Inputs", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][greenSidePlayer].piecesPlaced,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].piecesPlaced : snapshot.data!.stats[roundSelector][redSidePlayer].piecesPlaced,
|
||||||
|
label: "Pieces Placed", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].kpp :
|
||||||
|
roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kpp : snapshot.data!.stats[roundSelector][greenSidePlayer].kpp,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].kpp :
|
||||||
|
roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kpp : snapshot.data!.stats[roundSelector][redSidePlayer].kpp,
|
||||||
|
label: "KpP", higherIsBetter: false, fractionDigits: 2,),
|
||||||
|
CompareThingy(greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].kps :
|
||||||
|
roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].kps : snapshot.data!.stats[roundSelector][greenSidePlayer].kps,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].kps :
|
||||||
|
roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].kps : snapshot.data!.stats[roundSelector][redSidePlayer].kps,
|
||||||
|
label: "KpS", higherIsBetter: true, fractionDigits: 2,),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][greenSidePlayer].linesCleared,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][redSidePlayer].linesCleared,
|
||||||
|
label: "Lines Cleared", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].score : snapshot.data!.stats[roundSelector][greenSidePlayer].score,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].score : snapshot.data!.stats[roundSelector][redSidePlayer].score,
|
||||||
|
label: "Score", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].spp :
|
||||||
|
roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].spp : snapshot.data!.stats[roundSelector][greenSidePlayer].spp,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].spp :
|
||||||
|
roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].spp : snapshot.data!.stats[roundSelector][redSidePlayer].spp,
|
||||||
|
label: "SpP", higherIsBetter: true, fractionDigits: 2,),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][greenSidePlayer].finessePercentage * 100,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][redSidePlayer].finessePercentage * 100,
|
||||||
|
label: "Finnese", postfix: "%", fractionDigits: 2, higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topSpike : snapshot.data!.stats[roundSelector][greenSidePlayer].topSpike,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topSpike : snapshot.data!.stats[roundSelector][redSidePlayer].topSpike,
|
||||||
|
label: "Best Spike", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topCombo : snapshot.data!.stats[roundSelector][greenSidePlayer].topCombo,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topCombo : snapshot.data!.stats[roundSelector][redSidePlayer].topCombo,
|
||||||
|
label: "Best Combo", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].topBtB : snapshot.data!.stats[roundSelector][greenSidePlayer].topBtB,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].topBtB : snapshot.data!.stats[roundSelector][redSidePlayer].topBtB,
|
||||||
|
label: "Best BtB", higherIsBetter: true),
|
||||||
|
const Divider(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: Text("Garbage", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
||||||
|
),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.sent,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.sent : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.sent,
|
||||||
|
label: "Sent", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.recived,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.recived,
|
||||||
|
label: "Recived", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.attack,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.attack,
|
||||||
|
label: "Attack", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.cleared,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.cleared,
|
||||||
|
label: "Cleared", higherIsBetter: true),
|
||||||
|
const Divider(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: Text("Line Clears", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
||||||
|
),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.allClears,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][redSidePlayer].clears.allClears,
|
||||||
|
label: "PC", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].tspins : snapshot.data!.stats[roundSelector][greenSidePlayer].tspins,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].tspins : snapshot.data!.stats[roundSelector][redSidePlayer].tspins,
|
||||||
|
label: "T-spins", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.quads,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][redSidePlayer].clears.quads,
|
||||||
|
label: "Quads", higherIsBetter: true),
|
||||||
|
],),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: Text(t.nerdStats,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Eurostile Round Extended",
|
||||||
|
fontSize: bigScreen ? 42 : 28)),
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "APP",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.app :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].app,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.app :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.app : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].app,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "VS/APM",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.vsapm :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.vsapm :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.vsapm : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].vsapm,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "DS/S",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.dss :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dss,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.dss :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dss : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dss,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "DS/P",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.dsp :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].dsp,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.dsp :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.dsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].dsp,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "APP + DS/P",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.appdsp :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.appdsp :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.appdsp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].appdsp,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "),
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.cheese :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].cheese,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.cheese :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.cheese : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].cheese,
|
||||||
|
fractionDigits: 2,
|
||||||
|
higherIsBetter: false,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "Gb Eff.",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.gbe :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].gbe,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.gbe :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.gbe : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].gbe,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "wAPP",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.nyaapp :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.nyaapp :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.nyaapp : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].nyaapp,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "Area",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats.area :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector].area,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats.area :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats.area : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector].area,
|
||||||
|
fractionDigits: 2,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: t.statCellNum.estOfTRShort,
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].estTr.esttr :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTrTracking[roundSelector].esttr,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].estTr.esttr :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTr.esttr : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTrTracking[roundSelector].esttr,
|
||||||
|
fractionDigits: 2,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "Opener",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.opener :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].opener,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.opener :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.opener : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].opener,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "Plonk",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.plonk :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].plonk,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.plonk :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.plonk : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].plonk,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "Stride",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.stride :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].stride,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.stride :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.stride : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].stride,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
label: "Inf. DS",
|
||||||
|
greenSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle.infds :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector].infds,
|
||||||
|
redSide: (roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle.infds :
|
||||||
|
roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle.infds : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector].infds,
|
||||||
|
fractionDigits: 3,
|
||||||
|
higherIsBetter: true,
|
||||||
|
),
|
||||||
|
VsGraphs(
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].apm : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).secondaryTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].pps : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).tertiaryTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].vs : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).extraTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].nerdStats : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).nerdStatsTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[greenSidePlayer].playstyle : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).playstyleTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].apm : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).secondaryTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].pps : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiary : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).tertiaryTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].vs : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extra : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).extraTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].nerdStats : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStats : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).nerdStatsTracking[roundSelector],
|
||||||
|
(roundSelector == -2 && snapshot.hasData) ? snapshot.data!.timeWeightedStats[redSidePlayer].playstyle : roundSelector.isNegative ? widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyle : widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).playstyleTracking[roundSelector]
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (widget.record.ownId != widget.record.replayId) const Divider(),
|
||||||
|
if (widget.record.ownId != widget.record.replayId) Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: Text("Handling",
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Eurostile Round Extended",
|
||||||
|
fontSize: bigScreen ? 42 : 28)),
|
||||||
|
),
|
||||||
|
CompareThingy(
|
||||||
|
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.das,
|
||||||
|
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.das,
|
||||||
|
label: "DAS", fractionDigits: 1, postfix: "F",
|
||||||
|
higherIsBetter: false),
|
||||||
|
CompareThingy(
|
||||||
|
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.arr,
|
||||||
|
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.arr,
|
||||||
|
label: "ARR", fractionDigits: 1, postfix: "F",
|
||||||
|
higherIsBetter: false),
|
||||||
|
CompareThingy(
|
||||||
|
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.sdf,
|
||||||
|
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.sdf,
|
||||||
|
label: "SDF", prefix: "x",
|
||||||
|
higherIsBetter: true),
|
||||||
|
CompareBoolThingy(
|
||||||
|
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).handling.safeLock,
|
||||||
|
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).handling.safeLock,
|
||||||
|
label: "Safe HD",
|
||||||
|
trueIsBetter: true)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildRoundSelector(double width){
|
Widget buildRoundSelector(double width){
|
||||||
|
@ -684,21 +690,17 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
||||||
return Center(
|
return Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: const BoxConstraints(maxWidth: 768),
|
constraints: const BoxConstraints(maxWidth: 768),
|
||||||
child: buildComparison(viewportWidth > 768, true)
|
child: buildComparison(viewportWidth, true)
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
double comparisonWidth = viewportWidth - 450 - 16;
|
||||||
|
comparisonWidth = comparisonWidth > 768 ? 768 : comparisonWidth;
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
buildComparison(comparisonWidth, false),
|
||||||
width: 768,
|
buildRoundSelector(450)
|
||||||
child: buildComparison(true, false)
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
constraints: const BoxConstraints(maxWidth: 768),
|
|
||||||
child: buildRoundSelector(max(viewportWidth-768-16, 200)),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,10 @@ class Graphs extends StatelessWidget{
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
double attack = apm / 60 * 0.4;
|
||||||
|
double speed = pps / 3.75;
|
||||||
|
double defense = nerdStats.dss * 1.15;
|
||||||
|
double cheese = nerdStats.cheese / 110;
|
||||||
return Wrap(
|
return Wrap(
|
||||||
direction: Axis.horizontal,
|
direction: Axis.horizontal,
|
||||||
alignment: WrapAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
|
@ -27,7 +31,7 @@ class Graphs extends StatelessWidget{
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
if (true) Padding( // vs graph
|
||||||
padding: const EdgeInsets.fromLTRB(18, 0, 18, 44),
|
padding: const EdgeInsets.fromLTRB(18, 0, 18, 44),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 310,
|
height: 310,
|
||||||
|
@ -86,7 +90,7 @@ class Graphs extends StatelessWidget{
|
||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
dataEntries: [
|
dataEntries: [
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 0),
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 180),
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 0),
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 0),
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 0),
|
||||||
|
@ -104,7 +108,60 @@ class Graphs extends StatelessWidget{
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding( // sq graph
|
||||||
|
padding: const EdgeInsets.fromLTRB(18, 0, 18, 44),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 310,
|
||||||
|
width: 310,
|
||||||
|
child: RadarChart(
|
||||||
|
RadarChartData(
|
||||||
|
radarShape: RadarShape.polygon,
|
||||||
|
tickCount: 4,
|
||||||
|
ticksTextStyle: const TextStyle(color: Colors.white24, fontSize: 10),
|
||||||
|
radarBorderData: const BorderSide(color: Colors.transparent, width: 1),
|
||||||
|
gridBorderData: const BorderSide(color: Colors.white24, width: 1),
|
||||||
|
tickBorderData: const BorderSide(color: Colors.transparent, width: 1),
|
||||||
|
titleTextStyle: const TextStyle(height: 1.1),
|
||||||
|
radarTouchData: RadarTouchData(),
|
||||||
|
getTitle: (index, angle) {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return RadarChartTitle(text: 'Attack\n${f2.format(apm)} APM', angle: 0, positionPercentageOffset: 0.05);
|
||||||
|
case 1:
|
||||||
|
return RadarChartTitle(text: 'Speed\n${f2.format(pps)} PPS', angle: 0, positionPercentageOffset: 0.05);
|
||||||
|
case 2:
|
||||||
|
return RadarChartTitle(text: 'Defense\n${f2.format(nerdStats.dss)} DS/S', angle: angle + 180, positionPercentageOffset: 0.05);
|
||||||
|
case 3:
|
||||||
|
return RadarChartTitle(text: 'Cheese\n${f3.format(nerdStats.cheese)}', angle: 0, positionPercentageOffset: 0.05);
|
||||||
|
default:
|
||||||
|
return const RadarChartTitle(text: '');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataSets: [
|
||||||
|
RadarDataSet(
|
||||||
|
dataEntries: [
|
||||||
|
RadarEntry(value: attack),
|
||||||
|
RadarEntry(value: speed),
|
||||||
|
RadarEntry(value: defense),
|
||||||
|
RadarEntry(value: cheese),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
RadarDataSet(
|
||||||
|
fillColor: Colors.transparent,
|
||||||
|
borderColor: Colors.transparent,
|
||||||
|
dataEntries: [
|
||||||
|
const RadarEntry(value: 0),
|
||||||
|
const RadarEntry(value: 1.2),
|
||||||
|
const RadarEntry(value: 0),
|
||||||
|
const RadarEntry(value: 0),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Padding( // psq graph
|
||||||
padding: const EdgeInsets.fromLTRB(18, 0, 18, 44),
|
padding: const EdgeInsets.fromLTRB(18, 0, 18, 44),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 310,
|
height: 310,
|
||||||
|
@ -126,7 +183,7 @@ class Graphs extends StatelessWidget{
|
||||||
case 1:
|
case 1:
|
||||||
return RadarChartTitle(text: 'Stride\n${percentage.format(playstyle.stride)}', angle: 0, positionPercentageOffset: 0.05);
|
return RadarChartTitle(text: 'Stride\n${percentage.format(playstyle.stride)}', angle: 0, positionPercentageOffset: 0.05);
|
||||||
case 2:
|
case 2:
|
||||||
return RadarChartTitle(text: 'Inf Ds\n${percentage.format(playstyle.infds)}', angle: angle + 180, positionPercentageOffset: 0.05);
|
return RadarChartTitle(text: 'Inf DS\n${percentage.format(playstyle.infds)}', angle: angle + 180, positionPercentageOffset: 0.05);
|
||||||
case 3:
|
case 3:
|
||||||
return RadarChartTitle(text: 'Plonk\n${percentage.format(playstyle.plonk)}', angle: 0, positionPercentageOffset: 0.05);
|
return RadarChartTitle(text: 'Plonk\n${percentage.format(playstyle.plonk)}', angle: 0, positionPercentageOffset: 0.05);
|
||||||
default:
|
default:
|
||||||
|
@ -147,19 +204,9 @@ class Graphs extends StatelessWidget{
|
||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
dataEntries: [
|
dataEntries: [
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 0),
|
||||||
|
const RadarEntry(value: 1),
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 0),
|
||||||
const RadarEntry(value: 0),
|
const RadarEntry(value: 0),
|
||||||
const RadarEntry(value: 0),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
RadarDataSet(
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
borderColor: Colors.transparent,
|
|
||||||
dataEntries: [
|
|
||||||
const RadarEntry(value: 1),
|
|
||||||
const RadarEntry(value: 1),
|
|
||||||
const RadarEntry(value: 1),
|
|
||||||
const RadarEntry(value: 1),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||||
|
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||||
|
import 'package:tetra_stats/gen/strings.g.dart';
|
||||||
|
|
||||||
|
class TLProgress extends StatelessWidget{
|
||||||
|
final double tr;
|
||||||
|
final String rank;
|
||||||
|
final int position;
|
||||||
|
final String? nextRank;
|
||||||
|
final String? previousRank;
|
||||||
|
final int nextRankPosition;
|
||||||
|
final int previousRankPosition;
|
||||||
|
final double? nextRankTRcutoff;
|
||||||
|
final double? previousRankTRcutoff;
|
||||||
|
final double? nextRankTRcutoffTarget;
|
||||||
|
final double? previousRankTRcutoffTarget;
|
||||||
|
|
||||||
|
const TLProgress({super.key, required this.tr, required this.rank, required this.position, required this.nextRankPosition, required this.previousRankPosition, this.nextRank, this.previousRank, this.nextRankTRcutoff, this.previousRankTRcutoff, this.nextRankTRcutoffTarget, this.previousRankTRcutoffTarget});
|
||||||
|
|
||||||
|
double getBarPosition(){
|
||||||
|
return 1 - (position - nextRankPosition)/(previousRankPosition - nextRankPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
double? getBarTR(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
print(getBarPosition());
|
||||||
|
// return Container(
|
||||||
|
// alignment: Alignment.centerLeft,
|
||||||
|
// height: 50,
|
||||||
|
// width: MediaQuery.of(context).size.width,
|
||||||
|
// color: Colors.blue,
|
||||||
|
// child: Container(
|
||||||
|
// width: MediaQuery.of(context).size.width / 2,
|
||||||
|
// height: 50,
|
||||||
|
// color: Colors.red,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: SfLinearGauge(
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 1,
|
||||||
|
interval: 1,
|
||||||
|
ranges: [LinearGaugeRange(endValue: getBarPosition(), color: Colors.cyanAccent,)],
|
||||||
|
markerPointers: [LinearShapePointer(value: getBarPosition(), position: LinearElementPosition.inside, shapeType: LinearShapePointerType.triangle, color: Colors.white, height: 20),
|
||||||
|
LinearWidgetPointer(offset: 4, position: LinearElementPosition.outside, value: getBarPosition(), child: Text(NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0).format(position)))],
|
||||||
|
isMirrored: true,
|
||||||
|
showTicks: true,
|
||||||
|
showLabels: true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import 'package:tetra_stats/utils/numers_formats.dart';
|
||||||
import 'package:tetra_stats/widgets/gauget_num.dart';
|
import 'package:tetra_stats/widgets/gauget_num.dart';
|
||||||
import 'package:tetra_stats/widgets/graphs.dart';
|
import 'package:tetra_stats/widgets/graphs.dart';
|
||||||
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
||||||
|
import 'package:tetra_stats/widgets/tl_progress_bar.dart';
|
||||||
|
|
||||||
var fDiff = NumberFormat("+#,###.###;-#,###.###");
|
var fDiff = NumberFormat("+#,###.###;-#,###.###");
|
||||||
var intFDiff = NumberFormat("+#,###;-#,###");
|
var intFDiff = NumberFormat("+#,###;-#,###");
|
||||||
|
@ -139,20 +140,36 @@ class _TLThingyState extends State<TLThingy> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (currentTl.gamesPlayed >= 10 && currentTl.rd! < 100 && currentTl.nextAt >=0 && currentTl.prevAt >= 0) Padding(
|
if (currentTl.gamesPlayed >= 10 && currentTl.rd! < 100 && currentTl.nextAt >=0 && currentTl.prevAt >= 0)
|
||||||
padding: const EdgeInsets.all(8.0),
|
// Padding(
|
||||||
child: SfLinearGauge(
|
// padding: const EdgeInsets.all(8.0),
|
||||||
minimum: currentTl.nextAt.toDouble(),
|
// child: SfLinearGauge(
|
||||||
maximum: currentTl.prevAt.toDouble(),
|
// minimum: currentTl.nextAt.toDouble(),
|
||||||
interval: currentTl.prevAt.toDouble() - currentTl.nextAt.toDouble(),
|
// maximum: currentTl.prevAt.toDouble(),
|
||||||
ranges: [LinearGaugeRange(startValue: currentTl.standing.toDouble() <= currentTl.prevAt.toDouble() ? currentTl.standing.toDouble() : currentTl.prevAt.toDouble(), endValue: currentTl.prevAt.toDouble(), color: Colors.cyanAccent,)],
|
// interval: currentTl.prevAt.toDouble() - currentTl.nextAt.toDouble(),
|
||||||
markerPointers: [LinearShapePointer(value: currentTl.standing.toDouble() <= currentTl.prevAt.toDouble() ? currentTl.standing.toDouble() : currentTl.prevAt.toDouble(), position: LinearElementPosition.inside, shapeType: LinearShapePointerType.triangle, color: Colors.white, height: 20),
|
// ranges: [
|
||||||
LinearWidgetPointer(offset: 4, position: LinearElementPosition.outside, value: currentTl.standing.toDouble() <= currentTl.prevAt.toDouble() ? currentTl.standing.toDouble() : currentTl.prevAt.toDouble(), child: Text(NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0).format(currentTl.standing)))],
|
// LinearGaugeRange(startValue: currentTl.standing.toDouble() <= currentTl.prevAt.toDouble() ? currentTl.standing.toDouble() : currentTl.prevAt.toDouble(), endValue: currentTl.prevAt.toDouble(), color: Colors.cyanAccent, position: LinearElementPosition.cross,),
|
||||||
isAxisInversed: true,
|
// //LinearGaugeRange(startValue: currentTl.standing.toDouble() <= currentTl.prevAt.toDouble() ? currentTl.standing.toDouble() + 500.00 : currentTl.prevAt.toDouble(), endValue: currentTl.prevAt.toDouble(), color: Colors.amber, position: LinearElementPosition.inside,)
|
||||||
isMirrored: true,
|
// ],
|
||||||
showTicks: true,
|
// markerPointers: [LinearShapePointer(value: currentTl.standing.toDouble() <= currentTl.prevAt.toDouble() ? currentTl.standing.toDouble() : currentTl.prevAt.toDouble(), position: LinearElementPosition.inside, shapeType: LinearShapePointerType.triangle, color: Colors.white, height: 20),
|
||||||
showLabels: true
|
// LinearWidgetPointer(offset: 4, position: LinearElementPosition.outside, value: currentTl.standing.toDouble() <= currentTl.prevAt.toDouble() ? currentTl.standing.toDouble() : currentTl.prevAt.toDouble(), child: Text(NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0).format(currentTl.standing)))],
|
||||||
),
|
// isAxisInversed: true,
|
||||||
|
// isMirrored: true,
|
||||||
|
// showTicks: true,
|
||||||
|
// showLabels: true
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
TLProgress(
|
||||||
|
tr: currentTl.rating,
|
||||||
|
rank: currentTl.rank,
|
||||||
|
position: currentTl.standing,
|
||||||
|
nextRankPosition: currentTl.nextAt,
|
||||||
|
previousRankPosition: currentTl.prevAt,
|
||||||
|
previousRankTRcutoff: widget.thatRankCutoff,
|
||||||
|
previousRankTRcutoffTarget: widget.thatRankTarget,
|
||||||
|
nextRankTRcutoff: widget.nextRankCutoff,
|
||||||
|
nextRankTRcutoffTarget: widget.nextRankTarget,
|
||||||
|
nextRank: widget.tl.nextRank
|
||||||
),
|
),
|
||||||
if (currentTl.gamesPlayed < 10)
|
if (currentTl.gamesPlayed < 10)
|
||||||
Text(t.gamesUntilRanked(left: 10 - currentTl.gamesPlayed),
|
Text(t.gamesUntilRanked(left: 10 - currentTl.gamesPlayed),
|
||||||
|
@ -323,7 +340,7 @@ class _TLThingyState extends State<TLThingy> {
|
||||||
if (oldTl?.estTr?.esttr != null) TextSpan(text: comparef.format(currentTl.estTr!.esttr - oldTl!.estTr!.esttr), style: TextStyle(
|
if (oldTl?.estTr?.esttr != null) TextSpan(text: comparef.format(currentTl.estTr!.esttr - oldTl!.estTr!.esttr), style: TextStyle(
|
||||||
color: oldTl!.estTr!.esttr > currentTl.estTr!.esttr ? Colors.redAccent : Colors.greenAccent
|
color: oldTl!.estTr!.esttr > currentTl.estTr!.esttr ? Colors.redAccent : Colors.greenAccent
|
||||||
),),
|
),),
|
||||||
if (oldTl?.estTr?.esttr != null && widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
if (oldTl?.estTr?.esttr != null || widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
||||||
if (widget.lbPositions?.estTr != null) TextSpan(text: widget.lbPositions!.estTr!.position >= 1000 ? "${t.top} ${f2.format(widget.lbPositions!.estTr!.percentage*100)}%" : "№${widget.lbPositions!.estTr!.position}", style: TextStyle(color: getColorOfRank(widget.lbPositions!.estTr!.position))),
|
if (widget.lbPositions?.estTr != null) TextSpan(text: widget.lbPositions!.estTr!.position >= 1000 ? "${t.top} ${f2.format(widget.lbPositions!.estTr!.percentage*100)}%" : "№${widget.lbPositions!.estTr!.position}", style: TextStyle(color: getColorOfRank(widget.lbPositions!.estTr!.position))),
|
||||||
if (widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
if (widget.lbPositions?.estTr != null) const TextSpan(text: " • "),
|
||||||
TextSpan(text: "Glicko: ${f2.format(currentTl.estTr!.estglicko)}")
|
TextSpan(text: "Glicko: ${f2.format(currentTl.estTr!.estglicko)}")
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
"verdictGeneral": "$n $verdict than $rank rank average",
|
"verdictGeneral": "$n $verdict than $rank rank average",
|
||||||
"verdictBetter": "better",
|
"verdictBetter": "better",
|
||||||
"verdictWorse": "worse",
|
"verdictWorse": "worse",
|
||||||
|
"smooth": "Smooth",
|
||||||
"gamesUntilRanked": "${left} games until being ranked",
|
"gamesUntilRanked": "${left} games until being ranked",
|
||||||
"nerdStats": "Nerd Stats",
|
"nerdStats": "Nerd Stats",
|
||||||
"playersYouTrack": "Players you track",
|
"playersYouTrack": "Players you track",
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
"verdictGeneral": "$verdict среднего $rank ранга на $n",
|
"verdictGeneral": "$verdict среднего $rank ранга на $n",
|
||||||
"verdictBetter": "Лучше",
|
"verdictBetter": "Лучше",
|
||||||
"verdictWorse": "Хуже",
|
"verdictWorse": "Хуже",
|
||||||
|
"smooth": "Гладкий",
|
||||||
"gamesUntilRanked": "${left} матчей до получения рейтинга",
|
"gamesUntilRanked": "${left} матчей до получения рейтинга",
|
||||||
"nerdStats": "Для задротов",
|
"nerdStats": "Для задротов",
|
||||||
"playersYouTrack": "Отслеживаемые игроки",
|
"playersYouTrack": "Отслеживаемые игроки",
|
||||||
|
|
Loading…
Reference in New Issue