This commit is contained in:
dan63047 2024-11-03 01:46:42 +03:00
parent 14494db134
commit e3d7e94729
13 changed files with 769 additions and 470 deletions

View File

@ -1,6 +1,8 @@
// ignore_for_file: hash_and_equals // ignore_for_file: hash_and_equals
import 'package:tetra_stats/data_objects/beta_league_results.dart'; import 'package:tetra_stats/data_objects/beta_league_results.dart';
import 'package:tetra_stats/data_objects/record_extras.dart';
import 'package:tetra_stats/data_objects/tetrio_prisecter.dart';
class BetaRecord{ class BetaRecord{
late String id; late String id;
@ -10,6 +12,8 @@ class BetaRecord{
late String enemyUsername; late String enemyUsername;
late String enemyID; late String enemyID;
late BetaLeagueResults results; late BetaLeagueResults results;
late LeagueExtras extras;
late Prisecter prisecter;
BetaRecord({required this.id, required this.replayID, required this.gamemode, required this.ts, required this.enemyUsername, required this.enemyID, required this.results}); BetaRecord({required this.id, required this.replayID, required this.gamemode, required this.ts, required this.enemyUsername, required this.enemyID, required this.results});
@ -21,5 +25,7 @@ class BetaRecord{
enemyUsername = json['otherusers'][0]['username']; enemyUsername = json['otherusers'][0]['username'];
enemyID = json['otherusers'][0]['id']; enemyID = json['otherusers'][0]['id'];
results = BetaLeagueResults.fromJson(json['results']); results = BetaLeagueResults.fromJson(json['results']);
prisecter = Prisecter.fromJson(json['p']);
extras = LeagueExtras.fromJson(json['extras']);
} }
} }

View File

@ -13,3 +13,33 @@ class ZenithExtras extends RecordExtras{
} }
} }
} }
class SmallLeague{
late double glicko;
late double rd;
late double tr;
late String rank;
late int placement;
SmallLeague(this.glicko, this.rd, this.tr, this.rank, this.placement);
SmallLeague.fromJson(Map<String, dynamic> json){
glicko = json['glicko'];
rd = json['rd'];
tr = json['tr'];
rank = json['rank'];
placement = json['placement'];
}
}
class LeagueExtras extends RecordExtras{
late String result;
Map<String, List<SmallLeague?>> league = {};
LeagueExtras.fromJson(Map<String, dynamic> json){
result = json['result'];
for (String userID in json['league'].keys){
league[userID] = [json['league'][userID][0] != null ? SmallLeague.fromJson(json['league'][userID][0]) : null, json['league'][userID][1] != null ? SmallLeague.fromJson(json['league'][userID][1]) : null];
}
}
}

View File

