i18n for rank averages view

This commit is contained in:
dan63047 2023-08-21 00:57:01 +03:00
parent a996a0b356
commit 1ef2d7af4a
8 changed files with 235 additions and 111 deletions

View File

@ -32,7 +32,8 @@ const Map<String, double> rankCutoffs = {
"c-": 0.95,
"d+": 0.975,
"d": 1,
"z": -1
"z": -1,
"": 0.5
};
const Map<String, Color> rankColors = { // thanks osk for const rankColors at https://ch.tetr.io/res/js/base.js:418
'x': Color(0xFFFF45FF),
@ -921,8 +922,6 @@ class TetrioPlayersLeaderboard {
List<TetrioPlayerFromLeaderboard> filtredLeaderboard = List.from(leaderboard);
if (rank.isNotEmpty) {
filtredLeaderboard.removeWhere((element) => element.rank != rank);
} else {
rank = "z";
}
if (filtredLeaderboard.isNotEmpty){
double avgAPM = 0,
@ -1334,7 +1333,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, percentileRank: rank, percentile: rankCutoffs[rank]!, standing: -1, standingLocal: -1, nextAt: -1, prevAt: -1),
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),
{
"everyone": rank == "",
"totalGamesPlayed": totalGamesPlayed,

View File

@ -4,9 +4,9 @@
/// To regenerate, run: `dart run slang`
///
/// Locales: 2
/// Strings: 856 (428 per locale)
/// Strings: 896 (448 per locale)
///
/// Built on 2023-07-20 at 16:26 UTC
/// Built on 2023-08-20 at 21:53 UTC
// coverage:ignore-file
// ignore_for_file: type=lint
@ -252,7 +252,26 @@ class _StringsEn implements BaseTranslations<AppLocale, _StringsEn> {
String get averages => 'Averages';
String get lbViewZeroEntrys => 'Empty list. Looks like something is wrong...';
String get lbViewOneEntry => 'There is only one player... What?';
String lbViewManyEntrys({required Object numberOfPlayers}) => 'There are ${numberOfPlayers} ranked players.';
String lbViewManyEntrys({required Object numberOfPlayers}) => 'There are ${numberOfPlayers}.';
String get everyoneAverages => 'Values for leaderboard';
String rankAverages({required Object rank}) => 'Values for ${rank} rank';
String players({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
zero: '${n} players',
one: '${n} player',
two: '${n} players',
few: '${n} players',
many: '${n} players',
other: '${n} players',
);
String get chart => 'Chart';
String get entries => 'Entries';
String get minimums => 'Minimums';
String get maximums => 'Maximums';
String get lowestValues => 'Lowest Values';
String get averageValues => 'Average Values';
String get highestValues => 'Highest Values';
String forPlayer({required Object username}) => 'for player ${username}';
String currentAxis({required Object axis}) => '${axis} axis:';
String get p1nkl0bst3rAlert => 'That data was retrived from third party API maintained by p1nkl0bst3r';
String get notForWeb => 'Function is not available for web version';
late final _StringsStatCellNumEn statCellNum = _StringsStatCellNumEn._(_root);
@ -544,6 +563,8 @@ class _StringsStatCellNumEn {
String get hoursPlayed => 'Hours\nPlayed';
String get onlineGames => 'Online\nGames';
String get gamesWon => 'Games\nWon';
String get totalGames => 'Total Games Played';
String get totalWon => 'Total Games Won';
String get friends => 'Friends';
String get apm => 'Attack\nPer Minute';
String get vs => 'Versus\nScore';
@ -566,6 +587,7 @@ class _StringsStatCellNumEn {
String get kpp => 'KP Per\nPiece';
String get kps => 'KP Per\nSecond';
String get tr => 'Tetra Rating';
String get rd => 'Rating Deviation';
String get app => 'Attack Per Piece';
String get appDescription => '(Abbreviated as APP) Main efficiency metric. Tells how many attack you producing per piece';
String get vsapmDescription => 'Basically, tells how much and how efficient you using garbage in your attacks';
@ -753,7 +775,26 @@ class _StringsRu implements _StringsEn {
@override String get averages => 'Средние значения';
@override String get lbViewZeroEntrys => 'Рейтинговая таблица пуста. Похоже, что-то здесь не так...';
@override String get lbViewOneEntry => 'В рейтинговой таблице всего один игрок... Чего?';
@override String lbViewManyEntrys({required Object numberOfPlayers}) => 'В рейтинговой таблице находится ${numberOfPlayers} игроков.';
@override String lbViewManyEntrys({required Object numberOfPlayers}) => 'В рейтинговой таблице находится ${numberOfPlayers}.';
@override String get everyoneAverages => 'Значения таблицы';
@override String rankAverages({required Object rank}) => 'Значения для ${rank} ранга';
@override String players({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
zero: '${n} игроков',
one: '${n} игрок',
two: '${n} игрока',
few: '${n} игрока',
many: '${n} игроков',
other: '${n} игроков',
);
@override String get chart => 'График';
@override String get entries => 'Список';
@override String get minimums => 'Минимумы';
@override String get maximums => 'Максимумы';
@override String get lowestValues => 'Самые низкие показатели';
@override String get averageValues => 'Средние значения показателей';
@override String get highestValues => 'Самые высокие показатели';
@override String forPlayer({required Object username}) => 'для игрока ${username}';
@override String currentAxis({required Object axis}) => 'Ось ${axis}:';
@override String get p1nkl0bst3rAlert => 'Эти данные были получены из стороннего API, который поддерживается p1nkl0bst3r';
@override String get notForWeb => 'Функция недоступна для веб версии';
@override late final _StringsStatCellNumRu statCellNum = _StringsStatCellNumRu._(_root);
@ -1045,6 +1086,8 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
@override String get hoursPlayed => 'Часов\nСыграно';
@override String get onlineGames => 'Онлайн\nИгр';
@override String get gamesWon => 'Онлайн\nПобед';
@override String get totalGames => 'Всего матчей';
@override String get totalWon => 'Всего побед';
@override String get friends => 'Друзей';
@override String get apm => 'Атака в\nМинуту';
@override String get vs => 'Показатель\nVersus';
@ -1067,6 +1110,7 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
@override String get kpp => 'Нажатий\nна Фигуру';
@override String get kps => 'Нажатий\nв Секунду';
@override String get tr => 'Тетра Рейтинг';
@override String get rd => 'Отклонение рейтинга';
@override String get app => 'Атака на Фигуру';
@override String get appDescription => '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
@override String get vsapmDescription => 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';
@ -1233,7 +1277,26 @@ extension on _StringsEn {
case 'averages': return 'Averages';
case 'lbViewZeroEntrys': return 'Empty list. Looks like something is wrong...';
case 'lbViewOneEntry': return 'There is only one player... What?';
case 'lbViewManyEntrys': return ({required Object numberOfPlayers}) => 'There are ${numberOfPlayers} ranked players.';
case 'lbViewManyEntrys': return ({required Object numberOfPlayers}) => 'There are ${numberOfPlayers}.';
case 'everyoneAverages': return 'Values for leaderboard';
case 'rankAverages': return ({required Object rank}) => 'Values for ${rank} rank';
case 'players': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('en'))(n,
zero: '${n} players',
one: '${n} player',
two: '${n} players',
few: '${n} players',
many: '${n} players',
other: '${n} players',
);
case 'chart': return 'Chart';
case 'entries': return 'Entries';
case 'minimums': return 'Minimums';
case 'maximums': return 'Maximums';
case 'lowestValues': return 'Lowest Values';
case 'averageValues': return 'Average Values';
case 'highestValues': return 'Highest Values';
case 'forPlayer': return ({required Object username}) => 'for player ${username}';
case 'currentAxis': return ({required Object axis}) => '${axis} axis:';
case 'p1nkl0bst3rAlert': return 'That data was retrived from third party API maintained by p1nkl0bst3r';
case 'notForWeb': return 'Function is not available for web version';
case 'statCellNum.xpLevel': return 'XP Level';
@ -1242,6 +1305,8 @@ extension on _StringsEn {
case 'statCellNum.hoursPlayed': return 'Hours\nPlayed';
case 'statCellNum.onlineGames': return 'Online\nGames';
case 'statCellNum.gamesWon': return 'Games\nWon';
case 'statCellNum.totalGames': return 'Total Games Played';
case 'statCellNum.totalWon': return 'Total Games Won';
case 'statCellNum.friends': return 'Friends';
case 'statCellNum.apm': return 'Attack\nPer Minute';
case 'statCellNum.vs': return 'Versus\nScore';
@ -1264,6 +1329,7 @@ extension on _StringsEn {
case 'statCellNum.kpp': return 'KP Per\nPiece';
case 'statCellNum.kps': return 'KP Per\nSecond';
case 'statCellNum.tr': return 'Tetra Rating';
case 'statCellNum.rd': return 'Rating Deviation';
case 'statCellNum.app': return 'Attack Per Piece';
case 'statCellNum.appDescription': return '(Abbreviated as APP) Main efficiency metric. Tells how many attack you producing per piece';
case 'statCellNum.vsapmDescription': return 'Basically, tells how much and how efficient you using garbage in your attacks';
@ -1669,7 +1735,26 @@ extension on _StringsRu {
case 'averages': return 'Средние значения';
case 'lbViewZeroEntrys': return 'Рейтинговая таблица пуста. Похоже, что-то здесь не так...';
case 'lbViewOneEntry': return 'В рейтинговой таблице всего один игрок... Чего?';
case 'lbViewManyEntrys': return ({required Object numberOfPlayers}) => 'В рейтинговой таблице находится ${numberOfPlayers} игроков.';
case 'lbViewManyEntrys': return ({required Object numberOfPlayers}) => 'В рейтинговой таблице находится ${numberOfPlayers}.';
case 'everyoneAverages': return 'Значения таблицы';
case 'rankAverages': return ({required Object rank}) => 'Значения для ${rank} ранга';
case 'players': return ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('ru'))(n,
zero: '${n} игроков',
one: '${n} игрок',
two: '${n} игрока',
few: '${n} игрока',
many: '${n} игроков',
other: '${n} игроков',
);
case 'chart': return 'График';
case 'entries': return 'Список';
case 'minimums': return 'Минимумы';
case 'maximums': return 'Максимумы';
case 'lowestValues': return 'Самые низкие показатели';
case 'averageValues': return 'Средние значения показателей';
case 'highestValues': return 'Самые высокие показатели';
case 'forPlayer': return ({required Object username}) => 'для игрока ${username}';
case 'currentAxis': return ({required Object axis}) => 'Ось ${axis}:';
case 'p1nkl0bst3rAlert': return 'Эти данные были получены из стороннего API, который поддерживается p1nkl0bst3r';
case 'notForWeb': return 'Функция недоступна для веб версии';
case 'statCellNum.xpLevel': return 'Уровень\nопыта';
@ -1678,6 +1763,8 @@ extension on _StringsRu {
case 'statCellNum.hoursPlayed': return 'Часов\nСыграно';
case 'statCellNum.onlineGames': return 'Онлайн\nИгр';
case 'statCellNum.gamesWon': return 'Онлайн\nПобед';
case 'statCellNum.totalGames': return 'Всего матчей';
case 'statCellNum.totalWon': return 'Всего побед';
case 'statCellNum.friends': return 'Друзей';
case 'statCellNum.apm': return 'Атака в\nМинуту';
case 'statCellNum.vs': return 'Показатель\nVersus';
@ -1700,6 +1787,7 @@ extension on _StringsRu {
case 'statCellNum.kpp': return 'Нажатий\nна Фигуру';
case 'statCellNum.kps': return 'Нажатий\nв Секунду';
case 'statCellNum.tr': return 'Тетра Рейтинг';
case 'statCellNum.rd': return 'Отклонение рейтинга';
case 'statCellNum.app': return 'Атака на Фигуру';
case 'statCellNum.appDescription': return '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
case 'statCellNum.vsapmDescription': return 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';

View File

@ -81,7 +81,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
bool bigScreen = MediaQuery.of(context).size.width > 768;
return Scaffold(
appBar: AppBar(
title: Text(widget.rank[0].rank.toUpperCase()),
title: Text(widget.rank[1]["everyone"] ? t.everyoneAverages : t.rankAverages(rank: widget.rank[0].rank.toUpperCase())),
),
backgroundColor: Colors.black,
body: SafeArea(
@ -110,12 +110,12 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
child: Column(
children: [
Text(
"Values for ${widget.rank[0].rank.toUpperCase()} rank",
widget.rank[1]["everyone"] ? t.everyoneAverages : t.rankAverages(rank: widget.rank[0].rank.toUpperCase()),
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
Text(
"${widget.rank[1]["entries"].length} players",
t.players(n: widget.rank[1]["entries"].length),
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
@ -123,48 +123,19 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
)),
],
),
// Wrap(
// direction: Axis.horizontal,
// alignment: WrapAlignment.center,
// spacing: 25,
// crossAxisAlignment: WrapCrossAlignment.start,
// clipBehavior: Clip.hardEdge, // hard WHAT???
// children: [
// StatCellNum(
// playerStat: widget.rank[1]["totalGamesPlayed"],
// playerStatLabel: "Total games\nplayed",
// isScreenBig: bigScreen,
// higherIsBetter: true,
// ),
// StatCellNum(
// playerStat: widget.rank[1]["totalGamesWon"],
// playerStatLabel: "Total games\nwon",
// isScreenBig: bigScreen,
// higherIsBetter: true,
// ),
// StatCellNum(
// playerStat: (widget.rank[1]["totalGamesWon"] /
// widget.rank[1]["totalGamesPlayed"]) *
// 100,
// playerStatLabel: t.statCellNum.winrate,
// fractionDigits: 3,
// isScreenBig: bigScreen,
// higherIsBetter: true)
// ],
// ),
],
)),
SliverToBoxAdapter(
child: TabBar(
controller: _tabController,
isScrollable: true,
tabs: const [
Tab(text: "Chart"),
Tab(text: "Entries"),
Tab(text: "Minimums"),
Tab(text: "Averages"),
Tab(text: "Maximums"),
Tab(text: "Other"),
tabs: [
Tab(text: t.chart),
Tab(text: t.entries),
Tab(text: t.minimums),
Tab(text: t.averages),
Tab(text: t.maximums),
Tab(text: t.other),
],
)),
];
@ -174,15 +145,18 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.center,
spacing: 25,
children: [Column(
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("X axis:", style: const TextStyle(fontSize: 22))),
child: Text(t.currentAxis(axis: "X"), style: const TextStyle(fontSize: 22))),
DropdownButton(
items: chartsShortTitlesDropdowns,
value: chartsShortTitlesDropdowns[chartsIndexX].value,
@ -197,10 +171,11 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
),Column(
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Y axis:", style: const TextStyle(fontSize: 22)),
child: Text(t.currentAxis(axis: "Y"), style: const TextStyle(fontSize: 22)),
),
DropdownButton(
items: chartsShortTitlesDropdowns,
@ -225,15 +200,15 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
: const EdgeInsets.fromLTRB(0, 40, 16, 48),
child: ScatterChart(
ScatterChartData(
scatterSpots: [ for (TetrioPlayerFromLeaderboard entry in widget.rank[1]["entries"]) MyScatterSpot(takeStat(entry, chartsShortTitles[chartsIndexX]), takeStat(entry, chartsShortTitles[chartsIndexY]), entry.userId, entry.username, color: rankColors[entry.rank])],
scatterSpots: [ for (TetrioPlayerFromLeaderboard entry in widget.rank[1]["entries"]) _MyScatterSpot(takeStat(entry, chartsShortTitles[chartsIndexX]), takeStat(entry, chartsShortTitles[chartsIndexY]), entry.userId, entry.username, color: rankColors[entry.rank])],
scatterTouchData: ScatterTouchData(touchTooltipData: ScatterTouchTooltipData(
fitInsideHorizontally: true, fitInsideVertically: true, getTooltipItems: (touchedSpot) {
touchedSpot as MyScatterSpot;
touchedSpot as _MyScatterSpot;
return ScatterTooltipItem("${touchedSpot.nickname}\n", textStyle: TextStyle(fontFamily: "Eurostile Round Extended"), children: [TextSpan(text: "${f4.format(touchedSpot.x)} ${chartsShortTitles[chartsIndexX]}\n${f4.format(touchedSpot.y)} ${chartsShortTitles[chartsIndexY]}", style: TextStyle(fontFamily: "Eurostile Round"))]);
}),
touchCallback:(event, response) {
if (event.runtimeType == FlTapDownEvent && response?.touchedSpot?.spot != null){
var spot = response?.touchedSpot?.spot as MyScatterSpot;
var spot = response?.touchedSpot?.spot as _MyScatterSpot;
Navigator.push(
context,
MaterialPageRoute(
@ -255,7 +230,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
),
Column(
children: [
Text("Entries",
Text(t.entries,
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
@ -305,7 +280,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
),
Column(
children: [
Text("Lowest Values",
Text(t.lowestValues,
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
@ -314,7 +289,8 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
children: [
_ListEntry(
value: widget.rank[1]["lowestTR"],
label: "Tetra Rating",
label: t.statCellNum.tr
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestTRid"],
username: widget.rank[1]["lowestTRnick"],
approximate: false,
@ -328,49 +304,56 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["lowestRD"],
label: "Rating Deviation",
label: t.statCellNum.rd
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestRdID"],
username: widget.rank[1]["lowestRdNick"],
approximate: false,
fractionDigits: 3),
_ListEntry(
value: widget.rank[1]["lowestGamesPlayed"],
label: "Games Played",
label: t.statCellNum.gamesPlayed
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestGamesPlayedID"],
username: widget.rank[1]
["lowestGamesPlayedNick"],
approximate: false),
_ListEntry(
value: widget.rank[1]["lowestGamesWon"],
label: "Games Won",
label: t.statCellNum.gamesWonTL
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestGamesWonID"],
username: widget.rank[1]
["lowestGamesWonNick"],
approximate: false),
_ListEntry(
value: widget.rank[1]["lowestWinrate"] * 100,
label: "Winrate Percentage",
label: t.statCellNum.winrate
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestWinrateID"],
username: widget.rank[1]["lowestWinrateNick"],
approximate: false,
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["lowestAPM"],
label: "Attack Per Minute",
label: t.statCellNum.apm
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestAPMid"],
username: widget.rank[1]["lowestAPMnick"],
approximate: false,
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["lowestPPS"],
label: "Pieces Per Second",
label: t.statCellNum.pps
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestPPSid"],
username: widget.rank[1]["lowestPPSnick"],
approximate: false,
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["lowestVS"],
label: "Versus Score",
label: t.statCellNum.vs
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["lowestVSid"],
username: widget.rank[1]["lowestVSnick"],
approximate: false,
@ -485,7 +468,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
fractionDigits: 3),
_ListEntry(
value: widget.rank[1]["lowestInfDS"],
label: "InfDS",
label: "Inf. DS",
id: widget.rank[1]["lowestInfDSid"],
username: widget.rank[1]["lowestInfDSnick"],
approximate: false,
@ -497,7 +480,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
),
Column(
children: [
Text("Average Values",
Text(t.averageValues,
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
@ -505,7 +488,8 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
child: ListView(children: [
_ListEntry(
value: widget.rank[0].rating,
label: "Tetra Rating",
label: t.statCellNum.tr
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
@ -519,56 +503,64 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
fractionDigits: 2),
_ListEntry(
value: widget.rank[0].rd,
label: "Rating Deviation",
label: t.statCellNum.rd
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 3),
_ListEntry(
value: widget.rank[0].gamesPlayed,
label: "Games Played",
label: t.statCellNum.gamesPlayed
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 0),
_ListEntry(
value: widget.rank[0].gamesWon,
label: "Games Won",
label: t.statCellNum.gamesWonTL
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 0),
_ListEntry(
value: widget.rank[0].winrate * 100,
label: "Winrate",
label: t.statCellNum.winrate
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 2),
_ListEntry(
value: widget.rank[0].apm,
label: "Attack per Minute",
label: t.statCellNum.apm
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 2),
_ListEntry(
value: widget.rank[0].pps,
label: "Pieces per Second",
label: t.statCellNum.pps
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 2),
_ListEntry(
value: widget.rank[0].vs,
label: "Versus Score",
label: t.statCellNum.vs
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["avgAPP"],
label: "Attack Per Piece",
label: t.statCellNum.app
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
@ -675,7 +667,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
fractionDigits: 3),
_ListEntry(
value: widget.rank[1]["avgInfDS"],
label: "InfDS",
label: "Inf. DS",
id: "",
username: "",
approximate: true,
@ -685,7 +677,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
),
Column(
children: [
Text("Highest Values",
Text(t.highestValues,
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
@ -694,7 +686,8 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
children: [
_ListEntry(
value: widget.rank[1]["highestTR"],
label: "Tetra Rating",
label: t.statCellNum.tr
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestTRid"],
username: widget.rank[1]["highestTRnick"],
approximate: false,
@ -708,28 +701,32 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["highestRD"],
label: "Rating Deviation",
label: t.statCellNum.rd
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestRdID"],
username: widget.rank[1]["highestRdNick"],
approximate: false,
fractionDigits: 3),
_ListEntry(
value: widget.rank[1]["highestGamesPlayed"],
label: "Games Played",
label: t.statCellNum.gamesPlayed
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestGamesPlayedID"],
username: widget.rank[1]
["highestGamesPlayedNick"],
approximate: false),
_ListEntry(
value: widget.rank[1]["highestGamesWon"],
label: "Games Won",
label: t.statCellNum.gamesWonTL
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestGamesWonID"],
username: widget.rank[1]
["highestGamesWonNick"],
approximate: false),
_ListEntry(
value: widget.rank[1]["highestWinrate"] * 100,
label: "Winrate Percentage",
label: t.statCellNum.winrate
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestWinrateID"],
username: widget.rank[1]
["highestWinrateNick"],
@ -737,21 +734,24 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["highestAPM"],
label: "Attack Per Minute",
label: t.statCellNum.apm
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestAPMid"],
username: widget.rank[1]["highestAPMnick"],
approximate: false,
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["highestPPS"],
label: "Pieces Per Second",
label: t.statCellNum.pps
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestPPSid"],
username: widget.rank[1]["highestPPSnick"],
approximate: false,
fractionDigits: 2),
_ListEntry(
value: widget.rank[1]["highestVS"],
label: "Versus Score",
label: t.statCellNum.vs
.replaceAll(RegExp(r'\n'), " "),
id: widget.rank[1]["highestVSid"],
username: widget.rank[1]["highestVSnick"],
approximate: false,
@ -866,7 +866,7 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
fractionDigits: 3),
_ListEntry(
value: widget.rank[1]["highestInfDS"],
label: "InfDS",
label: "Inf. DS",
id: widget.rank[1]["highestInfDSid"],
username: widget.rank[1]["highestInfDSnick"],
approximate: false,
@ -883,14 +883,14 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
children: [
_ListEntry(
value: widget.rank[1]["totalGamesPlayed"],
label: "Total Games Played",
label: t.statCellNum.totalGames,
id: "",
username: "",
approximate: true,
fractionDigits: 0),
_ListEntry(
value: widget.rank[1]["totalGamesWon"],
label: "Total Games Won",
label: t.statCellNum.totalWon,
id: "",
username: "",
approximate: true,
@ -899,21 +899,13 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
value: (widget.rank[1]["totalGamesWon"] /
widget.rank[1]["totalGamesPlayed"]) *
100,
label: "Winrate",
label: t.statCellNum.winrate
.replaceAll(RegExp(r'\n'), " "),
id: "",
username: "",
approximate: true,
fractionDigits: 3),
Center(
child: Text("Typical TL profile",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28)),
),
SizedBox(
height: 800,
child: TLThingy(tl: widget.rank[0], userID: ""),
)
]
)
)
@ -952,7 +944,7 @@ class _ListEntry extends StatelessWidget {
children: [
Text(f.format(value),
style: const TextStyle(fontSize: 22, height: 0.9)),
if (id.isNotEmpty) Text('for player $username')
if (id.isNotEmpty) Text(t.forPlayer(username: username))
],
),
onTap: id.isNotEmpty
@ -1029,10 +1021,10 @@ double takeStat(TetrioPlayerFromLeaderboard entry, String stat) {
}
}
class MyScatterSpot extends ScatterSpot{
class _MyScatterSpot extends ScatterSpot{
String id;
String nickname;
MyScatterSpot(super.x, super.y, this.id, this.nickname, {super.color});
_MyScatterSpot(super.x, super.y, this.id, this.nickname, {super.color});
}

View File

@ -40,7 +40,7 @@ class RanksAverages extends State<RankAveragesView> {
List<String> keys = averages.keys.toList();
return ListTile(
leading: Image.asset("res/tetrio_tl_alpha_ranks/${keys[index]}.png", height: 48),
title: Text("${averages[keys[index]]?[1]["players"]} players", style: const TextStyle(fontFamily: "Eurostile Round Extended")),
title: Text(t.players(n: averages[keys[index]]?[1]["players"]), style: const TextStyle(fontFamily: "Eurostile Round Extended")),
subtitle: Text("${f2.format(averages[keys[index]]?[0].apm)} APM, ${f2.format(averages[keys[index]]?[0].pps)} PPS, ${f2.format(averages[keys[index]]?[0].vs)} VS, ${f2.format(averages[keys[index]]?[0].nerdStats.app)} APP, ${f2.format(averages[keys[index]]?[0].nerdStats.vsapm)} VS/APM"),
trailing: Text("${f2.format(averages[keys[index]]?[1]["toEnterTR"])} TR", style: bigScreen ? const TextStyle(fontSize: 28) : null),
onTap: (){

View File

@ -58,7 +58,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
numberOfPlayers,
zero: t.lbViewZeroEntrys,
one: t.lbViewOneEntry,
other: t.lbViewManyEntrys(numberOfPlayers: numberOfPlayers),
other: t.lbViewManyEntrys(numberOfPlayers: t.players(n: numberOfPlayers)),
name: 'howManyPeople',
args: [numberOfPlayers],
desc: 'Description of how many people are seen in a place.',
@ -82,7 +82,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
builder: (context) => RankView(rank: snapshot.data!.getAverageOfRank("")),
),
);
}, child: Text("Values for everyone",
}, child: Text(t.everyoneAverages,
style: const TextStyle(fontSize: 25)))
],)
)),

View File

@ -12,7 +12,8 @@ class TLThingy extends StatelessWidget {
final TetraLeagueAlpha tl;
final String userID;
final TetraLeagueAlpha? oldTl;
const TLThingy({Key? key, required this.tl, required this.userID, this.oldTl}) : super(key: key);
final bool showTitle;
const TLThingy({Key? key, required this.tl, required this.userID, this.oldTl, this.showTitle = true}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -29,7 +30,7 @@ class TLThingy extends StatelessWidget {
return Column(
children: (tl.gamesPlayed > 0)
? [
Text(t.tetraLeague, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
if (showTitle) Text(t.tetraLeague, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
if (oldTl != null) Text(t.comparingWith(date: dateFormat.format(oldTl!.timestamp))),
if (tl.gamesPlayed >= 10)
Wrap(

View File

@ -101,7 +101,26 @@
"averages": "Averages",
"lbViewZeroEntrys": "Empty list. Looks like something is wrong...",
"lbViewOneEntry": "There is only one player... What?",
"lbViewManyEntrys": "There are ${numberOfPlayers} ranked players.",
"lbViewManyEntrys": "There are ${numberOfPlayers}.",
"everyoneAverages": "Values for leaderboard",
"rankAverages": "Values for $rank rank",
"players":{
"zero": "$n players",
"one": "$n player",
"two": "$n players",
"few": "$n players",
"many": "$n players",
"other": "$n players"
},
"chart": "Chart",
"entries": "Entries",
"minimums": "Minimums",
"maximums": "Maximums",
"lowestValues": "Lowest Values",
"averageValues": "Average Values",
"highestValues": "Highest Values",
"forPlayer": "for player $username",
"currentAxis": "$axis axis:",
"p1nkl0bst3rAlert": "That data was retrived from third party API maintained by p1nkl0bst3r",
"notForWeb": "Function is not available for web version",
"statCellNum":{
@ -111,6 +130,8 @@
"hoursPlayed": "Hours\nPlayed",
"onlineGames": "Online\nGames",
"gamesWon": "Games\nWon",
"totalGames": "Total Games Played",
"totalWon": "Total Games Won",
"friends": "Friends",
"apm": "Attack\nPer Minute",
"vs": "Versus\nScore",
@ -133,6 +154,7 @@
"kpp": "KP Per\nPiece",
"kps": "KP Per\nSecond",
"tr": "Tetra Rating",
"rd": "Rating Deviation",
"app": "Attack Per Piece",
"appDescription": "(Abbreviated as APP) Main efficiency metric. Tells how many attack you producing per piece",
"vsapmDescription": "Basically, tells how much and how efficient you using garbage in your attacks",

View File

@ -101,7 +101,26 @@
"averages": "Средние значения",
"lbViewZeroEntrys": "Рейтинговая таблица пуста. Похоже, что-то здесь не так...",
"lbViewOneEntry": "В рейтинговой таблице всего один игрок... Чего?",
"lbViewManyEntrys": "В рейтинговой таблице находится ${numberOfPlayers} игроков.",
"lbViewManyEntrys": "В рейтинговой таблице находится ${numberOfPlayers}.",
"everyoneAverages": "Значения таблицы",
"rankAverages": "Значения для $rank ранга",
"players":{
"zero": "$n игроков",
"one": "$n игрок",
"two": "$n игрока",
"few": "$n игрока",
"many": "$n игроков",
"other": "$n игроков"
},
"chart": "График",
"entries": "Список",
"minimums": "Минимумы",
"maximums": "Максимумы",
"lowestValues": "Самые низкие показатели",
"averageValues": "Средние значения показателей",
"highestValues": "Самые высокие показатели",
"forPlayer": "для игрока $username",
"currentAxis": "Ось $axis:",
"p1nkl0bst3rAlert": "Эти данные были получены из стороннего API, который поддерживается p1nkl0bst3r",
"notForWeb": "Функция недоступна для веб версии",
"statCellNum": {
@ -111,6 +130,8 @@
"hoursPlayed": "Часов\nСыграно",
"onlineGames": "Онлайн\nИгр",
"gamesWon": "Онлайн\nПобед",
"totalGames": "Всего матчей",
"totalWon": "Всего побед",
"friends": "Друзей",
"apm": "Атака в\nМинуту",
"vs": "Показатель\nVersus",
@ -133,6 +154,7 @@
"kpp": "Нажатий\nна Фигуру",
"kps": "Нажатий\nв Секунду",
"tr": "Тетра Рейтинг",
"rd": "Отклонение рейтинга",
"app": "Атака на Фигуру",
"appDescription": "(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру",
"vsapmDescription": "В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.",