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

View File

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

View File

@ -17,7 +17,7 @@ enum Mode{
averages
}
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;
List<dynamic> theRedSide = [null, null, null];
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]!);
theRedSide = [null,
null,
TetraLeagueAlpha(
TetraLeague(
timestamp: DateTime.now(),
apm: apm,
pps: pps,
@ -92,7 +92,8 @@ class CompareState extends State<CompareView> {
gamesWon: -1,
bestRank: "z",
decaying: true,
rating: -1,
tr: -1,
gxe: -1,
rank: "z",
percentileRank: "z",
percentile: 1,
@ -156,7 +157,7 @@ class CompareState extends State<CompareView> {
double vs = double.parse(threeNumbers[2][0]!);
theGreenSide = [null,
null,
TetraLeagueAlpha(
TetraLeague(
timestamp: DateTime.now(),
apm: apm,
pps: pps,
@ -166,7 +167,8 @@ class CompareState extends State<CompareView> {
gamesWon: -1,
bestRank: "z",
decaying: true,
rating: -1,
tr: -1,
gxe: -1,
rank: "z",
percentileRank: "z",
percentile: 1,
@ -395,8 +397,8 @@ class CompareState extends State<CompareView> {
redSideMode != Mode.stats)
CompareThingy(
label: "TR",
greenSide: theGreenSide[2].rating,
redSide: theRedSide[2].rating,
greenSide: theGreenSide[2].tr,
redSide: theRedSide[2].tr,
fractionDigits: 2,
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
TetrioPlayersLeaderboard? everyone;
PlayerLeaderboardPosition? meAmongEveryone;
TetraLeagueAlpha? rankAverages;
TetraLeague? rankAverages;
double? thatRankCutoff;
double? nextRankCutoff;
double? thatRankGlickoCutoff;
@ -208,7 +208,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
// if (me.tlSeason1.gamesPlayed > 9) {
// thatRankCutoff = cutoffs?[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)];
// }
@ -217,13 +217,13 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
// Making list of Tetra League matches
bool isTracking = await teto.isPlayerTracking(me.userId);
List<TetrioPlayer> states = [];
TetraLeagueAlpha? compareWith;
Set<TetraLeagueAlpha> uniqueTL = {};
TetraLeague? compareWith;
Set<TetraLeague> uniqueTL = {};
List<TetraLeagueAlphaRecord> storedRecords = await teto.getTLMatchesbyPlayerID(me.userId); // get old matches
if (isTracking){ // if tracked - save data to local DB
await teto.storeState(me);
//await teto.saveTLMatchesFromStream(tlStream);
}
// if (isTracking){ // if tracked - save data to local DB
// await teto.storeState(me);
// //await teto.saveTLMatchesFromStream(tlStream);
// }
TetraLeagueAlphaStream? oldMatches;
// building list of TL matches
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
if (element.tlSeason1 != null && uniqueTL.isNotEmpty && uniqueTL.last != element.tlSeason1) 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){
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
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.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'), " "))),

View File

@ -285,7 +285,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
Future<List<DropdownMenuItem<List<_HistoryChartSpot>>>> getChartsData(bool fetchHistory) async {
List<TetrioPlayer> states = [];
Set<TetraLeagueAlpha> uniqueTL = {};
Set<TetraLeague> uniqueTL = {};
if(fetchHistory){
try{
@ -310,7 +310,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
if (uniqueTL.length >= 2){
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.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'), " "))),
@ -837,7 +837,7 @@ class _DestinationHomeState extends State<DestinationHome> {
);
}
Widget getTetraLeagueCard(TetraLeagueAlpha data){
Widget getTetraLeagueCard(TetraLeague data){
return Column(
children: [
Card(
@ -2287,7 +2287,7 @@ class _SearchDrawerState extends State<SearchDrawer> {
}
class TetraLeagueThingy extends StatelessWidget{
final TetraLeagueAlpha league;
final TetraLeague league;
const TetraLeagueThingy({super.key, required this.league});

View File

@ -360,7 +360,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
trailing: Row(
mainAxisSize: MainAxisSize.min,
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),
],
),
@ -412,7 +412,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
Text(t.averageValues, style: TextStyle( fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
Expanded(
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].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),

View File

@ -58,6 +58,6 @@ class StateState extends State<StateView> {
headerSliverBuilder: (context, value) {
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());
case ConnectionState.done:
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;
return NestedScrollView(
headerSliverBuilder: (context, value) {
@ -189,7 +189,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
trailing: Row(
mainAxisSize: MainAxisSize.min,
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),
],
),

View File

@ -382,8 +382,8 @@ class TlMatchResultState extends State<TlMatchResultView> {
),
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].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].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].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.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].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,

View File

@ -9,7 +9,7 @@ import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/utils/numers_formats.dart';
class TLProgress extends StatelessWidget{
final TetraLeagueAlpha tlData;
final TetraLeague tlData;
final double? nextRankTRcutoff;
final double? previousRankTRcutoff;
final double? nextRankGlickoCutoff;
@ -45,7 +45,7 @@ class TLProgress extends StatelessWidget{
children: [
if (tlData.prevAt > 0) TextSpan(text: "${f0.format(tlData.prevAt)}"),
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 (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: [
if (tlData.nextAt > 0) TextSpan(text: "${f0.format(tlData.nextAt)}"),
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 (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,
interval: 1,
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),
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)
],
markerPointers: [
LinearShapePointer(value: (previousRankTRcutoff != null && nextRankTRcutoff != null) ? getBarTR(tlData.rating)! : 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),))
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.tr)! : getBarPosition(), child: Text("${NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 0).format(tlData.standing)}", style: const TextStyle(fontSize: 14),))
],
isMirrored: true,
showTicks: true,

View File

@ -10,8 +10,8 @@ var fDiff = NumberFormat("+#,###.####;-#,###.####");
class TLRatingThingy extends StatelessWidget{
final String userID;
final TetraLeagueAlpha tlData;
final TetraLeagueAlpha? oldTl;
final TetraLeague tlData;
final TetraLeague? oldTl;
final double? topTR;
final DateTime? lastMatchPlayed;
@ -22,7 +22,7 @@ class TLRatingThingy extends StatelessWidget{
bool oskKagariGimmick = prefs.getBool("oskKagariGimmick")??true;
bool bigScreen = MediaQuery.of(context).size.width >= 768;
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> formatedPercentile = f4.format(tlData.percentile * 100).split(decimalSeparator);
//DateTime now = DateTime.now();
@ -66,11 +66,11 @@ class TLRatingThingy extends StatelessWidget{
switch(prefs.getInt("ratingMode")){
1 => "${fDiff.format(tlData.glicko! - oldTl!.glicko!)} Glicko",
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,
style: TextStyle(
color: tlData.rating - oldTl!.rating < 0 ?
color: tlData.tr - oldTl!.tr < 0 ?
Colors.red :
Colors.green
),
@ -83,11 +83,11 @@ class TLRatingThingy extends StatelessWidget{
text: TextSpan(
style: DefaultTextStyle.of(context).style,
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") TextSpan(text: "${t.topRank}: ${tlData.bestRank.toUpperCase()}"),
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),
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))

View File

@ -20,16 +20,15 @@ import 'package:tetra_stats/widgets/tl_rating_thingy.dart';
var intFDiff = NumberFormat("+#,###.000;-#,###.000");
class TLThingy extends StatefulWidget {
final TetraLeagueAlpha tl;
final TetraLeague tl;
final String userID;
final List<TetrioPlayer> states;
final bool showTitle;
final bool bot;
final bool hidePreSeasonThingy;
final bool guest;
final double? topTR;
final PlayerLeaderboardPosition? lbPositions;
final TetraLeagueAlpha? averages;
final TetraLeague? averages;
final double? thatRankCutoff;
final double? thatRankCutoffGlicko;
final double? thatRankTarget;
@ -37,7 +36,7 @@ class TLThingy extends StatefulWidget {
final double? nextRankCutoffGlicko;
final double? nextRankTarget;
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
State<TLThingy> createState() => _TLThingyState();
@ -45,13 +44,10 @@ class TLThingy extends StatefulWidget {
class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
late bool oskKagariGimmick;
late TetraLeagueAlpha? oldTl;
late TetraLeagueAlpha currentTl;
late TetraLeague? oldTl;
late TetraLeague currentTl;
late RangeValues _currentRangeValues;
late List<TetrioPlayer> sortedStates;
late Timer _countdownTimer;
//Duration seasonLeft = seasonEnd.difference(DateTime.now());
Duration postSeasonLeft = seasonStart.difference(DateTime.now());
@override
void initState() {
@ -60,20 +56,10 @@ class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
oldTl = sortedStates.elementAtOrNull(1)?.tlSeason1;
currentTl = widget.tl;
super.initState();
_countdownTimer = Timer.periodic(
Durations.extralong4,
(Timer timer) {
setState(() {
//seasonLeft = seasonEnd.difference(DateTime.now());
postSeasonLeft = seasonStart.difference(DateTime.now());
});
},
);
}
@override
void dispose() {
_countdownTimer.cancel();
super.dispose();
}
@ -84,47 +70,6 @@ class _TLThingyState extends State<TLThingy> with TickerProviderStateMixin {
String decimalSeparator = f2.symbols.DECIMAL_SEP;
List<String> estTRformated = currentTl.estTr != null ? f2.format(currentTl.estTr!.esttr).split(decimalSeparator) : [];
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,));
return LayoutBuilder(builder: (context, constraints) {
bool bigScreen = constraints.maxWidth >= 768;

View File

@ -2,7 +2,7 @@ name: tetra_stats
description: Track your and other player stats in TETR.IO
publish_to: 'none'
version: 1.6.2+22
version: 1.6.3+29
environment:
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.rank != "z", true); lol
// 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.gamesWon > 0, true);
// //expect(dan63047.tlSeason1.standing, -1);
@ -70,7 +70,7 @@
// expect(osk.tlSeason1.glicko != null, true);
// expect(osk.tlSeason1.rank == "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.gamesWon > 0, true);
// expect(osk.tlSeason1.standing, -1);
@ -102,7 +102,7 @@
// expect(kagari.tlSeason1.glicko, null);
// expect(kagari.tlSeason1.rank, "z");
// expect(kagari.tlSeason1.percentileRank, "z");
// expect(kagari.tlSeason1.rating, -1);
// expect(kagari.tlSeason1.tr, -1);
// expect(kagari.tlSeason1.decaying, false);
// expect(kagari.tlSeason1.gamesPlayed, 0);
// expect(kagari.tlSeason1.gamesWon, 0);
@ -133,7 +133,7 @@
// expect(furry.tlSeason1.glicko, null);
// expect(furry.tlSeason1.rank, "z");
// expect(furry.tlSeason1.percentileRank, "z");
// expect(furry.tlSeason1.rating, -1);
// expect(furry.tlSeason1.tr, -1);
// expect(furry.tlSeason1.decaying, false);
// expect(furry.tlSeason1.gamesPlayed, 0);
// expect(furry.tlSeason1.gamesWon, 0);
@ -163,7 +163,7 @@
// expect(oskwarefan.tlSeason1.glicko, null);
// expect(oskwarefan.tlSeason1.rank, "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.gamesPlayed, 0);
// expect(oskwarefan.tlSeason1.gamesWon, 0);