@ -2,6 +2,7 @@
import 'package:tetra_stats/data_objects/clears.dart'; import 'package:tetra_stats/data_objects/clears.dart';
import 'package:tetra_stats/data_objects/finesse.dart'; import 'package:tetra_stats/data_objects/finesse.dart';
import 'package:tetra_stats/data_objects/tetrio_multiplayer_replay.dart';
import 'package:tetra_stats/data_objects/zenith_results.dart'; import 'package:tetra_stats/data_objects/zenith_results.dart';
class ResultsStats { class ResultsStats {
@ -17,6 +18,7 @@ class ResultsStats {
late Duration finalTime; late Duration finalTime;
late int tSpins; late int tSpins;
late Clears clears; late Clears clears;
late Garbage garbage;
late int kills; late int kills;
Finesse? finesse; Finesse? finesse;
ZenithResults? zenith; ZenithResults? zenith;
@ -57,6 +59,7 @@ class ResultsStats {
tSpins = json['tspins']; tSpins = json['tspins'];
piecesPlaced = json['piecesplaced']; piecesPlaced = json['piecesplaced'];
clears = Clears.fromJson(json['clears']); clears = Clears.fromJson(json['clears']);
garbage = Garbage.fromJson(json['garbage']);
kills = json['kills']; kills = json['kills'];
if (json.containsKey("finesse")) finesse = Finesse.fromJson(json['finesse']); if (json.containsKey("finesse")) finesse = Finesse.fromJson(json['finesse']);
if (json.containsKey("zenith")) zenith = ZenithResults.fromJson(json['zenith']); if (json.containsKey("zenith")) zenith = ZenithResults.fromJson(json['zenith']);

View File

@ -37,8 +37,11 @@ int biggestSpikeFromReplay(events){
class Garbage{ // charsys where??? class Garbage{ // charsys where???
late int sent; late int sent;
late int recived; late int recived;
late int attack; int? attack;
late int cleared; late int cleared;
int? sent_normal;
int? maxspike;
int? maxspike_nomult;
Garbage({ Garbage({
required this.sent, required this.sent,
@ -52,6 +55,9 @@ class Garbage{ // charsys where???
recived = json['received']; recived = json['received'];
attack = json['attack']; attack = json['attack'];
cleared = json['cleared']; cleared = json['cleared'];
sent_normal = json['sent_normal'];
maxspike = json['maxspike'];
maxspike_nomult = json['maxspike_nomult'];
} }
Garbage.toJson(){ Garbage.toJson(){
@ -59,7 +65,7 @@ class Garbage{ // charsys where???
} }
Garbage operator + (Garbage other){ Garbage operator + (Garbage other){
return Garbage(sent: sent + other.sent, recived: recived + other.recived, attack: attack + other.attack, cleared: cleared + other.cleared); return Garbage(sent: sent + other.sent, recived: recived + other.recived, attack: attack??0 + (other.attack??0), cleared: cleared + other.cleared);
} }
} }

View File

@ -65,6 +65,28 @@ class TetrioPlayersLeaderboard {
} }
if (filtredLeaderboard.isNotEmpty){ if (filtredLeaderboard.isNotEmpty){
double double
avgAPM = 0,
avgPPS = 0,
avgVS = 0,
avgTR = 0,
avgGlixare = 0,
avgGlicko = 0,
avgRD = 0,
avgAPP = 0,
avgVSAPM = 0,
avgDSS = 0,
avgDSP = 0,
avgAPPDSP = 0,
avgCheese = 0,
avgGBE = 0,
avgNyaAPP = 0,
avgArea = 0,
avgEstTR = 0,
avgEstAcc = 0,
avgOpener = 0,
avgPlonk = 0,
avgStride = 0,
avgInfDS = 0,
lowestTR = 25000, lowestTR = 25000,
lowestGlixare = double.infinity, lowestGlixare = double.infinity,
lowestGlicko = double.infinity, lowestGlicko = double.infinity,
@ -110,11 +132,7 @@ class TetrioPlayersLeaderboard {
highestOpener = double.negativeInfinity, highestOpener = double.negativeInfinity,
highestPlonk = double.negativeInfinity, highestPlonk = double.negativeInfinity,
highestStride = double.negativeInfinity, highestStride = double.negativeInfinity,
highestInfDS = double.negativeInfinity, highestInfDS = double.negativeInfinity;
avgTR = 0,
avgGlixare = 0,
avgGlicko = 0,
avgRD = 0;
int avgGamesPlayed = 0, int avgGamesPlayed = 0,
avgGamesWon = 0, avgGamesWon = 0,
totalGamesPlayed = 0, totalGamesPlayed = 0,
@ -174,10 +192,28 @@ class TetrioPlayersLeaderboard {
highestStrideID = "", highestStrideNick = "", highestStrideID = "", highestStrideNick = "",
highestInfDSid = "", highestInfDSnick = ""; highestInfDSid = "", highestInfDSnick = "";
for (var entry in filtredLeaderboard){ for (var entry in filtredLeaderboard){
avgAPM += entry.apm;
avgPPS += entry.pps;
avgVS += entry.vs;
avgTR += entry.tr; avgTR += entry.tr;
avgGlixare += entry.gxe; avgGlixare += entry.gxe;
if (entry.glicko != null) avgGlicko += entry.glicko!; if (entry.glicko != null) avgGlicko += entry.glicko!;
if (entry.rd != null) avgRD += entry.rd!; if (entry.rd != null) avgRD += entry.rd!;
avgAPP += entry.nerdStats.app;
avgVSAPM += entry.nerdStats.vsapm;
avgDSS += entry.nerdStats.dss;
avgDSP += entry.nerdStats.dsp;
avgAPPDSP += entry.nerdStats.appdsp;
avgCheese += entry.nerdStats.cheese;
avgGBE += entry.nerdStats.gbe;
avgNyaAPP += entry.nerdStats.nyaapp;
avgArea += entry.nerdStats.area;
avgEstTR += entry.estTr.esttr;
avgEstAcc += entry.esttracc;
avgOpener += entry.playstyle.opener;
avgPlonk += entry.playstyle.plonk;
avgStride += entry.playstyle.stride;
avgInfDS += entry.playstyle.infds;
totalGamesPlayed += entry.gamesPlayed; totalGamesPlayed += entry.gamesPlayed;
totalGamesWon += entry.gamesWon; totalGamesWon += entry.gamesWon;
if (entry.tr < lowestTR){ if (entry.tr < lowestTR){
@ -431,13 +467,31 @@ class TetrioPlayersLeaderboard {
highestInfDSnick = entry.username; highestInfDSnick = entry.username;
} }
} }
avgAPM /= filtredLeaderboard.length;
avgPPS /= filtredLeaderboard.length;
avgVS /= filtredLeaderboard.length;
avgTR /= filtredLeaderboard.length; avgTR /= filtredLeaderboard.length;
avgGlixare /= filtredLeaderboard.length; avgGlixare /= filtredLeaderboard.length;
avgGlicko /= filtredLeaderboard.length; avgGlicko /= filtredLeaderboard.length;
avgRD /= filtredLeaderboard.length; avgRD /= filtredLeaderboard.length;
avgGamesPlayed = (totalGamesPlayed / filtredLeaderboard.length).floor(); avgGamesPlayed = (totalGamesPlayed / filtredLeaderboard.length).floor();
avgGamesWon = (totalGamesWon / filtredLeaderboard.length).floor(); avgGamesWon = (totalGamesWon / filtredLeaderboard.length).floor();
return [TetraLeague(id: "", timestamp: DateTime.now(), apm: null, pps: null, vs: null, gxe: avgGlixare, glicko: avgGlicko, rd: avgRD, gamesPlayed: avgGamesPlayed, gamesWon: avgGamesWon, bestRank: rank, decaying: false, tr: avgTR, rank: rank == "" ? "z" : rank, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1, season: currentSeason), avgAPP /= filtredLeaderboard.length;
avgVSAPM /= filtredLeaderboard.length;
avgDSS /= filtredLeaderboard.length;
avgDSP /= filtredLeaderboard.length;
avgAPPDSP /= leaderboard.length;
avgCheese /= filtredLeaderboard.length;
avgGBE /= filtredLeaderboard.length;
avgNyaAPP /= filtredLeaderboard.length;
avgArea /= filtredLeaderboard.length;
avgEstTR /= filtredLeaderboard.length;
avgEstAcc /= filtredLeaderboard.length;
avgOpener /= filtredLeaderboard.length;
avgPlonk /= filtredLeaderboard.length;
avgStride /= filtredLeaderboard.length;
avgInfDS /= filtredLeaderboard.length;
return [TetraLeague(id: "", timestamp: DateTime.now(), apm: avgAPM, pps: avgPPS, vs: avgVS, gxe: avgGlixare, glicko: avgGlicko, rd: avgRD, gamesPlayed: avgGamesPlayed, gamesWon: avgGamesWon, bestRank: rank, decaying: false, tr: avgTR, rank: rank == "" ? "z" : rank, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1, season: currentSeason),
{ {
"totalGamesPlayed": totalGamesPlayed, "totalGamesPlayed": totalGamesPlayed,
"totalGamesWon": totalGamesWon, "totalGamesWon": totalGamesWon,
@ -598,6 +652,21 @@ class TetrioPlayersLeaderboard {
"highestInfDS": highestInfDS, "highestInfDS": highestInfDS,
"highestInfDSid": highestInfDSid, "highestInfDSid": highestInfDSid,
"highestInfDSnick": highestInfDSnick, "highestInfDSnick": highestInfDSnick,
"avgAPP": avgAPP,
"avgVSAPM": avgVSAPM,
"avgDSS": avgDSS,
"avgDSP": avgDSP,
"avgAPPDSP": avgAPPDSP,
"avgCheese": avgCheese,
"avgGBE": avgGBE,
"avgNyaAPP": avgNyaAPP,
"avgArea": avgArea,
"avgEstTR": avgEstTR,
"avgEstAcc": avgEstAcc,
"avgOpener": avgOpener,
"avgPlonk": avgPlonk,
"avgStride": avgStride,
"avgInfDS": avgInfDS,
"toEnterGlicko": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].glicko : 0, "toEnterGlicko": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].glicko : 0,
}]; }];
}else{ }else{

View File

@ -284,230 +284,230 @@ class CompareState extends State<CompareView> {
zenithRun?.aggregateStats.playstyle.stride, zenithRun?.aggregateStats.playstyle.stride,
zenithRun?.aggregateStats.playstyle.infds, zenithRun?.aggregateStats.playstyle.infds,
]); ]);
rawValues[3].add([ rawValues[3].add([
zenithExRun?.stats.zenith?.altitude, zenithExRun?.stats.zenith?.altitude,
zenithExRun?.rank, zenithExRun?.rank,
zenithExRun?.aggregateStats.apm, zenithExRun?.aggregateStats.apm,
zenithExRun?.aggregateStats.pps, zenithExRun?.aggregateStats.pps,
zenithExRun?.aggregateStats.vs, zenithExRun?.aggregateStats.vs,
zenithExRun?.stats.kills, zenithExRun?.stats.kills,
zenithExRun?.stats.topBtB, zenithExRun?.stats.topBtB,
zenithExRun?.stats.cps, zenithExRun?.stats.cps,
zenithExRun?.stats.zenith?.peakrank, zenithExRun?.stats.zenith?.peakrank,
zenithExRun?.stats.finalTime, zenithExRun?.stats.finalTime,
zenithExRun?.stats.finessePercentage, zenithExRun?.stats.finessePercentage,
"", "",
zenithExRun?.aggregateStats.nerdStats.app, zenithExRun?.aggregateStats.nerdStats.app,
zenithExRun?.aggregateStats.nerdStats.vsapm, zenithExRun?.aggregateStats.nerdStats.vsapm,
zenithExRun?.aggregateStats.nerdStats.dss, zenithExRun?.aggregateStats.nerdStats.dss,
zenithExRun?.aggregateStats.nerdStats.dsp, zenithExRun?.aggregateStats.nerdStats.dsp,
zenithExRun?.aggregateStats.nerdStats.appdsp, zenithExRun?.aggregateStats.nerdStats.appdsp,
zenithExRun?.aggregateStats.nerdStats.cheese, zenithExRun?.aggregateStats.nerdStats.cheese,
zenithExRun?.aggregateStats.nerdStats.gbe, zenithExRun?.aggregateStats.nerdStats.gbe,
zenithExRun?.aggregateStats.nerdStats.nyaapp, zenithExRun?.aggregateStats.nerdStats.nyaapp,
zenithExRun?.aggregateStats.nerdStats.area, zenithExRun?.aggregateStats.nerdStats.area,
"", "",
zenithExRun?.aggregateStats.playstyle.opener, zenithExRun?.aggregateStats.playstyle.opener,
zenithExRun?.aggregateStats.playstyle.plonk, zenithExRun?.aggregateStats.playstyle.plonk,
zenithExRun?.aggregateStats.playstyle.stride, zenithExRun?.aggregateStats.playstyle.stride,
zenithExRun?.aggregateStats.playstyle.infds, zenithExRun?.aggregateStats.playstyle.infds,
]);; ]);;
rawValues[4].add([ rawValues[4].add([
s.sprint?.stats.finalTime, s.sprint?.stats.finalTime,
s.sprint?.stats.piecesPlaced, s.sprint?.stats.piecesPlaced,
s.sprint?.stats.inputs, s.sprint?.stats.inputs,
s.sprint?.stats.kpp, s.sprint?.stats.kpp,
s.sprint?.stats.pps, s.sprint?.stats.pps,
s.sprint?.stats.kps, s.sprint?.stats.kps,
s.sprint?.stats.finessePercentage, s.sprint?.stats.finessePercentage,
s.sprint?.stats.finesse?.faults, s.sprint?.stats.finesse?.faults,
"", "",
s.sprint?.stats.clears.quads, s.sprint?.stats.clears.quads,
s.sprint?.stats.clears.triples, s.sprint?.stats.clears.triples,
s.sprint?.stats.clears.doubles, s.sprint?.stats.clears.doubles,
s.sprint?.stats.clears.singles, s.sprint?.stats.clears.singles,
"", "",
s.sprint?.stats.clears.tSpinTriples, s.sprint?.stats.clears.tSpinTriples,
s.sprint?.stats.clears.tSpinDoubles, s.sprint?.stats.clears.tSpinDoubles,
s.sprint?.stats.clears.tSpinSingles, s.sprint?.stats.clears.tSpinSingles,
s.sprint?.stats.clears.tSpinZeros, s.sprint?.stats.clears.tSpinZeros,
s.sprint?.stats.clears.tSpinMiniDoubles, s.sprint?.stats.clears.tSpinMiniDoubles,
s.sprint?.stats.clears.tSpinMiniSingles, s.sprint?.stats.clears.tSpinMiniSingles,
s.sprint?.stats.clears.tSpinMiniZeros s.sprint?.stats.clears.tSpinMiniZeros
]); ]);
rawValues[5].add( rawValues[5].add(
[ [
s.blitz?.stats.score, s.blitz?.stats.score,
s.blitz?.stats.piecesPlaced, s.blitz?.stats.piecesPlaced,
s.blitz?.stats.lines, s.blitz?.stats.lines,
s.blitz?.stats.level, s.blitz?.stats.level,
s.blitz?.stats.inputs, s.blitz?.stats.inputs,
s.blitz?.stats.kpp, s.blitz?.stats.kpp,
s.blitz?.stats.pps, s.blitz?.stats.pps,
s.blitz?.stats.kps, s.blitz?.stats.kps,
s.blitz?.stats.finessePercentage, s.blitz?.stats.finessePercentage,
s.blitz?.stats.finesse?.faults, s.blitz?.stats.finesse?.faults,
"", "",
s.blitz?.stats.clears.quads, s.blitz?.stats.clears.quads,
s.blitz?.stats.clears.triples, s.blitz?.stats.clears.triples,
s.blitz?.stats.clears.doubles, s.blitz?.stats.clears.doubles,
s.blitz?.stats.clears.singles, s.blitz?.stats.clears.singles,
"", "",
s.blitz?.stats.clears.tSpinTriples, s.blitz?.stats.clears.tSpinTriples,
s.blitz?.stats.clears.tSpinDoubles, s.blitz?.stats.clears.tSpinDoubles,
s.blitz?.stats.clears.tSpinSingles, s.blitz?.stats.clears.tSpinSingles,
s.blitz?.stats.clears.tSpinZeros, s.blitz?.stats.clears.tSpinZeros,
s.blitz?.stats.clears.tSpinMiniDoubles, s.blitz?.stats.clears.tSpinMiniDoubles,
s.blitz?.stats.clears.tSpinMiniSingles, s.blitz?.stats.clears.tSpinMiniSingles,
s.blitz?.stats.clears.tSpinMiniZeros s.blitz?.stats.clears.tSpinMiniZeros
] ]
); );
rawValues[6].add([ rawValues[6].add([
s.zen.score, s.zen.score,
s.zen.level s.zen.level
]); ]);
formattedValues[0].add([ formattedValues[0].add([
Text(timestamp(p.registrationTime)), Text(timestamp(p.registrationTime)),
RichText(text: p.xp.isNegative ? TextSpan(text: "hidden", style: TextStyle(fontFamily: "Eurostile Round", color: Colors.grey)) : TextSpan(text: intf.format(p.xp), style: TextStyle(fontFamily: "Eurostile Round"), children: [TextSpan(text: " (lvl ${intf.format(p.level.floor())})", style: TextStyle(color: Colors.grey))])), RichText(text: p.xp.isNegative ? TextSpan(text: "hidden", style: TextStyle(fontFamily: "Eurostile Round", color: Colors.grey)) : TextSpan(text: intf.format(p.xp), style: TextStyle(fontFamily: "Eurostile Round"), children: [TextSpan(text: " (lvl ${intf.format(p.level.floor())})", style: TextStyle(color: Colors.grey))])),
Text(p.gameTime.isNegative ? "hidden" : playtime(p.gameTime), style: TextStyle(color: p.gameTime.isNegative ? Colors.grey : Colors.white)), Text(p.gameTime.isNegative ? "hidden" : playtime(p.gameTime), style: TextStyle(color: p.gameTime.isNegative ? Colors.grey : Colors.white)),
Text(p.gamesPlayed.isNegative ? "hidden" : intf.format(p.gamesPlayed), style: TextStyle(color: p.gamesPlayed.isNegative ? Colors.grey : Colors.white)), Text(p.gamesPlayed.isNegative ? "hidden" : intf.format(p.gamesPlayed), style: TextStyle(color: p.gamesPlayed.isNegative ? Colors.grey : Colors.white)),
Text(p.gamesWon.isNegative ? "hidden" : intf.format(p.gamesWon), style: TextStyle(color: p.gamesWon.isNegative ? Colors.grey : Colors.white)), Text(p.gamesWon.isNegative ? "hidden" : intf.format(p.gamesWon), style: TextStyle(color: p.gamesWon.isNegative ? Colors.grey : Colors.white)),
Text(intf.format(p.friendCount)) Text(intf.format(p.friendCount))
]); ]);
formattedValues[1].add([ formattedValues[1].add([
Text(s.league.tr.isNegative ? "---" : f4.format(s.league.tr)), Text(s.league.tr.isNegative ? "---" : f4.format(s.league.tr)),
Text(s.league.glicko!.isNegative ? "---" : f4.format(s.league.glicko)), Text(s.league.glicko!.isNegative ? "---" : f4.format(s.league.glicko)),
Text(s.league.rd!.isNegative ? "---" : f4.format(s.league.rd), style: TextStyle(color: s.league.rd!.isNegative ? Colors.grey : Colors.white)), Text(s.league.rd!.isNegative ? "---" : f4.format(s.league.rd), style: TextStyle(color: s.league.rd!.isNegative ? Colors.grey : Colors.white)),
Text(s.league.gxe.isNegative ? "---" : f4.format(s.league.gxe)), Text(s.league.gxe.isNegative ? "---" : f4.format(s.league.gxe)),
Text(s.league.s1tr.isNegative ? "---" : f4.format(s.league.s1tr)), Text(s.league.s1tr.isNegative ? "---" : f4.format(s.league.s1tr)),
Text(s.league.standing.isNegative ? "---" : ""+intf.format(s.league.standing)), Text(s.league.standing.isNegative ? "---" : ""+intf.format(s.league.standing)),
Text(intf.format(s.league.gamesPlayed)), Text(intf.format(s.league.gamesPlayed)),
Text(intf.format(s.league.gamesWon)), Text(intf.format(s.league.gamesWon)),
Text(s.league.winrate.isNaN ? "---" : f4.format(s.league.winrate*100)+"%"), Text(s.league.winrate.isNaN ? "---" : f4.format(s.league.winrate*100)+"%"),
Text(s.league.apm != null ? f2.format(s.league.apm) : "---"), Text(s.league.apm != null ? f2.format(s.league.apm) : "---"),
Text(s.league.pps != null ? f2.format(s.league.pps) : "---"), Text(s.league.pps != null ? f2.format(s.league.pps) : "---"),
Text(s.league.vs != null ? f2.format(s.league.vs) : "---"), Text(s.league.vs != null ? f2.format(s.league.vs) : "---"),
Text(""), Text(""),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.app) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.app) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.vsapm) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.vsapm) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.dss) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.dss) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.dsp) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.dsp) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.appdsp) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.appdsp) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.cheese) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.cheese) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.gbe) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.gbe) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.nyaapp) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.nyaapp) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.area) : "---"), Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.area) : "---"),
Text(""), Text(""),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.opener) : "---"), Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.opener) : "---"),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.plonk) : "---"), Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.plonk) : "---"),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.stride) : "---"), Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.stride) : "---"),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.infds) : "---"), Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.infds) : "---"),
]); ]);
formattedValues[2].add([ formattedValues[2].add([
RichText(text: TextSpan(text: zenithRun != null ? "${f2.format(zenithRun.stats.zenith!.altitude)} m" : "---", style: TextStyle(fontFamily: "Eurostile Round"), children: [if (zenithRun != null && oldZenithRun) TextSpan(text: " (${zenithRun.revolution})", style: TextStyle(color: Colors.grey))])), RichText(text: TextSpan(text: zenithRun != null ? "${f2.format(zenithRun.stats.zenith!.altitude)} m" : "---", style: TextStyle(fontFamily: "Eurostile Round"), children: [if (zenithRun != null && oldZenithRun) TextSpan(text: " (${zenithRun.revolution})", style: TextStyle(color: Colors.grey))])),
Text(zenithRun != null ? ""+intf.format(zenithRun.rank) : "---"), Text(zenithRun != null ? ""+intf.format(zenithRun.rank) : "---"),
Text(zenithRun != null ? f2.format(zenithRun.aggregateStats.apm) : "---"), Text(zenithRun != null ? f2.format(zenithRun.aggregateStats.apm) : "---"),
Text(zenithRun != null ? f2.format(zenithRun.aggregateStats.pps) : "---"), Text(zenithRun != null ? f2.format(zenithRun.aggregateStats.pps) : "---"),
Text(zenithRun != null ? f2.format(zenithRun.aggregateStats.vs) : "---"), Text(zenithRun != null ? f2.format(zenithRun.aggregateStats.vs) : "---"),
Text(zenithRun != null ? intf.format(zenithRun.stats.kills) : "---"), Text(zenithRun != null ? intf.format(zenithRun.stats.kills) : "---"),
Text(zenithRun != null ? intf.format(zenithRun.stats.topBtB) : "---"), Text(zenithRun != null ? intf.format(zenithRun.stats.topBtB) : "---"),
Text(zenithRun != null ? f4.format(zenithRun.stats.cps) : "---"), Text(zenithRun != null ? f4.format(zenithRun.stats.cps) : "---"),
Text(zenithRun != null ? f4.format(zenithRun.stats.zenith!.peakrank) : "---"), Text(zenithRun != null ? f4.format(zenithRun.stats.zenith!.peakrank) : "---"),
Text(zenithRun != null ? getMoreNormalTime(zenithRun.stats.finalTime) : "---"), Text(zenithRun != null ? getMoreNormalTime(zenithRun.stats.finalTime) : "---"),
Text(zenithRun != null ? f2.format(zenithRun.stats.finessePercentage*100)+"%" : "---"), Text(zenithRun != null ? f2.format(zenithRun.stats.finessePercentage*100)+"%" : "---"),
Text(""), Text(""),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.app) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.app) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.vsapm) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.vsapm) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.dss) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.dss) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.dsp) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.dsp) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.appdsp) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.appdsp) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.cheese) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.cheese) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.gbe) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.gbe) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.nyaapp) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.nyaapp) : "---"),
Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.area) : "---"), Text(zenithRun?.aggregateStats.nerdStats != null ? f4.format(zenithRun!.aggregateStats.nerdStats.area) : "---"),
Text(""), Text(""),
Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.opener) : "---"), Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.opener) : "---"),
Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.plonk) : "---"), Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.plonk) : "---"),
Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.stride) : "---"), Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.stride) : "---"),
Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.infds) : "---"), Text(zenithRun?.aggregateStats.playstyle != null ? f4.format(zenithRun!.aggregateStats.playstyle.infds) : "---"),
]); ]);
formattedValues[3].add([ formattedValues[3].add([
RichText(text: TextSpan(text: zenithExRun != null ? "${f2.format(zenithExRun.stats.zenith!.altitude)} m" : "---", style: TextStyle(fontFamily: "Eurostile Round"), children: [if (zenithExRun != null && oldZenithExRun) TextSpan(text: " (${zenithExRun.revolution})", style: TextStyle(color: Colors.grey))])), RichText(text: TextSpan(text: zenithExRun != null ? "${f2.format(zenithExRun.stats.zenith!.altitude)} m" : "---", style: TextStyle(fontFamily: "Eurostile Round"), children: [if (zenithExRun != null && oldZenithExRun) TextSpan(text: " (${zenithExRun.revolution})", style: TextStyle(color: Colors.grey))])),
Text(zenithExRun != null ? ""+intf.format(zenithExRun.rank) : "---"), Text(zenithExRun != null ? ""+intf.format(zenithExRun.rank) : "---"),
Text(zenithExRun != null ? f2.format(zenithExRun.aggregateStats.apm) : "---"), Text(zenithExRun != null ? f2.format(zenithExRun.aggregateStats.apm) : "---"),
Text(zenithExRun != null ? f2.format(zenithExRun.aggregateStats.pps) : "---"), Text(zenithExRun != null ? f2.format(zenithExRun.aggregateStats.pps) : "---"),
Text(zenithExRun != null ? f2.format(zenithExRun.aggregateStats.vs) : "---"), Text(zenithExRun != null ? f2.format(zenithExRun.aggregateStats.vs) : "---"),
Text(zenithExRun != null ? intf.format(zenithExRun.stats.kills) : "---"), Text(zenithExRun != null ? intf.format(zenithExRun.stats.kills) : "---"),
Text(zenithExRun != null ? intf.format(zenithExRun.stats.topBtB) : "---"), Text(zenithExRun != null ? intf.format(zenithExRun.stats.topBtB) : "---"),
Text(zenithExRun != null ? f4.format(zenithExRun.stats.cps) : "---"), Text(zenithExRun != null ? f4.format(zenithExRun.stats.cps) : "---"),
Text(zenithExRun != null ? f4.format(zenithExRun.stats.zenith!.peakrank) : "---"), Text(zenithExRun != null ? f4.format(zenithExRun.stats.zenith!.peakrank) : "---"),
Text(zenithExRun != null ? getMoreNormalTime(zenithExRun.stats.finalTime) : "---"), Text(zenithExRun != null ? getMoreNormalTime(zenithExRun.stats.finalTime) : "---"),
Text(zenithExRun != null ? f2.format(zenithExRun.stats.finessePercentage*100)+"%" : "---"), Text(zenithExRun != null ? f2.format(zenithExRun.stats.finessePercentage*100)+"%" : "---"),
Text(""), Text(""),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.app) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.app) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.vsapm) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.vsapm) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.dss) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.dss) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.dsp) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.dsp) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.appdsp) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.appdsp) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.cheese) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.cheese) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.gbe) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.gbe) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.nyaapp) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.nyaapp) : "---"),
Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.area) : "---"), Text(zenithExRun?.aggregateStats.nerdStats != null ? f4.format(zenithExRun!.aggregateStats.nerdStats.area) : "---"),
Text(""), Text(""),
Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.opener) : "---"), Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.opener) : "---"),
Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.plonk) : "---"), Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.plonk) : "---"),
Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.stride) : "---"), Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.stride) : "---"),
Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.infds) : "---"), Text(zenithExRun?.aggregateStats.playstyle != null ? f4.format(zenithExRun!.aggregateStats.playstyle.infds) : "---"),
]); ]);
formattedValues[4].add([ formattedValues[4].add([
Text(s.sprint != null ? getMoreNormalTime(s.sprint!.stats.finalTime) : "---"), Text(s.sprint != null ? getMoreNormalTime(s.sprint!.stats.finalTime) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.piecesPlaced) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.piecesPlaced) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.inputs) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.inputs) : "---"),
Text(s.sprint != null ? f4.format(s.sprint!.stats.kpp) : "---"), Text(s.sprint != null ? f4.format(s.sprint!.stats.kpp) : "---"),
Text(s.sprint != null ? f4.format(s.sprint!.stats.pps) : "---"), Text(s.sprint != null ? f4.format(s.sprint!.stats.pps) : "---"),
Text(s.sprint != null ? f4.format(s.sprint!.stats.kps) : "---"), Text(s.sprint != null ? f4.format(s.sprint!.stats.kps) : "---"),
Text(s.sprint != null ? percentage.format(s.sprint!.stats.finessePercentage) : "---"), Text(s.sprint != null ? percentage.format(s.sprint!.stats.finessePercentage) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.finesse?.faults) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.finesse?.faults) : "---"),
Text(""), Text(""),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.quads) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.quads) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.triples) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.triples) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.doubles) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.doubles) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.singles) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.singles) : "---"),
Text(""), Text(""),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinTriples) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinTriples) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinDoubles) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinDoubles) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinSingles) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinSingles) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinZeros) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinZeros) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinMiniDoubles) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinMiniDoubles) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinMiniSingles) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinMiniSingles) : "---"),
Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinMiniZeros) : "---"), Text(s.sprint != null ? intf.format(s.sprint!.stats.clears.tSpinMiniZeros) : "---"),
]); ]);
formattedValues[5].add([ formattedValues[5].add([
Text(s.blitz != null ? intf.format(s.blitz!.stats.score) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.score) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.piecesPlaced) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.piecesPlaced) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.lines) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.lines) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.level) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.level) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.inputs) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.inputs) : "---"),
Text(s.blitz != null ? f4.format(s.blitz!.stats.kpp) : "---"), Text(s.blitz != null ? f4.format(s.blitz!.stats.kpp) : "---"),
Text(s.blitz != null ? f4.format(s.blitz!.stats.pps) : "---"), Text(s.blitz != null ? f4.format(s.blitz!.stats.pps) : "---"),
Text(s.blitz != null ? f4.format(s.blitz!.stats.kps) : "---"), Text(s.blitz != null ? f4.format(s.blitz!.stats.kps) : "---"),
Text(s.blitz != null ? percentage.format(s.blitz!.stats.finessePercentage) : "---"), Text(s.blitz != null ? percentage.format(s.blitz!.stats.finessePercentage) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.finesse?.faults) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.finesse?.faults) : "---"),
Text(""), Text(""),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.quads) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.quads) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.triples) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.triples) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.doubles) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.doubles) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.singles) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.singles) : "---"),
Text(""), Text(""),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinTriples) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinTriples) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinDoubles) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinDoubles) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinSingles) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinSingles) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinZeros) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinZeros) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinMiniDoubles) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinMiniDoubles) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinMiniSingles) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinMiniSingles) : "---"),
Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinMiniZeros) : "---"), Text(s.blitz != null ? intf.format(s.blitz!.stats.clears.tSpinMiniZeros) : "---"),
]); ]);
formattedValues[6].add([ formattedValues[6].add([
Text(intf.format(s.zen.score)), Text(intf.format(s.zen.score)),
Text(intf.format(s.zen.level)) Text(intf.format(s.zen.level))
]); ]);
@ -684,6 +684,20 @@ class CompareState extends State<CompareView> {
}); });
} }
void removePlayer(String nickname) async {
int id = players.indexWhere((e) => e.username == nickname);
players.removeAt(id);
summaries.removeAt(id);
for (int i = 0; i < 7; i++){
rawValues[i].removeAt(id);
formattedValues[i].removeAt(id);
}
if (players.isNotEmpty) best = recalculateBestEntries();
setState(() {
});
}
double getWinrateByTR(double yourGlicko, double yourRD, double notyourGlicko,double notyourRD) { double getWinrateByTR(double yourGlicko, double yourRD, double notyourGlicko,double notyourRD) {
return ((1 / return ((1 /
(1 + pow(10, (1 + pow(10,
@ -739,7 +753,7 @@ class CompareState extends State<CompareView> {
), ),
for (var p in players) SizedBox( for (var p in players) SizedBox(
width: 300.0, width: 300.0,
child: HeaderCard(p), child: HeaderCard(p, removePlayer),
), ),
SizedBox(width: 300, child: AddNewColumnCard(addPlayer)) SizedBox(width: 300, child: AddNewColumnCard(addPlayer))
] ]
@ -787,8 +801,9 @@ class CompareState extends State<CompareView> {
class HeaderCard extends StatelessWidget{ class HeaderCard extends StatelessWidget{
final TetrioPlayer player; final TetrioPlayer player;
final Function removePlayer;
const HeaderCard(this.player); const HeaderCard(this.player, this.removePlayer);
String fontStyle(int length){ String fontStyle(int length){
if (length < 10) return "Eurostile Round Extended"; if (length < 10) return "Eurostile Round Extended";
@ -826,6 +841,12 @@ class HeaderCard extends StatelessWidget{
: Image.asset("res/avatars/tetrio_anon.png", fit: BoxFit.fitHeight, height: 128), : Image.asset("res/avatars/tetrio_anon.png", fit: BoxFit.fitHeight, height: 128),
) )
), ),
Positioned(
right: 0,
child: IconButton(onPressed: (){
removePlayer(player.username);
}, icon: Icon(Icons.close, shadows: textShadow,))
)
], ],
), ),
RichText( RichText(

View File

@ -244,7 +244,8 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
), ),
if (playstyle != null) Card( if (playstyle != null) Card(
child: GraphsThingy(nerdStats: nerdStats!, playstyle: playstyle!, apm: apm!, pps: pps!, vs: vs!) child: GraphsThingy(nerdStats: nerdStats!, playstyle: playstyle!, apm: apm!, pps: pps!, vs: vs!)
) ),
if (nerdStats == null) InfoThingy("Enter values and press \"Calc\" to see Nerd Stats for them")
], ],
), ),
); );
@ -467,14 +468,7 @@ class _DestinationCalculatorState extends State<DestinationCalculator> {
SizedBox( SizedBox(
width: widget.constraints.maxWidth - 350 - 80, width: widget.constraints.maxWidth - 350 - 80,
height: widget.constraints.maxHeight - 108, height: widget.constraints.maxHeight - 108,
child: clears.isEmpty ? Center(child: Column( child: clears.isEmpty ? InfoThingy("Click on the actions on the left to add them here") :
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.info_outline, size: 128.0, color: Colors.grey.shade800),
SizedBox(height: 5.0),
Text("Click on the actions on the left to add them here", textAlign: ui.TextAlign.center),
],
)) :
Card( Card(
child: Column( child: Column(
children: [ children: [

View File

@ -211,9 +211,9 @@ class _DestinationCutoffsState extends State<DestinationCutoffs> {
), ),
Padding( Padding(
padding: const EdgeInsets.only(right: 8.0), padding: const EdgeInsets.only(right: 8.0),
child: TextButton(child: Text("More Info", textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white)), onPressed: () { child: TextButton(child: Text("More Info", textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500)), onPressed: () {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
builder: (context) => RankView(rank: "", nextRankTR: snapshot.data!.data["top1"]!.tr, nextRankPercentile: 0.00, nextRankTargetTR: 25000.00, totalPlayers: snapshot.data!.total, cutoffTetrio: CutoffTetrio(apm: 0, pps: 0, vs: 0, pos: 0, percentile: 0, count: snapshot.data!.total, countPercentile: 1, tr: 10000.00, targetTr: 10000.00)), builder: (context) => RankView(rank: "", nextRankTR: snapshot.data!.data["top1"]!.tr, nextRankPercentile: 0.00, nextRankTargetTR: 25000.00, totalPlayers: snapshot.data!.total, cutoffTetrio: CutoffTetrio(apm: 0, pps: 0, vs: 0, pos: 0, percentile: 1, count: snapshot.data!.total, countPercentile: 1, tr: snapshot.data!.data["d"]!.tr, targetTr: snapshot.data!.data['d']!.targetTr)),
), ),
); );
},), },),
@ -278,7 +278,7 @@ class _DestinationCutoffsState extends State<DestinationCutoffs> {
), ),
Padding( Padding(
padding: const EdgeInsets.only(right: 8.0), padding: const EdgeInsets.only(right: 8.0),
child: TextButton(child: Text("View", textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white)), onPressed: () { child: TextButton(child: Text("View", textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500)), onPressed: () {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
builder: (context) => RankView(rank: rank, nextRankTR: rank == "x+" ? snapshot.data!.data["top1"]!.tr : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.tr, nextRankPercentile: rank == "x+" ? 0.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.percentile, nextRankTargetTR: rank == "x+" ? 25000.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.targetTr, totalPlayers: snapshot.data!.total, cutoffTetrio: snapshot.data!.data[rank]!), builder: (context) => RankView(rank: rank, nextRankTR: rank == "x+" ? snapshot.data!.data["top1"]!.tr : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.tr, nextRankPercentile: rank == "x+" ? 0.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.percentile, nextRankTargetTR: rank == "x+" ? 25000.00 : snapshot.data!.data[ranks[ranks.indexOf(rank)+1]]!.targetTr, totalPlayers: snapshot.data!.total, cutoffTetrio: snapshot.data!.data[rank]!),
), ),

View File

@ -483,7 +483,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
], ],
), ),
SizedBox( SizedBox(
height: 400, height: constraints.maxHeight - 192,
child: TabBarView( child: TabBarView(
children: [ children: [
FutureBuilder<SingleplayerStream>( FutureBuilder<SingleplayerStream>(
@ -496,35 +496,37 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
case ConnectionState.done: case ConnectionState.done:
if (snapshot.hasData){ if (snapshot.hasData){
return Column( return SingleChildScrollView(
children: [ child: Column(
for (int i = 0; i < snapshot.data!.records.length; i++) ListTile( children: [
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => SingleplayerRecordView(record: snapshot.data!.records[i]))), for (int i = 0; i < snapshot.data!.records.length; i++) ListTile(
leading: Text( onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => SingleplayerRecordView(record: snapshot.data!.records[i]))),
switch (snapshot.data!.records[i].gamemode){ leading: Text(
"40l" => "40L", switch (snapshot.data!.records[i].gamemode){
"blitz" => "BLZ", "40l" => "40L",
"5mblast" => "5MB", "blitz" => "BLZ",
"zenith" => "QP", "5mblast" => "5MB",
"zenithex" => "QPE", "zenith" => "QP",
String() => "huh", "zenithex" => "QPE",
}, String() => "huh",
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, shadows: textShadow, height: 0.9) },
), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, shadows: textShadow, height: 0.9)
title: Text( ),
switch (snapshot.data!.records[i].gamemode){ title: Text(
"40l" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds), switch (snapshot.data!.records[i].gamemode){
"blitz" => t.blitzScore(p: NumberFormat.decimalPattern().format(snapshot.data!.records[i].stats.score)), "40l" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds),
"5mblast" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds), "blitz" => t.blitzScore(p: NumberFormat.decimalPattern().format(snapshot.data!.records[i].stats.score)),
"zenith" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}", "5mblast" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds),
"zenithex" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}", "zenith" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}",
String() => "huh", "zenithex" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}",
}, String() => "huh",
style: Theme.of(context).textTheme.displayLarge), },
subtitle: Text(timestamp(snapshot.data!.records[i].timestamp), style: const TextStyle(color: Colors.grey, height: 0.85)), style: Theme.of(context).textTheme.displayLarge),
trailing: SpTrailingStats(snapshot.data!.records[i], snapshot.data!.records[i].gamemode) subtitle: Text(timestamp(snapshot.data!.records[i].timestamp), style: const TextStyle(color: Colors.grey, height: 0.85)),
) trailing: SpTrailingStats(snapshot.data!.records[i], snapshot.data!.records[i].gamemode)
], )
],
),
); );
} }
if (snapshot.hasError){ return FutureError(snapshot); } if (snapshot.hasError){ return FutureError(snapshot); }
@ -542,28 +544,30 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
case ConnectionState.done: case ConnectionState.done:
if (snapshot.hasData){ if (snapshot.hasData){
return Column( return SingleChildScrollView(
children: [ child: Column(
for (int i = 0; i < snapshot.data!.records.length; i++) ListTile( children: [
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => SingleplayerRecordView(record: snapshot.data!.records[i]))), for (int i = 0; i < snapshot.data!.records.length; i++) ListTile(
leading: Text( onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => SingleplayerRecordView(record: snapshot.data!.records[i]))),
"#${i+1}", leading: Text(
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, shadows: textShadow, height: 0.9) "#${i+1}",
), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, shadows: textShadow, height: 0.9)
title: Text( ),
switch (snapshot.data!.records[i].gamemode){ title: Text(
"40l" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds), switch (snapshot.data!.records[i].gamemode){
"blitz" => t.blitzScore(p: NumberFormat.decimalPattern().format(snapshot.data!.records[i].stats.score)), "40l" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds),
"5mblast" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds), "blitz" => t.blitzScore(p: NumberFormat.decimalPattern().format(snapshot.data!.records[i].stats.score)),
"zenith" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}", "5mblast" => get40lTime(snapshot.data!.records[i].stats.finalTime.inMicroseconds),
"zenithex" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}", "zenith" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}",
String() => "huh", "zenithex" => "${f2.format(snapshot.data!.records[i].stats.zenith!.altitude)} m${(snapshot.data!.records[i].extras as ZenithExtras).mods.isNotEmpty ? " (${t.withModsPlural(n: (snapshot.data!.records[i].extras as ZenithExtras).mods.length)})" : ""}",
}, String() => "huh",
style: Theme.of(context).textTheme.displayLarge), },
subtitle: Text(timestamp(snapshot.data!.records[i].timestamp), style: const TextStyle(color: Colors.grey, height: 0.85)), style: Theme.of(context).textTheme.displayLarge),
trailing: SpTrailingStats(snapshot.data!.records[i], snapshot.data!.records[i].gamemode) subtitle: Text(timestamp(snapshot.data!.records[i].timestamp), style: const TextStyle(color: Colors.grey, height: 0.85)),
) trailing: SpTrailingStats(snapshot.data!.records[i], snapshot.data!.records[i].gamemode)
], )
],
),
); );
} }
if (snapshot.hasError){ return FutureError(snapshot); } if (snapshot.hasError){ return FutureError(snapshot); }
@ -582,7 +586,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
); );
} }
Widget getRecentTLrecords(BoxConstraints constraints){ Widget getRecentTLrecords(BoxConstraints constraints, String userID){
return Column( return Column(
children: [ children: [
Card( Card(
@ -599,26 +603,27 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
), ),
), ),
), ),
Card( TLRecords(userID),
clipBehavior: Clip.antiAlias, // Card(
child: FutureBuilder<TetraLeagueBetaStream>( // clipBehavior: Clip.antiAlias,
future: teto.fetchTLStream(widget.searchFor), // child: FutureBuilder<TetraLeagueBetaStream>(
builder: (context, snapshot) { // future: teto.fetchTLStream(widget.searchFor),
switch (snapshot.connectionState){ // builder: (context, snapshot) {
case ConnectionState.none: // switch (snapshot.connectionState){
case ConnectionState.waiting: // case ConnectionState.none:
case ConnectionState.active: // case ConnectionState.waiting:
return const Center(child: CircularProgressIndicator()); // case ConnectionState.active:
case ConnectionState.done: // return const Center(child: CircularProgressIndicator());
if (snapshot.hasData){ // case ConnectionState.done:
return SizedBox(height: constraints.maxHeight - 145, child: TLRecords(userID: widget.searchFor, changePlayer: (){}, data: snapshot.data!.records, wasActiveInTL: snapshot.data!.records.isNotEmpty, oldMathcesHere: false)); // if (snapshot.hasData){
} // return SizedBox(height: constraints.maxHeight - 145, child: TLRecords(userID: userID, changePlayer: (){}, data: snapshot.data!.records, wasActiveInTL: snapshot.data!.records.isNotEmpty, oldMathcesHere: false));
if (snapshot.hasError){ return FutureError(snapshot); } // }
} // if (snapshot.hasError){ return FutureError(snapshot); }
return const Text("what?"); // }
}, // return const Text("what?");
), // },
), // ),
// ),
], ],
); );
} }
@ -1088,7 +1093,7 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
Cards.tetraLeague => switch (cardMod){ Cards.tetraLeague => switch (cardMod){
CardMod.info => getTetraLeagueCard(snapshot.data!.summaries!.league, snapshot.data!.cutoffs, (snapshot.data!.averages != null && snapshot.data!.summaries!.league.rank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.rank] : (snapshot.data!.averages != null && snapshot.data!.summaries!.league.percentileRank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.percentileRank] : null, snapshot.data!.states), CardMod.info => getTetraLeagueCard(snapshot.data!.summaries!.league, snapshot.data!.cutoffs, (snapshot.data!.averages != null && snapshot.data!.summaries!.league.rank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.rank] : (snapshot.data!.averages != null && snapshot.data!.summaries!.league.percentileRank != "z") ? snapshot.data!.averages!.data[snapshot.data!.summaries!.league.percentileRank] : null, snapshot.data!.states),
CardMod.ex => getPreviousSeasonsList(snapshot.data!.summaries!.pastLeague), CardMod.ex => getPreviousSeasonsList(snapshot.data!.summaries!.pastLeague),
CardMod.records => getRecentTLrecords(widget.constraints), CardMod.records => getRecentTLrecords(widget.constraints, snapshot.data!.player!.userId),
_ => const Center(child: Text("huh?")) _ => const Center(child: Text("huh?"))
}, },
Cards.quickPlay => switch (cardMod){ Cards.quickPlay => switch (cardMod){

View File

@ -29,11 +29,11 @@ class _DestinationSavedData extends State<DestinationSavedData> {
Widget getTetraLeagueListTile(TetraLeague data){ Widget getTetraLeagueListTile(TetraLeague data){
return ListTile( return ListTile(
title: Text("${timestamp(data.timestamp)}"), title: Text("${timestamp(data.timestamp)}"),
subtitle: Text("${f2.format(data.apm)} APM, ${f2.format(data.pps)} PPS, ${f2.format(data.vs)} VS, ${intf.format(data.gamesPlayed)} games", style: TextStyle(color: Colors.grey)), subtitle: Text("${data.apm != null ? f2.format(data.apm) : "-.--"} APM, ${data.pps != null ? f2.format(data.pps) : "-.--"} PPS, ${data.vs != null ? f2.format(data.vs) : "-.--"} VS, ${intf.format(data.gamesPlayed)} games", style: TextStyle(color: Colors.grey)),
trailing: Row( trailing: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text("${f2.format(data.tr)} TR", style: TextStyle(fontSize: 28)), Text("${data.tr != -1.00 ? f2.format(data.tr) : "-.--"} TR", style: TextStyle(fontSize: 28)),
Image.asset("res/tetrio_tl_alpha_ranks/${data.rank}.png", height: 36) Image.asset("res/tetrio_tl_alpha_ranks/${data.rank}.png", height: 36)
], ],
), ),
@ -138,9 +138,7 @@ class _DestinationSavedData extends State<DestinationSavedData> {
ListView.builder( ListView.builder(
itemCount: snapshot.data!.$3.length, itemCount: snapshot.data!.$3.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return ListTile( return AlphaLeagueEntryThingy(snapshot.data!.$3[index], selectedID!);
title: Text(snapshot.data!.$3[index].toString()),
);
},), },),
] ]
), ),
@ -154,7 +152,7 @@ class _DestinationSavedData extends State<DestinationSavedData> {
} }
} }
) : ) :
Text("Select nickname on the left to see data assosiated with it") InfoThingy("Select nickname on the left to see data assosiated with it")
) )
], ],
); );

