Full leaderboard - full capabilities
This commit is contained in:
parent
e21ec84fc1
commit
c0d395235b
|
@ -66,6 +66,8 @@ const Map<String, double> rankCutoffs = {
|
||||||
enum Stats {
|
enum Stats {
|
||||||
tr,
|
tr,
|
||||||
glicko,
|
glicko,
|
||||||
|
gxe,
|
||||||
|
s1tr,
|
||||||
rd,
|
rd,
|
||||||
gp,
|
gp,
|
||||||
gw,
|
gw,
|
||||||
|
@ -95,6 +97,8 @@ enum Stats {
|
||||||
|
|
||||||
const Map<Stats, String> chartsShortTitles = {
|
const Map<Stats, String> chartsShortTitles = {
|
||||||
Stats.tr: "TR",
|
Stats.tr: "TR",
|
||||||
|
Stats.gxe: "Glixare",
|
||||||
|
Stats.s1tr: "S1 TR",
|
||||||
Stats.glicko: "Glicko",
|
Stats.glicko: "Glicko",
|
||||||
Stats.rd: "RD",
|
Stats.rd: "RD",
|
||||||
Stats.gp: "GP",
|
Stats.gp: "GP",
|
||||||
|
@ -351,6 +355,10 @@ class TetrioPlayer {
|
||||||
return tlSeason1?.tr;
|
return tlSeason1?.tr;
|
||||||
case Stats.glicko:
|
case Stats.glicko:
|
||||||
return tlSeason1?.glicko;
|
return tlSeason1?.glicko;
|
||||||
|
case Stats.gxe:
|
||||||
|
return tlSeason1?.gxe;
|
||||||
|
case Stats.s1tr:
|
||||||
|
return tlSeason1?.s1tr;
|
||||||
case Stats.rd:
|
case Stats.rd:
|
||||||
return tlSeason1?.rd;
|
return tlSeason1?.rd;
|
||||||
case Stats.gp:
|
case Stats.gp:
|
||||||
|
@ -1414,6 +1422,7 @@ class TetraLeague {
|
||||||
}
|
}
|
||||||
|
|
||||||
double get winrate => gamesWon / gamesPlayed;
|
double get winrate => gamesWon / gamesPlayed;
|
||||||
|
double get s1tr => gxe * 250;
|
||||||
|
|
||||||
TetraLeague.fromJson(Map<String, dynamic> json, ts) {
|
TetraLeague.fromJson(Map<String, dynamic> json, ts) {
|
||||||
timestamp = ts;
|
timestamp = ts;
|
||||||
|
@ -1451,7 +1460,7 @@ class TetraLeague {
|
||||||
|
|
||||||
TetrioPlayerFromLeaderboard convertToPlayerFromLeaderboard(String id) => TetrioPlayerFromLeaderboard(
|
TetrioPlayerFromLeaderboard convertToPlayerFromLeaderboard(String id) => TetrioPlayerFromLeaderboard(
|
||||||
id, "", "user", -1, null, timestamp, gamesPlayed, gamesWon,
|
id, "", "user", -1, null, timestamp, gamesPlayed, gamesWon,
|
||||||
tr, glicko??0, rd??noTrRd, rank, bestRank, apm??0, pps??0, vs??0, decaying);
|
tr, gxe, glicko??0, rd??noTrRd, rank, bestRank, apm??0, pps??0, vs??0, decaying);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
@ -1757,6 +1766,7 @@ class TetrioPlayersLeaderboard {
|
||||||
avgPPS = 0,
|
avgPPS = 0,
|
||||||
avgVS = 0,
|
avgVS = 0,
|
||||||
avgTR = 0,
|
avgTR = 0,
|
||||||
|
avgGlixare = 0,
|
||||||
avgGlicko = 0,
|
avgGlicko = 0,
|
||||||
avgRD = 0,
|
avgRD = 0,
|
||||||
avgAPP = 0,
|
avgAPP = 0,
|
||||||
|
@ -1775,6 +1785,7 @@ class TetrioPlayersLeaderboard {
|
||||||
avgStride = 0,
|
avgStride = 0,
|
||||||
avgInfDS = 0,
|
avgInfDS = 0,
|
||||||
lowestTR = 25000,
|
lowestTR = 25000,
|
||||||
|
lowestGlixare = double.infinity,
|
||||||
lowestGlicko = double.infinity,
|
lowestGlicko = double.infinity,
|
||||||
lowestRD = double.infinity,
|
lowestRD = double.infinity,
|
||||||
lowestWinrate = double.infinity,
|
lowestWinrate = double.infinity,
|
||||||
|
@ -1797,6 +1808,7 @@ class TetrioPlayersLeaderboard {
|
||||||
lowestStride = double.infinity,
|
lowestStride = double.infinity,
|
||||||
lowestInfDS = double.infinity,
|
lowestInfDS = double.infinity,
|
||||||
highestTR = double.negativeInfinity,
|
highestTR = double.negativeInfinity,
|
||||||
|
highestGlixare = double.negativeInfinity,
|
||||||
highestGlicko = double.negativeInfinity,
|
highestGlicko = double.negativeInfinity,
|
||||||
highestRD = double.negativeInfinity,
|
highestRD = double.negativeInfinity,
|
||||||
highestWinrate = double.negativeInfinity,
|
highestWinrate = double.negativeInfinity,
|
||||||
|
@ -1827,6 +1839,7 @@ class TetrioPlayersLeaderboard {
|
||||||
highestGamesPlayed = 0,
|
highestGamesPlayed = 0,
|
||||||
highestGamesWon = 0;
|
highestGamesWon = 0;
|
||||||
String lowestTRid = "", lowestTRnick = "",
|
String lowestTRid = "", lowestTRnick = "",
|
||||||
|
lowestGlixareID = "", lowestGlixareNick = "",
|
||||||
lowestGlickoID = "", lowestGlickoNick = "",
|
lowestGlickoID = "", lowestGlickoNick = "",
|
||||||
lowestRdID = "", lowestRdNick = "",
|
lowestRdID = "", lowestRdNick = "",
|
||||||
lowestGamesPlayedID = "", lowestGamesPlayedNick = "",
|
lowestGamesPlayedID = "", lowestGamesPlayedNick = "",
|
||||||
|
@ -1851,6 +1864,7 @@ class TetrioPlayersLeaderboard {
|
||||||
lowestStrideID = "", lowestStrideNick = "",
|
lowestStrideID = "", lowestStrideNick = "",
|
||||||
lowestInfDSid = "", lowestInfDSnick = "",
|
lowestInfDSid = "", lowestInfDSnick = "",
|
||||||
highestTRid = "", highestTRnick = "",
|
highestTRid = "", highestTRnick = "",
|
||||||
|
highestGlixareID = "", highestGlixareNick = "",
|
||||||
highestGlickoID = "", highestGlickoNick = "",
|
highestGlickoID = "", highestGlickoNick = "",
|
||||||
highestRdID = "", highestRdNick = "",
|
highestRdID = "", highestRdNick = "",
|
||||||
highestGamesPlayedID = "", highestGamesPlayedNick = "",
|
highestGamesPlayedID = "", highestGamesPlayedNick = "",
|
||||||
|
@ -1879,6 +1893,7 @@ class TetrioPlayersLeaderboard {
|
||||||
avgPPS += entry.pps;
|
avgPPS += entry.pps;
|
||||||
avgVS += entry.vs;
|
avgVS += entry.vs;
|
||||||
avgTR += entry.tr;
|
avgTR += entry.tr;
|
||||||
|
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;
|
avgAPP += entry.nerdStats.app;
|
||||||
|
@ -1903,6 +1918,11 @@ class TetrioPlayersLeaderboard {
|
||||||
lowestTRid = entry.userId;
|
lowestTRid = entry.userId;
|
||||||
lowestTRnick = entry.username;
|
lowestTRnick = entry.username;
|
||||||
}
|
}
|
||||||
|
if (entry.gxe < lowestGlixare){
|
||||||
|
lowestGlixare = entry.gxe;
|
||||||
|
lowestGlixareID = entry.userId;
|
||||||
|
lowestGlixareNick = entry.username;
|
||||||
|
}
|
||||||
if (entry.glicko != null && entry.glicko! < lowestGlicko){
|
if (entry.glicko != null && entry.glicko! < lowestGlicko){
|
||||||
lowestGlicko = entry.glicko!;
|
lowestGlicko = entry.glicko!;
|
||||||
lowestGlickoID = entry.userId;
|
lowestGlickoID = entry.userId;
|
||||||
|
@ -2023,6 +2043,11 @@ class TetrioPlayersLeaderboard {
|
||||||
highestTRid = entry.userId;
|
highestTRid = entry.userId;
|
||||||
highestTRnick = entry.username;
|
highestTRnick = entry.username;
|
||||||
}
|
}
|
||||||
|
if (entry.gxe > highestGlixare){
|
||||||
|
highestGlixare = entry.gxe;
|
||||||
|
highestGlixareID = entry.userId;
|
||||||
|
highestGlixareNick = entry.username;
|
||||||
|
}
|
||||||
if (entry.glicko != null && entry.glicko! > highestGlicko){
|
if (entry.glicko != null && entry.glicko! > highestGlicko){
|
||||||
highestGlicko = entry.glicko!;
|
highestGlicko = entry.glicko!;
|
||||||
highestGlickoID = entry.userId;
|
highestGlickoID = entry.userId;
|
||||||
|
@ -2143,6 +2168,7 @@ class TetrioPlayersLeaderboard {
|
||||||
avgPPS /= filtredLeaderboard.length;
|
avgPPS /= filtredLeaderboard.length;
|
||||||
avgVS /= filtredLeaderboard.length;
|
avgVS /= filtredLeaderboard.length;
|
||||||
avgTR /= filtredLeaderboard.length;
|
avgTR /= filtredLeaderboard.length;
|
||||||
|
avgGlixare /= filtredLeaderboard.length;
|
||||||
avgGlicko /= filtredLeaderboard.length;
|
avgGlicko /= filtredLeaderboard.length;
|
||||||
avgRD /= filtredLeaderboard.length;
|
avgRD /= filtredLeaderboard.length;
|
||||||
avgAPP /= filtredLeaderboard.length;
|
avgAPP /= filtredLeaderboard.length;
|
||||||
|
@ -2162,7 +2188,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 [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),
|
return [TetraLeague(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),
|
||||||
{
|
{
|
||||||
"everyone": rank == "",
|
"everyone": rank == "",
|
||||||
"totalGamesPlayed": totalGamesPlayed,
|
"totalGamesPlayed": totalGamesPlayed,
|
||||||
|
@ -2171,6 +2197,12 @@ class TetrioPlayersLeaderboard {
|
||||||
"lowestTR": lowestTR,
|
"lowestTR": lowestTR,
|
||||||
"lowestTRid": lowestTRid,
|
"lowestTRid": lowestTRid,
|
||||||
"lowestTRnick": lowestTRnick,
|
"lowestTRnick": lowestTRnick,
|
||||||
|
"lowestGlixare": lowestGlixare,
|
||||||
|
"lowestGlixareID": lowestGlixareID,
|
||||||
|
"lowestGlixareNick": lowestGlixareNick,
|
||||||
|
"lowestS1tr": lowestGlixare * 250,
|
||||||
|
"lowestS1trID": lowestGlixareID,
|
||||||
|
"lowestS1trNick": lowestGlixareNick,
|
||||||
"lowestGlicko": lowestGlicko,
|
"lowestGlicko": lowestGlicko,
|
||||||
"lowestGlickoID": lowestGlickoID,
|
"lowestGlickoID": lowestGlickoID,
|
||||||
"lowestGlickoNick": lowestGlickoNick,
|
"lowestGlickoNick": lowestGlickoNick,
|
||||||
|
@ -2243,6 +2275,12 @@ class TetrioPlayersLeaderboard {
|
||||||
"highestTR": highestTR,
|
"highestTR": highestTR,
|
||||||
"highestTRid": highestTRid,
|
"highestTRid": highestTRid,
|
||||||
"highestTRnick": highestTRnick,
|
"highestTRnick": highestTRnick,
|
||||||
|
"highestGlixare": highestGlixare,
|
||||||
|
"highestGlixareID": highestGlixareID,
|
||||||
|
"highestGlixareNick": highestGlixareNick,
|
||||||
|
"highestS1tr": highestGlixare * 250,
|
||||||
|
"highestS1trID": highestGlixareID,
|
||||||
|
"highestS1trNick": highestGlixareNick,
|
||||||
"highestGlicko": highestGlicko,
|
"highestGlicko": highestGlicko,
|
||||||
"highestGlickoID": highestGlickoID,
|
"highestGlickoID": highestGlickoID,
|
||||||
"highestGlickoNick": highestGlickoNick,
|
"highestGlickoNick": highestGlickoNick,
|
||||||
|
@ -2327,8 +2365,8 @@ class TetrioPlayersLeaderboard {
|
||||||
"avgPlonk": avgPlonk,
|
"avgPlonk": avgPlonk,
|
||||||
"avgStride": avgStride,
|
"avgStride": avgStride,
|
||||||
"avgInfDS": avgInfDS,
|
"avgInfDS": avgInfDS,
|
||||||
"toEnterTR": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()].tr : lowestTR,
|
"toEnterTR": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].tr : lowestTR,
|
||||||
"toEnterGlicko": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()].glicko : 0,
|
"toEnterGlicko": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].glicko : 0,
|
||||||
"entries": filtredLeaderboard
|
"entries": filtredLeaderboard
|
||||||
}];
|
}];
|
||||||
}else{
|
}else{
|
||||||
|
@ -2447,6 +2485,7 @@ class TetrioPlayerFromLeaderboard {
|
||||||
late int gamesPlayed;
|
late int gamesPlayed;
|
||||||
late int gamesWon;
|
late int gamesWon;
|
||||||
late double tr;
|
late double tr;
|
||||||
|
late double gxe;
|
||||||
late double? glicko;
|
late double? glicko;
|
||||||
late double? rd;
|
late double? rd;
|
||||||
late String rank;
|
late String rank;
|
||||||
|
@ -2469,6 +2508,7 @@ class TetrioPlayerFromLeaderboard {
|
||||||
this.gamesPlayed,
|
this.gamesPlayed,
|
||||||
this.gamesWon,
|
this.gamesWon,
|
||||||
this.tr,
|
this.tr,
|
||||||
|
this.gxe,
|
||||||
this.glicko,
|
this.glicko,
|
||||||
this.rd,
|
this.rd,
|
||||||
this.rank,
|
this.rank,
|
||||||
|
@ -2484,6 +2524,7 @@ class TetrioPlayerFromLeaderboard {
|
||||||
|
|
||||||
double get winrate => gamesWon / gamesPlayed;
|
double get winrate => gamesWon / gamesPlayed;
|
||||||
double get esttracc => estTr.esttr - tr;
|
double get esttracc => estTr.esttr - tr;
|
||||||
|
double get s1tr => gxe * 250;
|
||||||
|
|
||||||
TetrioPlayerFromLeaderboard.fromJson(Map<String, dynamic> json, DateTime ts) {
|
TetrioPlayerFromLeaderboard.fromJson(Map<String, dynamic> json, DateTime ts) {
|
||||||
userId = json['_id'];
|
userId = json['_id'];
|
||||||
|
@ -2495,6 +2536,7 @@ class TetrioPlayerFromLeaderboard {
|
||||||
gamesPlayed = json['league']['gamesplayed'] as int;
|
gamesPlayed = json['league']['gamesplayed'] as int;
|
||||||
gamesWon = json['league']['gameswon'] as int;
|
gamesWon = json['league']['gameswon'] as int;
|
||||||
tr = json['league']['tr'] != null ? json['league']['tr'].toDouble() : 0;
|
tr = json['league']['tr'] != null ? json['league']['tr'].toDouble() : 0;
|
||||||
|
gxe = json['league']['gxe']??-1;
|
||||||
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'];
|
||||||
|
@ -2514,6 +2556,10 @@ class TetrioPlayerFromLeaderboard {
|
||||||
return tr;
|
return tr;
|
||||||
case Stats.glicko:
|
case Stats.glicko:
|
||||||
return glicko??-1;
|
return glicko??-1;
|
||||||
|
case Stats.gxe:
|
||||||
|
return gxe;
|
||||||
|
case Stats.s1tr:
|
||||||
|
return s1tr;
|
||||||
case Stats.rd:
|
case Stats.rd:
|
||||||
return rd??-1;
|
return rd??-1;
|
||||||
case Stats.gp:
|
case Stats.gp:
|
||||||
|
|
|
@ -636,18 +636,12 @@ class TetrioService extends DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves full Tetra League leaderboard from Tetra Channel api. Returns a leaderboard object. Throws an exception if fails to retrieve.
|
/// Retrieves full Tetra League leaderboard from Tetra Channel api. Returns a leaderboard object. Throws an exception if fails to retrieve.
|
||||||
Future<TetrioPlayersLeaderboard> fetchTLLeaderboard({double? after}) async {
|
Future<TetrioPlayersLeaderboard> fetchTLLeaderboard() async {
|
||||||
TetrioPlayersLeaderboard? cached = _cache.get("league${after != null ? after.toString() : ""}", TetrioPlayersLeaderboard);
|
TetrioPlayersLeaderboard? cached = _cache.get("league", TetrioPlayersLeaderboard);
|
||||||
if (cached != null) return cached;
|
if (cached != null) return cached;
|
||||||
Uri url;
|
|
||||||
if (kIsWeb) {
|
Uri url = Uri.https('ts.dan63.by', 'beanserver_blaster/leaderboard.json');
|
||||||
url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLLeaderboard"});
|
|
||||||
} else {
|
|
||||||
url = Uri.https('ch.tetr.io', 'api/users/by/league', {
|
|
||||||
"limit": "100",
|
|
||||||
if (after != null) "after": "$after:0:0"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
try{
|
try{
|
||||||
final response = await client.get(url);
|
final response = await client.get(url);
|
||||||
|
|
||||||
|
@ -655,16 +649,10 @@ class TetrioService extends DB {
|
||||||
case 200:
|
case 200:
|
||||||
_lbPositions.clear();
|
_lbPositions.clear();
|
||||||
var rawJson = jsonDecode(response.body);
|
var rawJson = jsonDecode(response.body);
|
||||||
if (rawJson['success']) { // if api confirmed that everything ok
|
TetrioPlayersLeaderboard leaderboard = TetrioPlayersLeaderboard.fromJson(rawJson['data'], "league", DateTime.fromMillisecondsSinceEpoch(rawJson['created']));
|
||||||
TetrioPlayersLeaderboard leaderboard = TetrioPlayersLeaderboard.fromJson(rawJson['data']['entries'], "league", DateTime.fromMillisecondsSinceEpoch(rawJson['cache']['cached_at']));
|
developer.log("fetchTLLeaderboard: Leaderboard retrieved and cached", name: "services/tetrio_crud");
|
||||||
developer.log("fetchTLLeaderboard: Leaderboard retrieved and cached", name: "services/tetrio_crud");
|
_cache.store(leaderboard, rawJson['cache_until']);
|
||||||
//_leaderboardsCache[rawJson['cache']['cached_until'].toString()] = leaderboard;
|
return leaderboard;
|
||||||
_cache.store(leaderboard, rawJson['cache']['cached_until']);
|
|
||||||
return leaderboard;
|
|
||||||
} else { // idk how to hit that one
|
|
||||||
developer.log("fetchTLLeaderboard: Bruh", name: "services/tetrio_crud", error: rawJson);
|
|
||||||
throw Exception("Failed to get leaderboard (problems on the tetr.io side)"); // will it be on tetr.io side?
|
|
||||||
}
|
|
||||||
case 403:
|
case 403:
|
||||||
throw TetrioForbidden();
|
throw TetrioForbidden();
|
||||||
case 429:
|
case 429:
|
||||||
|
@ -686,19 +674,19 @@ class TetrioService extends DB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<TetrioPlayersLeaderboard> fetchFullLeaderboard() async* {
|
// Stream<TetrioPlayersLeaderboard> fetchFullLeaderboard() async* {
|
||||||
late double after;
|
// late double after;
|
||||||
int lbLength = 100;
|
// int lbLength = 100;
|
||||||
TetrioPlayersLeaderboard leaderboard = await fetchTLLeaderboard();
|
// TetrioPlayersLeaderboard leaderboard = await fetchTLLeaderboard();
|
||||||
after = leaderboard.leaderboard.last.tr;
|
// after = leaderboard.leaderboard.last.tr;
|
||||||
while (lbLength == 100){
|
// while (lbLength == 100){
|
||||||
TetrioPlayersLeaderboard pseudoLb = await fetchTLLeaderboard(after: after);
|
// TetrioPlayersLeaderboard pseudoLb = await fetchTLLeaderboard(after: after);
|
||||||
leaderboard.addPlayers(pseudoLb.leaderboard);
|
// leaderboard.addPlayers(pseudoLb.leaderboard);
|
||||||
lbLength = pseudoLb.leaderboard.length;
|
// lbLength = pseudoLb.leaderboard.length;
|
||||||
after = pseudoLb.leaderboard.last.tr;
|
// after = pseudoLb.leaderboard.last.tr;
|
||||||
yield leaderboard;
|
// yield leaderboard;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// i want to know progress, so i trying to figure out this thing:
|
// i want to know progress, so i trying to figure out this thing:
|
||||||
// Stream<TetrioPlayersLeaderboard> fetchTLLeaderboardAsStream() async {
|
// Stream<TetrioPlayersLeaderboard> fetchTLLeaderboardAsStream() async {
|
||||||
|
|
|
@ -213,7 +213,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
nextRankGlickoCutoff = (summaries.league.rank != "z" ? summaries.league.rank == "x+" : summaries.league.percentileRank == "x+") ? topOne?.glicko??double.infinity : cutoffsGlicko?[ranks.elementAtOrNull(ranks.indexOf(summaries.league.rank != "z" ? summaries.league.rank : summaries.league.percentileRank)+1)];
|
nextRankGlickoCutoff = (summaries.league.rank != "z" ? summaries.league.rank == "x+" : summaries.league.percentileRank == "x+") ? topOne?.glicko??double.infinity : cutoffsGlicko?[ranks.elementAtOrNull(ranks.indexOf(summaries.league.rank != "z" ? summaries.league.rank : summaries.league.percentileRank)+1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (everyone != null && summaries.league.gamesPlayed > 9) rankAverages = everyone?.averages[summaries.league.percentileRank]?[0];
|
if (everyone != null && summaries.league.gamesPlayed > 9) rankAverages = everyone?.averages[summaries.league.percentileRank]?[0];
|
||||||
|
|
||||||
// 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);
|
||||||
|
@ -482,8 +482,8 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
nextRankCutoff: nextRankCutoff,
|
nextRankCutoff: nextRankCutoff,
|
||||||
nextRankCutoffGlicko: nextRankGlickoCutoff,
|
nextRankCutoffGlicko: nextRankGlickoCutoff,
|
||||||
//nextRankTarget: (snapshot.data![1].league.rank != "z" && snapshot.data![1].league.rank != "x") ? rankTargets[ranks.elementAtOrNull(ranks.indexOf(snapshot.data![1].league.rank)+1)] : null,
|
//nextRankTarget: (snapshot.data![1].league.rank != "z" && snapshot.data![1].league.rank != "x") ? rankTargets[ranks.elementAtOrNull(ranks.indexOf(snapshot.data![1].league.rank)+1)] : null,
|
||||||
//averages: rankAverages,
|
averages: rankAverages,
|
||||||
//lbPositions: meAmongEveryone
|
lbPositions: meAmongEveryone
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
@ -523,8 +523,8 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
||||||
nextRankCutoff: nextRankCutoff,
|
nextRankCutoff: nextRankCutoff,
|
||||||
nextRankCutoffGlicko: nextRankGlickoCutoff,
|
nextRankCutoffGlicko: nextRankGlickoCutoff,
|
||||||
//nextRankTarget: (snapshot.data![1].league.rank != "z" && snapshot.data![1].league.rank != "x") ? rankTargets[ranks.elementAtOrNull(ranks.indexOf(snapshot.data![1].league.rank)+1)] : null,
|
//nextRankTarget: (snapshot.data![1].league.rank != "z" && snapshot.data![1].league.rank != "x") ? rankTargets[ranks.elementAtOrNull(ranks.indexOf(snapshot.data![1].league.rank)+1)] : null,
|
||||||
//averages: rankAverages,
|
averages: rankAverages,
|
||||||
//lbPositions: meAmongEveryone
|
lbPositions: meAmongEveryone
|
||||||
),
|
),
|
||||||
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3].records, wasActiveInTL: true, oldMathcesHere: _TLHistoryWasFetched, separateScrollController: true),
|
_TLRecords(userID: snapshot.data![0].userId, changePlayer: changePlayer, data: snapshot.data![3].records, wasActiveInTL: true, oldMathcesHere: _TLHistoryWasFetched, separateScrollController: true),
|
||||||
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![1].league.gamesPlayed > 0),
|
_History(chartsData: chartsData, changePlayer: changePlayer, userID: _searchFor, update: _justUpdate, wasActiveInTL: snapshot.data![1].league.gamesPlayed > 0),
|
||||||
|
|
|
@ -379,6 +379,8 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
_ListEntry(value: widget.rank[1]["lowestTR"], label: t.statCellNum.tr.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["lowestTRid"], username: widget.rank[1]["lowestTRnick"], approximate: false, fractionDigits: 2),
|
_ListEntry(value: widget.rank[1]["lowestTR"], label: t.statCellNum.tr.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["lowestTRid"], username: widget.rank[1]["lowestTRnick"], approximate: false, fractionDigits: 2),
|
||||||
|
_ListEntry(value: widget.rank[1]["lowestGlixare"], label: "Glixare", id: widget.rank[1]["lowestGlixareID"], username: widget.rank[1]["lowestGlixareNick"], approximate: false, fractionDigits: 3),
|
||||||
|
_ListEntry(value: widget.rank[1]["lowestS1tr"], label: "S1 ${t.statCellNum.tr.replaceAll(RegExp(r'\n'), " ")}", id: widget.rank[1]["lowestS1trID"], username: widget.rank[1]["lowestS1trNick"], approximate: false, fractionDigits: 2),
|
||||||
_ListEntry(value: widget.rank[1]["lowestGlicko"], label: "Glicko", id: widget.rank[1]["lowestGlickoID"], username: widget.rank[1]["lowestGlickoNick"], approximate: false, fractionDigits: 2),
|
_ListEntry(value: widget.rank[1]["lowestGlicko"], label: "Glicko", id: widget.rank[1]["lowestGlickoID"], username: widget.rank[1]["lowestGlickoNick"], approximate: false, fractionDigits: 2),
|
||||||
_ListEntry(value: widget.rank[1]["lowestRD"], label: t.statCellNum.rd.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["lowestRdID"], username: widget.rank[1]["lowestRdNick"], approximate: false, fractionDigits: 3),
|
_ListEntry(value: widget.rank[1]["lowestRD"], label: t.statCellNum.rd.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["lowestRdID"], username: widget.rank[1]["lowestRdNick"], approximate: false, fractionDigits: 3),
|
||||||
_ListEntry(value: widget.rank[1]["lowestGamesPlayed"], label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["lowestGamesPlayedID"], username: widget.rank[1]["lowestGamesPlayedNick"], approximate: false),
|
_ListEntry(value: widget.rank[1]["lowestGamesPlayed"], label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["lowestGamesPlayedID"], username: widget.rank[1]["lowestGamesPlayedNick"], approximate: false),
|
||||||
|
@ -413,6 +415,8 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(children: [
|
child: ListView(children: [
|
||||||
_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].tr, label: t.statCellNum.tr.replaceAll(RegExp(r'\n'), " "), id: "", username: "", approximate: true, fractionDigits: 2),
|
||||||
|
_ListEntry(value: widget.rank[0].gxe, label: "Glixare", id: "", username: "", approximate: false, fractionDigits: 3),
|
||||||
|
_ListEntry(value: widget.rank[0].s1tr, label: "S1 ${t.statCellNum.tr.replaceAll(RegExp(r'\n'), " ")}", id: "", username: "", approximate: false, 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),
|
||||||
|
@ -446,6 +450,8 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
_ListEntry(value: widget.rank[1]["highestTR"], label: t.statCellNum.tr.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["highestTRid"], username: widget.rank[1]["highestTRnick"], approximate: false, fractionDigits: 2),
|
_ListEntry(value: widget.rank[1]["highestTR"], label: t.statCellNum.tr.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["highestTRid"], username: widget.rank[1]["highestTRnick"], approximate: false, fractionDigits: 2),
|
||||||
|
_ListEntry(value: widget.rank[1]["highestGlixare"], label: "Glixare", id: widget.rank[1]["highestGlixareID"], username: widget.rank[1]["highestGlixareNick"], approximate: false, fractionDigits: 3),
|
||||||
|
_ListEntry(value: widget.rank[1]["highestS1tr"], label: "S1 ${t.statCellNum.tr.replaceAll(RegExp(r'\n'), " ")}", id: widget.rank[1]["highestS1trID"], username: widget.rank[1]["highestS1trNick"], approximate: false, fractionDigits: 2),
|
||||||
_ListEntry(value: widget.rank[1]["highestGlicko"], label: "Glicko", id: widget.rank[1]["highestGlickoID"], username: widget.rank[1]["highestGlickoNick"], approximate: false, fractionDigits: 2),
|
_ListEntry(value: widget.rank[1]["highestGlicko"], label: "Glicko", id: widget.rank[1]["highestGlickoID"], username: widget.rank[1]["highestGlickoNick"], approximate: false, fractionDigits: 2),
|
||||||
_ListEntry(value: widget.rank[1]["highestRD"], label: t.statCellNum.rd.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["highestRdID"], username: widget.rank[1]["highestRdNick"], approximate: false, fractionDigits: 3),
|
_ListEntry(value: widget.rank[1]["highestRD"], label: t.statCellNum.rd.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["highestRdID"], username: widget.rank[1]["highestRdNick"], approximate: false, fractionDigits: 3),
|
||||||
_ListEntry(value: widget.rank[1]["highestGamesPlayed"], label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["highestGamesPlayedID"], username: widget.rank[1]["highestGamesPlayedNick"], approximate: false),
|
_ListEntry(value: widget.rank[1]["highestGamesPlayed"], label: t.statCellNum.gamesPlayed.replaceAll(RegExp(r'\n'), " "), id: widget.rank[1]["highestGamesPlayedID"], username: widget.rank[1]["highestGamesPlayedNick"], approximate: false),
|
||||||
|
@ -517,7 +523,7 @@ class _ListEntry extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Text(f.format(value),
|
Text(f.format(value),
|
||||||
style: const TextStyle(fontSize: 22, height: 0.9)),
|
style: const TextStyle(fontSize: 22, height: 0.9)),
|
||||||
if (id.isNotEmpty) Text(t.forPlayer(username: username))
|
if (id.isNotEmpty) Text(t.forPlayer(username: username), style: TextStyle(color: Colors.grey, fontWeight: FontWeight.w100),)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: id.isNotEmpty
|
onTap: id.isNotEmpty
|
||||||
|
|
|
@ -4,13 +4,13 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||||
import 'package:tetra_stats/gen/strings.g.dart';
|
import 'package:tetra_stats/gen/strings.g.dart';
|
||||||
import 'package:tetra_stats/services/tetrio_crud.dart';
|
import 'package:tetra_stats/main.dart';
|
||||||
import 'package:tetra_stats/views/main_view.dart';
|
import 'package:tetra_stats/views/main_view.dart';
|
||||||
import 'package:tetra_stats/views/rank_averages_view.dart';
|
import 'package:tetra_stats/views/rank_averages_view.dart';
|
||||||
import 'package:tetra_stats/views/ranks_averages_view.dart';
|
import 'package:tetra_stats/views/ranks_averages_view.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
import 'package:tetra_stats/widgets/text_timestamp.dart';
|
||||||
|
|
||||||
final TetrioService _teto = TetrioService();
|
|
||||||
List<DropdownMenuItem> _itemStats = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuItem(value: e.key, child: Text(e.value))];
|
List<DropdownMenuItem> _itemStats = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuItem(value: e.key, child: Text(e.value))];
|
||||||
Stats _sortBy = Stats.tr;
|
Stats _sortBy = Stats.tr;
|
||||||
bool reversed = false;
|
bool reversed = false;
|
||||||
|
@ -64,148 +64,155 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: FutureBuilder(
|
child: FutureBuilder(
|
||||||
future: _teto.fetchTLLeaderboard(),
|
future: teto.fetchTLLeaderboard(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
switch (snapshot.connectionState) {
|
switch (snapshot.connectionState) {
|
||||||
case ConnectionState.none:
|
case ConnectionState.none:
|
||||||
case ConnectionState.waiting:
|
case ConnectionState.waiting:
|
||||||
case ConnectionState.active:
|
case ConnectionState.active:
|
||||||
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);
|
if (snapshot.hasData){
|
||||||
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) windowManager.setTitle("Tetra Stats: ${t.tlLeaderboard} - ${t.players(n: allPlayers != null ? allPlayers.length : 0)}");
|
final allPlayers = snapshot.data?.getStatRanking(snapshot.data!.leaderboard, _sortBy, reversed: reversed, country: _country);
|
||||||
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) windowManager.setTitle("Tetra Stats: ${t.tlLeaderboard} - ${t.players(n: allPlayers != null ? allPlayers.length : 0)}");
|
||||||
return NestedScrollView(
|
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
||||||
headerSliverBuilder: (context, value) {
|
return NestedScrollView(
|
||||||
String howManyPlayers(int numberOfPlayers) => Intl.plural(
|
headerSliverBuilder: (context, value) {
|
||||||
numberOfPlayers,
|
return [
|
||||||
zero: t.lbViewZeroEntrys,
|
SliverToBoxAdapter(
|
||||||
one: t.lbViewOneEntry,
|
child: Padding(
|
||||||
other: t.lbViewManyEntrys(numberOfPlayers: t.players(n: numberOfPlayers)),
|
padding: const EdgeInsets.only(left: 16),
|
||||||
name: 'howManyPeople',
|
child: Wrap(
|
||||||
args: [numberOfPlayers],
|
direction: Axis.horizontal,
|
||||||
desc: 'Description of how many people are seen in a place.',
|
alignment: WrapAlignment.spaceBetween,
|
||||||
examples: const {'numberOfPeople': 3},
|
children: [
|
||||||
);
|
Text(
|
||||||
return [
|
"${t.players(n: allPlayers.length)} • ${t.sprintAndBlitsRelevance(date: timestamp(snapshot.data!.timestamp))}",
|
||||||
SliverToBoxAdapter(
|
style: const TextStyle(color: Colors.white, fontSize: 25),
|
||||||
child: Padding(
|
),
|
||||||
padding: const EdgeInsets.only(left: 16),
|
TextButton(onPressed: (){
|
||||||
child: Wrap(
|
Navigator.push(
|
||||||
direction: Axis.horizontal,
|
context,
|
||||||
alignment: WrapAlignment.spaceBetween,
|
MaterialPageRoute(
|
||||||
children: [
|
builder: (context) => RankView(rank: snapshot.data!.getAverageOfRank("")),
|
||||||
Text(
|
|
||||||
howManyPlayers(allPlayers.length),
|
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 25),
|
|
||||||
),
|
|
||||||
TextButton(onPressed: (){
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => RankView(rank: snapshot.data!.getAverageOfRank("")),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}, child: Text(t.everyoneAverages,
|
|
||||||
style: const TextStyle(fontSize: 25)))
|
|
||||||
],)
|
|
||||||
)),
|
|
||||||
SliverToBoxAdapter(child: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 16),
|
|
||||||
child: Wrap(
|
|
||||||
direction: Axis.horizontal,
|
|
||||||
alignment: WrapAlignment.start,
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
|
||||||
spacing: 16,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
||||||
textBaseline: TextBaseline.alphabetic,
|
|
||||||
children: [
|
|
||||||
Text("${t.sortBy}: ",
|
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
|
||||||
DropdownButton(items: _itemStats, value: _sortBy, onChanged: ((value) {
|
|
||||||
_sortBy = value;
|
|
||||||
setState(() {});
|
|
||||||
}),),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
||||||
textBaseline: TextBaseline.alphabetic,
|
|
||||||
children: [
|
|
||||||
Text("${t.reversed}: ",
|
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(0, 5.5, 0, 7.5),
|
|
||||||
child: Checkbox(value: reversed,
|
|
||||||
checkColor: Colors.black,
|
|
||||||
onChanged: ((value) {
|
|
||||||
reversed = value!;
|
|
||||||
setState(() {});
|
|
||||||
}),),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
|
||||||
textBaseline: TextBaseline.alphabetic,
|
|
||||||
children: [
|
|
||||||
Text("${t.country}: ",
|
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
|
||||||
DropdownButton(items: _itemCountries, value: _country, onChanged: ((value) {
|
|
||||||
_country = value;
|
|
||||||
setState(() {});
|
|
||||||
}),),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),),
|
|
||||||
const SliverToBoxAdapter(child: Divider())
|
|
||||||
];
|
|
||||||
},
|
|
||||||
body: ListView.builder(
|
|
||||||
itemCount: allPlayers!.length,
|
|
||||||
prototypeItem: ListTile(
|
|
||||||
leading: Text("0", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 28 : 24, height: 0.9)),
|
|
||||||
title: Text("ehhh...", style: TextStyle(fontFamily: bigScreen ? "Eurostile Round Extended" : "Eurostile Round", height: 0.9)),
|
|
||||||
trailing: SizedBox(height: bigScreen ? 48 : 36, width: 1,),
|
|
||||||
subtitle: const Text("eh..."),
|
|
||||||
),
|
),
|
||||||
itemBuilder: (context, index) {
|
);
|
||||||
return ListTile(
|
}, child: Text(t.everyoneAverages,
|
||||||
leading: Text(
|
style: const TextStyle(fontSize: 25)))
|
||||||
(index+1).toString(),
|
],)
|
||||||
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 28 : 24, height: 0.9)
|
)),
|
||||||
|
SliverToBoxAdapter(child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 16),
|
||||||
|
child: Wrap(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
alignment: WrapAlignment.start,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
spacing: 16,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||||
|
textBaseline: TextBaseline.alphabetic,
|
||||||
|
children: [
|
||||||
|
Text("${t.sortBy}: ",
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
||||||
|
DropdownButton(items: _itemStats, value: _sortBy, onChanged: ((value) {
|
||||||
|
_sortBy = value;
|
||||||
|
setState(() {});
|
||||||
|
}),),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||||
|
textBaseline: TextBaseline.alphabetic,
|
||||||
|
children: [
|
||||||
|
Text("${t.reversed}: ",
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(0, 5.5, 0, 7.5),
|
||||||
|
child: Checkbox(value: reversed,
|
||||||
|
checkColor: Colors.black,
|
||||||
|
onChanged: ((value) {
|
||||||
|
reversed = value!;
|
||||||
|
setState(() {});
|
||||||
|
}),),
|
||||||
),
|
),
|
||||||
title: Text(allPlayers[index].username, style: TextStyle(fontFamily: bigScreen ? "Eurostile Round Extended" : "Eurostile Round", height: 0.9)),
|
],
|
||||||
subtitle: (bigScreen || _sortBy != Stats.tr) ? Text(_sortBy == Stats.tr ? "${f2.format(allPlayers[index].apm)} APM, ${f2.format(allPlayers[index].pps)} PPS, ${f2.format(allPlayers[index].vs)} VS, ${f2.format(allPlayers[index].nerdStats.app)} APP, ${f2.format(allPlayers[index].nerdStats.vsapm)} VS/APM" : "${_f4.format(allPlayers[index].getStatByEnum(_sortBy))} ${chartsShortTitles[_sortBy]}",
|
),
|
||||||
style: TextStyle(fontFamily: "Eurostile Round Condensed", fontSize: bigScreen ? null : 13, color: _sortBy == Stats.tr ? Colors.grey : null)) : null,
|
Row(
|
||||||
trailing: Row(
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisSize: MainAxisSize.min,
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||||
children: [
|
textBaseline: TextBaseline.alphabetic,
|
||||||
Text("${f2.format(allPlayers[index].tr)} TR", style: const TextStyle(fontSize: 28)),
|
children: [
|
||||||
Image.asset("res/tetrio_tl_alpha_ranks/${allPlayers[index].rank}.png", height: bigScreen ? 48 : 36),
|
Text("${t.country}: ",
|
||||||
],
|
style: const TextStyle(color: Colors.white, fontSize: 25)),
|
||||||
),
|
DropdownButton(items: _itemCountries, value: _country, onChanged: ((value) {
|
||||||
onTap: () {
|
_country = value;
|
||||||
Navigator.push(
|
setState(() {});
|
||||||
context,
|
}),),
|
||||||
MaterialPageRoute(
|
],
|
||||||
builder: (context) => MainView(player: allPlayers[index].userId),
|
),
|
||||||
maintainState: false,
|
],
|
||||||
),
|
),
|
||||||
);
|
),),
|
||||||
},
|
const SliverToBoxAdapter(child: Divider())
|
||||||
);
|
];
|
||||||
}));
|
},
|
||||||
}
|
body: ListView.builder(
|
||||||
})),
|
itemCount: allPlayers!.length,
|
||||||
|
prototypeItem: ListTile(
|
||||||
|
leading: Text("0", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 28 : 24, height: 0.9)),
|
||||||
|
title: Text("ehhh...", style: TextStyle(fontFamily: bigScreen ? "Eurostile Round Extended" : "Eurostile Round", height: 0.9)),
|
||||||
|
trailing: SizedBox(height: bigScreen ? 48 : 36, width: 1,),
|
||||||
|
subtitle: const Text("eh..."),
|
||||||
|
),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return ListTile(
|
||||||
|
leading: Text(
|
||||||
|
(index+1).toString(),
|
||||||
|
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 28 : 24, height: 0.9)
|
||||||
|
),
|
||||||
|
title: Text(allPlayers[index].username, style: TextStyle(fontFamily: bigScreen ? "Eurostile Round Extended" : "Eurostile Round", height: 0.9)),
|
||||||
|
subtitle: (bigScreen || _sortBy != Stats.tr) ? Text(_sortBy == Stats.tr ? "${f2.format(allPlayers[index].apm)} APM, ${f2.format(allPlayers[index].pps)} PPS, ${f2.format(allPlayers[index].vs)} VS, ${f2.format(allPlayers[index].nerdStats.app)} APP, ${f2.format(allPlayers[index].nerdStats.vsapm)} VS/APM" : "${_f4.format(allPlayers[index].getStatByEnum(_sortBy))} ${chartsShortTitles[_sortBy]}",
|
||||||
|
style: TextStyle(fontFamily: "Eurostile Round Condensed", fontSize: bigScreen ? null : 13, color: _sortBy == Stats.tr ? Colors.grey : null)) : null,
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
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),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => MainView(player: allPlayers[index].userId),
|
||||||
|
maintainState: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (snapshot.hasError){
|
||||||
|
return Center(child:
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(snapshot.error.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
||||||
|
if (snapshot.stackTrace != null) Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: Text(snapshot.stackTrace.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 18), textAlign: TextAlign.center),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Text("end of FutureBuilder");
|
||||||
|
}
|
||||||
|
})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.5+31
|
version: 1.6.6+32
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0'
|
sdk: '>=3.0.0'
|
||||||
|
|
Loading…
Reference in New Issue