diff --git a/lib/data_objects/tetrio.dart b/lib/data_objects/tetrio.dart index 093601c..1683e1b 100644 --- a/lib/data_objects/tetrio.dart +++ b/lib/data_objects/tetrio.dart @@ -21,6 +21,7 @@ const List ranks = [ "d", "d+", "c-", "c", "c+", "b-", "b", "b+", "a-", "a", "a+", "s-", "s", "s+", "ss", "u", "x" ]; const Map 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 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 json, ts) { + TetraLeague.fromJson(Map 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 toJson() { final Map data = {}; 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> 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 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: diff --git a/lib/services/tetrio_crud.dart b/lib/services/tetrio_crud.dart index 23b0732..3a39315 100644 --- a/lib/services/tetrio_crud.dart +++ b/lib/services/tetrio_crud.dart @@ -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]]!, diff --git a/lib/views/compare_view.dart b/lib/views/compare_view.dart index 2916a0e..abc0a81 100644 --- a/lib/views/compare_view.dart +++ b/lib/views/compare_view.dart @@ -17,7 +17,7 @@ enum Mode{ averages } Mode greenSideMode = Mode.player; -List theGreenSide = [null, null, null]; // TetrioPlayer?, List>?, TetraLeagueAlpha? +List theGreenSide = [null, null, null]; // TetrioPlayer?, List>?, TetraLeague? Mode redSideMode = Mode.player; List theRedSide = [null, null, null]; final DateFormat dateFormat = DateFormat.yMd(LocaleSettings.currentLocale.languageCode).add_Hm(); @@ -82,7 +82,7 @@ class CompareState extends State { 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 { 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 { 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 { 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 { 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, ), diff --git a/lib/views/main_view.dart b/lib/views/main_view.dart index cb22558..3fa3e66 100644 --- a/lib/views/main_view.dart +++ b/lib/views/main_view.dart @@ -64,7 +64,7 @@ class _MainState extends State with TickerProviderStateMixin { Future 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 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 with TickerProviderStateMixin { // Making list of Tetra League matches bool isTracking = await teto.isPlayerTracking(me.userId); List states = []; - TetraLeagueAlpha? compareWith; - Set uniqueTL = {}; + TetraLeague? compareWith; + Set uniqueTL = {}; List 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 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 with TickerProviderStateMixin { if (uniqueTL.length >= 2){ compareWith = uniqueTL.toList().elementAtOrNull(uniqueTL.length - 2); chartsData = >>[ // 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'), " "))), diff --git a/lib/views/main_view_tiles.dart b/lib/views/main_view_tiles.dart index 3e32811..4e04035 100644 --- a/lib/views/main_view_tiles.dart +++ b/lib/views/main_view_tiles.dart @@ -285,7 +285,7 @@ class _DestinationGraphsState extends State { Future>>> getChartsData(bool fetchHistory) async { List states = []; - Set uniqueTL = {}; + Set uniqueTL = {}; if(fetchHistory){ try{ @@ -310,7 +310,7 @@ class _DestinationGraphsState extends State { if (uniqueTL.length >= 2){ chartsData = >>[ // 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 { ); } - Widget getTetraLeagueCard(TetraLeagueAlpha data){ + Widget getTetraLeagueCard(TetraLeague data){ return Column( children: [ Card( @@ -2287,7 +2287,7 @@ class _SearchDrawerState extends State { } class TetraLeagueThingy extends StatelessWidget{ - final TetraLeagueAlpha league; + final TetraLeague league; const TetraLeagueThingy({super.key, required this.league}); diff --git a/lib/views/rank_averages_view.dart b/lib/views/rank_averages_view.dart index b55fae0..4ff0446 100644 --- a/lib/views/rank_averages_view.dart +++ b/lib/views/rank_averages_view.dart @@ -360,7 +360,7 @@ class RankState extends State 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 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), diff --git a/lib/views/state_view.dart b/lib/views/state_view.dart index 5e367d2..19b190e 100644 --- a/lib/views/state_view.dart +++ b/lib/views/state_view.dart @@ -58,6 +58,6 @@ class StateState extends State { 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 [])))); } } diff --git a/lib/views/tl_leaderboard_view.dart b/lib/views/tl_leaderboard_view.dart index 8b16a28..b3c181d 100644 --- a/lib/views/tl_leaderboard_view.dart +++ b/lib/views/tl_leaderboard_view.dart @@ -74,7 +74,7 @@ class TLLeaderboardState extends State { 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 { 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), ], ), diff --git a/lib/views/tl_match_view.dart b/lib/views/tl_match_view.dart index 18f3d2a..fc4b50d 100644 --- a/lib/views/tl_match_view.dart +++ b/lib/views/tl_match_view.dart @@ -382,8 +382,8 @@ class TlMatchResultState extends State { ), 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, diff --git a/lib/widgets/tl_progress_bar.dart b/lib/widgets/tl_progress_bar.dart index 59fddcf..b59b181 100644 --- a/lib/widgets/tl_progress_bar.dart +++ b/lib/widgets/tl_progress_bar.dart @@ -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, diff --git a/lib/widgets/tl_rating_thingy.dart b/lib/widgets/tl_rating_thingy.dart index a0702f6..3fc69be 100644 --- a/lib/widgets/tl_rating_thingy.dart +++ b/lib/widgets/tl_rating_thingy.dart @@ -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 formatedTR = f4.format(tlData.rating).split(decimalSeparator); + List formatedTR = f4.format(tlData.tr).split(decimalSeparator); List formatedGlicko = tlData.glicko != null ? f4.format(tlData.glicko).split(decimalSeparator) : ["---","--"]; List 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)) diff --git a/lib/widgets/tl_thingy.dart b/lib/widgets/tl_thingy.dart index 4cf6f95..0731e10 100644 --- a/lib/widgets/tl_thingy.dart +++ b/lib/widgets/tl_thingy.dart @@ -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 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 createState() => _TLThingyState(); @@ -45,13 +44,10 @@ class TLThingy extends StatefulWidget { class _TLThingyState extends State with TickerProviderStateMixin { late bool oskKagariGimmick; - late TetraLeagueAlpha? oldTl; - late TetraLeagueAlpha currentTl; + late TetraLeague? oldTl; + late TetraLeague currentTl; late RangeValues _currentRangeValues; late List 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 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 with TickerProviderStateMixin { String decimalSeparator = f2.symbols.DECIMAL_SEP; List estTRformated = currentTl.estTr != null ? f2.format(currentTl.estTr!.esttr).split(decimalSeparator) : []; List 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; diff --git a/pubspec.yaml b/pubspec.yaml index 260bb80..f8a3f3e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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' diff --git a/res/tetrio_tl_alpha_ranks/x+.png b/res/tetrio_tl_alpha_ranks/x+.png new file mode 100644 index 0000000..f23e262 Binary files /dev/null and b/res/tetrio_tl_alpha_ranks/x+.png differ diff --git a/test/api_test.dart b/test/api_test.dart index 4f4f8d6..b05b70a 100644 --- a/test/api_test.dart +++ b/test/api_test.dart @@ -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);