View File

@ -1,10 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart' hide Badge; import 'package:flutter/material.dart' hide Badge;
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
@ -23,12 +21,12 @@ import 'package:tetra_stats/data_objects/record_extras.dart';
import 'package:tetra_stats/data_objects/record_single.dart'; import 'package:tetra_stats/data_objects/record_single.dart';
import 'package:tetra_stats/data_objects/summaries.dart'; import 'package:tetra_stats/data_objects/summaries.dart';
import 'package:tetra_stats/data_objects/tetra_league.dart'; import 'package:tetra_stats/data_objects/tetra_league.dart';
import 'package:tetra_stats/data_objects/tetra_league_alpha_record.dart';
import 'package:tetra_stats/data_objects/tetrio_constants.dart'; import 'package:tetra_stats/data_objects/tetrio_constants.dart';
import 'package:tetra_stats/data_objects/tetrio_player.dart'; import 'package:tetra_stats/data_objects/tetrio_player.dart';
import 'package:tetra_stats/gen/strings.g.dart'; import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/services/crud_exceptions.dart'; import 'package:tetra_stats/services/crud_exceptions.dart';
import 'package:tetra_stats/utils/colors_functions.dart'; import 'package:tetra_stats/utils/colors_functions.dart';
import 'package:tetra_stats/utils/filesizes_converter.dart';
import 'package:tetra_stats/utils/numers_formats.dart'; import 'package:tetra_stats/utils/numers_formats.dart';
import 'package:tetra_stats/utils/relative_timestamps.dart'; import 'package:tetra_stats/utils/relative_timestamps.dart';
import 'package:tetra_stats/utils/text_shadow.dart'; import 'package:tetra_stats/utils/text_shadow.dart';
@ -64,6 +62,7 @@ Future<FetchResults> getData(String searchFor) async {
}else{ }else{
player = await teto.fetchPlayer(searchFor); // Otherwise it's probably a user id or username player = await teto.fetchPlayer(searchFor); // Otherwise it's probably a user id or username
} }
}on TetrioPlayerNotExist{ }on TetrioPlayerNotExist{
return FetchResults(false, null, [], null, null, null, false, TetrioPlayerNotExist()); return FetchResults(false, null, [], null, null, null, false, TetrioPlayerNotExist());
} }
@ -1535,8 +1534,8 @@ class ZenithThingy extends StatelessWidget{
const Text(" B2B", style: TextStyle(fontSize: 21)) const Text(" B2B", style: TextStyle(fontSize: 21))
]), ]),
TableRow(children: [ TableRow(children: [
Text(zenith!.stats.zenith!.floor.toString(), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)), Text(zenith!.stats.garbage.maxspike_nomult.toString(), textAlign: TextAlign.right, style: const TextStyle(fontSize: 21)),
const Text(" Floor", style: TextStyle(fontSize: 21)) const Text(" Top spike", style: TextStyle(fontSize: 21))
]) ])
], ],
), ),
@ -1582,7 +1581,7 @@ class ZenithThingy extends StatelessWidget{
]), ]),
const TableRow(children: [ const TableRow(children: [
Text("---", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: Colors.grey)), Text("---", textAlign: TextAlign.right, style: TextStyle(fontSize: 21, color: Colors.grey)),
Text(" Floor", style: TextStyle(fontSize: 21, color: Colors.grey)) Text(" Top spike", style: TextStyle(fontSize: 21, color: Colors.grey))
]) ])
], ],
), ),
@ -1598,72 +1597,197 @@ class ZenithThingy extends StatelessWidget{
} }
class TLRecords extends StatelessWidget { class AlphaLeagueEntryThingy extends StatelessWidget{
final TetraLeagueAlphaRecord record;
final String userID; final String userID;
final Function changePlayer;
final List<BetaRecord> data;
final bool wasActiveInTL;
final bool oldMathcesHere;
/// Widget, that displays Tetra League records. const AlphaLeagueEntryThingy(this.record, this.userID);
/// Accepts list of TL records ([data]) and [userID] of player from the view
const TLRecords({required this.userID, required this.changePlayer, required this.data, required this.wasActiveInTL, required this.oldMathcesHere});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (data.isEmpty) { var accentColor = record.endContext.firstWhere((element) => element.userId == userID).success ? Colors.green : Colors.red;
return Center(child: Column( return Container(
mainAxisSize: MainAxisSize.min, decoration: BoxDecoration(
children: [ gradient: LinearGradient(
Text(t.noRecords, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)), stops: const [0, 0.05],
if (wasActiveInTL) Text(t.errors.actionSuggestion), colors: [accentColor, Colors.transparent]
if (wasActiveInTL) TextButton(onPressed: (){changePlayer(userID, fetchTLmatches: true);}, child: Text(t.fetchAndSaveOldTLmatches)) )
], ),
)); child: ListTile(
} leading: Text("${record.endContext.firstWhere((element) => element.userId == userID).points} : ${record.endContext.firstWhere((element) => element.userId != userID).points}",
bool bigScreen = MediaQuery.of(context).size.width >= 768; style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, shadows: textShadow)),
int length = data.length; title: Text("vs. ${record.endContext.firstWhere((element) => element.userId != userID).username}"),
return ListView.builder( subtitle: Text(timestamp(record.timestamp), style: const TextStyle(color: Colors.grey)),
physics: const AlwaysScrollableScrollPhysics(), trailing: TrailingStats(
//controller: separateScrollController ? ScrollController() : null, record.endContext.firstWhere((element) => element.userId == userID).secondary,
itemCount: oldMathcesHere ? length : length + 1, record.endContext.firstWhere((element) => element.userId == userID).tertiary,
itemBuilder: (BuildContext context, int index) { record.endContext.firstWhere((element) => element.userId == userID).extra,
if (index == length) { record.endContext.firstWhere((element) => element.userId != userID).secondary,
return Center(child: Column( record.endContext.firstWhere((element) => element.userId != userID).tertiary,
mainAxisSize: MainAxisSize.min, record.endContext.firstWhere((element) => element.userId != userID).extra
children: [ ),
Text(t.noOldRecords(n: length), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)), //onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => TlMatchResultView(record: record, initPlayerId: userID))),
if (wasActiveInTL) Text(t.errors.actionSuggestion), ),
if (wasActiveInTL) TextButton(onPressed: (){changePlayer(userID, fetchTLmatches: true);}, child: Text(t.fetchAndSaveOldTLmatches)) );
], }
)); }
}
var accentColor = data[index].results.leaderboard.firstWhere((element) => element.id == userID).wins > data[index].results.leaderboard.firstWhere((element) => element.id != userID).wins ? Colors.green : Colors.red; class BetaLeagueEntryThingy extends StatelessWidget{
return Container( final BetaRecord record;
decoration: BoxDecoration( final String userID;
gradient: LinearGradient(
stops: const [0, 0.05], const BetaLeagueEntryThingy(this.record, this.userID);
colors: [accentColor, Colors.transparent]
) TextSpan matchResult(String result){
), return switch(result){
child: ListTile( "victory" => TextSpan(
leading: Text("${data[index].results.leaderboard.firstWhere((element) => element.id == userID).wins} : ${data[index].results.leaderboard.firstWhere((element) => element.id != userID).wins}", text: "Victory",
style: bigScreen ? const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28, shadows: textShadow) : const TextStyle(fontSize: 28, shadows: textShadow)), style: TextStyle(color: Colors.greenAccent)
title: Text("vs. ${data[index].results.leaderboard.firstWhere((element) => element.id != userID).username}"), ),
subtitle: Text(timestamp(data[index].ts), style: const TextStyle(color: Colors.grey)), "defeat" => TextSpan(
trailing: TrailingStats( text: "Defeat",
data[index].results.leaderboard.firstWhere((element) => element.id == userID).stats.apm, style: TextStyle(color: Colors.redAccent)
data[index].results.leaderboard.firstWhere((element) => element.id == userID).stats.pps, ),
data[index].results.leaderboard.firstWhere((element) => element.id == userID).stats.vs, "tie" => TextSpan(
data[index].results.leaderboard.firstWhere((element) => element.id != userID).stats.apm, text: "Tie",
data[index].results.leaderboard.firstWhere((element) => element.id != userID).stats.pps, style: TextStyle(color: Colors.white)
data[index].results.leaderboard.firstWhere((element) => element.id != userID).stats.vs, ),
"dqvictory" => TextSpan(
text: "Opponent was DQ'ed",
style: TextStyle(color: Colors.lightGreenAccent)
),
"dqdefeat" => TextSpan(
text: "Player was DQ'ed",
style: TextStyle(color: Colors.red)
),
"nocontest" => TextSpan(
text: "No Contest",
style: TextStyle(color: Colors.blueAccent)
),
"nullified" => TextSpan(
text: "Nullified",
style: TextStyle(color: Colors.purpleAccent)
),
_ => TextSpan(
text: "${result.toUpperCase()}",
style: TextStyle(color: Colors.orangeAccent)
)
};
}
Color deltaColor(double? delta){
if (delta == null || delta.isNaN) return Colors.grey;
if (delta.isNegative) return Colors.redAccent;
else return Colors.greenAccent;
}
@override
Widget build(BuildContext context) {
double? deltaTR = (record.extras.league[userID]?[1]?.tr != null && record.extras.league[userID]?[0]?.tr != null) ? record.extras.league[userID]![1]!.tr - record.extras.league[userID]![0]!.tr : null;
double? deltaGlicko = (record.extras.league[userID]?[1]?.glicko != null && record.extras.league[userID]?[0]?.glicko != null) ? record.extras.league[userID]![1]!.glicko - record.extras.league[userID]![0]!.glicko : null;
double? deltaRD = (record.extras.league[userID]?[1]?.rd != null && record.extras.league[userID]?[0]?.rd != null) ? record.extras.league[userID]![1]!.rd - record.extras.league[userID]![0]!.rd : null;
return Card(
child: ListTile(
title: Row(
children: [
Text(
"${record.results.leaderboard.firstWhere((element) => element.id != record.enemyID).wins} - ${record.results.leaderboard.firstWhere((element) => element.id == record.enemyID).wins} ",
style: TextStyle(fontSize: 26, height: 0.75, fontWeight: FontWeight.bold),
), ),
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => TlMatchResultView(record: data[index], initPlayerId: userID))) //Navigator.push(context, MaterialPageRoute(builder: (context) => TlMatchResultView(record: data[index], initPlayerId: userID))), Text(
"vs.\n${record.enemyUsername}",
style: TextStyle(fontSize: 14, height: 0.8, fontWeight: FontWeight.w100),
),
],
), ),
); subtitle: Padding(
}); padding: const EdgeInsets.only(top: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
RichText(
text: TextSpan(
style: TextStyle(fontFamily: "Eurostile Round", fontSize: 14, color: Colors.grey),
children: [
matchResult(record.extras.result),
TextSpan(
text: ", ${timestamp(record.ts)}\n"
),
TextSpan(
text: deltaTR != null ? "${fDiff.format(deltaTR)} TR" : "??? TR",
style: TextStyle(
color: deltaColor(deltaTR)
)
),
TextSpan(
text: ", "
),
TextSpan(
text: deltaGlicko != null ? "${fDiff.format(deltaGlicko)} Glicko" : "??? Glicko",
style: TextStyle(
color: deltaColor(deltaGlicko)
)
),
TextSpan(
text: ", "
),
TextSpan(
text: deltaRD != null ? "${fDiff.format(deltaRD)} RD" : "??? RD",
style: TextStyle(
color: Colors.grey
)
),
]
)
),
],
),
),
trailing: TrailingStats(
record.results.leaderboard.firstWhere((element) => element.id != record.enemyID).stats.apm,
record.results.leaderboard.firstWhere((element) => element.id != record.enemyID).stats.pps,
record.results.leaderboard.firstWhere((element) => element.id != record.enemyID).stats.vs,
record.results.leaderboard.firstWhere((element) => element.id == record.enemyID).stats.apm,
record.results.leaderboard.firstWhere((element) => element.id == record.enemyID).stats.pps,
record.results.leaderboard.firstWhere((element) => element.id == record.enemyID).stats.vs,
),
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => TlMatchResultView(record: record, initPlayerId: userID))) //Navigator.push(context, MaterialPageRoute(builder: (context) => TlMatchResultView(record: data[index], initPlayerId: userID))),
),
);
}
}
class TLRecords extends StatelessWidget {
final String userID;
/// Widget, that displays Tetra League records.
/// Accepts list of TL records ([data]) and [userID] of player from the view
const TLRecords(this.userID);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: teto.fetchTLStream(userID),
builder: (context, snapshot) {
switch (snapshot.connectionState){
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return const Center(child: CircularProgressIndicator());
case ConnectionState.done:
if (snapshot.hasData){
return Column(
children: [
for (BetaRecord record in snapshot.data!.records) BetaLeagueEntryThingy(record, userID)
],
);
}
if (snapshot.hasError){ return FutureError(snapshot); }
}
return const Text("what?");
},
);
} }
} }
@ -1918,3 +2042,22 @@ class ErrorThingy extends StatelessWidget{
); );
} }
} }
class InfoThingy extends StatelessWidget{
final String info;
const InfoThingy(this.info);
@override
Widget build(BuildContext context) {
return Center(child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.info_outline, size: 128.0, color: Colors.grey.shade800),
SizedBox(height: 5.0),
Text(info, textAlign: TextAlign.center),
],
));
}
}

