i18n implemented, time to ask for help
This commit is contained in:
parent
758439f9c4
commit
c69ba0a90f
|
@ -18,10 +18,10 @@
|
|||
- ~~Ability to compare player with APM-PPS-VS stats~~
|
||||
- ~~Ability to fetch Tetra League leaderboard~~
|
||||
- ~~Average stats for ranks~~
|
||||
- ~~Ability to compare player with avgRank~~ *dev build are here*
|
||||
- UI Animations
|
||||
- i18n, EN and RU locales
|
||||
- Talk with osk about CORS and EndContext in TL matches
|
||||
- ~~Ability to compare player with avgRank~~
|
||||
- UI Animations *lol*
|
||||
- ~~i18n, EN and RU locales~~ *dev build are here*
|
||||
- Talk with osk about CORS and EndContext in TL matches *idk lol*
|
||||
- RELEASE ??? *that will be v1.0.0*
|
||||
|
||||
---
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/// Generated file. Do not edit.
|
||||
///
|
||||
/// 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
|
||||
// ignore_for_file: type=lint
|
||||
|
@ -159,6 +159,8 @@ class _StringsEn implements BaseTranslations<AppLocale, _StringsEn> {
|
|||
String get other => 'Other';
|
||||
String get zen => 'Zen';
|
||||
String get bio => 'Bio';
|
||||
String get openSearch => 'Search player';
|
||||
String get closeSearch => 'Close search';
|
||||
String get refresh => 'Refresh';
|
||||
String get showStoredData => 'Show stored data';
|
||||
String get statsCalc => 'Stats Calculator';
|
||||
|
@ -242,6 +244,11 @@ class _StringsEn implements BaseTranslations<AppLocale, _StringsEn> {
|
|||
String get fromBeginning => 'From beginning';
|
||||
String get calc => 'Calc';
|
||||
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);
|
||||
Map<String, String> get playerRole => {
|
||||
'user': 'User',
|
||||
|
@ -551,6 +558,7 @@ class _StringsStatCellNumEn {
|
|||
String get keys => 'Key\nPresses';
|
||||
String get kpp => 'KP Per\nPiece';
|
||||
String get kps => 'KP Per\nSecond';
|
||||
String get tr => 'Tetra Rating';
|
||||
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';
|
||||
|
@ -569,7 +577,9 @@ class _StringsStatCellNumEn {
|
|||
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 estOfTR => 'Est. of TR';
|
||||
String get estOfTRShort => 'Est. TR';
|
||||
String get accOfEst => 'Accuracy';
|
||||
String get accOfEstShort => 'Acc.';
|
||||
}
|
||||
|
||||
// Path: numOfGameActions
|
||||
|
@ -646,6 +656,8 @@ class _StringsRu implements _StringsEn {
|
|||
@override String get other => 'Другое';
|
||||
@override String get zen => 'Дзен';
|
||||
@override String get bio => 'Биография';
|
||||
@override String get openSearch => 'Искать игрока';
|
||||
@override String get closeSearch => 'Закрыть поиск';
|
||||
@override String get refresh => 'Обновить';
|
||||
@override String get showStoredData => 'Показать сохранённые данные';
|
||||
@override String get statsCalc => 'Калькулятор статистики';
|
||||
|
@ -655,7 +667,7 @@ class _StringsRu implements _StringsEn {
|
|||
@override String get becameTracked => 'Добавлен в список отслеживания!';
|
||||
@override String get stoppedBeingTracked => 'Удалён из списка отслеживания!';
|
||||
@override String get compare => 'Сравнить';
|
||||
@override String get tlLeaderboard => 'Таблица лидеров Тетра Лиги';
|
||||
@override String get tlLeaderboard => 'Рейтинговая таблица';
|
||||
@override String get noRecords => 'Нет записей';
|
||||
@override String get noRecord => 'Нет рекорда';
|
||||
@override String get notEnoughData => 'Недостаточно данных';
|
||||
|
@ -725,10 +737,15 @@ class _StringsRu implements _StringsEn {
|
|||
@override String get yes => 'Да';
|
||||
@override String get no => 'Нет';
|
||||
@override String get daysLater => 'дней позже';
|
||||
@override String get dayseBefore => 'дней до';
|
||||
@override String get dayseBefore => 'дней раньше';
|
||||
@override String get fromBeginning => 'С начала';
|
||||
@override String get calc => 'Считать';
|
||||
@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 Map<String, String> get playerRole => {
|
||||
'user': 'Пользователь',
|
||||
|
@ -1038,6 +1055,7 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
|
|||
@override String get keys => 'Нажатий\nКлавиш';
|
||||
@override String get kpp => 'Нажатий\nна Фигуру';
|
||||
@override String get kps => 'Нажатий\nв Секунду';
|
||||
@override String get tr => 'Тетра Рейтинг';
|
||||
@override String get app => 'Атака на Фигуру';
|
||||
@override String get appDescription => '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
|
||||
@override String get vsapmDescription => 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';
|
||||
|
@ -1056,7 +1074,9 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
|
|||
@override String get area => 'Area';
|
||||
@override String get areaDescription => 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM';
|
||||
@override String get estOfTR => 'Расчётный TR';
|
||||
@override String get estOfTRShort => 'Расч. TR';
|
||||
@override String get accOfEst => 'Точность расчёта';
|
||||
@override String get accOfEstShort => 'Точность';
|
||||
}
|
||||
|
||||
// Path: numOfGameActions
|
||||
|
@ -1112,6 +1132,8 @@ extension on _StringsEn {
|
|||
case 'other': return 'Other';
|
||||
case 'zen': return 'Zen';
|
||||
case 'bio': return 'Bio';
|
||||
case 'openSearch': return 'Search player';
|
||||
case 'closeSearch': return 'Close search';
|
||||
case 'refresh': return 'Refresh';
|
||||
case 'showStoredData': return 'Show stored data';
|
||||
case 'statsCalc': return 'Stats Calculator';
|
||||
|
@ -1195,6 +1217,11 @@ extension on _StringsEn {
|
|||
case 'fromBeginning': return 'From beginning';
|
||||
case 'calc': return 'Calc';
|
||||
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.xpProgress': return 'Progress to next level';
|
||||
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.kpp': return 'KP Per\nPiece';
|
||||
case 'statCellNum.kps': return 'KP Per\nSecond';
|
||||
case 'statCellNum.tr': return 'Tetra Rating';
|
||||
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';
|
||||
|
@ -1239,7 +1267,9 @@ extension on _StringsEn {
|
|||
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.estOfTR': return 'Est. of TR';
|
||||
case 'statCellNum.estOfTRShort': return 'Est. TR';
|
||||
case 'statCellNum.accOfEst': return 'Accuracy';
|
||||
case 'statCellNum.accOfEstShort': return 'Acc.';
|
||||
case 'playerRole.user': return 'User';
|
||||
case 'playerRole.banned': return 'Banned';
|
||||
case 'playerRole.bot': return 'Bot';
|
||||
|
@ -1534,6 +1564,8 @@ extension on _StringsRu {
|
|||
case 'other': return 'Другое';
|
||||
case 'zen': return 'Дзен';
|
||||
case 'bio': return 'Биография';
|
||||
case 'openSearch': return 'Искать игрока';
|
||||
case 'closeSearch': return 'Закрыть поиск';
|
||||
case 'refresh': return 'Обновить';
|
||||
case 'showStoredData': return 'Показать сохранённые данные';
|
||||
case 'statsCalc': return 'Калькулятор статистики';
|
||||
|
@ -1543,7 +1575,7 @@ extension on _StringsRu {
|
|||
case 'becameTracked': return 'Добавлен в список отслеживания!';
|
||||
case 'stoppedBeingTracked': return 'Удалён из списка отслеживания!';
|
||||
case 'compare': return 'Сравнить';
|
||||
case 'tlLeaderboard': return 'Таблица лидеров Тетра Лиги';
|
||||
case 'tlLeaderboard': return 'Рейтинговая таблица';
|
||||
case 'noRecords': return 'Нет записей';
|
||||
case 'noRecord': return 'Нет рекорда';
|
||||
case 'notEnoughData': return 'Недостаточно данных';
|
||||
|
@ -1613,10 +1645,15 @@ extension on _StringsRu {
|
|||
case 'yes': return 'Да';
|
||||
case 'no': return 'Нет';
|
||||
case 'daysLater': return 'дней позже';
|
||||
case 'dayseBefore': return 'дней до';
|
||||
case 'dayseBefore': return 'дней раньше';
|
||||
case 'fromBeginning': return 'С начала';
|
||||
case 'calc': 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.xpProgress': return 'Прогресс до следующего уровня';
|
||||
case 'statCellNum.xpFrom0To5000': return 'Прогресс от 0 XP до 5000 уровня';
|
||||
|
@ -1643,6 +1680,7 @@ extension on _StringsRu {
|
|||
case 'statCellNum.keys': return 'Нажатий\nКлавиш';
|
||||
case 'statCellNum.kpp': return 'Нажатий\nна Фигуру';
|
||||
case 'statCellNum.kps': return 'Нажатий\nв Секунду';
|
||||
case 'statCellNum.tr': return 'Тетра Рейтинг';
|
||||
case 'statCellNum.app': return 'Атака на Фигуру';
|
||||
case 'statCellNum.appDescription': return '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
|
||||
case 'statCellNum.vsapmDescription': return 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';
|
||||
|
@ -1661,7 +1699,9 @@ extension on _StringsRu {
|
|||
case 'statCellNum.area': return 'Area';
|
||||
case 'statCellNum.areaDescription': return 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM';
|
||||
case 'statCellNum.estOfTR': return 'Расчётный TR';
|
||||
case 'statCellNum.estOfTRShort': return 'Расч. TR';
|
||||
case 'statCellNum.accOfEst': return 'Точность расчёта';
|
||||
case 'statCellNum.accOfEstShort': return 'Точность';
|
||||
case 'playerRole.user': return 'Пользователь';
|
||||
case 'playerRole.banned': return 'Заблокированный пользователь';
|
||||
case 'playerRole.bot': return 'Бот';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.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/calc_view.dart';
|
||||
|
||||
void main() {
|
||||
void main() async {
|
||||
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
|
||||
sqfliteFfiInit();
|
||||
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(
|
||||
child: MyApp(),
|
||||
));
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
|
|
|
@ -297,8 +297,7 @@ class _ListEntry extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var f = NumberFormat("#,###.##");
|
||||
f.maximumFractionDigits = fractionDigits ?? 0;
|
||||
NumberFormat f = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: fractionDigits ?? 0);
|
||||
return ListTile(title: Text(label), trailing: Text(f.format(value), style: const TextStyle(fontSize: 22)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -593,7 +593,7 @@ class CompareState extends State<CompareView> {
|
|||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.estOfTR,
|
||||
label: t.statCellNum.estOfTRShort,
|
||||
greenSide: theGreenSide[2].estTr!.esttr,
|
||||
redSide: theRedSide[2].estTr!.esttr,
|
||||
fractionDigits: 2,
|
||||
|
@ -604,7 +604,7 @@ class CompareState extends State<CompareView> {
|
|||
greenSideMode != Mode.stats &&
|
||||
redSideMode != Mode.stats)
|
||||
CompareThingy(
|
||||
label: t.statCellNum.accOfEst,
|
||||
label: t.statCellNum.accOfEstShort,
|
||||
greenSide: theGreenSide[2].esttracc!,
|
||||
redSide: theRedSide[2].esttracc!,
|
||||
fractionDigits: 2,
|
||||
|
@ -964,7 +964,7 @@ class CompareThingy extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var f = NumberFormat("#,###.##");
|
||||
var f = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode);
|
||||
f.maximumFractionDigits = fractionDigits ?? 0;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
|
||||
|
@ -1278,7 +1278,7 @@ class CompareRegTimeThingy extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
DateFormat f = DateFormat.yMMMd();
|
||||
DateFormat f = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
|
||||
child: Row(
|
||||
|
|
|
@ -27,8 +27,8 @@ const allowedHeightForPlayerIdInPixels = 40.0;
|
|||
const allowedHeightForPlayerBioInPixels = 30.0;
|
||||
const givenTextHeightByScreenPercentage = 0.3;
|
||||
final NumberFormat timeInSec = NumberFormat("#,###.###s.");
|
||||
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2);
|
||||
final NumberFormat f4 = NumberFormat.decimalPatternDigits(decimalDigits: 4);
|
||||
final NumberFormat f2 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 2);
|
||||
final NumberFormat f4 = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: 4);
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
|
||||
class MainView extends StatefulWidget {
|
||||
|
@ -132,25 +132,24 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
|||
}on RangeError {
|
||||
compareWith = null;
|
||||
}
|
||||
|
||||
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.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.pps != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.pps!)], child: const Text("Pieces Per Second")),
|
||||
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.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!.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!.dsp)], child: const Text("Downstack Per Piece")),
|
||||
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: 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: 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: 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: 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: 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!.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!.gbe)], child: const Text("Garbage Efficiency")),
|
||||
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!.area)], child: const Text("Area")),
|
||||
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.esttracc != null) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.esttracc!)], child: const Text("Accuracy of Est.")),
|
||||
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: 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: 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: 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: 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: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))),
|
||||
];
|
||||
tlMatches.addAll(await teto.getTLMatchesbyPlayerID(me.userId));
|
||||
for (var match in tlStream.records) {
|
||||
|
@ -208,7 +207,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
|||
});
|
||||
},
|
||||
icon: const Icon(Icons.search),
|
||||
tooltip: "Search player",
|
||||
tooltip: t.openSearch,
|
||||
)
|
||||
: IconButton(
|
||||
onPressed: () {
|
||||
|
@ -217,7 +216,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
|||
});
|
||||
},
|
||||
icon: const Icon(Icons.clear),
|
||||
tooltip: "Close search",
|
||||
tooltip: t.closeSearch,
|
||||
),
|
||||
PopupMenuButton(
|
||||
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){
|
||||
return value != meta.min && value != meta.max ? SideTitleWidget(
|
||||
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();
|
||||
})),
|
||||
leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: leftSpace, getTitlesWidget: (double value, TitleMeta meta){
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
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';
|
||||
|
||||
class RankAveragesView extends StatefulWidget {
|
||||
|
@ -23,9 +25,10 @@ class RanksAverages extends State<RankAveragesView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final NumberFormat f2 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Ranks averages"),
|
||||
title: Text(t.rankAveragesViewTitle),
|
||||
),
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
|
|
|
@ -221,7 +221,14 @@ class SettingsState extends State<SettingsView> {
|
|||
trailing: DropdownButton(
|
||||
items: locales,
|
||||
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(),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.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/views/main_view.dart';
|
||||
import 'package:tetra_stats/views/ranks_averages_view.dart';
|
||||
|
@ -13,15 +14,15 @@ class TLLeaderboardView extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => TLLeaderboardState();
|
||||
}
|
||||
|
||||
final DateFormat dateFormat = DateFormat.yMMMd().add_Hms();
|
||||
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2);
|
||||
|
||||
class TLLeaderboardState extends State<TLLeaderboardView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
final NumberFormat f2 = NumberFormat.decimalPattern(LocaleSettings.currentLocale.languageCode)..maximumFractionDigits = 2;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Tetra League Leaderboard"),
|
||||
title: Text(t.tlLeaderboard),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
|
@ -34,7 +35,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
|
|||
);
|
||||
},
|
||||
icon: const Icon(Icons.compress),
|
||||
tooltip: "Averages",
|
||||
tooltip: t.averages,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -54,9 +55,9 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
|
|||
headerSliverBuilder: (context, value) {
|
||||
String howManyPlayers(int numberOfPlayers) => Intl.plural(
|
||||
numberOfPlayers,
|
||||
zero: 'Empty list. Looks like something is wrong...',
|
||||
one: 'There is only one player... What?',
|
||||
other: 'There are $numberOfPlayers ranked players.',
|
||||
zero: t.lbViewZeroEntrys,
|
||||
one: t.lbViewOneEntry,
|
||||
other: t.lbViewManyEntrys(numberOfPlayers: numberOfPlayers),
|
||||
name: 'howManyPeople',
|
||||
args: [numberOfPlayers],
|
||||
desc: 'Description of how many people are seen in a place.',
|
||||
|
|
|
@ -207,7 +207,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
higherIsBetter: true,
|
||||
),
|
||||
CompareThingy(
|
||||
label: t.statCellNum.estOfTR,
|
||||
label: t.statCellNum.estOfTRShort,
|
||||
greenSide: 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,
|
||||
|
@ -475,8 +475,7 @@ class CompareThingy extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var f = NumberFormat("#,###.##");
|
||||
f.maximumFractionDigits = fractionDigits ?? 0;
|
||||
NumberFormat f = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: fractionDigits ?? 0);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
|
||||
child: Row(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
|
||||
class StatCellNum extends StatelessWidget {
|
||||
const StatCellNum(
|
||||
|
@ -24,8 +25,7 @@ class StatCellNum extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
NumberFormat f =
|
||||
NumberFormat.decimalPatternDigits(decimalDigits: fractionDigits ?? 0);
|
||||
NumberFormat f = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: fractionDigits ?? 0);
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
|
@ -54,7 +54,7 @@ class StatCellNum extends StatelessWidget {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text(playerStatLabel,
|
||||
title: Text(playerStatLabel.replaceAll(RegExp(r'\n'), " "),
|
||||
style: const TextStyle(
|
||||
fontFamily: "Eurostile Round Extended")),
|
||||
content: SingleChildScrollView(
|
||||
|
|
|
@ -7,8 +7,6 @@ import 'package:tetra_stats/gen/strings.g.dart';
|
|||
import 'package:tetra_stats/widgets/stat_sell_num.dart';
|
||||
|
||||
var fDiff = NumberFormat("+#,###.###;-#,###.###");
|
||||
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2);
|
||||
final NumberFormat f3 = NumberFormat.decimalPatternDigits(decimalDigits: 3);
|
||||
|
||||
class TLThingy extends StatelessWidget {
|
||||
final TetraLeagueAlpha tl;
|
||||
|
@ -20,6 +18,8 @@ class TLThingy extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
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) {
|
||||
bool bigScreen = constraints.maxWidth > 768;
|
||||
return ListView.builder(
|
||||
|
@ -315,7 +315,7 @@ class TLThingy extends StatelessWidget {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"${t.statCellNum.estOfTR}:",
|
||||
"${bigScreen ? t.statCellNum.estOfTR : t.statCellNum.estOfTRShort}:",
|
||||
style: const TextStyle(fontSize: 24),
|
||||
),
|
||||
Text(
|
||||
|
@ -329,7 +329,7 @@ class TLThingy extends StatelessWidget {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"${t.statCellNum.accOfEst}:",
|
||||
"${bigScreen ? t.statCellNum.accOfEst : t.statCellNum.accOfEstShort}:",
|
||||
style: const TextStyle(fontSize: 24),
|
||||
),
|
||||
Text(
|
||||
|
|
|
@ -170,7 +170,7 @@ class UserThingy extends StatelessWidget {
|
|||
playerStat: player.level,
|
||||
playerStatLabel: t.statCellNum.xpLevel,
|
||||
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,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
"other": "Other",
|
||||
"zen": "Zen",
|
||||
"bio": "Bio",
|
||||
"openSearch": "Search player",
|
||||
"closeSearch": "Close search",
|
||||
"refresh": "Refresh",
|
||||
"showStoredData": "Show stored data",
|
||||
"statsCalc": "Stats Calculator",
|
||||
|
@ -94,6 +96,11 @@
|
|||
"fromBeginning": "From beginning",
|
||||
"calc": "Calc",
|
||||
"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":{
|
||||
"xpLevel": "XP Level",
|
||||
"xpProgress": "Progress to next level",
|
||||
|
@ -121,6 +128,7 @@
|
|||
"keys": "Key\nPresses",
|
||||
"kpp": "KP Per\nPiece",
|
||||
"kps": "KP Per\nSecond",
|
||||
"tr": "Tetra Rating",
|
||||
"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",
|
||||
|
@ -139,7 +147,9 @@
|
|||
"area": "Area",
|
||||
"areaDescription": "How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections",
|
||||
"estOfTR": "Est. of TR",
|
||||
"accOfEst": "Accuracy"
|
||||
"estOfTRShort": "Est. TR",
|
||||
"accOfEst": "Accuracy",
|
||||
"accOfEstShort": "Acc."
|
||||
},
|
||||
"playerRole(map)": {
|
||||
"user": "User",
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
"other": "Другое",
|
||||
"zen": "Дзен",
|
||||
"bio": "Биография",
|
||||
"openSearch": "Искать игрока",
|
||||
"closeSearch": "Закрыть поиск",
|
||||
"refresh": "Обновить",
|
||||
"showStoredData": "Показать сохранённые данные",
|
||||
"statsCalc": "Калькулятор статистики",
|
||||
|
@ -20,7 +22,7 @@
|
|||
"becameTracked": "Добавлен в список отслеживания!",
|
||||
"stoppedBeingTracked": "Удалён из списка отслеживания!",
|
||||
"compare": "Сравнить",
|
||||
"tlLeaderboard": "Таблица лидеров Тетра Лиги",
|
||||
"tlLeaderboard": "Рейтинговая таблица",
|
||||
"noRecords": "Нет записей",
|
||||
"noRecord": "Нет рекорда",
|
||||
"notEnoughData": "Недостаточно данных",
|
||||
|
@ -90,10 +92,15 @@
|
|||
"yes": "Да",
|
||||
"no": "Нет",
|
||||
"daysLater": "дней позже",
|
||||
"dayseBefore": "дней до",
|
||||
"dayseBefore": "дней раньше",
|
||||
"fromBeginning": "С начала",
|
||||
"calc": "Считать",
|
||||
"calcViewNoValues": "Введите значения, чтобы посчитать статистику",
|
||||
"rankAveragesViewTitle": "Требования рангов и средние значения",
|
||||
"averages": "Средние значения",
|
||||
"lbViewZeroEntrys": "Рейтинговая таблица пуста. Похоже, что-то здесь не так...",
|
||||
"lbViewOneEntry": "В рейтинговой таблице всего один игрок... Чего?",
|
||||
"lbViewManyEntrys": "В рейтинговой таблице находится ${numberOfPlayers} игроков.",
|
||||
"statCellNum": {
|
||||
"xpLevel": "Уровень\nопыта",
|
||||
"xpProgress": "Прогресс до следующего уровня",
|
||||
|
@ -121,6 +128,7 @@
|
|||
"keys": "Нажатий\nКлавиш",
|
||||
"kpp": "Нажатий\nна Фигуру",
|
||||
"kps": "Нажатий\nв Секунду",
|
||||
"tr": "Тетра Рейтинг",
|
||||
"app": "Атака на Фигуру",
|
||||
"appDescription": "(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру",
|
||||
"vsapmDescription": "В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.",
|
||||
|
@ -139,7 +147,9 @@
|
|||
"area": "Area",
|
||||
"areaDescription": "Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM",
|
||||
"estOfTR": "Расчётный TR",
|
||||
"accOfEst": "Точность расчёта"
|
||||
"estOfTRShort": "Расч. TR",
|
||||
"accOfEst": "Точность расчёта",
|
||||
"accOfEstShort": "Точность"
|
||||
},
|
||||
"playerRole(map)": {
|
||||
"user": "Пользователь",
|
||||
|
|
Loading…
Reference in New Issue