ok, 1.6.3, a lot of things i should fix, a lot of things to consider...

This commit is contained in:
dan63047 2024-08-17 01:40:09 +03:00
parent 54030def54
commit 2376c0eb58
15 changed files with 93 additions and 143 deletions

View File

@ -21,6 +21,7 @@ const List<String> ranks = [
"d", "d+", "c-", "c", "c+", "b-", "b", "b+", "a-", "a", "a+", "s-", "s", "s+", "ss", "u", "x" "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.002,
"x": 0.01, "x": 0.01,
"u": 0.05, "u": 0.05,
"ss": 0.11, "ss": 0.11,
@ -220,7 +221,7 @@ class TetrioPlayer {
bool? badstanding; bool? badstanding;
String? botmaster; String? botmaster;
Connections? connections; Connections? connections;
TetraLeagueAlpha? tlSeason1; TetraLeague? tlSeason1;
TetrioZen? zen; TetrioZen? zen;
Distinguishment? distinguishment; Distinguishment? distinguishment;
DateTime? cachedUntil; DateTime? cachedUntil;
@ -273,7 +274,7 @@ class TetrioPlayer {
country = json['country']; country = json['country'];
supporterTier = json['supporter_tier'] ?? 0; supporterTier = json['supporter_tier'] ?? 0;
verified = json['verified'] ?? false; verified = json['verified'] ?? false;
tlSeason1 = json['league'] != null ? TetraLeagueAlpha.fromJson(json['league'], stateTime) : null; tlSeason1 = json['league'] != null ? TetraLeague.fromJson(json['league'], stateTime) : null;
avatarRevision = json['avatar_revision']; avatarRevision = json['avatar_revision'];
bannerRevision = json['banner_revision']; bannerRevision = json['banner_revision'];
bio = json['bio']; bio = json['bio'];
@ -339,8 +340,8 @@ class TetrioPlayer {
} }
TetrioPlayerFromLeaderboard convertToPlayerFromLeaderboard() => TetrioPlayerFromLeaderboard( TetrioPlayerFromLeaderboard convertToPlayerFromLeaderboard() => TetrioPlayerFromLeaderboard(
userId, username, role, xp, country, verified, state, gamesPlayed, gamesWon, userId, username, role, xp, country, state, gamesPlayed, gamesWon,
tlSeason1!.rating, tlSeason1!.glicko??0, tlSeason1!.rd??noTrRd, tlSeason1!.rank, tlSeason1!.bestRank, tlSeason1!.apm??0, tlSeason1!.pps??0, tlSeason1!.vs??0, tlSeason1!.decaying); tlSeason1!.tr, tlSeason1!.glicko??0, tlSeason1!.rd??noTrRd, tlSeason1!.rank, tlSeason1!.bestRank, tlSeason1!.apm??0, tlSeason1!.pps??0, tlSeason1!.vs??0, tlSeason1!.decaying);
@override @override
String toString() { String toString() {
@ -350,7 +351,7 @@ class TetrioPlayer {
num? getStatByEnum(Stats stat){ num? getStatByEnum(Stats stat){
switch (stat) { switch (stat) {
case Stats.tr: case Stats.tr:
return tlSeason1?.rating; return tlSeason1?.tr;
case Stats.glicko: case Stats.glicko:
return tlSeason1?.glicko; return tlSeason1?.glicko;
case Stats.rd: case Stats.rd:
@ -420,7 +421,7 @@ class Summaries{
RecordSingle? zenith; RecordSingle? zenith;
RecordSingle? zenithEx; RecordSingle? zenithEx;
late List<Achievement> achievements; late List<Achievement> achievements;
late TetraLeagueAlpha league; late TetraLeague league;
late TetrioZen zen; late TetrioZen zen;
Summaries(this.id, this.league, this.zen); Summaries(this.id, this.league, this.zen);
@ -432,7 +433,7 @@ class Summaries{
if (json['zenith']['record'] != null) zenith = RecordSingle.fromJson(json['zenith']['record'], json['zenith']['rank'], json['zenith']['rank_local']); if (json['zenith']['record'] != null) zenith = RecordSingle.fromJson(json['zenith']['record'], json['zenith']['rank'], json['zenith']['rank_local']);
if (json['zenithex']['record'] != null) zenithEx = RecordSingle.fromJson(json['zenithex']['record'], json['zenithex']['rank'], json['zenithex']['rank_local']); if (json['zenithex']['record'] != null) zenithEx = RecordSingle.fromJson(json['zenithex']['record'], json['zenithex']['rank'], json['zenithex']['rank_local']);
achievements = [for (var achievement in json['achievements']) Achievement.fromJson(achievement)]; achievements = [for (var achievement in json['achievements']) Achievement.fromJson(achievement)];
league = TetraLeagueAlpha.fromJson(json['league'], DateTime.now()); league = TetraLeague.fromJson(json['league'], DateTime.now());
zen = TetrioZen.fromJson(json['zen']); zen = TetrioZen.fromJson(json['zen']);
} }
} }
@ -1360,13 +1361,14 @@ class EndContextMulti {
} }
} }
class TetraLeagueAlpha { class TetraLeague {
late DateTime timestamp; late DateTime timestamp;
late int gamesPlayed; late int gamesPlayed;
late int gamesWon; late int gamesWon;
late String bestRank; late String bestRank;
late bool decaying; late bool decaying;
late double rating; late double tr;
late double gxe;
late String rank; late String rank;
double? glicko; double? glicko;
double? rd; double? rd;
@ -1386,13 +1388,14 @@ class TetraLeagueAlpha {
Playstyle? playstyle; Playstyle? playstyle;
List? records; List? records;
TetraLeagueAlpha( TetraLeague(
{required this.timestamp, {required this.timestamp,
required this.gamesPlayed, required this.gamesPlayed,
required this.gamesWon, required this.gamesWon,
required this.bestRank, required this.bestRank,
required this.decaying, required this.decaying,
required this.rating, required this.tr,
required this.gxe,
required this.rank, required this.rank,
this.glicko, this.glicko,
this.rd, this.rd,
@ -1415,13 +1418,14 @@ class TetraLeagueAlpha {
double get winrate => gamesWon / gamesPlayed; double get winrate => gamesWon / gamesPlayed;
TetraLeagueAlpha.fromJson(Map<String, dynamic> json, ts) { TetraLeague.fromJson(Map<String, dynamic> json, ts) {
timestamp = ts; timestamp = ts;
gamesPlayed = json['gamesplayed'] ?? 0; gamesPlayed = json['gamesplayed'] ?? 0;
gamesWon = json['gameswon'] ?? 0; gamesWon = json['gameswon'] ?? 0;
rating = json['rating'] != null ? json['rating'].toDouble() : -1; tr = json['tr'] != null ? json['tr'].toDouble() : -1;
glicko = json['glicko']?.toDouble(); glicko = json['glicko']?.toDouble();
rd = json['rd'] != null ? json['rd']!.toDouble() : noTrRd; rd = json['rd'] != null ? json['rd']!.toDouble() : noTrRd;
gxe = json['gxe'].toDouble();
rank = json['rank'] != null ? json['rank']!.toString() : 'z'; rank = json['rank'] != null ? json['rank']!.toString() : 'z';
bestRank = json['bestrank'] != null ? json['bestrank']!.toString() : 'z'; bestRank = json['bestrank'] != null ? json['bestrank']!.toString() : 'z';
apm = json['apm']?.toDouble(); apm = json['apm']?.toDouble();
@ -1442,17 +1446,17 @@ class TetraLeagueAlpha {
} }
@override @override
bool operator ==(covariant TetraLeagueAlpha other) => gamesPlayed == other.gamesPlayed && rd == other.rd; bool operator ==(covariant TetraLeague other) => gamesPlayed == other.gamesPlayed && rd == other.rd;
bool lessStrictCheck (covariant TetraLeagueAlpha other) => gamesPlayed == other.gamesPlayed && glicko == other.glicko; bool lessStrictCheck (covariant TetraLeague other) => gamesPlayed == other.gamesPlayed && glicko == other.glicko;
double? get esttracc => (estTr != null) ? estTr!.esttr - rating : null; double? get esttracc => (estTr != null) ? estTr!.esttr - tr : null;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
if (gamesPlayed > 0) data['gamesplayed'] = gamesPlayed; if (gamesPlayed > 0) data['gamesplayed'] = gamesPlayed;
if (gamesWon > 0) data['gameswon'] = gamesWon; if (gamesWon > 0) data['gameswon'] = gamesWon;
if (rating >= 0) data['rating'] = rating; if (tr >= 0) data['tr'] = tr;
if (glicko != null) data['glicko'] = glicko; if (glicko != null) data['glicko'] = glicko;
if (rd != null && rd != noTrRd) data['rd'] = rd; if (rd != null && rd != noTrRd) data['rd'] = rd;
if (rank != 'z') data['rank'] = rank; if (rank != 'z') data['rank'] = rank;
@ -1868,7 +1872,7 @@ class TetrioPlayersLeaderboard {
avgAPM += entry.apm; avgAPM += entry.apm;
avgPPS += entry.pps; avgPPS += entry.pps;
avgVS += entry.vs; avgVS += entry.vs;
avgTR += entry.rating; avgTR += entry.tr;
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; avgAPP += entry.nerdStats.app;
@ -1888,8 +1892,8 @@ class TetrioPlayersLeaderboard {
avgInfDS += entry.playstyle.infds; avgInfDS += entry.playstyle.infds;
totalGamesPlayed += entry.gamesPlayed; totalGamesPlayed += entry.gamesPlayed;
totalGamesWon += entry.gamesWon; totalGamesWon += entry.gamesWon;
if (entry.rating < lowestTR){ if (entry.tr < lowestTR){
lowestTR = entry.rating; lowestTR = entry.tr;
lowestTRid = entry.userId; lowestTRid = entry.userId;
lowestTRnick = entry.username; lowestTRnick = entry.username;
} }
@ -2008,8 +2012,8 @@ class TetrioPlayersLeaderboard {
lowestInfDSid = entry.userId; lowestInfDSid = entry.userId;
lowestInfDSnick = entry.username; lowestInfDSnick = entry.username;
} }
if (entry.rating > highestTR){ if (entry.tr > highestTR){
highestTR = entry.rating; highestTR = entry.tr;
highestTRid = entry.userId; highestTRid = entry.userId;
highestTRnick = entry.username; highestTRnick = entry.username;
} }
@ -2152,7 +2156,7 @@ class TetrioPlayersLeaderboard {
avgInfDS /= filtredLeaderboard.length; avgInfDS /= filtredLeaderboard.length;
avgGamesPlayed = (totalGamesPlayed / filtredLeaderboard.length).floor(); avgGamesPlayed = (totalGamesPlayed / filtredLeaderboard.length).floor();
avgGamesWon = (totalGamesWon / filtredLeaderboard.length).floor(); avgGamesWon = (totalGamesWon / filtredLeaderboard.length).floor();
return [TetraLeagueAlpha(timestamp: DateTime.now(), apm: avgAPM, pps: avgPPS, vs: avgVS, glicko: avgGlicko, rd: avgRD, gamesPlayed: avgGamesPlayed, gamesWon: avgGamesWon, bestRank: rank, decaying: false, rating: avgTR, rank: rank == "" ? "z" : rank, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1), return [TetraLeague(timestamp: DateTime.now(), apm: avgAPM, pps: avgPPS, vs: avgVS, glicko: avgGlicko, rd: avgRD, gamesPlayed: avgGamesPlayed, gamesWon: avgGamesWon, bestRank: rank, gxe: -1, decaying: false, tr: avgTR, rank: rank == "" ? "z" : rank, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1),
{ {
"everyone": rank == "", "everyone": rank == "",
"totalGamesPlayed": totalGamesPlayed, "totalGamesPlayed": totalGamesPlayed,
@ -2317,12 +2321,12 @@ class TetrioPlayersLeaderboard {
"avgPlonk": avgPlonk, "avgPlonk": avgPlonk,
"avgStride": avgStride, "avgStride": avgStride,
"avgInfDS": avgInfDS, "avgInfDS": avgInfDS,
"toEnterTR": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].rating : lowestTR, "toEnterTR": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()].tr : lowestTR,
"toEnterGlicko": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].glicko : 0, "toEnterGlicko": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()].glicko : 0,
"entries": filtredLeaderboard "entries": filtredLeaderboard
}]; }];
}else{ }else{
return [TetraLeagueAlpha(timestamp: DateTime.now(), apm: 0, pps: 0, vs: 0, glicko: 0, rd: noTrRd, gamesPlayed: 0, gamesWon: 0, bestRank: rank, decaying: false, rating: 0, rank: rank, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1), return [TetraLeague(timestamp: DateTime.now(), apm: 0, pps: 0, vs: 0, glicko: 0, rd: noTrRd, gamesPlayed: 0, gamesWon: 0, bestRank: rank, decaying: false, tr: 0, rank: rank, percentileRank: rank, gxe: -1, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1),
{"players": filtredLeaderboard.length, "lowestTR": 0, "toEnterTR": 0, "toEnterGlicko": 0}]; {"players": filtredLeaderboard.length, "lowestTR": 0, "toEnterTR": 0, "toEnterGlicko": 0}];
} }
} }
@ -2352,6 +2356,7 @@ class TetrioPlayersLeaderboard {
} }
Map<String, List<dynamic>> get averages => { Map<String, List<dynamic>> get averages => {
'x+': getAverageOfRank("x+"),
'x': getAverageOfRank("x"), 'x': getAverageOfRank("x"),
'u': getAverageOfRank("u"), 'u': getAverageOfRank("u"),
'ss': getAverageOfRank("ss"), 'ss': getAverageOfRank("ss"),
@ -2428,11 +2433,10 @@ class TetrioPlayerFromLeaderboard {
late String role; late String role;
late double xp; late double xp;
String? country; String? country;
late bool verified;
late DateTime timestamp; late DateTime timestamp;
late int gamesPlayed; late int gamesPlayed;
late int gamesWon; late int gamesWon;
late double rating; late double tr;
late double? glicko; late double? glicko;
late double? rd; late double? rd;
late String rank; late String rank;
@ -2451,11 +2455,10 @@ class TetrioPlayerFromLeaderboard {
this.role, this.role,
this.xp, this.xp,
this.country, this.country,
this.verified,
this.timestamp, this.timestamp,
this.gamesPlayed, this.gamesPlayed,
this.gamesWon, this.gamesWon,
this.rating, this.tr,
this.glicko, this.glicko,
this.rd, this.rd,
this.rank, this.rank,
@ -2470,7 +2473,7 @@ class TetrioPlayerFromLeaderboard {
} }
double get winrate => gamesWon / gamesPlayed; double get winrate => gamesWon / gamesPlayed;
double get esttracc => estTr.esttr - rating; double get esttracc => estTr.esttr - tr;
TetrioPlayerFromLeaderboard.fromJson(Map<String, dynamic> json, DateTime ts) { TetrioPlayerFromLeaderboard.fromJson(Map<String, dynamic> json, DateTime ts) {
userId = json['_id']; userId = json['_id'];
@ -2478,11 +2481,10 @@ class TetrioPlayerFromLeaderboard {
role = json['role']; role = json['role'];
xp = json['xp'].toDouble(); xp = json['xp'].toDouble();
country = json['country']; country = json['country'];
verified = json['verified'];
timestamp = ts; timestamp = ts;
gamesPlayed = json['league']['gamesplayed'] as int; gamesPlayed = json['league']['gamesplayed'] as int;
gamesWon = json['league']['gameswon'] as int; gamesWon = json['league']['gameswon'] as int;
rating = json['league']['rating'] != null ? json['league']['rating'].toDouble() : 0; tr = json['league']['tr'] != null ? json['league']['tr'].toDouble() : 0;
glicko = json['league']['glicko']?.toDouble(); glicko = json['league']['glicko']?.toDouble();
rd = json['league']['rd']?.toDouble(); rd = json['league']['rd']?.toDouble();
rank = json['league']['rank']; rank = json['league']['rank'];
@ -2499,7 +2501,7 @@ class TetrioPlayerFromLeaderboard {
num getStatByEnum(Stats stat){ num getStatByEnum(Stats stat){
switch (stat) { switch (stat) {
case Stats.tr: case Stats.tr:
return rating; return tr;
case Stats.glicko: case Stats.glicko:
return glicko??-1; return glicko??-1;
case Stats.rd: case Stats.rd:

View File

@ -536,7 +536,7 @@ class TetrioService extends DB {
supporterTier: 0, supporterTier: 0,
verified: false, verified: false,
connections: null, connections: null,
tlSeason1: TetraLeagueAlpha( tlSeason1: TetraLeague(
timestamp: DateTime.parse(entry[9]), timestamp: DateTime.parse(entry[9]),
apm: entry[6] != '' ? entry[6] : null, apm: entry[6] != '' ? entry[6] : null,
pps: entry[7] != '' ? entry[7] : null, pps: entry[7] != '' ? entry[7] : null,
@ -547,7 +547,8 @@ class TetrioService extends DB {
gamesWon: entry[2], gamesWon: entry[2],
bestRank: "z", bestRank: "z",
decaying: false, decaying: false,
rating: entry[3], tr: entry[3],
gxe: -1,
rank: entry[5], rank: entry[5],
percentileRank: entry[5], percentileRank: entry[5],
percentile: rankCutoffs[entry[5]]!, percentile: rankCutoffs[entry[5]]!,

View File

@ -17,7 +17,7 @@ enum Mode{
averages averages
} }
Mode greenSideMode = Mode.player; Mode greenSideMode = Mode.player;
List<dynamic> theGreenSide = [null, null, null]; // TetrioPlayer?, List<DropdownMenuItem<TetrioPlayer>>?, TetraLeagueAlpha? List<dynamic> theGreenSide = [null, null, null]; // TetrioPlayer?, List<DropdownMenuItem<TetrioPlayer>>?, TetraLeague?
Mode redSideMode = Mode.player; Mode redSideMode = Mode.player;
List<dynamic> theRedSide = [null, null, null]; List<dynamic> theRedSide = [null, null, null];
final DateFormat dateFormat = DateFormat.yMd(LocaleSettings.currentLocale.languageCode).add_Hm(); final DateFormat dateFormat = DateFormat.yMd(LocaleSettings.currentLocale.languageCode).add_Hm();
@ -82,7 +82,7 @@ class CompareState extends State<CompareView> {
double vs = double.parse(threeNumbers[2][0]!); double vs = double.parse(threeNumbers[2][0]!);
theRedSide = [null, theRedSide = [null,
null, null,
TetraLeagueAlpha( TetraLeague(
timestamp: DateTime.now(), timestamp: DateTime.now(),
apm: apm, apm: apm,
pps: pps, pps: pps,
@ -92,7 +92,8 @@ class CompareState extends State<CompareView> {
gamesWon: -1, gamesWon: -1,
bestRank: "z", bestRank: "z",
decaying: true, decaying: true,
rating: -1, tr: -1,
gxe: -1,
rank: "z", rank: "z",
percentileRank: "z", percentileRank: "z",
percentile: 1, percentile: 1,
@ -156,7 +157,7 @@ class CompareState extends State<CompareView> {
double vs = double.parse(threeNumbers[2][0]!); double vs = double.parse(threeNumbers[2][0]!);
theGreenSide = [null, theGreenSide = [null,
null, null,
TetraLeagueAlpha( TetraLeague(
timestamp: DateTime.now(), timestamp: DateTime.now(),
apm: apm, apm: apm,
pps: pps, pps: pps,
@ -166,7 +167,8 @@ class CompareState extends State<CompareView> {
gamesWon: -1, gamesWon: -1,
bestRank: "z", bestRank: "z",
decaying: true, decaying: true,
rating: -1, tr: -1,
gxe: -1,
rank: "z", rank: "z",
percentileRank: "z", percentileRank: "z",
percentile: 1, percentile: 1,
@ -395,8 +397,8 @@ class CompareState extends State<CompareView> {
redSideMode != Mode.stats) redSideMode != Mode.stats)
CompareThingy( CompareThingy(
label: "TR", label: "TR",
greenSide: theGreenSide[2].rating, greenSide: theGreenSide[2].tr,
redSide: theRedSide[2].rating, redSide: theRedSide[2].tr,
fractionDigits: 2, fractionDigits: 2,
higherIsBetter: true, higherIsBetter: true,
), ),

View File

@ -64,7 +64,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
Future<List> me = Future.delayed(const Duration(seconds: 60), () => [null, null, null, null, null, null]); // I love lists shut up Future<List> me = Future.delayed(const Duration(seconds: 60), () => [null, null, null, null, null, null]); // I love lists shut up
TetrioPlayersLeaderboard? everyone; TetrioPlayersLeaderboard? everyone;
PlayerLeaderboardPosition? meAmongEveryone; PlayerLeaderboardPosition? meAmongEveryone;
TetraLeagueAlpha? rankAverages; TetraLeague? rankAverages;
double? thatRankCutoff; double? thatRankCutoff;
double? nextRankCutoff; double? nextRankCutoff;
double? thatRankGlickoCutoff; double? thatRankGlickoCutoff;
@ -208,7 +208,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
// if (me.tlSeason1.gamesPlayed > 9) { // if (me.tlSeason1.gamesPlayed > 9) {
// thatRankCutoff = cutoffs?[me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank]; // thatRankCutoff = cutoffs?[me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank];
// thatRankGlickoCutoff = cutoffsGlicko?[me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank]; // thatRankGlickoCutoff = cutoffsGlicko?[me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank];
// nextRankCutoff = (me.tlSeason1.rank != "z" ? me.tlSeason1.rank == "x" : me.tlSeason1.percentileRank == "x") ? topOne?.rating??25000 : cutoffs?[ranks.elementAtOrNull(ranks.indexOf(me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank)+1)]; // nextRankCutoff = (me.tlSeason1.rank != "z" ? me.tlSeason1.rank == "x" : me.tlSeason1.percentileRank == "x") ? topOne?.tr??25000 : cutoffs?[ranks.elementAtOrNull(ranks.indexOf(me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank)+1)];
// nextRankGlickoCutoff = (me.tlSeason1.rank != "z" ? me.tlSeason1.rank == "x" : me.tlSeason1.percentileRank == "x") ? topOne?.glicko??double.infinity : cutoffsGlicko?[ranks.elementAtOrNull(ranks.indexOf(me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank)+1)]; // nextRankGlickoCutoff = (me.tlSeason1.rank != "z" ? me.tlSeason1.rank == "x" : me.tlSeason1.percentileRank == "x") ? topOne?.glicko??double.infinity : cutoffsGlicko?[ranks.elementAtOrNull(ranks.indexOf(me.tlSeason1.rank != "z" ? me.tlSeason1.rank : me.tlSeason1.percentileRank)+1)];
// } // }
@ -217,13 +217,13 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
// Making list of Tetra League matches // Making list of Tetra League matches
bool isTracking = await teto.isPlayerTracking(me.userId); bool isTracking = await teto.isPlayerTracking(me.userId);
List<TetrioPlayer> states = []; List<TetrioPlayer> states = [];
TetraLeagueAlpha? compareWith; TetraLeague? compareWith;
Set<TetraLeagueAlpha> uniqueTL = {}; Set<TetraLeague> uniqueTL = {};
List<TetraLeagueAlphaRecord> storedRecords = await teto.getTLMatchesbyPlayerID(me.userId); // get old matches List<TetraLeagueAlphaRecord> storedRecords = await teto.getTLMatchesbyPlayerID(me.userId); // get old matches
if (isTracking){ // if tracked - save data to local DB // if (isTracking){ // if tracked - save data to local DB
await teto.storeState(me); // await teto.storeState(me);
//await teto.saveTLMatchesFromStream(tlStream); // //await teto.saveTLMatchesFromStream(tlStream);
} // }
TetraLeagueAlphaStream? oldMatches; TetraLeagueAlphaStream? oldMatches;
// building list of TL matches // building list of TL matches
if(fetchTLmatches) { if(fetchTLmatches) {
@ -270,7 +270,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
} }
} }
states.addAll(await teto.getPlayer(me.userId)); //states.addAll(await teto.getPlayer(me.userId));
for (var element in states) { // For graphs I need only unique entries for (var element in states) { // For graphs I need only unique entries
if (element.tlSeason1 != null && uniqueTL.isNotEmpty && uniqueTL.last != element.tlSeason1) uniqueTL.add(element.tlSeason1!); if (element.tlSeason1 != null && uniqueTL.isNotEmpty && uniqueTL.last != element.tlSeason1) uniqueTL.add(element.tlSeason1!);
if (uniqueTL.isEmpty) uniqueTL.add(element.tlSeason1!); if (uniqueTL.isEmpty) uniqueTL.add(element.tlSeason1!);
@ -279,7 +279,7 @@ 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<_HistoryChartSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid chartsData = <DropdownMenuItem<List<_HistoryChartSpot>>>[ // 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) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rating)], child: Text(t.statCellNum.tr)), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.tr)], child: Text(t.statCellNum.tr)),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.glicko!)], child: const Text("Glicko")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.glicko!)], child: const Text("Glicko")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rd!)], child: const Text("Rating Deviation")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rd!)], child: const Text("Rating Deviation")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),

View File

@ -285,7 +285,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
Future<List<DropdownMenuItem<List<_HistoryChartSpot>>>> getChartsData(bool fetchHistory) async { Future<List<DropdownMenuItem<List<_HistoryChartSpot>>>> getChartsData(bool fetchHistory) async {
List<TetrioPlayer> states = []; List<TetrioPlayer> states = [];
Set<TetraLeagueAlpha> uniqueTL = {}; Set<TetraLeague> uniqueTL = {};
if(fetchHistory){ if(fetchHistory){
try{ try{
@ -310,7 +310,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
if (uniqueTL.length >= 2){ if (uniqueTL.length >= 2){
chartsData = <DropdownMenuItem<List<_HistoryChartSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid chartsData = <DropdownMenuItem<List<_HistoryChartSpot>>>[ // 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) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rating)], child: Text(t.statCellNum.tr)), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.tr)], child: Text(t.statCellNum.tr)),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.glicko!)], child: const Text("Glicko")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.glicko!)], child: const Text("Glicko")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rd!)], child: const Text("Rating Deviation")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rd!)], child: const Text("Rating Deviation")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),
@ -837,7 +837,7 @@ class _DestinationHomeState extends State<DestinationHome> {
); );
} }
Widget getTetraLeagueCard(TetraLeagueAlpha data){ Widget getTetraLeagueCard(TetraLeague data){
return Column( return Column(
children: [ children: [
Card( Card(
@ -2287,7 +2287,7 @@ class _SearchDrawerState extends State<SearchDrawer> {
} }
class TetraLeagueThingy extends StatelessWidget{ class TetraLeagueThingy extends StatelessWidget{
final TetraLeagueAlpha league; final TetraLeague league;
const TetraLeagueThingy({super.key, required this.league}); const TetraLeagueThingy({super.key, required this.league});

View File

@ -360,7 +360,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
trailing: Row( trailing: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text("${_f2.format(they[index].rating)} TR", style: bigScreen ? const TextStyle(fontSize: 28) : null), Text("${_f2.format(they[index].tr)} TR", style: bigScreen ? const TextStyle(fontSize: 28) : null),
Image.asset("res/tetrio_tl_alpha_ranks/${they[index].rank}.png", height: bigScreen ? 48 : 16), Image.asset("res/tetrio_tl_alpha_ranks/${they[index].rank}.png", height: bigScreen ? 48 : 16),
], ],
), ),
@ -412,7 +412,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
Text(t.averageValues, style: TextStyle( fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), Text(t.averageValues, style: TextStyle( fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
Expanded( Expanded(
child: ListView(children: [ child: ListView(children: [
_ListEntry(value: widget.rank[0].rating, label: t.statCellNum.tr.replaceAll(RegExp(r'\n'), " "), id: "", username: "", approximate: true, fractionDigits: 2), _ListEntry(value: widget.rank[0].tr, label: t.statCellNum.tr.replaceAll(RegExp(r'\n'), " "), id: "", username: "", approximate: true, fractionDigits: 2),
_ListEntry(value: widget.rank[0].glicko, label: "Glicko", id: "", username: "", approximate: true, fractionDigits: 2), _ListEntry(value: widget.rank[0].glicko, label: "Glicko", id: "", username: "", approximate: true, fractionDigits: 2),
_ListEntry(value: widget.rank[0].rd, label: t.statCellNum.rd.replaceAll(RegExp(r'\n'), " "), id: "", username: "", approximate: true, fractionDigits: 3), _ListEntry(value: widget.rank[0].rd, label: t.statCellNum.rd.replaceAll(RegExp(r'\n'), " "), id: "", username: "", approximate: true, fractionDigits: 3),
_ListEntry(value: widget.rank[0].gamesPlayed, label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), id: "", username: "", approximate: true, fractionDigits: 0), _ListEntry(value: widget.rank[0].gamesPlayed, label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), id: "", username: "", approximate: true, fractionDigits: 0),

View File

@ -58,6 +58,6 @@ class StateState extends State<StateView> {
headerSliverBuilder: (context, value) { headerSliverBuilder: (context, value) {
return [SliverToBoxAdapter(child: UserThingy(player: widget.state, showStateTimestamp: true, setState: _justUpdate))]; return [SliverToBoxAdapter(child: UserThingy(player: widget.state, showStateTimestamp: true, setState: _justUpdate))];
}, },
body: TLThingy(tl: widget.state.tlSeason1!, userID: widget.state.userId, states: const [], hidePreSeasonThingy: true,)))); body: TLThingy(tl: widget.state.tlSeason1!, userID: widget.state.userId, states: const []))));
} }
} }

View File

@ -74,7 +74,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
case ConnectionState.done: case ConnectionState.done:
final allPlayers = snapshot.data?.getStatRanking(snapshot.data!.leaderboard, _sortBy, reversed: reversed, country: _country); final allPlayers = snapshot.data?.getStatRanking(snapshot.data!.leaderboard, _sortBy, reversed: reversed, country: _country);
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) windowManager.setTitle("Tetra Stats: ${t.tlLeaderboard} - ${t.players(n: allPlayers!.length)}"); if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) windowManager.setTitle("Tetra Stats: ${t.tlLeaderboard} - ${t.players(n: allPlayers != null ? allPlayers.length : 0)}");
bool bigScreen = MediaQuery.of(context).size.width > 768; bool bigScreen = MediaQuery.of(context).size.width > 768;
return NestedScrollView( return NestedScrollView(
headerSliverBuilder: (context, value) { headerSliverBuilder: (context, value) {
@ -189,7 +189,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
trailing: Row( trailing: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text("${f2.format(allPlayers[index].rating)} TR", style: const TextStyle(fontSize: 28)), Text("${f2.format(allPlayers[index].tr)} TR", style: const TextStyle(fontSize: 28)),
Image.asset("res/tetrio_tl_alpha_ranks/${allPlayers[index].rank}.png", height: bigScreen ? 48 : 36), Image.asset("res/tetrio_tl_alpha_ranks/${allPlayers[index].rank}.png", height: bigScreen ? 48 : 36),
], ],
), ),

View File

@ -382,8 +382,8 @@ class TlMatchResultState extends State<TlMatchResultView> {
), ),
VsGraphs( VsGraphs(
roundSelector == -2 ? timeWeightedStats[0].apm : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.apm : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.apm, roundSelector == -2 ? timeWeightedStats[0].apm : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.apm : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.apm,
roundSelector == -2 ? timeWeightedStats[0].pps : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.pps : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.vs, roundSelector == -2 ? timeWeightedStats[0].pps : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.pps : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.pps,
roundSelector == -2 ? timeWeightedStats[0].vs : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.vs : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.pps, roundSelector == -2 ? timeWeightedStats[0].vs : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.vs : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.vs,
roundSelector == -2 ? timeWeightedStats[0].nerdStats : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.nerdStats : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.nerdStats, roundSelector == -2 ? timeWeightedStats[0].nerdStats : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.nerdStats : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.nerdStats,
roundSelector == -2 ? timeWeightedStats[0].playstyle : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.playstyle : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.playstyle, roundSelector == -2 ? timeWeightedStats[0].playstyle : roundSelector.isNegative ? widget.record.results.leaderboard[greenSidePlayer].stats.playstyle : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id == widget.initPlayerId).stats.playstyle,
roundSelector == -2 ? timeWeightedStats[1].apm : roundSelector.isNegative ? widget.record.results.leaderboard[redSidePlayer].stats.apm : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id != widget.initPlayerId).stats.apm, roundSelector == -2 ? timeWeightedStats[1].apm : roundSelector.isNegative ? widget.record.results.leaderboard[redSidePlayer].stats.apm : widget.record.results.rounds[roundSelector].firstWhere((element) => element.id != widget.initPlayerId).stats.apm,

View File

@ -9,7 +9,7 @@ import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/utils/numers_formats.dart'; import 'package:tetra_stats/utils/numers_formats.dart';
class TLProgress extends StatelessWidget{ class TLProgress extends StatelessWidget{
final TetraLeagueAlpha tlData; final TetraLeague tlData;
final double? nextRankTRcutoff; final double? nextRankTRcutoff;
final double? previousRankTRcutoff; final double? previousRankTRcutoff;
final double? nextRankGlickoCutoff; final double? nextRankGlickoCutoff;
@ -45,7 +45,7 @@ class TLProgress extends StatelessWidget{
children: [ children: [
if (tlData.prevAt > 0) TextSpan(text: "${f0.format(tlData.prevAt)}"), if (tlData.prevAt > 0) TextSpan(text: "${f0.format(tlData.prevAt)}"),
if (tlData.prevAt > 0 && previousRankTRcutoff != null) const TextSpan(text: "\n"), if (tlData.prevAt > 0 && previousRankTRcutoff != null) const TextSpan(text: "\n"),
if (previousRankTRcutoff != null) TextSpan(text: "${f2.format(previousRankTRcutoff)} (${comparef2.format(previousRankTRcutoff!-tlData.rating)}) TR"), if (previousRankTRcutoff != null) TextSpan(text: "${f2.format(previousRankTRcutoff)} (${comparef2.format(previousRankTRcutoff!-tlData.tr)}) TR"),
if ((tlData.prevAt > 0 || previousRankTRcutoff != null) && previousGlickoCutoff != null) const TextSpan(text: "\n"), if ((tlData.prevAt > 0 || previousRankTRcutoff != null) && previousGlickoCutoff != null) const TextSpan(text: "\n"),
if (previousGlickoCutoff != null) TextSpan(text: (tlData.standing > tlData.prevAt || ((tlData.glicko!-previousGlickoCutoff!)/glickoForWin < 0.5 && tlData.percentileRank != "d")) ? t.demotionOnNextLoss : t.numOfdefeats(losses: f2.format((tlData.glicko!-previousGlickoCutoff!)/glickoForWin)), style: TextStyle(color: (tlData.standing > tlData.prevAt || ((tlData.glicko!-previousGlickoCutoff!)/glickoForWin < 0.5 && tlData.percentileRank != "d")) ? Colors.redAccent : null)) if (previousGlickoCutoff != null) TextSpan(text: (tlData.standing > tlData.prevAt || ((tlData.glicko!-previousGlickoCutoff!)/glickoForWin < 0.5 && tlData.percentileRank != "d")) ? t.demotionOnNextLoss : t.numOfdefeats(losses: f2.format((tlData.glicko!-previousGlickoCutoff!)/glickoForWin)), style: TextStyle(color: (tlData.standing > tlData.prevAt || ((tlData.glicko!-previousGlickoCutoff!)/glickoForWin < 0.5 && tlData.percentileRank != "d")) ? Colors.redAccent : null))
] ]
@ -59,7 +59,7 @@ class TLProgress extends StatelessWidget{
children: [ children: [
if (tlData.nextAt > 0) TextSpan(text: "${f0.format(tlData.nextAt)}"), if (tlData.nextAt > 0) TextSpan(text: "${f0.format(tlData.nextAt)}"),
if (tlData.nextAt > 0 && nextRankTRcutoff != null) const TextSpan(text: "\n"), if (tlData.nextAt > 0 && nextRankTRcutoff != null) const TextSpan(text: "\n"),
if (nextRankTRcutoff != null) TextSpan(text: "${f2.format(nextRankTRcutoff)} (${comparef2.format(nextRankTRcutoff!-tlData.rating)}) TR"), if (nextRankTRcutoff != null) TextSpan(text: "${f2.format(nextRankTRcutoff)} (${comparef2.format(nextRankTRcutoff!-tlData.tr)}) TR"),
if ((tlData.nextAt > 0 || nextRankTRcutoff != null) && nextRankGlickoCutoff != null) const TextSpan(text: "\n"), if ((tlData.nextAt > 0 || nextRankTRcutoff != null) && nextRankGlickoCutoff != null) const TextSpan(text: "\n"),
if (nextRankGlickoCutoff != null) TextSpan(text: (tlData.standing < tlData.nextAt || ((nextRankGlickoCutoff!-tlData.glicko!)/glickoForWin < 0.5 && ((tlData.rank != "x" && tlData.rank != "z") || tlData.percentileRank != "x"))) ? t.promotionOnNextWin : t.numOfVictories(wins: f2.format((nextRankGlickoCutoff!-tlData.glicko!)/glickoForWin)), style: TextStyle(color: (tlData.standing < tlData.nextAt || ((nextRankGlickoCutoff!-tlData.glicko!)/glickoForWin < 0.5 && tlData.percentileRank != "x")) ? Colors.greenAccent : null)) if (nextRankGlickoCutoff != null) TextSpan(text: (tlData.standing < tlData.nextAt || ((nextRankGlickoCutoff!-tlData.glicko!)/glickoForWin < 0.5 && ((tlData.rank != "x" && tlData.rank != "z") || tlData.percentileRank != "x"))) ? t.promotionOnNextWin : t.numOfVictories(wins: f2.format((nextRankGlickoCutoff!-tlData.glicko!)/glickoForWin)), style: TextStyle(color: (tlData.standing < tlData.nextAt || ((nextRankGlickoCutoff!-tlData.glicko!)/glickoForWin < 0.5 && tlData.percentileRank != "x")) ? Colors.greenAccent : null))
] ]
@ -72,14 +72,14 @@ class TLProgress extends StatelessWidget{
maximum: 1, maximum: 1,
interval: 1, interval: 1,
ranges: [ ranges: [
if (previousRankTRcutoff != null && nextRankTRcutoff != null) LinearGaugeRange(endValue: getBarTR(tlData.rating)!, color: Theme.of(context).colorScheme.primary, position: LinearElementPosition.cross) if (previousRankTRcutoff != null && nextRankTRcutoff != null) LinearGaugeRange(endValue: getBarTR(tlData.tr)!, color: Theme.of(context).colorScheme.primary, position: LinearElementPosition.cross)
else if (tlData.standing != -1) LinearGaugeRange(endValue: getBarPosition(), color: Theme.of(context).colorScheme.primary, position: LinearElementPosition.cross), else if (tlData.standing != -1) LinearGaugeRange(endValue: getBarPosition(), color: Theme.of(context).colorScheme.primary, position: LinearElementPosition.cross),
if (previousRankTRcutoff != null && previousRankTRcutoffTarget != null) LinearGaugeRange(endValue: getBarTR(previousRankTRcutoffTarget!)!, color: Colors.greenAccent, position: LinearElementPosition.inside), if (previousRankTRcutoff != null && previousRankTRcutoffTarget != null) LinearGaugeRange(endValue: getBarTR(previousRankTRcutoffTarget!)!, color: Colors.greenAccent, position: LinearElementPosition.inside),
if (nextRankTRcutoff != null && nextRankTRcutoffTarget != null && previousRankTRcutoff != null) LinearGaugeRange(startValue: getBarTR(nextRankTRcutoffTarget!)!, endValue: 1, color: Colors.yellowAccent, position: LinearElementPosition.inside) if (nextRankTRcutoff != null && nextRankTRcutoffTarget != null && previousRankTRcutoff != null) LinearGaugeRange(startValue: getBarTR(nextRankTRcutoffTarget!)!, endValue: 1, color: Colors.yellowAccent, position: LinearElementPosition.inside)
], ],
markerPointers: [ markerPointers: [
LinearShapePointer(value: (previousRankTRcutoff != null && nextRankTRcutoff != null) ? getBarTR(tlData.rating)! : getBarPosition(), position: LinearElementPosition.cross, shapeType: LinearShapePointerType.diamond, color: Colors.white, height: 20), LinearShapePointer(value: (previousRankTRcutoff != null && nextRankTRcutoff != null) ? getBarTR(tlData.tr)! : getBarPosition(), position: LinearElementPosition.cross, shapeType: LinearShapePointerType.diamond, color: Colors.white, height: 20),
if (tlData.standing != -1) LinearWidgetPointer(offset: 4, position: LinearElementPosition.outside, value: (previousRankTRcutoff != null && nextRankTRcutoff != null) ? getBarTR(tlData.rating)! : getBarPosition(), child: Text("${NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0).format(tlData.standing)}", style: const TextStyle(fontSize: 14),)) if (tlData.standing != -1) LinearWidgetPointer(offset: 4, position: LinearElementPosition.outside, value: (previousRankTRcutoff != null && nextRankTRcutoff != null) ? getBarTR(tlData.tr)! : getBarPosition(), child: Text("${NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0).format(tlData.standing)}", style: const TextStyle(fontSize: 14),))
], ],
isMirrored: true, isMirrored: true,
showTicks: true, showTicks: true,

View File

@ -10,8 +10,8 @@ var fDiff = NumberFormat("+#,###.####;-#,###.####");
class TLRatingThingy extends StatelessWidget{ class TLRatingThingy extends StatelessWidget{
final String userID; final String userID;
final TetraLeagueAlpha tlData; final TetraLeague tlData;
final TetraLeagueAlpha? oldTl; final TetraLeague? oldTl;
final double? topTR; final double? topTR;
final DateTime? lastMatchPlayed; final DateTime? lastMatchPlayed;
@ -22,7 +22,7 @@ class TLRatingThingy extends StatelessWidget{
bool oskKagariGimmick = prefs.getBool("oskKagariGimmick")??true; bool oskKagariGimmick = prefs.getBool("oskKagariGimmick")??true;
bool bigScreen = MediaQuery.of(context).size.width >= 768; bool bigScreen = MediaQuery.of(context).size.width >= 768;
String decimalSeparator = f4.symbols.DECIMAL_SEP; String decimalSeparator = f4.symbols.DECIMAL_SEP;
List<String> formatedTR = f4.format(tlData.rating).split(decimalSeparator); List<String> formatedTR = f4.format(tlData.tr).split(decimalSeparator);
List<String> formatedGlicko = tlData.glicko != null ? f4.format(tlData.glicko).split(decimalSeparator) : ["---","--"]; List<String> formatedGlicko = tlData.glicko != null ? f4.format(tlData.glicko).split(decimalSeparator) : ["---","--"];
List<String> formatedPercentile = f4.format(tlData.percentile * 100).split(decimalSeparator); List<String> formatedPercentile = f4.format(tlData.percentile * 100).split(decimalSeparator);
//DateTime now = DateTime.now(); //DateTime now = DateTime.now();
@ -66,11 +66,11 @@ class TLRatingThingy extends StatelessWidget{
switch(prefs.getInt("ratingMode")){ switch(prefs.getInt("ratingMode")){
1 => "${fDiff.format(tlData.glicko! - oldTl!.glicko!)} Glicko", 1 => "${fDiff.format(tlData.glicko! - oldTl!.glicko!)} Glicko",
2 => "${fDiff.format(tlData.percentile * 100 - oldTl!.percentile * 100)} %", 2 => "${fDiff.format(tlData.percentile * 100 - oldTl!.percentile * 100)} %",
_ => "${fDiff.format(tlData.rating - oldTl!.rating)} TR" _ => "${fDiff.format(tlData.tr - oldTl!.tr)} TR"
}, },
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: tlData.rating - oldTl!.rating < 0 ? color: tlData.tr - oldTl!.tr < 0 ?
Colors.red : Colors.red :
Colors.green Colors.green
), ),
@ -83,11 +83,11 @@ class TLRatingThingy extends StatelessWidget{
text: TextSpan( text: TextSpan(
style: DefaultTextStyle.of(context).style, style: DefaultTextStyle.of(context).style,
children: [ children: [
TextSpan(text: prefs.getInt("ratingMode") == 2 ? "${f2.format(tlData.rating)} TR • % ${t.rank}: ${tlData.percentileRank.toUpperCase()}" : "${t.top} ${f2.format(tlData.percentile * 100)}% (${tlData.percentileRank.toUpperCase()})"), TextSpan(text: prefs.getInt("ratingMode") == 2 ? "${f2.format(tlData.tr)} TR • % ${t.rank}: ${tlData.percentileRank.toUpperCase()}" : "${t.top} ${f2.format(tlData.percentile * 100)}% (${tlData.percentileRank.toUpperCase()})"),
if (tlData.bestRank != "z") const TextSpan(text: ""), if (tlData.bestRank != "z") const TextSpan(text: ""),
if (tlData.bestRank != "z") TextSpan(text: "${t.topRank}: ${tlData.bestRank.toUpperCase()}"), if (tlData.bestRank != "z") TextSpan(text: "${t.topRank}: ${tlData.bestRank.toUpperCase()}"),
if (topTR != null) TextSpan(text: " (${f2.format(topTR)} TR)"), if (topTR != null) TextSpan(text: " (${f2.format(topTR)} TR)"),
TextSpan(text: "${prefs.getInt("ratingMode") == 1 ? "${f2.format(tlData.rating)} TR • RD: " : "Glicko: ${tlData.glicko != null ? f2.format(tlData.glicko) : "---"}±"}"), TextSpan(text: "${prefs.getInt("ratingMode") == 1 ? "${f2.format(tlData.tr)} TR • RD: " : "Glicko: ${tlData.glicko != null ? f2.format(tlData.glicko) : "---"}±"}"),
TextSpan(text: f2.format(tlData.rd!), style: tlData.decaying ? TextStyle(color: tlData.rd! > 98 ? Colors.red : Colors.yellow) : null), TextSpan(text: f2.format(tlData.rd!), style: tlData.decaying ? TextStyle(color: tlData.rd! > 98 ? Colors.red : Colors.yellow) : null),
if (tlData.decaying) WidgetSpan(child: Icon(Icons.trending_up, color: tlData.rd! > 98 ? Colors.red : Colors.yellow,), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic), if (tlData.decaying) WidgetSpan(child: Icon(Icons.trending_up, color: tlData.rd! > 98 ? Colors.red : Colors.yellow,), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic),
//if (beforeS1end) tlData.rd! <= safeRD ? TextSpan(text: " (Safe)", style: TextStyle(color: Colors.greenAccent)) : TextSpan(text: " (> ${safeRD} RD !!!)", style: TextStyle(color: Colors.redAccent)) //if (beforeS1end) tlData.rd! <= safeRD ? TextSpan(text: " (Safe)", style: TextStyle(color: Colors.greenAccent)) : TextSpan(text: " (> ${safeRD} RD !!!)", style: TextStyle(color: Colors.redAccent))

View File

@ -20,16 +20,15 @@ import 'package:tetra_stats/widgets/tl_rating_thingy.dart';
var intFDiff = NumberFormat("+#,###.000;-#,###.000"); var intFDiff = NumberFormat("+#,###.000;-#,###.000");
class TLThingy extends StatefulWidget { class TLThingy extends StatefulWidget {
final TetraLeagueAlpha tl; final TetraLeague tl;
final String userID; final String userID;
final List<TetrioPlayer> states; final List<TetrioPlayer> states;
final bool showTitle; final bool showTitle;
final bool bot; final bool bot;
final bool hidePreSeasonThingy;
final bool guest; final bool guest;
final double? topTR; final double? topTR;
final PlayerLeaderboardPosition? lbPositions; final PlayerLeaderboardPosition? lbPositions;
final TetraLeagueAlpha? averages; final TetraLeague? averages;
final double? thatRankCutoff; final double? thatRankCutoff;
final double? thatRankCutoffGlicko; final double? thatRankCutoffGlicko;
final double? thatRankTarget; final double? thatRankTarget;
@ -37,7 +36,7 @@ class TLThingy extends StatefulWidget {
final double? nextRankCutoffGlicko; final double? nextRankCutoffGlicko;
final double? nextRankTarget; final double? nextRankTarget;
final DateTime? lastMatchPlayed; final DateTime? lastMatchPlayed;
const TLThingy({super.key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.guest=false, this.hidePreSeasonThingy=false, this.topTR, this.lbPositions, this.averages, this.nextRankCutoff, this.thatRankCutoff, this.thatRankCutoffGlicko, this.nextRankCutoffGlicko, this.nextRankTarget, this.thatRankTarget, this.lastMatchPlayed}); const TLThingy({super.key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.guest=false, this.topTR, this.lbPositions, this.averages, this.nextRankCutoff, this.thatRankCutoff, this.thatRankCutoffGlicko, this.nextRankCutoffGlicko, this.nextRankTarget, this.thatRankTarget, this.lastMatchPlayed});
@override @override
State<TLThingy> createState() => _TLThingyState(); State<TLThingy> createState() => _TLThingyState();
@ -45,13 +44,10 @@ class TLThingy extends StatefulWidget {
class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin { class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
late bool oskKagariGimmick; late bool oskKagariGimmick;
late TetraLeagueAlpha? oldTl; late TetraLeague? oldTl;
late TetraLeagueAlpha currentTl; late TetraLeague currentTl;
late RangeValues _currentRangeValues; late RangeValues _currentRangeValues;
late List<TetrioPlayer> sortedStates; late List<TetrioPlayer> sortedStates;
late Timer _countdownTimer;
//Duration seasonLeft = seasonEnd.difference(DateTime.now());
Duration postSeasonLeft = seasonStart.difference(DateTime.now());
@override @override
void initState() { void initState() {
@ -60,20 +56,10 @@ class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
oldTl = sortedStates.elementAtOrNull(1)?.tlSeason1; oldTl = sortedStates.elementAtOrNull(1)?.tlSeason1;
currentTl = widget.tl; currentTl = widget.tl;
super.initState(); super.initState();
_countdownTimer = Timer.periodic(
Durations.extralong4,
(Timer timer) {
setState(() {
//seasonLeft = seasonEnd.difference(DateTime.now());
postSeasonLeft = seasonStart.difference(DateTime.now());
});
},
);
} }
@override @override
void dispose() { void dispose() {
_countdownTimer.cancel();
super.dispose(); super.dispose();
} }
@ -84,47 +70,6 @@ class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
String decimalSeparator = f2.symbols.DECIMAL_SEP; String decimalSeparator = f2.symbols.DECIMAL_SEP;
List<String> estTRformated = currentTl.estTr != null ? f2.format(currentTl.estTr!.esttr).split(decimalSeparator) : []; List<String> estTRformated = currentTl.estTr != null ? f2.format(currentTl.estTr!.esttr).split(decimalSeparator) : [];
List<String> estTRaccFormated = currentTl.esttracc != null ? intFDiff.format(currentTl.esttracc!).split(".") : []; List<String> estTRaccFormated = currentTl.esttracc != null ? intFDiff.format(currentTl.esttracc!).split(".") : [];
if (DateTime.now().isBefore(seasonStart) && !widget.hidePreSeasonThingy) {
return Center(child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(t.postSeason.toUpperCase(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28), textAlign: TextAlign.center),
Text(t.seasonStarts, textAlign: TextAlign.center),
const Spacer(),
Text(countdown(postSeasonLeft), textAlign: TextAlign.center, style: const TextStyle(fontSize: 36.0),),
if (prefs.getBool("hideDanMessadge") != true) const Spacer(),
if (prefs.getBool("hideDanMessadge") != true) Card(
child: Container(
constraints: const BoxConstraints(maxWidth: 450.0),
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
Text(
t.myMessadgeHeader,
textAlign: TextAlign.center,
style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, fontWeight: FontWeight.bold)
),
const Spacer(),
IconButton(onPressed: (){setState(() {
prefs.setBool("hideDanMessadge", true);
});}, icon: const Icon(Icons.close))
],
),
Text(t.myMessadgeBody, textAlign: TextAlign.center),
],
),
),
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(t.preSeasonMessage(n: postSeasonLeft.inDays >= 14 ? "1" : "2"), textAlign: TextAlign.center),
),
],
));
}
if (currentTl.gamesPlayed == 0) return Center(child: Text(widget.guest ? t.anonTL : widget.bot ? t.botTL : t.neverPlayedTL, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28), textAlign: TextAlign.center,)); if (currentTl.gamesPlayed == 0) return Center(child: Text(widget.guest ? t.anonTL : widget.bot ? t.botTL : t.neverPlayedTL, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28), textAlign: TextAlign.center,));
return LayoutBuilder(builder: (context, constraints) { return LayoutBuilder(builder: (context, constraints) {
bool bigScreen = constraints.maxWidth >= 768; bool bigScreen = constraints.maxWidth >= 768;

View File

@ -2,7 +2,7 @@ name: tetra_stats
description: Track your and other player stats in TETR.IO description: Track your and other player stats in TETR.IO
publish_to: 'none' publish_to: 'none'
version: 1.6.2+22 version: 1.6.3+29
environment: environment:
sdk: '>=3.0.0' sdk: '>=3.0.0'

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

View File

@ -42,7 +42,7 @@
// expect(dan63047.tlSeason1.glicko != null, true); // expect(dan63047.tlSeason1.glicko != null, true);
// //expect(dan63047.tlSeason1.rank != "z", true); lol // //expect(dan63047.tlSeason1.rank != "z", true); lol
// expect(dan63047.tlSeason1.percentileRank != "z", true); // expect(dan63047.tlSeason1.percentileRank != "z", true);
// expect(dan63047.tlSeason1.rating > -1, true); // expect(dan63047.tlSeason1.tr > -1, true);
// expect(dan63047.tlSeason1.gamesPlayed > 9, true); // expect(dan63047.tlSeason1.gamesPlayed > 9, true);
// expect(dan63047.tlSeason1.gamesWon > 0, true); // expect(dan63047.tlSeason1.gamesWon > 0, true);
// //expect(dan63047.tlSeason1.standing, -1); // //expect(dan63047.tlSeason1.standing, -1);
@ -70,7 +70,7 @@
// expect(osk.tlSeason1.glicko != null, true); // expect(osk.tlSeason1.glicko != null, true);
// expect(osk.tlSeason1.rank == "z", true); // expect(osk.tlSeason1.rank == "z", true);
// expect(osk.tlSeason1.percentileRank != "z", true); // expect(osk.tlSeason1.percentileRank != "z", true);
// expect(osk.tlSeason1.rating > -1, true); // expect(osk.tlSeason1.tr > -1, true);
// expect(osk.tlSeason1.gamesPlayed > 9, true); // expect(osk.tlSeason1.gamesPlayed > 9, true);
// expect(osk.tlSeason1.gamesWon > 0, true); // expect(osk.tlSeason1.gamesWon > 0, true);
// expect(osk.tlSeason1.standing, -1); // expect(osk.tlSeason1.standing, -1);
@ -102,7 +102,7 @@
// expect(kagari.tlSeason1.glicko, null); // expect(kagari.tlSeason1.glicko, null);
// expect(kagari.tlSeason1.rank, "z"); // expect(kagari.tlSeason1.rank, "z");
// expect(kagari.tlSeason1.percentileRank, "z"); // expect(kagari.tlSeason1.percentileRank, "z");
// expect(kagari.tlSeason1.rating, -1); // expect(kagari.tlSeason1.tr, -1);
// expect(kagari.tlSeason1.decaying, false); // expect(kagari.tlSeason1.decaying, false);
// expect(kagari.tlSeason1.gamesPlayed, 0); // expect(kagari.tlSeason1.gamesPlayed, 0);
// expect(kagari.tlSeason1.gamesWon, 0); // expect(kagari.tlSeason1.gamesWon, 0);
@ -133,7 +133,7 @@
// expect(furry.tlSeason1.glicko, null); // expect(furry.tlSeason1.glicko, null);
// expect(furry.tlSeason1.rank, "z"); // expect(furry.tlSeason1.rank, "z");
// expect(furry.tlSeason1.percentileRank, "z"); // expect(furry.tlSeason1.percentileRank, "z");
// expect(furry.tlSeason1.rating, -1); // expect(furry.tlSeason1.tr, -1);
// expect(furry.tlSeason1.decaying, false); // expect(furry.tlSeason1.decaying, false);
// expect(furry.tlSeason1.gamesPlayed, 0); // expect(furry.tlSeason1.gamesPlayed, 0);
// expect(furry.tlSeason1.gamesWon, 0); // expect(furry.tlSeason1.gamesWon, 0);
@ -163,7 +163,7 @@
// expect(oskwarefan.tlSeason1.glicko, null); // expect(oskwarefan.tlSeason1.glicko, null);
// expect(oskwarefan.tlSeason1.rank, "z"); // expect(oskwarefan.tlSeason1.rank, "z");
// expect(oskwarefan.tlSeason1.percentileRank, "z"); // expect(oskwarefan.tlSeason1.percentileRank, "z");
// expect(oskwarefan.tlSeason1.rating, -1); // expect(oskwarefan.tlSeason1.tr, -1);
// expect(oskwarefan.tlSeason1.decaying, true); // ??? why true? // expect(oskwarefan.tlSeason1.decaying, true); // ??? why true?
// expect(oskwarefan.tlSeason1.gamesPlayed, 0); // expect(oskwarefan.tlSeason1.gamesPlayed, 0);
// expect(oskwarefan.tlSeason1.gamesWon, 0); // expect(oskwarefan.tlSeason1.gamesWon, 0);