View File

@ -32,6 +32,81 @@ class _RankState extends State<RankView> {
return lb.getRankData(rank); return lb.getRankData(rank);
} }
Widget partOfTheWidget(List<dynamic>? data){
return Column(
children: [
Divider(),
Text("Average Stats", style: Theme.of(context).textTheme.displayLarge),
Text("${f2.format(data != null ? data[0].apm : widget.cutoffTetrio.apm)} APM • ${f2.format(data != null ? data[0].pps : widget.cutoffTetrio.pps)} PPS • ${f2.format(data != null ? data[0].vs : widget.cutoffTetrio.vs)} VS", style: Theme.of(context).textTheme.displayLarge),
Divider(),
Center(child: Text("Average Nerd Stats", style: Theme.of(context).textTheme.displayLarge)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Attack Per Piece", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(data != null ? data[1]["avgAPP"] : widget.cutoffTetrio.nerdStats?.app), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("VS / APM", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(data != null ? data[1]["avgVSAPM"] : widget.cutoffTetrio.nerdStats?.vsapm), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Downstack Per Second", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(data != null ? data[1]["avgDSS"] : widget.cutoffTetrio.nerdStats?.dss), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Downstack Per Piece", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(data != null ? data[1]["avgDSP"] : widget.cutoffTetrio.nerdStats?.dsp), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("APP + DSP", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(data != null ? data[1]["avgAPPDSP"] : widget.cutoffTetrio.nerdStats?.appdsp), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Cheese Index", style: Theme.of(context).textTheme.displayLarge),
Text(f2.format(data != null ? data[1]["avgCheese"] : widget.cutoffTetrio.nerdStats?.cheese), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Garbage Efficiency", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(data != null ? data[1]["avgGBE"] : widget.cutoffTetrio.nerdStats?.gbe), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Weighted APP", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(data != null ? data[1]["avgNyaAPP"] : widget.cutoffTetrio.nerdStats?.nyaapp), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Area", style: Theme.of(context).textTheme.displayLarge),
Text(f1.format(data != null ? data[1]["avgArea"] : widget.cutoffTetrio.nerdStats?.area), style: Theme.of(context).textTheme.displayLarge)
],
),
],
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double percentileGap = widget.cutoffTetrio.percentile - widget.nextRankPercentile; double percentileGap = widget.cutoffTetrio.percentile - widget.nextRankPercentile;
@ -58,7 +133,7 @@ class _RankState extends State<RankView> {
children: [ children: [
Card(child: Center(child: Padding( Card(child: Center(child: Padding(
padding: const EdgeInsets.fromLTRB(0.0, 8.0, 5.0, 10.0), padding: const EdgeInsets.fromLTRB(0.0, 8.0, 5.0, 10.0),
child: Text("${widget.rank.toUpperCase()} rank data", style: TextStyle(fontSize: 28)), child: Text(widget.rank == "" ? "Everyone" : "${widget.rank.toUpperCase()} rank data", style: TextStyle(fontSize: 28)),
))), ))),
Card( Card(
child: Center( child: Center(
@ -67,7 +142,7 @@ class _RankState extends State<RankView> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Image.asset("res/tetrio_tl_alpha_ranks/${widget.rank}.png",fit: BoxFit.fitHeight,height: 128), Image.asset("res/tetrio_tl_alpha_ranks/${widget.rank == "" ? "z" : widget.rank}.png",fit: BoxFit.fitHeight,height: 128),
Text("${intf.format(widget.cutoffTetrio.count)} players", style: Theme.of(context).textTheme.titleSmall,), Text("${intf.format(widget.cutoffTetrio.count)} players", style: Theme.of(context).textTheme.titleSmall,),
], ],
), ),
@ -96,14 +171,14 @@ class _RankState extends State<RankView> {
], ],
), ),
), ),
Row( if (widget.rank != "") Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("Supposed to be", style: Theme.of(context).textTheme.displayLarge), Text("Supposed to be", style: Theme.of(context).textTheme.displayLarge),
Text("${intf.format(widget.cutoffTetrio.targetTr)}${intf.format(widget.nextRankTargetTR)}", style: Theme.of(context).textTheme.displayLarge) Text("${intf.format(widget.cutoffTetrio.targetTr)}${intf.format(widget.nextRankTargetTR)}", style: Theme.of(context).textTheme.displayLarge)
], ],
), ),
Padding( if (widget.rank != "") Padding(
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
child: Row( child: Row(
children: [ children: [
@ -126,14 +201,14 @@ class _RankState extends State<RankView> {
Text("${f2.format(widget.cutoffTetrio.targetTr - widget.cutoffTetrio.tr)} TR", style: Theme.of(context).textTheme.displayLarge!.copyWith(color: Colors.greenAccent)) Text("${f2.format(widget.cutoffTetrio.targetTr - widget.cutoffTetrio.tr)} TR", style: Theme.of(context).textTheme.displayLarge!.copyWith(color: Colors.greenAccent))
], ],
), ),
Row( if (widget.rank != "") Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("LB pos range", style: Theme.of(context).textTheme.displayLarge), Text("LB pos range", style: Theme.of(context).textTheme.displayLarge),
Text("${percentage.format(widget.cutoffTetrio.percentile)}${percentage.format(widget.nextRankPercentile)}", style: Theme.of(context).textTheme.displayLarge) Text("${percentage.format(widget.cutoffTetrio.percentile)}${percentage.format(widget.nextRankPercentile)}", style: Theme.of(context).textTheme.displayLarge)
], ],
), ),
Padding( if (widget.rank != "") Padding(
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
child: Row( child: Row(
children: [ children: [
@ -142,14 +217,14 @@ class _RankState extends State<RankView> {
], ],
), ),
), ),
Row( if (widget.rank != "") Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("Supposed to be", style: Theme.of(context).textTheme.displayLarge), Text("Supposed to be", style: Theme.of(context).textTheme.displayLarge),
Text("${intf.format(supposedToBePlayers)} players", style: Theme.of(context).textTheme.displayLarge) Text("${intf.format(supposedToBePlayers)} players", style: Theme.of(context).textTheme.displayLarge)
], ],
), ),
Padding( if (widget.rank != "") Padding(
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
child: Row( child: Row(
children: [ children: [
@ -160,75 +235,24 @@ class _RankState extends State<RankView> {
], ],
), ),
), ),
Divider(), if (widget.rank == "") FutureBuilder<List<dynamic>>(
Text("Average Stats", style: Theme.of(context).textTheme.displayLarge), future: getRanksAverages(widget.rank),
Text("${f2.format(widget.cutoffTetrio.apm)} APM • ${f2.format(widget.cutoffTetrio.pps)} PPS • ${f2.format(widget.cutoffTetrio.vs)} VS", style: Theme.of(context).textTheme.displayLarge), builder: (context, snapshot) {
Divider(), switch (snapshot.connectionState){
Center(child: Text("Average Nerd Stats", style: Theme.of(context).textTheme.displayLarge)), case ConnectionState.none:
Row( case ConnectionState.waiting:
mainAxisAlignment: MainAxisAlignment.spaceBetween, return const Center(child: CircularProgressIndicator());
children: [ case ConnectionState.active:
Text("Attack Per Piece", style: Theme.of(context).textTheme.displayLarge), case ConnectionState.done:
Text(f3.format(widget.cutoffTetrio.nerdStats?.app), style: Theme.of(context).textTheme.displayLarge) if (snapshot.hasData){
], return partOfTheWidget(snapshot.data);
), }
Row( if (snapshot.hasError) return FutureError(snapshot);
mainAxisAlignment: MainAxisAlignment.spaceBetween, }
children: [ return Text("End of the FutureBuilder");
Text("VS / APM", style: Theme.of(context).textTheme.displayLarge), },
Text(f3.format(widget.cutoffTetrio.nerdStats?.vsapm), style: Theme.of(context).textTheme.displayLarge) )
], else partOfTheWidget(null)
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Downstack Per Second", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(widget.cutoffTetrio.nerdStats?.dss), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Downstack Per Piece", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(widget.cutoffTetrio.nerdStats?.dsp), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("APP + DSP", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(widget.cutoffTetrio.nerdStats?.appdsp), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Cheese Index", style: Theme.of(context).textTheme.displayLarge),
Text(f2.format(widget.cutoffTetrio.nerdStats?.cheese), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Garbage Efficiency", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(widget.cutoffTetrio.nerdStats?.gbe), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Weighted APP", style: Theme.of(context).textTheme.displayLarge),
Text(f3.format(widget.cutoffTetrio.nerdStats?.nyaapp), style: Theme.of(context).textTheme.displayLarge)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Area", style: Theme.of(context).textTheme.displayLarge),
Text(f1.format(widget.cutoffTetrio.nerdStats?.area), style: Theme.of(context).textTheme.displayLarge)
],
),
], ],
), ),
), ),

