i18n implemented, time to ask for help

This commit is contained in:
dan63047 2023-07-15 19:22:25 +03:00
parent 758439f9c4
commit c69ba0a90f
15 changed files with 139 additions and 61 deletions

View File

@ -18,10 +18,10 @@
- ~~Ability to compare player with APM-PPS-VS stats~~ - ~~Ability to compare player with APM-PPS-VS stats~~
- ~~Ability to fetch Tetra League leaderboard~~ - ~~Ability to fetch Tetra League leaderboard~~
- ~~Average stats for ranks~~ - ~~Average stats for ranks~~
- ~~Ability to compare player with avgRank~~ *dev build are here* - ~~Ability to compare player with avgRank~~
- UI Animations - UI Animations *lol*
- i18n, EN and RU locales - ~~i18n, EN and RU locales~~ *dev build are here*
- Talk with osk about CORS and EndContext in TL matches - Talk with osk about CORS and EndContext in TL matches *idk lol*
- RELEASE ??? *that will be v1.0.0* - RELEASE ??? *that will be v1.0.0*
--- ---

View File

@ -1,9 +1,9 @@
/// Generated file. Do not edit. /// Generated file. Do not edit.
/// ///
/// Locales: 2 /// Locales: 2
/// Strings: 828 (414 per locale) /// Strings: 848 (424 per locale)
/// ///
/// Built on 2023-07-14 at 20:17 UTC /// Built on 2023-07-15 at 16:11 UTC
// coverage:ignore-file // coverage:ignore-file
// ignore_for_file: type=lint // ignore_for_file: type=lint
@ -159,6 +159,8 @@ class _StringsEn implements BaseTranslations<AppLocale, _StringsEn> {
String get other => 'Other'; String get other => 'Other';
String get zen => 'Zen'; String get zen => 'Zen';
String get bio => 'Bio'; String get bio => 'Bio';
String get openSearch => 'Search player';
String get closeSearch => 'Close search';
String get refresh => 'Refresh'; String get refresh => 'Refresh';
String get showStoredData => 'Show stored data'; String get showStoredData => 'Show stored data';
String get statsCalc => 'Stats Calculator'; String get statsCalc => 'Stats Calculator';
@ -242,6 +244,11 @@ class _StringsEn implements BaseTranslations<AppLocale, _StringsEn> {
String get fromBeginning => 'From beginning'; String get fromBeginning => 'From beginning';
String get calc => 'Calc'; String get calc => 'Calc';
String get calcViewNoValues => 'Enter values to calculate the stats'; String get calcViewNoValues => 'Enter values to calculate the stats';
String get rankAveragesViewTitle => 'Ranks cutoff and average stats';
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.';
late final _StringsStatCellNumEn statCellNum = _StringsStatCellNumEn._(_root); late final _StringsStatCellNumEn statCellNum = _StringsStatCellNumEn._(_root);
Map<String, String> get playerRole => { Map<String, String> get playerRole => {
'user': 'User', 'user': 'User',
@ -551,6 +558,7 @@ class _StringsStatCellNumEn {
String get keys => 'Key\nPresses'; String get keys => 'Key\nPresses';
String get kpp => 'KP Per\nPiece'; String get kpp => 'KP Per\nPiece';
String get kps => 'KP Per\nSecond'; String get kps => 'KP Per\nSecond';
String get tr => 'Tetra Rating';
String get app => 'Attack Per Piece'; 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 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'; String get vsapmDescription => 'Basically, tells how much and how efficient you using garbage in your attacks';
@ -569,7 +577,9 @@ class _StringsStatCellNumEn {
String get area => 'Area'; String get area => 'Area';
String get areaDescription => 'How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections'; String get areaDescription => 'How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections';
String get estOfTR => 'Est. of TR'; String get estOfTR => 'Est. of TR';
String get estOfTRShort => 'Est. TR';
String get accOfEst => 'Accuracy'; String get accOfEst => 'Accuracy';
String get accOfEstShort => 'Acc.';
} }
// Path: numOfGameActions // Path: numOfGameActions
@ -646,6 +656,8 @@ class _StringsRu implements _StringsEn {
@override String get other => 'Другое'; @override String get other => 'Другое';
@override String get zen => 'Дзен'; @override String get zen => 'Дзен';
@override String get bio => 'Биография'; @override String get bio => 'Биография';
@override String get openSearch => 'Искать игрока';
@override String get closeSearch => 'Закрыть поиск';
@override String get refresh => 'Обновить'; @override String get refresh => 'Обновить';
@override String get showStoredData => 'Показать сохранённые данные'; @override String get showStoredData => 'Показать сохранённые данные';
@override String get statsCalc => 'Калькулятор статистики'; @override String get statsCalc => 'Калькулятор статистики';
@ -655,7 +667,7 @@ class _StringsRu implements _StringsEn {
@override String get becameTracked => 'Добавлен в список отслеживания!'; @override String get becameTracked => 'Добавлен в список отслеживания!';
@override String get stoppedBeingTracked => 'Удалён из списка отслеживания!'; @override String get stoppedBeingTracked => 'Удалён из списка отслеживания!';
@override String get compare => 'Сравнить'; @override String get compare => 'Сравнить';
@override String get tlLeaderboard => 'Таблица лидеров Тетра Лиги'; @override String get tlLeaderboard => 'Рейтинговая таблица';
@override String get noRecords => 'Нет записей'; @override String get noRecords => 'Нет записей';
@override String get noRecord => 'Нет рекорда'; @override String get noRecord => 'Нет рекорда';
@override String get notEnoughData => 'Недостаточно данных'; @override String get notEnoughData => 'Недостаточно данных';
@ -725,10 +737,15 @@ class _StringsRu implements _StringsEn {
@override String get yes => 'Да'; @override String get yes => 'Да';
@override String get no => 'Нет'; @override String get no => 'Нет';
@override String get daysLater => 'дней позже'; @override String get daysLater => 'дней позже';
@override String get dayseBefore => 'дней до'; @override String get dayseBefore => 'дней раньше';
@override String get fromBeginning => 'С начала'; @override String get fromBeginning => 'С начала';
@override String get calc => 'Считать'; @override String get calc => 'Считать';
@override String get calcViewNoValues => 'Введите значения, чтобы посчитать статистику'; @override String get calcViewNoValues => 'Введите значения, чтобы посчитать статистику';
@override String get rankAveragesViewTitle => 'Требования рангов и средние значения';
@override String get averages => 'Средние значения';
@override String get lbViewZeroEntrys => 'Рейтинговая таблица пуста. Похоже, что-то здесь не так...';
@override String get lbViewOneEntry => 'В рейтинговой таблице всего один игрок... Чего?';
@override String lbViewManyEntrys({required Object numberOfPlayers}) => 'В рейтинговой таблице находится ${numberOfPlayers} игроков.';
@override late final _StringsStatCellNumRu statCellNum = _StringsStatCellNumRu._(_root); @override late final _StringsStatCellNumRu statCellNum = _StringsStatCellNumRu._(_root);
@override Map<String, String> get playerRole => { @override Map<String, String> get playerRole => {
'user': 'Пользователь', 'user': 'Пользователь',
@ -1038,6 +1055,7 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
@override String get keys => 'Нажатий\nКлавиш'; @override String get keys => 'Нажатий\nКлавиш';
@override String get kpp => 'Нажатий\nна Фигуру'; @override String get kpp => 'Нажатий\nна Фигуру';
@override String get kps => 'Нажатий\nв Секунду'; @override String get kps => 'Нажатий\nв Секунду';
@override String get tr => 'Тетра Рейтинг';
@override String get app => 'Атака на Фигуру'; @override String get app => 'Атака на Фигуру';
@override String get appDescription => '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру'; @override String get appDescription => '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
@override String get vsapmDescription => 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.'; @override String get vsapmDescription => 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';
@ -1056,7 +1074,9 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
@override String get area => 'Area'; @override String get area => 'Area';
@override String get areaDescription => 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM'; @override String get areaDescription => 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM';
@override String get estOfTR => 'Расчётный TR'; @override String get estOfTR => 'Расчётный TR';
@override String get estOfTRShort => 'Расч. TR';
@override String get accOfEst => 'Точность расчёта'; @override String get accOfEst => 'Точность расчёта';
@override String get accOfEstShort => 'Точность';
} }
// Path: numOfGameActions // Path: numOfGameActions
@ -1112,6 +1132,8 @@ extension on _StringsEn {
case 'other': return 'Other'; case 'other': return 'Other';
case 'zen': return 'Zen'; case 'zen': return 'Zen';
case 'bio': return 'Bio'; case 'bio': return 'Bio';
case 'openSearch': return 'Search player';
case 'closeSearch': return 'Close search';
case 'refresh': return 'Refresh'; case 'refresh': return 'Refresh';
case 'showStoredData': return 'Show stored data'; case 'showStoredData': return 'Show stored data';
case 'statsCalc': return 'Stats Calculator'; case 'statsCalc': return 'Stats Calculator';
@ -1195,6 +1217,11 @@ extension on _StringsEn {
case 'fromBeginning': return 'From beginning'; case 'fromBeginning': return 'From beginning';
case 'calc': return 'Calc'; case 'calc': return 'Calc';
case 'calcViewNoValues': return 'Enter values to calculate the stats'; case 'calcViewNoValues': return 'Enter values to calculate the stats';
case 'rankAveragesViewTitle': return 'Ranks cutoff and average stats';
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 'statCellNum.xpLevel': return 'XP Level'; case 'statCellNum.xpLevel': return 'XP Level';
case 'statCellNum.xpProgress': return 'Progress to next level'; case 'statCellNum.xpProgress': return 'Progress to next level';
case 'statCellNum.xpFrom0To5000': return 'Progress from 0 XP to level 5000'; case 'statCellNum.xpFrom0To5000': return 'Progress from 0 XP to level 5000';
@ -1221,6 +1248,7 @@ extension on _StringsEn {
case 'statCellNum.keys': return 'Key\nPresses'; case 'statCellNum.keys': return 'Key\nPresses';
case 'statCellNum.kpp': return 'KP Per\nPiece'; case 'statCellNum.kpp': return 'KP Per\nPiece';
case 'statCellNum.kps': return 'KP Per\nSecond'; case 'statCellNum.kps': return 'KP Per\nSecond';
case 'statCellNum.tr': return 'Tetra Rating';
case 'statCellNum.app': return 'Attack Per Piece'; 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.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'; case 'statCellNum.vsapmDescription': return 'Basically, tells how much and how efficient you using garbage in your attacks';
@ -1239,7 +1267,9 @@ extension on _StringsEn {
case 'statCellNum.area': return 'Area'; case 'statCellNum.area': return 'Area';
case 'statCellNum.areaDescription': return 'How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections'; case 'statCellNum.areaDescription': return 'How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections';
case 'statCellNum.estOfTR': return 'Est. of TR'; case 'statCellNum.estOfTR': return 'Est. of TR';
case 'statCellNum.estOfTRShort': return 'Est. TR';
case 'statCellNum.accOfEst': return 'Accuracy'; case 'statCellNum.accOfEst': return 'Accuracy';
case 'statCellNum.accOfEstShort': return 'Acc.';
case 'playerRole.user': return 'User'; case 'playerRole.user': return 'User';
case 'playerRole.banned': return 'Banned'; case 'playerRole.banned': return 'Banned';
case 'playerRole.bot': return 'Bot'; case 'playerRole.bot': return 'Bot';
@ -1534,6 +1564,8 @@ extension on _StringsRu {
case 'other': return 'Другое'; case 'other': return 'Другое';
case 'zen': return 'Дзен'; case 'zen': return 'Дзен';
case 'bio': return 'Биография'; case 'bio': return 'Биография';
case 'openSearch': return 'Искать игрока';
case 'closeSearch': return 'Закрыть поиск';
case 'refresh': return 'Обновить'; case 'refresh': return 'Обновить';
case 'showStoredData': return 'Показать сохранённые данные'; case 'showStoredData': return 'Показать сохранённые данные';
case 'statsCalc': return 'Калькулятор статистики'; case 'statsCalc': return 'Калькулятор статистики';
@ -1543,7 +1575,7 @@ extension on _StringsRu {
case 'becameTracked': return 'Добавлен в список отслеживания!'; case 'becameTracked': return 'Добавлен в список отслеживания!';
case 'stoppedBeingTracked': return 'Удалён из списка отслеживания!'; case 'stoppedBeingTracked': return 'Удалён из списка отслеживания!';
case 'compare': return 'Сравнить'; case 'compare': return 'Сравнить';
case 'tlLeaderboard': return 'Таблица лидеров Тетра Лиги'; case 'tlLeaderboard': return 'Рейтинговая таблица';
case 'noRecords': return 'Нет записей'; case 'noRecords': return 'Нет записей';
case 'noRecord': return 'Нет рекорда'; case 'noRecord': return 'Нет рекорда';
case 'notEnoughData': return 'Недостаточно данных'; case 'notEnoughData': return 'Недостаточно данных';
@ -1613,10 +1645,15 @@ extension on _StringsRu {
case 'yes': return 'Да'; case 'yes': return 'Да';
case 'no': return 'Нет'; case 'no': return 'Нет';
case 'daysLater': return 'дней позже'; case 'daysLater': return 'дней позже';
case 'dayseBefore': return 'дней до'; case 'dayseBefore': return 'дней раньше';
case 'fromBeginning': return 'С начала'; case 'fromBeginning': return 'С начала';
case 'calc': return 'Считать'; case 'calc': return 'Считать';
case 'calcViewNoValues': return 'Введите значения, чтобы посчитать статистику'; case 'calcViewNoValues': return 'Введите значения, чтобы посчитать статистику';
case 'rankAveragesViewTitle': return 'Требования рангов и средние значения';
case 'averages': return 'Средние значения';
case 'lbViewZeroEntrys': return 'Рейтинговая таблица пуста. Похоже, что-то здесь не так...';
case 'lbViewOneEntry': return 'В рейтинговой таблице всего один игрок... Чего?';
case 'lbViewManyEntrys': return ({required Object numberOfPlayers}) => 'В рейтинговой таблице находится ${numberOfPlayers} игроков.';
case 'statCellNum.xpLevel': return 'Уровень\nопыта'; case 'statCellNum.xpLevel': return 'Уровень\nопыта';
case 'statCellNum.xpProgress': return 'Прогресс до следующего уровня'; case 'statCellNum.xpProgress': return 'Прогресс до следующего уровня';
case 'statCellNum.xpFrom0To5000': return 'Прогресс от 0 XP до 5000 уровня'; case 'statCellNum.xpFrom0To5000': return 'Прогресс от 0 XP до 5000 уровня';
@ -1643,6 +1680,7 @@ extension on _StringsRu {
case 'statCellNum.keys': return 'Нажатий\nКлавиш'; case 'statCellNum.keys': return 'Нажатий\nКлавиш';
case 'statCellNum.kpp': return 'Нажатий\nна Фигуру'; case 'statCellNum.kpp': return 'Нажатий\nна Фигуру';
case 'statCellNum.kps': return 'Нажатий\nв Секунду'; case 'statCellNum.kps': return 'Нажатий\nв Секунду';
case 'statCellNum.tr': return 'Тетра Рейтинг';
case 'statCellNum.app': return 'Атака на Фигуру'; case 'statCellNum.app': return 'Атака на Фигуру';
case 'statCellNum.appDescription': return '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру'; case 'statCellNum.appDescription': return '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
case 'statCellNum.vsapmDescription': return 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.'; case 'statCellNum.vsapmDescription': return 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';
@ -1661,7 +1699,9 @@ extension on _StringsRu {
case 'statCellNum.area': return 'Area'; case 'statCellNum.area': return 'Area';
case 'statCellNum.areaDescription': return 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM'; case 'statCellNum.areaDescription': return 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM';
case 'statCellNum.estOfTR': return 'Расчётный TR'; case 'statCellNum.estOfTR': return 'Расчётный TR';
case 'statCellNum.estOfTRShort': return 'Расч. TR';
case 'statCellNum.accOfEst': return 'Точность расчёта'; case 'statCellNum.accOfEst': return 'Точность расчёта';
case 'statCellNum.accOfEstShort': return 'Точность';
case 'playerRole.user': return 'Пользователь'; case 'playerRole.user': return 'Пользователь';
case 'playerRole.banned': return 'Заблокированный пользователь'; case 'playerRole.banned': return 'Заблокированный пользователь';
case 'playerRole.bot': return 'Бот'; case 'playerRole.bot': return 'Бот';

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:tetra_stats/gen/strings.g.dart'; import 'package:tetra_stats/gen/strings.g.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
@ -8,18 +9,27 @@ import 'package:tetra_stats/views/settings_view.dart';
import 'package:tetra_stats/views/tracked_players_view.dart'; import 'package:tetra_stats/views/tracked_players_view.dart';
import 'package:tetra_stats/views/calc_view.dart'; import 'package:tetra_stats/views/calc_view.dart';
void main() { void main() async {
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) { if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
sqfliteFfiInit(); sqfliteFfiInit();
databaseFactory = databaseFactoryFfi; databaseFactory = databaseFactoryFfi;
} }
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
prefs = await SharedPreferences.getInstance();
String? locale = prefs.getString("locale");
if (locale == null){
LocaleSettings.useDeviceLocale();
}else{
LocaleSettings.setLocaleRaw(locale);
}
runApp(TranslationProvider( runApp(TranslationProvider(
child: MyApp(), child: MyApp(),
)); ));
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(

View File

@ -297,8 +297,7 @@ class _ListEntry extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var f = NumberFormat("#,###.##"); NumberFormat f = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: fractionDigits ?? 0);
f.maximumFractionDigits = fractionDigits ?? 0;
return ListTile(title: Text(label), trailing: Text(f.format(value), style: const TextStyle(fontSize: 22))); return ListTile(title: Text(label), trailing: Text(f.format(value), style: const TextStyle(fontSize: 22)));
} }
} }

View File

@ -593,7 +593,7 @@ class CompareState extends State<CompareView> {
higherIsBetter: true, higherIsBetter: true,
), ),
CompareThingy( CompareThingy(
label: t.statCellNum.estOfTR, label: t.statCellNum.estOfTRShort,
greenSide: theGreenSide[2].estTr!.esttr, greenSide: theGreenSide[2].estTr!.esttr,
redSide: theRedSide[2].estTr!.esttr, redSide: theRedSide[2].estTr!.esttr,
fractionDigits: 2, fractionDigits: 2,
@ -604,7 +604,7 @@ class CompareState extends State<CompareView> {
greenSideMode != Mode.stats && greenSideMode != Mode.stats &&
redSideMode != Mode.stats) redSideMode != Mode.stats)
CompareThingy( CompareThingy(
label: t.statCellNum.accOfEst, label: t.statCellNum.accOfEstShort,
greenSide: theGreenSide[2].esttracc!, greenSide: theGreenSide[2].esttracc!,
redSide: theRedSide[2].esttracc!, redSide: theRedSide[2].esttracc!,
fractionDigits: 2, fractionDigits: 2,
@ -964,7 +964,7 @@ class CompareThingy extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var f = NumberFormat("#,###.##"); var f = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode);
f.maximumFractionDigits = fractionDigits ?? 0; f.maximumFractionDigits = fractionDigits ?? 0;
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2), padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
@ -1278,7 +1278,7 @@ class CompareRegTimeThingy extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
DateFormat f = DateFormat.yMMMd(); DateFormat f = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode);
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2), padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
child: Row( child: Row(

View File

@ -27,8 +27,8 @@ const allowedHeightForPlayerIdInPixels = 40.0;
const allowedHeightForPlayerBioInPixels = 30.0; const allowedHeightForPlayerBioInPixels = 30.0;
const givenTextHeightByScreenPercentage = 0.3; const givenTextHeightByScreenPercentage = 0.3;
final NumberFormat timeInSec = NumberFormat("#,###.###s."); final NumberFormat timeInSec = NumberFormat("#,###.###s.");
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2); final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
final NumberFormat f4 = NumberFormat.decimalPatternDigits(decimalDigits: 4); final NumberFormat f4 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 4);
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms(); final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
class MainView extends StatefulWidget { class MainView extends StatefulWidget {
@ -132,25 +132,24 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
}on RangeError { }on RangeError {
compareWith = null; compareWith = null;
} }
chartsData = <DropdownMenuItem<List<FlSpot>>>[ chartsData = <DropdownMenuItem<List<FlSpot>>>[
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rating)], child: const Text("Tetra Rating")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rating)], child: Text(t.statCellNum.tr)),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.glicko!)], child: const Text("Glicko")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.glicko!)], child: const Text("Glicko")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rd!)], child: const Text("Rating Deviation")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rd!)], child: const Text("Rating Deviation")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.apm!)], child: const Text("Attack Per Minute")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.pps!)], child: const Text("Pieces Per Second")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.pps!)], child: Text(t.statCellNum.pps.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.vs!)], child: const Text("Versus Score")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.vs!)], child: Text(t.statCellNum.vs.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.app)], child: const Text("Attack Per Piece")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.app)], child: Text(t.statCellNum.app.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dss)], child: const Text("Downstack Per Second")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dss)], child: Text(t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dsp)], child: const Text("Downstack Per Piece")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.dsp)], child: Text(t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.vsapm)], child: const Text("VS/APM")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.vsapm)], child: const Text("VS/APM")),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.cheese)], child: const Text("Cheese Index")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.cheese)], child: Text(t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.gbe)], child: const Text("Garbage Efficiency")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.gbe)], child: Text(t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.nyaapp)], child: const Text("Weighted APP")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.nyaapp)], child: Text(t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.area)], child: const Text("Area")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.nerdStats!.area)], child: Text(t.statCellNum.area.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.estTr!.esttr)], child: const Text("Est. of TR")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.estTr!.esttr)], child: Text(t.statCellNum.estOfTR.replaceAll(RegExp(r'\n'), " "))),
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.esttracc!)], child: const Text("Accuracy of Est.")), DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))),
]; ];
tlMatches.addAll(await teto.getTLMatchesbyPlayerID(me.userId)); tlMatches.addAll(await teto.getTLMatchesbyPlayerID(me.userId));
for (var match in tlStream.records) { for (var match in tlStream.records) {
@ -208,7 +207,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
}); });
}, },
icon: const Icon(Icons.search), icon: const Icon(Icons.search),
tooltip: "Search player", tooltip: t.openSearch,
) )
: IconButton( : IconButton(
onPressed: () { onPressed: () {
@ -217,7 +216,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
}); });
}, },
icon: const Icon(Icons.clear), icon: const Icon(Icons.clear),
tooltip: "Close search", tooltip: t.closeSearch,
), ),
PopupMenuButton( PopupMenuButton(
itemBuilder: (BuildContext context) => <PopupMenuEntry>[ itemBuilder: (BuildContext context) => <PopupMenuEntry>[
@ -564,7 +563,7 @@ class _HistoryChartThigy extends StatelessWidget{
bottomTitles: AxisTitles(sideTitles: SideTitles(interval: xInterval, showTitles: true, reservedSize: 30, getTitlesWidget: (double value, TitleMeta meta){ bottomTitles: AxisTitles(sideTitles: SideTitles(interval: xInterval, showTitles: true, reservedSize: 30, getTitlesWidget: (double value, TitleMeta meta){
return value != meta.min && value != meta.max ? SideTitleWidget( return value != meta.min && value != meta.max ? SideTitleWidget(
axisSide: meta.axisSide, axisSide: meta.axisSide,
child: Text(DateFormat(DateFormat.YEAR_ABBR_MONTH_DAY).format(DateTime.fromMillisecondsSinceEpoch(value.floor()))), child: Text(DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode) .format(DateTime.fromMillisecondsSinceEpoch(value.floor()))),
) : Container(); ) : Container();
})), })),
leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: leftSpace, getTitlesWidget: (double value, TitleMeta meta){ leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: leftSpace, getTitlesWidget: (double value, TitleMeta meta){

View File

@ -1,4 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/views/tl_leaderboard_view.dart'; import 'package:tetra_stats/views/tl_leaderboard_view.dart';
class RankAveragesView extends StatefulWidget { class RankAveragesView extends StatefulWidget {
@ -23,9 +25,10 @@ class RanksAverages extends State<RankAveragesView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final NumberFormat f2 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("Ranks averages"), title: Text(t.rankAveragesViewTitle),
), ),
backgroundColor: Colors.black, backgroundColor: Colors.black,
body: SafeArea( body: SafeArea(

View File

@ -221,7 +221,14 @@ class SettingsState extends State<SettingsView> {
trailing: DropdownButton( trailing: DropdownButton(
items: locales, items: locales,
value: LocaleSettings.currentLocale, value: LocaleSettings.currentLocale,
onChanged: (value) => LocaleSettings.setLocale(value!), onChanged: (value){
LocaleSettings.setLocale(value!);
if(value.languageCode == Platform.localeName.substring(0, 2)){
prefs.remove('locale');
}else{
prefs.setString('locale', value.languageCode);
}
},
), ),
), ),
const Divider(), const Divider(),

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/services/tetrio_crud.dart'; import 'package:tetra_stats/services/tetrio_crud.dart';
import 'package:tetra_stats/views/main_view.dart'; import 'package:tetra_stats/views/main_view.dart';
import 'package:tetra_stats/views/ranks_averages_view.dart'; import 'package:tetra_stats/views/ranks_averages_view.dart';
@ -13,15 +14,15 @@ class TLLeaderboardView extends StatefulWidget {
State<StatefulWidget> createState() => TLLeaderboardState(); State<StatefulWidget> createState() => TLLeaderboardState();
} }
final DateFormat dateFormat = DateFormat.yMMMd().add_Hms();
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2);
class TLLeaderboardState extends State<TLLeaderboardView> { class TLLeaderboardState extends State<TLLeaderboardView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final t = Translations.of(context);
final NumberFormat f2 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("Tetra League Leaderboard"), title: Text(t.tlLeaderboard),
actions: [ actions: [
IconButton( IconButton(
onPressed: () { onPressed: () {
@ -34,7 +35,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
); );
}, },
icon: const Icon(Icons.compress), icon: const Icon(Icons.compress),
tooltip: "Averages", tooltip: t.averages,
), ),
], ],
), ),
@ -54,9 +55,9 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
headerSliverBuilder: (context, value) { headerSliverBuilder: (context, value) {
String howManyPlayers(int numberOfPlayers) => Intl.plural( String howManyPlayers(int numberOfPlayers) => Intl.plural(
numberOfPlayers, numberOfPlayers,
zero: 'Empty list. Looks like something is wrong...', zero: t.lbViewZeroEntrys,
one: 'There is only one player... What?', one: t.lbViewOneEntry,
other: 'There are $numberOfPlayers ranked players.', other: t.lbViewManyEntrys(numberOfPlayers: numberOfPlayers),
name: 'howManyPeople', name: 'howManyPeople',
args: [numberOfPlayers], args: [numberOfPlayers],
desc: 'Description of how many people are seen in a place.', desc: 'Description of how many people are seen in a place.',

View File

@ -207,7 +207,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
higherIsBetter: true, higherIsBetter: true,
), ),
CompareThingy( CompareThingy(
label: t.statCellNum.estOfTR, label: t.statCellNum.estOfTRShort,
greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTr.esttr, greenSide: widget.record.endContext.firstWhere((element) => element.userId == widget.initPlayerId).estTr.esttr,
redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTr.esttr, redSide: widget.record.endContext.firstWhere((element) => element.userId != widget.initPlayerId).estTr.esttr,
fractionDigits: 2, fractionDigits: 2,
@ -475,8 +475,7 @@ class CompareThingy extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var f = NumberFormat("#,###.##"); NumberFormat f = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: fractionDigits ?? 0);
f.maximumFractionDigits = fractionDigits ?? 0;
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2), padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
child: Row( child: Row(

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:tetra_stats/gen/strings.g.dart';
class StatCellNum extends StatelessWidget { class StatCellNum extends StatelessWidget {
const StatCellNum( const StatCellNum(
@ -24,8 +25,7 @@ class StatCellNum extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
NumberFormat f = NumberFormat f = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: fractionDigits ?? 0);
NumberFormat.decimalPatternDigits(decimalDigits: fractionDigits ?? 0);
return Column( return Column(
children: [ children: [
Text( Text(
@ -54,7 +54,7 @@ class StatCellNum extends StatelessWidget {
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext context) => AlertDialog( builder: (BuildContext context) => AlertDialog(
title: Text(playerStatLabel, title: Text(playerStatLabel.replaceAll(RegExp(r'\n'), " "),
style: const TextStyle( style: const TextStyle(
fontFamily: "Eurostile Round Extended")), fontFamily: "Eurostile Round Extended")),
content: SingleChildScrollView( content: SingleChildScrollView(

View File

@ -7,8 +7,6 @@ import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/widgets/stat_sell_num.dart'; import 'package:tetra_stats/widgets/stat_sell_num.dart';
var fDiff = NumberFormat("+#,###.###;-#,###.###"); var fDiff = NumberFormat("+#,###.###;-#,###.###");
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2);
final NumberFormat f3 = NumberFormat.decimalPatternDigits(decimalDigits: 3);
class TLThingy extends StatelessWidget { class TLThingy extends StatelessWidget {
final TetraLeagueAlpha tl; final TetraLeagueAlpha tl;
@ -20,6 +18,8 @@ class TLThingy extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final t = Translations.of(context); final t = Translations.of(context);
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms(); final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
final NumberFormat f3 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 3);
return LayoutBuilder(builder: (context, constraints) { return LayoutBuilder(builder: (context, constraints) {
bool bigScreen = constraints.maxWidth > 768; bool bigScreen = constraints.maxWidth > 768;
return ListView.builder( return ListView.builder(
@ -315,7 +315,7 @@ class TLThingy extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"${t.statCellNum.estOfTR}:", "${bigScreen ? t.statCellNum.estOfTR : t.statCellNum.estOfTRShort}:",
style: const TextStyle(fontSize: 24), style: const TextStyle(fontSize: 24),
), ),
Text( Text(
@ -329,7 +329,7 @@ class TLThingy extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"${t.statCellNum.accOfEst}:", "${bigScreen ? t.statCellNum.accOfEst : t.statCellNum.accOfEstShort}:",
style: const TextStyle(fontSize: 24), style: const TextStyle(fontSize: 24),
), ),
Text( Text(

View File

@ -170,7 +170,7 @@ class UserThingy extends StatelessWidget {
playerStat: player.level, playerStat: player.level,
playerStatLabel: t.statCellNum.xpLevel, playerStatLabel: t.statCellNum.xpLevel,
isScreenBig: bigScreen, isScreenBig: bigScreen,
alertWidgets: [Text("${NumberFormat.decimalPatternDigits(decimalDigits: 2).format(player.xp)} XP", style: const TextStyle(fontFamily: "Eurostile Round Extended"),), Text("${t.statCellNum.xpProgress}: ${((player.level - player.level.floor()) * 100).toStringAsFixed(2)} %"), Text("${t.statCellNum.xpFrom0To5000}: ${((player.xp / 67009017.7589378) * 100).toStringAsFixed(2)} %")], alertWidgets: [Text("${NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2).format(player.xp)} XP", style: const TextStyle(fontFamily: "Eurostile Round Extended"),), Text("${t.statCellNum.xpProgress}: ${((player.level - player.level.floor()) * 100).toStringAsFixed(2)} %"), Text("${t.statCellNum.xpFrom0To5000}: ${((player.xp / 67009017.7589378) * 100).toStringAsFixed(2)} %")],
okText: t.popupActions.ok, okText: t.popupActions.ok,
higherIsBetter: true, higherIsBetter: true,
), ),

View File

@ -11,6 +11,8 @@
"other": "Other", "other": "Other",
"zen": "Zen", "zen": "Zen",
"bio": "Bio", "bio": "Bio",
"openSearch": "Search player",
"closeSearch": "Close search",
"refresh": "Refresh", "refresh": "Refresh",
"showStoredData": "Show stored data", "showStoredData": "Show stored data",
"statsCalc": "Stats Calculator", "statsCalc": "Stats Calculator",
@ -94,6 +96,11 @@
"fromBeginning": "From beginning", "fromBeginning": "From beginning",
"calc": "Calc", "calc": "Calc",
"calcViewNoValues": "Enter values to calculate the stats", "calcViewNoValues": "Enter values to calculate the stats",
"rankAveragesViewTitle": "Ranks cutoff and average stats",
"averages": "Averages",
"lbViewZeroEntrys": "Empty list. Looks like something is wrong...",
"lbViewOneEntry": "There is only one player... What?",
"lbViewManyEntrys": "There are ${numberOfPlayers} ranked players.",
"statCellNum":{ "statCellNum":{
"xpLevel": "XP Level", "xpLevel": "XP Level",
"xpProgress": "Progress to next level", "xpProgress": "Progress to next level",
@ -121,6 +128,7 @@
"keys": "Key\nPresses", "keys": "Key\nPresses",
"kpp": "KP Per\nPiece", "kpp": "KP Per\nPiece",
"kps": "KP Per\nSecond", "kps": "KP Per\nSecond",
"tr": "Tetra Rating",
"app": "Attack Per Piece", "app": "Attack Per Piece",
"appDescription": "(Abbreviated as APP) Main efficiency metric. Tells how many attack you producing 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", "vsapmDescription": "Basically, tells how much and how efficient you using garbage in your attacks",
@ -139,7 +147,9 @@
"area": "Area", "area": "Area",
"areaDescription": "How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections", "areaDescription": "How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections",
"estOfTR": "Est. of TR", "estOfTR": "Est. of TR",
"accOfEst": "Accuracy" "estOfTRShort": "Est. TR",
"accOfEst": "Accuracy",
"accOfEstShort": "Acc."
}, },
"playerRole(map)": { "playerRole(map)": {
"user": "User", "user": "User",

View File

@ -11,6 +11,8 @@
"other": "Другое", "other": "Другое",
"zen": "Дзен", "zen": "Дзен",
"bio": "Биография", "bio": "Биография",
"openSearch": "Искать игрока",
"closeSearch": "Закрыть поиск",
"refresh": "Обновить", "refresh": "Обновить",
"showStoredData": "Показать сохранённые данные", "showStoredData": "Показать сохранённые данные",
"statsCalc": "Калькулятор статистики", "statsCalc": "Калькулятор статистики",
@ -20,7 +22,7 @@
"becameTracked": "Добавлен в список отслеживания!", "becameTracked": "Добавлен в список отслеживания!",
"stoppedBeingTracked": "Удалён из списка отслеживания!", "stoppedBeingTracked": "Удалён из списка отслеживания!",
"compare": "Сравнить", "compare": "Сравнить",
"tlLeaderboard": "Таблица лидеров Тетра Лиги", "tlLeaderboard": "Рейтинговая таблица",
"noRecords": "Нет записей", "noRecords": "Нет записей",
"noRecord": "Нет рекорда", "noRecord": "Нет рекорда",
"notEnoughData": "Недостаточно данных", "notEnoughData": "Недостаточно данных",
@ -90,10 +92,15 @@
"yes": "Да", "yes": "Да",
"no": "Нет", "no": "Нет",
"daysLater": "дней позже", "daysLater": "дней позже",
"dayseBefore": "дней до", "dayseBefore": "дней раньше",
"fromBeginning": "С начала", "fromBeginning": "С начала",
"calc": "Считать", "calc": "Считать",
"calcViewNoValues": "Введите значения, чтобы посчитать статистику", "calcViewNoValues": "Введите значения, чтобы посчитать статистику",
"rankAveragesViewTitle": "Требования рангов и средние значения",
"averages": "Средние значения",
"lbViewZeroEntrys": "Рейтинговая таблица пуста. Похоже, что-то здесь не так...",
"lbViewOneEntry": "В рейтинговой таблице всего один игрок... Чего?",
"lbViewManyEntrys": "В рейтинговой таблице находится ${numberOfPlayers} игроков.",
"statCellNum": { "statCellNum": {
"xpLevel": "Уровень\nопыта", "xpLevel": "Уровень\nопыта",
"xpProgress": "Прогресс до следующего уровня", "xpProgress": "Прогресс до следующего уровня",
@ -121,6 +128,7 @@
"keys": "Нажатий\nКлавиш", "keys": "Нажатий\nКлавиш",
"kpp": "Нажатий\nна Фигуру", "kpp": "Нажатий\nна Фигуру",
"kps": "Нажатий\nв Секунду", "kps": "Нажатий\nв Секунду",
"tr": "Тетра Рейтинг",
"app": "Атака на Фигуру", "app": "Атака на Фигуру",
"appDescription": "(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру", "appDescription": "(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру",
"vsapmDescription": "В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.", "vsapmDescription": "В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.",
@ -139,7 +147,9 @@
"area": "Area", "area": "Area",
"areaDescription": "Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM", "areaDescription": "Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM",
"estOfTR": "Расчётный TR", "estOfTR": "Расчётный TR",
"accOfEst": "Точность расчёта" "estOfTRShort": "Расч. TR",
"accOfEst": "Точность расчёта",
"accOfEstShort": "Точность"
}, },
"playerRole(map)": { "playerRole(map)": {
"user": "Пользователь", "user": "Пользователь",