diff --git a/lib/data_objects/tetrio_constants.dart b/lib/data_objects/tetrio_constants.dart index 2c3b217..3d9d127 100644 --- a/lib/data_objects/tetrio_constants.dart +++ b/lib/data_objects/tetrio_constants.dart @@ -132,7 +132,7 @@ const Map chartsShortTitles = { Stats.area: "Area", Stats.eTR: "eTR", Stats.acceTR: "±eTR", - Stats.acceTRabs: "+eTR absolute", + Stats.acceTRabs: "±eTR absolute", Stats.opener: "Opener", Stats.plonk: "Plonk", Stats.infDS: "Inf. DS", diff --git a/lib/data_objects/tetrio_players_leaderboard.dart b/lib/data_objects/tetrio_players_leaderboard.dart index 91e3336..75a8f6f 100644 --- a/lib/data_objects/tetrio_players_leaderboard.dart +++ b/lib/data_objects/tetrio_players_leaderboard.dart @@ -57,35 +57,14 @@ class TetrioPlayersLeaderboard { return lb; } - List getAverageOfRank(String rank){ // i tried to refactor it and that's was terrible + List getRankData(String rank){ if (rank.isNotEmpty && !rankCutoffs.keys.contains(rank)) throw Exception("Invalid rank"); List filtredLeaderboard = List.from(leaderboard); if (rank.isNotEmpty) { filtredLeaderboard.removeWhere((element) => element.rank != rank); } if (filtredLeaderboard.isNotEmpty){ - double avgAPM = 0, - avgPPS = 0, - avgVS = 0, - avgTR = 0, - avgGlixare = 0, - avgGlicko = 0, - avgRD = 0, - avgAPP = 0, - avgVSAPM = 0, - avgDSS = 0, - avgDSP = 0, - avgAPPDSP = 0, - avgCheese = 0, - avgGBE = 0, - avgNyaAPP = 0, - avgArea = 0, - avgEstTR = 0, - avgEstAcc = 0, - avgOpener = 0, - avgPlonk = 0, - avgStride = 0, - avgInfDS = 0, + double lowestTR = 25000, lowestGlixare = double.infinity, lowestGlicko = double.infinity, @@ -131,7 +110,11 @@ class TetrioPlayersLeaderboard { highestOpener = double.negativeInfinity, highestPlonk = double.negativeInfinity, highestStride = double.negativeInfinity, - highestInfDS = double.negativeInfinity; + highestInfDS = double.negativeInfinity, + avgTR = 0, + avgGlixare = 0, + avgGlicko = 0, + avgRD = 0; int avgGamesPlayed = 0, avgGamesWon = 0, totalGamesPlayed = 0, @@ -191,28 +174,10 @@ class TetrioPlayersLeaderboard { highestStrideID = "", highestStrideNick = "", highestInfDSid = "", highestInfDSnick = ""; for (var entry in filtredLeaderboard){ - avgAPM += entry.apm; - avgPPS += entry.pps; - avgVS += entry.vs; avgTR += entry.tr; avgGlixare += entry.gxe; if (entry.glicko != null) avgGlicko += entry.glicko!; if (entry.rd != null) avgRD += entry.rd!; - avgAPP += entry.nerdStats.app; - avgVSAPM += entry.nerdStats.vsapm; - avgDSS += entry.nerdStats.dss; - avgDSP += entry.nerdStats.dsp; - avgAPPDSP += entry.nerdStats.appdsp; - avgCheese += entry.nerdStats.cheese; - avgGBE += entry.nerdStats.gbe; - avgNyaAPP += entry.nerdStats.nyaapp; - avgArea += entry.nerdStats.area; - avgEstTR += entry.estTr.esttr; - avgEstAcc += entry.esttracc; - avgOpener += entry.playstyle.opener; - avgPlonk += entry.playstyle.plonk; - avgStride += entry.playstyle.stride; - avgInfDS += entry.playstyle.infds; totalGamesPlayed += entry.gamesPlayed; totalGamesWon += entry.gamesWon; if (entry.tr < lowestTR){ @@ -466,33 +431,14 @@ class TetrioPlayersLeaderboard { highestInfDSnick = entry.username; } } - avgAPM /= filtredLeaderboard.length; - avgPPS /= filtredLeaderboard.length; - avgVS /= filtredLeaderboard.length; avgTR /= filtredLeaderboard.length; avgGlixare /= filtredLeaderboard.length; avgGlicko /= filtredLeaderboard.length; avgRD /= filtredLeaderboard.length; - avgAPP /= filtredLeaderboard.length; - avgVSAPM /= filtredLeaderboard.length; - avgDSS /= filtredLeaderboard.length; - avgDSP /= filtredLeaderboard.length; - avgAPPDSP /= leaderboard.length; - avgCheese /= filtredLeaderboard.length; - avgGBE /= filtredLeaderboard.length; - avgNyaAPP /= filtredLeaderboard.length; - avgArea /= filtredLeaderboard.length; - avgEstTR /= filtredLeaderboard.length; - avgEstAcc /= filtredLeaderboard.length; - avgOpener /= filtredLeaderboard.length; - avgPlonk /= filtredLeaderboard.length; - avgStride /= filtredLeaderboard.length; - avgInfDS /= filtredLeaderboard.length; avgGamesPlayed = (totalGamesPlayed / filtredLeaderboard.length).floor(); avgGamesWon = (totalGamesWon / filtredLeaderboard.length).floor(); - return [TetraLeague(id: "", timestamp: DateTime.now(), apm: avgAPM, pps: avgPPS, vs: avgVS, gxe: avgGlixare, glicko: avgGlicko, rd: avgRD, gamesPlayed: avgGamesPlayed, gamesWon: avgGamesWon, bestRank: rank, decaying: false, tr: avgTR, rank: rank == "" ? "z" : rank, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1, season: currentSeason), + return [TetraLeague(id: "", timestamp: DateTime.now(), apm: null, pps: null, vs: null, gxe: avgGlixare, glicko: avgGlicko, rd: avgRD, gamesPlayed: avgGamesPlayed, gamesWon: avgGamesWon, bestRank: rank, decaying: false, tr: avgTR, rank: rank == "" ? "z" : rank, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1, season: currentSeason), { - "everyone": rank == "", "totalGamesPlayed": totalGamesPlayed, "totalGamesWon": totalGamesWon, "players": filtredLeaderboard.length, @@ -652,24 +598,7 @@ class TetrioPlayersLeaderboard { "highestInfDS": highestInfDS, "highestInfDSid": highestInfDSid, "highestInfDSnick": highestInfDSnick, - "avgAPP": avgAPP, - "avgVSAPM": avgVSAPM, - "avgDSS": avgDSS, - "avgDSP": avgDSP, - "avgAPPDSP": avgAPPDSP, - "avgCheese": avgCheese, - "avgGBE": avgGBE, - "avgNyaAPP": avgNyaAPP, - "avgArea": avgArea, - "avgEstTR": avgEstTR, - "avgEstAcc": avgEstAcc, - "avgOpener": avgOpener, - "avgPlonk": avgPlonk, - "avgStride": avgStride, - "avgInfDS": avgInfDS, - "toEnterTR": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].tr : lowestTR, "toEnterGlicko": rank.toLowerCase() != "z" ? leaderboard[(leaderboard.length * rankCutoffs[rank]!).floor()-1].glicko : 0, - "entries": filtredLeaderboard }]; }else{ return [TetraLeague(id: "", 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, season: currentSeason), @@ -702,65 +631,45 @@ class TetrioPlayersLeaderboard { } Map> get averages => { - 'x+': getAverageOfRank("x+"), - 'x': getAverageOfRank("x"), - 'u': getAverageOfRank("u"), - 'ss': getAverageOfRank("ss"), - 's+': getAverageOfRank("s+"), - 's': getAverageOfRank("s"), - 's-': getAverageOfRank("s-"), - 'a+': getAverageOfRank("a+"), - 'a': getAverageOfRank("a"), - 'a-': getAverageOfRank("a-"), - 'b+': getAverageOfRank("b+"), - 'b': getAverageOfRank("b"), - 'b-': getAverageOfRank("b-"), - 'c+': getAverageOfRank("c+"), - 'c': getAverageOfRank("c"), - 'c-': getAverageOfRank("c-"), - 'd+': getAverageOfRank("d+"), - 'd': getAverageOfRank("d"), - 'z': getAverageOfRank("z") - }; - - Map get cutoffs => { - 'x': getAverageOfRank("x")[1]["toEnterTR"], - 'u': getAverageOfRank("u")[1]["toEnterTR"], - 'ss': getAverageOfRank("ss")[1]["toEnterTR"], - 's+': getAverageOfRank("s+")[1]["toEnterTR"], - 's': getAverageOfRank("s")[1]["toEnterTR"], - 's-': getAverageOfRank("s-")[1]["toEnterTR"], - 'a+': getAverageOfRank("a+")[1]["toEnterTR"], - 'a': getAverageOfRank("a")[1]["toEnterTR"], - 'a-': getAverageOfRank("a-")[1]["toEnterTR"], - 'b+': getAverageOfRank("b+")[1]["toEnterTR"], - 'b': getAverageOfRank("b")[1]["toEnterTR"], - 'b-': getAverageOfRank("b-")[1]["toEnterTR"], - 'c+': getAverageOfRank("c+")[1]["toEnterTR"], - 'c': getAverageOfRank("c")[1]["toEnterTR"], - 'c-': getAverageOfRank("c-")[1]["toEnterTR"], - 'd+': getAverageOfRank("d+")[1]["toEnterTR"], - 'd': getAverageOfRank("d")[1]["toEnterTR"] + 'x+': getRankData("x+"), + 'x': getRankData("x"), + 'u': getRankData("u"), + 'ss': getRankData("ss"), + 's+': getRankData("s+"), + 's': getRankData("s"), + 's-': getRankData("s-"), + 'a+': getRankData("a+"), + 'a': getRankData("a"), + 'a-': getRankData("a-"), + 'b+': getRankData("b+"), + 'b': getRankData("b"), + 'b-': getRankData("b-"), + 'c+': getRankData("c+"), + 'c': getRankData("c"), + 'c-': getRankData("c-"), + 'd+': getRankData("d+"), + 'd': getRankData("d"), + 'z': getRankData("z") }; Map get cutoffsGlicko => { - 'x': getAverageOfRank("x")[1]["toEnterGlicko"], - 'u': getAverageOfRank("u")[1]["toEnterGlicko"], - 'ss': getAverageOfRank("ss")[1]["toEnterGlicko"], - 's+': getAverageOfRank("s+")[1]["toEnterGlicko"], - 's': getAverageOfRank("s")[1]["toEnterGlicko"], - 's-': getAverageOfRank("s-")[1]["toEnterGlicko"], - 'a+': getAverageOfRank("a+")[1]["toEnterGlicko"], - 'a': getAverageOfRank("a")[1]["toEnterGlicko"], - 'a-': getAverageOfRank("a-")[1]["toEnterGlicko"], - 'b+': getAverageOfRank("b+")[1]["toEnterGlicko"], - 'b': getAverageOfRank("b")[1]["toEnterGlicko"], - 'b-': getAverageOfRank("b-")[1]["toEnterGlicko"], - 'c+': getAverageOfRank("c+")[1]["toEnterGlicko"], - 'c': getAverageOfRank("c")[1]["toEnterGlicko"], - 'c-': getAverageOfRank("c-")[1]["toEnterGlicko"], - 'd+': getAverageOfRank("d+")[1]["toEnterGlicko"], - 'd': getAverageOfRank("d")[1]["toEnterGlicko"] + 'x': getRankData("x")[1]["toEnterGlicko"], + 'u': getRankData("u")[1]["toEnterGlicko"], + 'ss': getRankData("ss")[1]["toEnterGlicko"], + 's+': getRankData("s+")[1]["toEnterGlicko"], + 's': getRankData("s")[1]["toEnterGlicko"], + 's-': getRankData("s-")[1]["toEnterGlicko"], + 'a+': getRankData("a+")[1]["toEnterGlicko"], + 'a': getRankData("a")[1]["toEnterGlicko"], + 'a-': getRankData("a-")[1]["toEnterGlicko"], + 'b+': getRankData("b+")[1]["toEnterGlicko"], + 'b': getRankData("b")[1]["toEnterGlicko"], + 'b-': getRankData("b-")[1]["toEnterGlicko"], + 'c+': getRankData("c+")[1]["toEnterGlicko"], + 'c': getRankData("c")[1]["toEnterGlicko"], + 'c-': getRankData("c-")[1]["toEnterGlicko"], + 'd+': getRankData("d+")[1]["toEnterGlicko"], + 'd': getRankData("d")[1]["toEnterGlicko"] }; TetrioPlayersLeaderboard.fromJson(List json, String t, DateTime ts) { diff --git a/lib/views/compare_view.dart b/lib/views/compare_view.dart index 208f9b4..8e78493 100644 --- a/lib/views/compare_view.dart +++ b/lib/views/compare_view.dart @@ -68,10 +68,10 @@ class CompareState extends State { try { if (user.startsWith("\$avg")){ try{ - var average = (await teto.fetchTLLeaderboard()).getAverageOfRank(user.substring(4).toLowerCase())[0]; - Summaries summary = Summaries("avg${user.substring(4).toLowerCase()}", average, TetrioZen(level: 0, score: 0)); + //var average = (await teto.fetchTLLeaderboard()).getAverageOfRank(user.substring(4).toLowerCase())[0]; + //Summaries summary = Summaries("avg${user.substring(4).toLowerCase()}", average, TetrioZen(level: 0, score: 0)); redSideMode = Mode.averages; - theRedSide = [null, null, summary]; + //theRedSide = [null, null, summary]; return setState(() {}); }on Exception { if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.compareViewWrongValue(value: user)))); @@ -147,10 +147,10 @@ class CompareState extends State { try { if (user.startsWith("\$avg")){ try{ - var average = (await teto.fetchTLLeaderboard()).getAverageOfRank(user.substring(4).toLowerCase())[0]; - Summaries summary = Summaries("avg${user.substring(4).toLowerCase()}", average, TetrioZen(level: 0, score: 0)); + //var average = (await teto.fetchTLLeaderboard()).getAverageOfRank(user.substring(4).toLowerCase())[0]; + //Summaries summary = Summaries("avg${user.substring(4).toLowerCase()}", average, TetrioZen(level: 0, score: 0)); greenSideMode = Mode.averages; - theGreenSide = [null, null, summary]; + //theGreenSide = [null, null, summary]; return setState(() {}); }on Exception { if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Falied to assign $user"))); diff --git a/lib/views/destination_cutoffs.dart b/lib/views/destination_cutoffs.dart index 5e4ad0a..df3c550 100644 --- a/lib/views/destination_cutoffs.dart +++ b/lib/views/destination_cutoffs.dart @@ -211,7 +211,12 @@ class _DestinationCutoffsState extends State { ), Padding( padding: const EdgeInsets.only(right: 8.0), - child: Text("More info", textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white)), + child: TextButton(child: Text("More Info", textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white)), onPressed: () { + Navigator.push(context, MaterialPageRoute( + builder: (context) => RankView(rank: "", nextRankTR: snapshot.data!.data["top1"]!.tr, nextRankPercentile: 0.00, nextRankTargetTR: 25000.00, totalPlayers: snapshot.data!.total, cutoffTetrio: CutoffTetrio(apm: 0, pps: 0, vs: 0, pos: 0, percentile: 0, count: snapshot.data!.total, countPercentile: 1, tr: 10000.00, targetTr: 10000.00)), + ), + ); + },), ), ] ), diff --git a/lib/views/destination_graphs.dart b/lib/views/destination_graphs.dart index b7b32d6..64221d6 100644 --- a/lib/views/destination_graphs.dart +++ b/lib/views/destination_graphs.dart @@ -166,6 +166,8 @@ class _DestinationGraphsState extends State { } fetchData = false; + historyPlayerUsername.value = await teto.getNicknameByID(widget.searchFor); + return historyData; } diff --git a/lib/views/destination_leaderboards.dart b/lib/views/destination_leaderboards.dart index 4fad288..8862e69 100644 --- a/lib/views/destination_leaderboards.dart +++ b/lib/views/destination_leaderboards.dart @@ -1,11 +1,14 @@ import 'dart:async'; +import 'dart:math'; import 'package:flutter/material.dart'; import 'package:tetra_stats/data_objects/tetrio_constants.dart'; +import 'package:tetra_stats/data_objects/tetrio_player_from_leaderboard.dart'; import 'package:tetra_stats/gen/strings.g.dart'; import 'package:tetra_stats/main.dart'; import 'package:tetra_stats/utils/numers_formats.dart'; import 'package:tetra_stats/utils/relative_timestamps.dart'; import 'package:tetra_stats/views/main_view_tiles.dart'; +import 'package:tetra_stats/views/tl_leaderboard_view.dart'; import 'package:tetra_stats/views/user_view.dart'; class DestinationLeaderboards extends StatefulWidget{ @@ -46,12 +49,20 @@ class _DestinationLeaderboardsState extends State { Stream> get dataStream => _dataStreamController.stream; List list = []; bool _isFetchingData = false; + List _excludeRanks = []; + bool _reverse = false; String? prisecter; List _countries = [for (MapEntry e in t.countries.entries) DropdownMenuEntry(value: e.key, label: e.value)]; List _stats = [for (MapEntry e in chartsShortTitles.entries) DropdownMenuEntry(value: e.key, label: e.value)]; String? _country; Stats stat = Stats.tr; + bool? getTotalFilterValue(){ + if (_excludeRanks.isEmpty) return true; + if (_excludeRanks.length == ranks.length) return false; + return null; + } + Future _fetchData() async { if (_isFetchingData) { // Avoid fetching new data while already fetching @@ -72,7 +83,9 @@ class _DestinationLeaderboardsState extends State { Leaderboards.zenithex => await teto.fetchTetrioRecordsLeaderboard(prisecter: prisecter, lb: "zenithex_global", country: _country), }; - list.addAll(items); + if (_currentLb == Leaderboards.fullTL && _excludeRanks.isNotEmpty) items.removeWhere((e) => _excludeRanks.indexOf((e as TetrioPlayerFromLeaderboard).rank) != -1); + + list.addAll((_reverse && _currentLb == Leaderboards.fullTL) ? items.reversed : items); _dataStreamController.add(list); prisecter = list.last.prisecter.toString(); @@ -129,10 +142,10 @@ class _DestinationLeaderboardsState extends State { itemCount: leaderboards.length, itemBuilder: (BuildContext context, int index) { return Card( - surfaceTintColor: index == 1 ? Colors.redAccent : theme.colorScheme.primary, child: ListTile( title: Text(leaderboards.values.elementAt(index)), - subtitle: index == 1 ? Text("Heavy, but allows you to sort players by their stats", style: TextStyle(color: Colors.grey, fontSize: 12)) : null, + trailing: Icon(Icons.arrow_right, color: _currentLb.index == index ? Colors.white : Colors.grey), + subtitle: index == 1 ? Text("Heavy, but allows you to sort players by their stats and filter them by ranks", style: TextStyle(color: Colors.grey, fontSize: 12)) : null, onTap: () { _currentLb = leaderboards.keys.elementAt(index); list.clear(); @@ -198,6 +211,71 @@ class _DestinationLeaderboardsState extends State { _isFetchingData = false; setState((){_fetchData();}); }) + ), + if (_currentLb == Leaderboards.fullTL) IconButton( + color: _excludeRanks.isNotEmpty ? Theme.of(context).colorScheme.primary : null, + onPressed: (){ + showDialog(context: context, builder: (BuildContext context) { + return StatefulBuilder( + builder: (context, StateSetter setAlertState) { + return AlertDialog( + title: Text("Filter", textAlign: TextAlign.center), + content: SingleChildScrollView( + child: Column( + children: [ + CheckboxListTile(value: getTotalFilterValue(), tristate: true, title: Text("All", style: TextStyle(fontFamily: "Eurostile Round Extended")), onChanged: (value){ + setAlertState( + (){ + if (_excludeRanks.length*2 > ranks.length){ + _excludeRanks.clear(); + }else{ + _excludeRanks = List.of(ranks); + } + } + ); + }), + for(String rank in ranks.reversed) CheckboxListTile(value: _excludeRanks.indexOf(rank) == -1, onChanged: (value){ + setAlertState( + (){ + if (_excludeRanks.indexOf(rank) == -1){ + _excludeRanks.add(rank); + }else{ + _excludeRanks.remove(rank); + } + } + ); + }, title: Text(rank.toUpperCase()),) + ], + ), + ), + actions: [ + TextButton( + child: const Text("Apply"), + onPressed: () {Navigator.of(context).pop(); setState((){ + _currentLb = Leaderboards.fullTL; + list.clear(); + prisecter = null; + _fetchData();}); + } + ) + ] + ); + } + ); + }); + }, icon: Icon(Icons.filter_alt)), + if (_currentLb == Leaderboards.fullTL) IconButton( + color: _reverse ? Theme.of(context).colorScheme.primary : null, + icon: Container(transform: _reverse ? Matrix4.rotationX(pi) : null, child: Icon(Icons.filter_list)), + onPressed: (){ + setState((){ + _reverse = !_reverse; + _currentLb = Leaderboards.fullTL; + list.clear(); + prisecter = null; + _fetchData(); + }); + }, ) ], ), diff --git a/lib/views/rank_view.dart b/lib/views/rank_view.dart index e98c800..074b234 100644 --- a/lib/views/rank_view.dart +++ b/lib/views/rank_view.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:tetra_stats/data_objects/cutoff_tetrio.dart'; +import 'package:tetra_stats/main.dart'; import 'package:tetra_stats/utils/numers_formats.dart'; +import 'package:tetra_stats/views/main_view_tiles.dart'; class RankView extends StatefulWidget { final String rank; @@ -25,6 +27,11 @@ enum CardMod{ class _RankState extends State { CardMod cardMod = CardMod.graph; + Future getRanksAverages(String rank) async { + var lb = await teto.fetchTLLeaderboard(); + return lb.getRankData(rank); + } + @override Widget build(BuildContext context) { double percentileGap = widget.cutoffTetrio.percentile - widget.nextRankPercentile; @@ -228,36 +235,141 @@ class _RankState extends State { ) ], ), - ), + ) ), SizedBox( width: constraints.maxWidth - 350, - height: constraints.maxHeight, - child: Row( - children: [ - SizedBox( - width: 200.0, - child: Card( - child: Column( - children: [], - ), - ), - ), - Expanded( - child: Card( - child: Column( - children: [], - ), - ), - ), - Expanded( - child: Card( - child: Column( - children: [], - ), - ), - ) - ], + child: FutureBuilder>( + future: getRanksAverages(widget.rank), + builder: (context, snapshot) { + switch (snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const Center(child: CircularProgressIndicator()); + case ConnectionState.done: + if (snapshot.hasError){ return FutureError(snapshot); } + if (snapshot.hasData){ + return SingleChildScrollView( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 200.0, + child: Card( + child: Column( + children: [ + Text("Cheese Index", style: TextStyle(fontSize: 28, color: Colors.transparent)), + Divider(), + RankViewEntry("Tetra Rating", null, null), + RankViewEntry("Glicko", null, null, differentBG: true), + RankViewEntry("RD", null, null), + RankViewEntry("Glixare", null, null, differentBG: true), + RankViewEntry("S1 TR", null, null), + RankViewEntry("Games Played", null, null, differentBG: true), + RankViewEntry("Games Won", null, null), + RankViewEntry("Winrate", null, null, differentBG: true), + RankViewEntry("Attack Per Minute", null, null), + RankViewEntry("Pieces Per Second", null, null, differentBG: true), + RankViewEntry("Versus Score", null, null), + RankViewEntry("Attack Per Piece", null, null, differentBG: true), + RankViewEntry("VS / APM", null, null), + RankViewEntry("Downstack Per Second", null, null, differentBG: true), + RankViewEntry("Downstack Per Piece", null, null), + RankViewEntry("APP + DS/P", null, null, differentBG: true), + RankViewEntry("Cheese Index", null, null), + RankViewEntry("Garbage Efficiency", null, null, differentBG: true), + RankViewEntry("Weighted APP", null, null), + RankViewEntry("Area", null, null, differentBG: true), + RankViewEntry("Estimated TR", null, null), + RankViewEntry("Est. TR Accuracy", null, null, differentBG: true), + RankViewEntry("Opener", null, null), + RankViewEntry("Plonk", null, null, differentBG: true), + RankViewEntry("Stride", null, null), + RankViewEntry("Infinite Downstack", null, null, differentBG: true), + ], + ), + ), + ), + Expanded( + child: Card( + child: Column( + children: [ + Text("Minimums", style: TextStyle(fontSize: 28)), + Divider(), + RankViewEntry("${f4.format(snapshot.data![1]["lowestTR"])} TR", snapshot.data![1]["lowestTRnick"], snapshot.data![1]["lowestTRid"]), + RankViewEntry(f4.format(snapshot.data![1]["lowestGlicko"]), snapshot.data![1]["lowestGlickoNick"], snapshot.data![1]["lowestGlickoID"], differentBG: true), + RankViewEntry(f4.format(snapshot.data![1]["lowestRD"]), snapshot.data![1]["lowestRdNick"], snapshot.data![1]["lowestRdID"]), + RankViewEntry(f4.format(snapshot.data![1]["lowestGlixare"]), snapshot.data![1]["lowestGlixareNick"], snapshot.data![1]["lowestGlixareID"], differentBG: true), + RankViewEntry(f2.format(snapshot.data![1]["lowestS1tr"]), snapshot.data![1]["lowestS1trNick"], snapshot.data![1]["lowestS1trID"]), + RankViewEntry(intf.format(snapshot.data![1]["lowestGamesPlayed"]), snapshot.data![1]["lowestGamesPlayedNick"], snapshot.data![1]["lowestGamesPlayedID"], differentBG: true), + RankViewEntry(intf.format(snapshot.data![1]["lowestGamesWon"]), snapshot.data![1]["lowestGamesWonNick"], snapshot.data![1]["lowestGamesWonID"]), + RankViewEntry(percentage.format(snapshot.data![1]["lowestWinrate"]), snapshot.data![1]["lowestWinrateNick"], snapshot.data![1]["lowestWinrateID"], differentBG: true), + RankViewEntry("${f2.format(snapshot.data![1]["lowestAPM"])} APM", snapshot.data![1]["lowestAPMnick"], snapshot.data![1]["lowestAPMid"]), + RankViewEntry("${f2.format(snapshot.data![1]["lowestPPS"])} PPS", snapshot.data![1]["lowestPPSnick"], snapshot.data![1]["lowestPPSid"], differentBG: true), + RankViewEntry("${f2.format(snapshot.data![1]["lowestVS"])} VS", snapshot.data![1]["lowestVSnick"], snapshot.data![1]["lowestVSid"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestAPP"])} APP", snapshot.data![1]["lowestAPPnick"], snapshot.data![1]["lowestAPPid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["lowestVSAPM"])} VS/APM", snapshot.data![1]["lowestVSAPMnick"], snapshot.data![1]["lowestVSAPMid"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestDSS"])} DS/S", snapshot.data![1]["lowestDSSnick"], snapshot.data![1]["lowestDSSid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["lowestDSP"])} DS/P", snapshot.data![1]["lowestDSPnick"], snapshot.data![1]["lowestDSPid"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestAPPDSP"])} APP+DS/P", snapshot.data![1]["lowestAPPDSPnick"], snapshot.data![1]["lowestAPPDSPid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["lowestCheese"])} Cheese", snapshot.data![1]["lowestCheeseNick"], snapshot.data![1]["lowestCheeseID"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestGBE"])} Gbe", snapshot.data![1]["lowestGBEnick"], snapshot.data![1]["lowestGBEid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["lowestNyaAPP"])} wAPP", snapshot.data![1]["lowestNyaAPPnick"], snapshot.data![1]["lowestNyaAPPid"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestArea"])} Area", snapshot.data![1]["lowestAreaNick"], snapshot.data![1]["lowestAreaID"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["lowestEstTR"])} eTR", snapshot.data![1]["lowestEstTRnick"], snapshot.data![1]["lowestEstTRid"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestEstAcc"])} ±eTR", snapshot.data![1]["lowestEstAccNick"], snapshot.data![1]["lowestEstAccID"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["lowestOpener"])}", snapshot.data![1]["lowestOpenerNick"], snapshot.data![1]["lowestOpenerID"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestPlonk"])}", snapshot.data![1]["lowestPlonkNick"], snapshot.data![1]["lowestPlonkID"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["lowestStride"])}", snapshot.data![1]["lowestStrideNick"], snapshot.data![1]["lowestStrideID"]), + RankViewEntry("${f4.format(snapshot.data![1]["lowestInfDS"])}", snapshot.data![1]["lowestInfDSnick"], snapshot.data![1]["lowestInfDSid"], differentBG: true) + ], + ), + ), + ), + Expanded( + child: Card( + child: Column( + children: [ + Text("Maximums", style: TextStyle(fontSize: 28)), + Divider(), + RankViewEntry("${f4.format(snapshot.data![1]["highestTR"])} TR", snapshot.data![1]["highestTRnick"], snapshot.data![1]["highestTRid"]), + RankViewEntry(f4.format(snapshot.data![1]["highestGlicko"]), snapshot.data![1]["highestGlickoNick"], snapshot.data![1]["highestGlickoID"], differentBG: true), + RankViewEntry(f4.format(snapshot.data![1]["highestRD"]), snapshot.data![1]["highestRdNick"], snapshot.data![1]["highestRdID"]), + RankViewEntry(f4.format(snapshot.data![1]["highestGlixare"]), snapshot.data![1]["highestGlixareNick"], snapshot.data![1]["highestGlixareID"], differentBG: true), + RankViewEntry(f2.format(snapshot.data![1]["highestS1tr"]), snapshot.data![1]["highestS1trNick"], snapshot.data![1]["highestS1trID"]), + RankViewEntry(intf.format(snapshot.data![1]["highestGamesPlayed"]), snapshot.data![1]["highestGamesPlayedNick"], snapshot.data![1]["highestGamesPlayedID"], differentBG: true), + RankViewEntry(intf.format(snapshot.data![1]["highestGamesWon"]), snapshot.data![1]["highestGamesWonNick"], snapshot.data![1]["highestGamesWonID"]), + RankViewEntry(percentage.format(snapshot.data![1]["highestWinrate"]), snapshot.data![1]["highestWinrateNick"], snapshot.data![1]["highestWinrateID"], differentBG: true), + RankViewEntry("${f2.format(snapshot.data![1]["highestAPM"])} APM", snapshot.data![1]["highestAPMnick"], snapshot.data![1]["highestAPMid"]), + RankViewEntry("${f2.format(snapshot.data![1]["highestPPS"])} PPS", snapshot.data![1]["highestPPSnick"], snapshot.data![1]["highestPPSid"], differentBG: true), + RankViewEntry("${f2.format(snapshot.data![1]["highestVS"])} VS", snapshot.data![1]["highestVSnick"], snapshot.data![1]["highestVSid"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestAPP"])} APP", snapshot.data![1]["highestAPPnick"], snapshot.data![1]["highestAPPid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["highestVSAPM"])} VS/APM", snapshot.data![1]["highestVSAPMnick"], snapshot.data![1]["highestVSAPMid"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestDSS"])} DS/S", snapshot.data![1]["highestDSSnick"], snapshot.data![1]["highestDSSid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["highestDSP"])} DS/P", snapshot.data![1]["highestDSPnick"], snapshot.data![1]["highestDSPid"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestAPPDSP"])} APP+DS/P", snapshot.data![1]["highestAPPDSPnick"], snapshot.data![1]["highestAPPDSPid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["highestCheese"])} Cheese", snapshot.data![1]["highestCheeseNick"], snapshot.data![1]["highestCheeseID"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestGBE"])} Gbe", snapshot.data![1]["highestGBEnick"], snapshot.data![1]["highestGBEid"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["highestNyaAPP"])} wAPP", snapshot.data![1]["highestNyaAPPnick"], snapshot.data![1]["highestNyaAPPid"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestArea"])} Area", snapshot.data![1]["highestAreaNick"], snapshot.data![1]["highestAreaID"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["highestEstTR"])} eTR", snapshot.data![1]["highestEstTRnick"], snapshot.data![1]["highestEstTRid"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestEstAcc"])} ±eTR", snapshot.data![1]["highestEstAccNick"], snapshot.data![1]["highestEstAccID"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["highestOpener"])}", snapshot.data![1]["highestOpenerNick"], snapshot.data![1]["highestOpenerID"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestPlonk"])}", snapshot.data![1]["highestPlonkNick"], snapshot.data![1]["highestPlonkID"], differentBG: true), + RankViewEntry("${f4.format(snapshot.data![1]["highestStride"])}", snapshot.data![1]["highestStrideNick"], snapshot.data![1]["highestStrideID"]), + RankViewEntry("${f4.format(snapshot.data![1]["highestInfDS"])}", snapshot.data![1]["highestInfDSnick"], snapshot.data![1]["highestInfDSid"], differentBG: true) + ], + ), + ), + ) + ], + ), + ); + } + } + return const Text("End of FutureBuilder"); + } ), ) ], @@ -266,4 +378,35 @@ class _RankState extends State { ), ); } +} + +class RankViewEntry extends StatelessWidget { + final String formattedValue; + final String? username; + final String? userId; + final bool differentBG; + + const RankViewEntry(this.formattedValue, this.username, this.userId, {this.differentBG = false}); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration(color: differentBG ? Colors.black26 : null), + child: Center( + child: Padding( + padding: username != null ? EdgeInsets.only(bottom: 4.0) : EdgeInsets.all(0), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: formattedValue, + style: Theme.of(context).textTheme.displayLarge, + children: [ + TextSpan(text: username != null ? "\n(${username!.toUpperCase()})" : "\n", style: Theme.of(context).textTheme.displayLarge!.copyWith(color: Colors.grey, fontSize: 14)) + ] + )), + ), + ), + ); + } + } \ No newline at end of file diff --git a/lib/views/tl_leaderboard_view.dart b/lib/views/tl_leaderboard_view.dart index 47945e9..3c6f41d 100644 --- a/lib/views/tl_leaderboard_view.dart +++ b/lib/views/tl_leaderboard_view.dart @@ -95,7 +95,7 @@ class TLLeaderboardState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => RankView(rank: snapshot.data!.getAverageOfRank("")), + builder: (context) => RankView(rank: snapshot.data!.getRankData("")), ), ); }, child: Text(t.everyoneAverages,