View File

@ -13,14 +13,14 @@ class TrailingStats extends StatelessWidget{
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const TextStyle style = TextStyle(height: 1.1, fontWeight: FontWeight.w100, fontSize: 13); const TextStyle style = TextStyle(height: 1.1, fontWeight: FontWeight.w100, fontSize: 15);
return Table( return Table(
defaultColumnWidth: const IntrinsicColumnWidth(), defaultColumnWidth: const IntrinsicColumnWidth(),
defaultVerticalAlignment: TableCellVerticalAlignment.baseline, defaultVerticalAlignment: TableCellVerticalAlignment.baseline,
textBaseline: TextBaseline.alphabetic, textBaseline: TextBaseline.alphabetic,
columnWidths: const { columnWidths: const {
0: FixedColumnWidth(48), 0: FixedColumnWidth(54),
2: FixedColumnWidth(48), 2: FixedColumnWidth(54),
}, },
children: [ children: [
TableRow(children: [Text(f2.format(yourAPM), textAlign: TextAlign.right, style: style), const Text(" :", style: style), Text(f2.format(notyourAPM), textAlign: TextAlign.right, style: style), const Text(" APM", textAlign: TextAlign.right, style: style)]), TableRow(children: [Text(f2.format(yourAPM), textAlign: TextAlign.right, style: style), const Text(" :", style: style), Text(f2.format(notyourAPM), textAlign: TextAlign.right, style: style), const Text(" APM", textAlign: TextAlign.right, style: style)]),