Continuing to implement i18n
This commit is contained in:
parent
079c922b29
commit
1db203b3a5
|
@ -59,7 +59,7 @@ jobs:
|
|||
prerelease: true
|
||||
allowUpdates: true
|
||||
discussionCategory: autobuilded-releases
|
||||
artifacts: "build/app/outputs/apk/debug/*"
|
||||
artifacts: "build/app/outputs/apk/flutter-apk/*"
|
||||
tag: Auto-${{ github.run_number }}
|
||||
body: This build was builded with GitHub Action workflow
|
||||
token: ${{ secrets.TOKEN }}
|
|
@ -1,9 +1,9 @@
|
|||
/// Generated file. Do not edit.
|
||||
///
|
||||
/// Locales: 2
|
||||
/// Strings: 680 (340 per locale)
|
||||
/// Strings: 788 (394 per locale)
|
||||
///
|
||||
/// Built on 2023-07-11 at 16:43 UTC
|
||||
/// Built on 2023-07-12 at 15:02 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
|
@ -193,6 +193,37 @@ class _StringsEn implements BaseTranslations<AppLocale, _StringsEn> {
|
|||
String gamesUntilRanked({required Object left}) => '${left} games until being ranked';
|
||||
String get nerdStats => 'Nerd Stats';
|
||||
String get playersYouTrack => 'Players you track';
|
||||
String get formula => 'Formula';
|
||||
String get exactValue => 'Exact value';
|
||||
String get neverPlayedTL => 'That user never played Tetra League';
|
||||
String get exportDB => 'Export local database';
|
||||
String get exportDBDescription => 'It contains states and Tetra League records of the tracked players and list of tracked players.';
|
||||
String get desktopExportAlertTitle => 'Desktop export';
|
||||
String get desktopExportText => 'It seems like you using this app on desktop. Check your documents folder, you should find "TetraStats.db". Copy it somewhere';
|
||||
String get androidExportAlertTitle => 'Android export';
|
||||
String androidExportText({required Object exportedDB}) => 'Exported.\n${exportedDB}';
|
||||
String get importDB => 'Import local database';
|
||||
String get importDBDescription => 'Restore your backup. Notice that already stored database will be overwritten.';
|
||||
String get importWrongFileType => 'Wrong file type';
|
||||
String get importCancelled => 'Operation was cancelled';
|
||||
String get importSuccess => 'Import successful';
|
||||
String get yourID => 'Your TETR.IO account';
|
||||
String get yourIDAlertTitle => 'Your TETR.IO account nickname or ID';
|
||||
String get yourIDText => 'Every time when app loads, stats of that player will be fetched. Please prefer ID over nickname because nickname can be changed.';
|
||||
String get language => 'Language';
|
||||
String get aboutApp => 'About app';
|
||||
String aboutAppText({required Object appName, required Object packageName, required Object version, required Object buildNumber}) => '${appName} (${packageName}) Version ${version} Build ${buildNumber}\n\nDeveloped by dan63047\nFormulas provided by kerrmunism';
|
||||
String stateViewTitle({required Object nickname, required Object date}) => '${nickname} account on ${date}';
|
||||
String statesViewTitle({required Object number, required Object nickname}) => '${number} states of ${nickname} account';
|
||||
String statesViewEntry({required Object level, required Object gameTime, required Object friends, required Object rd}) => 'Level ${level}, ${gameTime} of gametime, ${friends} friends, ${rd} RD';
|
||||
String stateRemoved({required Object date}) => '${date} state was removed from database!';
|
||||
String get trackedPlayersViewTitle => 'Stored data';
|
||||
String get trackedPlayersZeroEntrys => 'Empty list. Press "Track" button in previous view to add current player here';
|
||||
String get trackedPlayersOneEntry => 'There is only one player';
|
||||
String trackedPlayersManyEntrys({required Object numberOfPlayers}) => 'There are ${numberOfPlayers} players';
|
||||
String trackedPlayersEntry({required Object nickname, required Object numberOfStates}) => '${nickname}: ${numberOfStates} states';
|
||||
String trackedPlayersDescription({required Object firstStateDate, required Object lastStateDate}) => 'From ${firstStateDate} until ${lastStateDate}';
|
||||
String trackedPlayersStatesDeleted({required Object nickname}) => '${nickname} states was removed from database!';
|
||||
late final _StringsStatCellNumEn statCellNum = _StringsStatCellNumEn._(_root);
|
||||
Map<String, String> get playerRole => {
|
||||
'user': 'User',
|
||||
|
@ -477,6 +508,8 @@ class _StringsStatCellNumEn {
|
|||
|
||||
// Translations
|
||||
String get xpLevel => 'XP Level';
|
||||
String get xpProgress => 'Progress to next level';
|
||||
String get xpFrom0To5000 => 'Progress from 0 XP to level 5000';
|
||||
String get hoursPlayed => 'Hours\nPlayed';
|
||||
String get onlineGames => 'Online\nGames';
|
||||
String get gamesWon => 'Games\nWon';
|
||||
|
@ -498,6 +531,25 @@ class _StringsStatCellNumEn {
|
|||
String get keys => 'Key\nPresses';
|
||||
String get kpp => 'KP Per\nPiece';
|
||||
String get kps => 'KP Per\nSecond';
|
||||
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';
|
||||
String get dss => 'Downstack\nPer Second';
|
||||
String get dssDescription => 'Downstack per Second measures how many garbage lines you clear in a second.';
|
||||
String get dsp => 'Downstack\nPer Piece';
|
||||
String get dspDescription => 'Downstack per Piece measures how many garbage lines you clear per piece.';
|
||||
String get appdsp => 'APP + DS/P';
|
||||
String get appdspDescription => 'Just a sum of Attack per Piece and Downstack per Piece.';
|
||||
String get cheese => 'Cheese\nIndex';
|
||||
String get cheeseDescription => 'Cheese Index is an approximation how much clean / cheese garbage player sends. Lower = more clean. Higher = more cheese.\nInvented by kerrmunism';
|
||||
String get gbe => 'Garbage\nEfficiency';
|
||||
String get gbeDescription => 'Garbage Efficiency measures how well player uses their garbage. Higher = better or they use their garbage more. Lower = they mostly send their garbage back at cheese or rarely clear garbage.\nInvented by Zepheniah and Dragonboy.';
|
||||
String get nyaapp => 'Weighted\nAPP';
|
||||
String get nyaappDescription => 'Essentially, a measure of your ability to send cheese while still maintaining a high APP.\nInvented by Wertj.';
|
||||
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 accOfEst => 'Accuracy';
|
||||
}
|
||||
|
||||
// Path: numOfGameActions
|
||||
|
@ -520,6 +572,8 @@ class _StringsPopupActionsEn {
|
|||
final _StringsEn _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
String get cancel => 'Cancel';
|
||||
String get submit => 'Submit';
|
||||
String get ok => 'OK';
|
||||
}
|
||||
|
||||
|
@ -606,6 +660,37 @@ class _StringsRu implements _StringsEn {
|
|||
@override String gamesUntilRanked({required Object left}) => '${left} матчей до получения рейтинга';
|
||||
@override String get nerdStats => 'Для задротов';
|
||||
@override String get playersYouTrack => 'Отслеживаемые игроки';
|
||||
@override String get formula => 'Формула';
|
||||
@override String get exactValue => 'Точное значение';
|
||||
@override String get neverPlayedTL => 'Этот игрок никогда не играл в Тетра Лигу';
|
||||
@override String get exportDB => 'Экспортировать локальную базу данных';
|
||||
@override String get exportDBDescription => 'Она содержит состояния аккаунтов и их матчей в Тетра Лиге для отслеживаемых игроков и список таких игроков.';
|
||||
@override String get desktopExportAlertTitle => 'Экспорт на десктопе';
|
||||
@override String get desktopExportText => 'Похоже, вы используете десктопную версию. Проверьте папку "Документы", там вы должны найти файл "TetraStats.db". Скопируйте его куда-нибудь';
|
||||
@override String get androidExportAlertTitle => 'Экспорт на Android';
|
||||
@override String androidExportText({required Object exportedDB}) => 'Экспортировано.\n${exportedDB}';
|
||||
@override String get importDB => 'Импортировать локальную базу данных';
|
||||
@override String get importDBDescription => 'Восстановите свою резеврную копию. Обратите внимание, что текущая база данных будет перезаписана.';
|
||||
@override String get importWrongFileType => 'Неверный тип файла';
|
||||
@override String get importCancelled => 'Операция была отменена';
|
||||
@override String get importSuccess => 'Успешно импортировано';
|
||||
@override String get yourID => 'Ваш аккаунт в TETR.IO';
|
||||
@override String get yourIDAlertTitle => 'Никнейм или ID вашего аккаунта в TETR.IO';
|
||||
@override String get yourIDText => 'Каждый раз, когда приложение запускается, приложение будет получать статистику этого игрока. Пожалуйста, отдайте предпочтение ID, так как никнейм можно изменить.';
|
||||
@override String get language => 'Язык (Language)';
|
||||
@override String get aboutApp => 'О приложении';
|
||||
@override String aboutAppText({required Object appName, required Object packageName, required Object version, required Object buildNumber}) => '${appName} (${packageName}) Версия ${version} Сборка ${buildNumber}\n\nРазработал dan63047\nФормулы предоставил kerrmunism';
|
||||
@override String stateViewTitle({required Object nickname, required Object date}) => 'Аккаунт ${nickname} ${date}';
|
||||
@override String statesViewTitle({required Object number, required Object nickname}) => '${number} состояний аккаунта ${nickname}';
|
||||
@override String statesViewEntry({required Object level, required Object gameTime, required Object friends, required Object rd}) => '${level} уровень, ${gameTime} сыграно, ${friends} друзей, ${rd} RD';
|
||||
@override String stateRemoved({required Object }) => '${}Состояние от {date} было удалено из локальной базы данных!';
|
||||
@override String get trackedPlayersViewTitle => 'Сохранённые данные';
|
||||
@override String get trackedPlayersZeroEntrys => 'Пустой список. Вернитесь на предыдущий экран и нажмите кнопку "Отслеживать", чтобы текущий игрок появился здесь';
|
||||
@override String get trackedPlayersOneEntry => 'В списке только один игрок';
|
||||
@override String trackedPlayersManyEntrys({required Object numberOfPlayers}) => 'В списке ${numberOfPlayers} игроков';
|
||||
@override String trackedPlayersEntry({required Object nickname, required Object numberOfStates}) => '${nickname}: ${numberOfStates} состояний';
|
||||
@override String trackedPlayersDescription({required Object firstStateDate, required Object lastStateDate}) => 'Начиная с ${firstStateDate} и заканчивая ${lastStateDate}';
|
||||
@override String trackedPlayersStatesDeleted({required Object nickname}) => 'Состояния аккаунта ${nickname} были удалены из локальной базы данных!';
|
||||
@override late final _StringsStatCellNumRu statCellNum = _StringsStatCellNumRu._(_root);
|
||||
@override Map<String, String> get playerRole => {
|
||||
'user': 'Пользователь',
|
||||
|
@ -890,6 +975,8 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
|
|||
|
||||
// Translations
|
||||
@override String get xpLevel => 'Уровень\nопыта';
|
||||
@override String get xpProgress => 'Прогресс до следующего уровня';
|
||||
@override String get xpFrom0To5000 => 'Прогресс от 0 XP до 5000 уровня';
|
||||
@override String get hoursPlayed => 'Часов\nСыграно';
|
||||
@override String get onlineGames => 'Онлайн\nИгр';
|
||||
@override String get gamesWon => 'Онлайн\nПобед';
|
||||
|
@ -911,6 +998,25 @@ class _StringsStatCellNumRu implements _StringsStatCellNumEn {
|
|||
@override String get keys => 'Нажатий\nКлавиш';
|
||||
@override String get kpp => 'Нажатий\nна Фигуру';
|
||||
@override String get kps => 'Нажатий\nв Секунду';
|
||||
@override String get app => 'Атака на Фигуру';
|
||||
@override String get appDescription => '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
|
||||
@override String get vsapmDescription => 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';
|
||||
@override String get dss => 'Downstack\nв Секунду';
|
||||
@override String get dssDescription => '(Сокращенно DS/S) Downstack (спуск вниз) в Секунду показывает как много мусорных линий в среднем игрок убирает за одну секунду.';
|
||||
@override String get dsp => 'Downstack\nна Фигуру';
|
||||
@override String get dspDescription => '(Сокращенно DS/P) Downstack (спуск вниз) на Фигуру показывает как много мусорных линий в среднем игрок убирает одну фигуру.';
|
||||
@override String get appdsp => 'APP + DS/P';
|
||||
@override String get appdspDescription => 'Просто сумма Атаки на Фигуру и Downstack на Фигуру.';
|
||||
@override String get cheese => 'Индекс сыра';
|
||||
@override String get cheeseDescription => '(Сокращенно Cheese) Индекс сыра является аппроксимацией того, насколько чистый / дырявый мусор игрок отправляет. Меньше = более чистый. Больше = более дырявый.\nПридумал kerrmunism';
|
||||
@override String get gbe => 'Garbage\nEfficiency';
|
||||
@override String get gbeDescription => '(Сокращенно Gb Eff.) Garbage Efficiency показывает насколько хорошо игрок использует свой мусор. Больше = лучше (или он использует больше мусора). Меньше = в основном отправляют сыр (или он редко чистит мусор).\nПридумали Zepheniah и Dragonboy.';
|
||||
@override String get nyaapp => 'Взвешенный\nAPP';
|
||||
@override String get nyaappDescription => '(Сокращенно wAPP) По сути, показывает способность отправлять сыр, сохраняя при этом высокую эффективность.\nПридумал Wertj.';
|
||||
@override String get area => 'Area';
|
||||
@override String get areaDescription => 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM';
|
||||
@override String get estOfTR => 'Расчётный TR';
|
||||
@override String get accOfEst => 'Точность расчёта';
|
||||
}
|
||||
|
||||
// Path: numOfGameActions
|
||||
|
@ -933,6 +1039,8 @@ class _StringsPopupActionsRu implements _StringsPopupActionsEn {
|
|||
@override final _StringsRu _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get cancel => 'Отменить';
|
||||
@override String get submit => 'Подтвердить';
|
||||
@override String get ok => 'OK';
|
||||
}
|
||||
|
||||
|
@ -998,7 +1106,40 @@ extension on _StringsEn {
|
|||
case 'gamesUntilRanked': return ({required Object left}) => '${left} games until being ranked';
|
||||
case 'nerdStats': return 'Nerd Stats';
|
||||
case 'playersYouTrack': return 'Players you track';
|
||||
case 'formula': return 'Formula';
|
||||
case 'exactValue': return 'Exact value';
|
||||
case 'neverPlayedTL': return 'That user never played Tetra League';
|
||||
case 'exportDB': return 'Export local database';
|
||||
case 'exportDBDescription': return 'It contains states and Tetra League records of the tracked players and list of tracked players.';
|
||||
case 'desktopExportAlertTitle': return 'Desktop export';
|
||||
case 'desktopExportText': return 'It seems like you using this app on desktop. Check your documents folder, you should find "TetraStats.db". Copy it somewhere';
|
||||
case 'androidExportAlertTitle': return 'Android export';
|
||||
case 'androidExportText': return ({required Object exportedDB}) => 'Exported.\n${exportedDB}';
|
||||
case 'importDB': return 'Import local database';
|
||||
case 'importDBDescription': return 'Restore your backup. Notice that already stored database will be overwritten.';
|
||||
case 'importWrongFileType': return 'Wrong file type';
|
||||
case 'importCancelled': return 'Operation was cancelled';
|
||||
case 'importSuccess': return 'Import successful';
|
||||
case 'yourID': return 'Your TETR.IO account';
|
||||
case 'yourIDAlertTitle': return 'Your TETR.IO account nickname or ID';
|
||||
case 'yourIDText': return 'Every time when app loads, stats of that player will be fetched. Please prefer ID over nickname because nickname can be changed.';
|
||||
case 'language': return 'Language';
|
||||
case 'aboutApp': return 'About app';
|
||||
case 'aboutAppText': return ({required Object appName, required Object packageName, required Object version, required Object buildNumber}) => '${appName} (${packageName}) Version ${version} Build ${buildNumber}\n\nDeveloped by dan63047\nFormulas provided by kerrmunism';
|
||||
case 'stateViewTitle': return ({required Object nickname, required Object date}) => '${nickname} account on ${date}';
|
||||
case 'statesViewTitle': return ({required Object number, required Object nickname}) => '${number} states of ${nickname} account';
|
||||
case 'statesViewEntry': return ({required Object level, required Object gameTime, required Object friends, required Object rd}) => 'Level ${level}, ${gameTime} of gametime, ${friends} friends, ${rd} RD';
|
||||
case 'stateRemoved': return ({required Object date}) => '${date} state was removed from database!';
|
||||
case 'trackedPlayersViewTitle': return 'Stored data';
|
||||
case 'trackedPlayersZeroEntrys': return 'Empty list. Press "Track" button in previous view to add current player here';
|
||||
case 'trackedPlayersOneEntry': return 'There is only one player';
|
||||
case 'trackedPlayersManyEntrys': return ({required Object numberOfPlayers}) => 'There are ${numberOfPlayers} players';
|
||||
case 'trackedPlayersEntry': return ({required Object nickname, required Object numberOfStates}) => '${nickname}: ${numberOfStates} states';
|
||||
case 'trackedPlayersDescription': return ({required Object firstStateDate, required Object lastStateDate}) => 'From ${firstStateDate} until ${lastStateDate}';
|
||||
case 'trackedPlayersStatesDeleted': return ({required Object nickname}) => '${nickname} states was removed from database!';
|
||||
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';
|
||||
case 'statCellNum.hoursPlayed': return 'Hours\nPlayed';
|
||||
case 'statCellNum.onlineGames': return 'Online\nGames';
|
||||
case 'statCellNum.gamesWon': return 'Games\nWon';
|
||||
|
@ -1020,6 +1161,25 @@ 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.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';
|
||||
case 'statCellNum.dss': return 'Downstack\nPer Second';
|
||||
case 'statCellNum.dssDescription': return 'Downstack per Second measures how many garbage lines you clear in a second.';
|
||||
case 'statCellNum.dsp': return 'Downstack\nPer Piece';
|
||||
case 'statCellNum.dspDescription': return 'Downstack per Piece measures how many garbage lines you clear per piece.';
|
||||
case 'statCellNum.appdsp': return 'APP + DS/P';
|
||||
case 'statCellNum.appdspDescription': return 'Just a sum of Attack per Piece and Downstack per Piece.';
|
||||
case 'statCellNum.cheese': return 'Cheese\nIndex';
|
||||
case 'statCellNum.cheeseDescription': return 'Cheese Index is an approximation how much clean / cheese garbage player sends. Lower = more clean. Higher = more cheese.\nInvented by kerrmunism';
|
||||
case 'statCellNum.gbe': return 'Garbage\nEfficiency';
|
||||
case 'statCellNum.gbeDescription': return 'Garbage Efficiency measures how well player uses their garbage. Higher = better or they use their garbage more. Lower = they mostly send their garbage back at cheese or rarely clear garbage.\nInvented by Zepheniah and Dragonboy.';
|
||||
case 'statCellNum.nyaapp': return 'Weighted\nAPP';
|
||||
case 'statCellNum.nyaappDescription': return 'Essentially, a measure of your ability to send cheese while still maintaining a high APP.\nInvented by Wertj.';
|
||||
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.accOfEst': return 'Accuracy';
|
||||
case 'playerRole.user': return 'User';
|
||||
case 'playerRole.banned': return 'Banned';
|
||||
case 'playerRole.bot': return 'Bot';
|
||||
|
@ -1032,6 +1192,8 @@ extension on _StringsEn {
|
|||
case 'numOfGameActions.hold': return 'Holds';
|
||||
case 'numOfGameActions.tspinsTotal': return 'T-spins total';
|
||||
case 'numOfGameActions.lineClears': return 'Line clears';
|
||||
case 'popupActions.cancel': return 'Cancel';
|
||||
case 'popupActions.submit': return 'Submit';
|
||||
case 'popupActions.ok': return 'OK';
|
||||
case 'errors.connection': return ({required Object code, required Object message}) => 'Some issue with connection: ${code} ${message}';
|
||||
case 'errors.noSuchUser': return 'No such user';
|
||||
|
@ -1346,7 +1508,40 @@ extension on _StringsRu {
|
|||
case 'gamesUntilRanked': return ({required Object left}) => '${left} матчей до получения рейтинга';
|
||||
case 'nerdStats': return 'Для задротов';
|
||||
case 'playersYouTrack': return 'Отслеживаемые игроки';
|
||||
case 'formula': return 'Формула';
|
||||
case 'exactValue': return 'Точное значение';
|
||||
case 'neverPlayedTL': return 'Этот игрок никогда не играл в Тетра Лигу';
|
||||
case 'exportDB': return 'Экспортировать локальную базу данных';
|
||||
case 'exportDBDescription': return 'Она содержит состояния аккаунтов и их матчей в Тетра Лиге для отслеживаемых игроков и список таких игроков.';
|
||||
case 'desktopExportAlertTitle': return 'Экспорт на десктопе';
|
||||
case 'desktopExportText': return 'Похоже, вы используете десктопную версию. Проверьте папку "Документы", там вы должны найти файл "TetraStats.db". Скопируйте его куда-нибудь';
|
||||
case 'androidExportAlertTitle': return 'Экспорт на Android';
|
||||
case 'androidExportText': return ({required Object exportedDB}) => 'Экспортировано.\n${exportedDB}';
|
||||
case 'importDB': return 'Импортировать локальную базу данных';
|
||||
case 'importDBDescription': return 'Восстановите свою резеврную копию. Обратите внимание, что текущая база данных будет перезаписана.';
|
||||
case 'importWrongFileType': return 'Неверный тип файла';
|
||||
case 'importCancelled': return 'Операция была отменена';
|
||||
case 'importSuccess': return 'Успешно импортировано';
|
||||
case 'yourID': return 'Ваш аккаунт в TETR.IO';
|
||||
case 'yourIDAlertTitle': return 'Никнейм или ID вашего аккаунта в TETR.IO';
|
||||
case 'yourIDText': return 'Каждый раз, когда приложение запускается, приложение будет получать статистику этого игрока. Пожалуйста, отдайте предпочтение ID, так как никнейм можно изменить.';
|
||||
case 'language': return 'Язык (Language)';
|
||||
case 'aboutApp': return 'О приложении';
|
||||
case 'aboutAppText': return ({required Object appName, required Object packageName, required Object version, required Object buildNumber}) => '${appName} (${packageName}) Версия ${version} Сборка ${buildNumber}\n\nРазработал dan63047\nФормулы предоставил kerrmunism';
|
||||
case 'stateViewTitle': return ({required Object nickname, required Object date}) => 'Аккаунт ${nickname} ${date}';
|
||||
case 'statesViewTitle': return ({required Object number, required Object nickname}) => '${number} состояний аккаунта ${nickname}';
|
||||
case 'statesViewEntry': return ({required Object level, required Object gameTime, required Object friends, required Object rd}) => '${level} уровень, ${gameTime} сыграно, ${friends} друзей, ${rd} RD';
|
||||
case 'stateRemoved': return ({required Object }) => '${}Состояние от {date} было удалено из локальной базы данных!';
|
||||
case 'trackedPlayersViewTitle': return 'Сохранённые данные';
|
||||
case 'trackedPlayersZeroEntrys': return 'Пустой список. Вернитесь на предыдущий экран и нажмите кнопку "Отслеживать", чтобы текущий игрок появился здесь';
|
||||
case 'trackedPlayersOneEntry': return 'В списке только один игрок';
|
||||
case 'trackedPlayersManyEntrys': return ({required Object numberOfPlayers}) => 'В списке ${numberOfPlayers} игроков';
|
||||
case 'trackedPlayersEntry': return ({required Object nickname, required Object numberOfStates}) => '${nickname}: ${numberOfStates} состояний';
|
||||
case 'trackedPlayersDescription': return ({required Object firstStateDate, required Object lastStateDate}) => 'Начиная с ${firstStateDate} и заканчивая ${lastStateDate}';
|
||||
case 'trackedPlayersStatesDeleted': return ({required Object nickname}) => 'Состояния аккаунта ${nickname} были удалены из локальной базы данных!';
|
||||
case 'statCellNum.xpLevel': return 'Уровень\nопыта';
|
||||
case 'statCellNum.xpProgress': return 'Прогресс до следующего уровня';
|
||||
case 'statCellNum.xpFrom0To5000': return 'Прогресс от 0 XP до 5000 уровня';
|
||||
case 'statCellNum.hoursPlayed': return 'Часов\nСыграно';
|
||||
case 'statCellNum.onlineGames': return 'Онлайн\nИгр';
|
||||
case 'statCellNum.gamesWon': return 'Онлайн\nПобед';
|
||||
|
@ -1368,6 +1563,25 @@ extension on _StringsRu {
|
|||
case 'statCellNum.keys': return 'Нажатий\nКлавиш';
|
||||
case 'statCellNum.kpp': return 'Нажатий\nна Фигуру';
|
||||
case 'statCellNum.kps': return 'Нажатий\nв Секунду';
|
||||
case 'statCellNum.app': return 'Атака на Фигуру';
|
||||
case 'statCellNum.appDescription': return '(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру';
|
||||
case 'statCellNum.vsapmDescription': return 'В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.';
|
||||
case 'statCellNum.dss': return 'Downstack\nв Секунду';
|
||||
case 'statCellNum.dssDescription': return '(Сокращенно DS/S) Downstack (спуск вниз) в Секунду показывает как много мусорных линий в среднем игрок убирает за одну секунду.';
|
||||
case 'statCellNum.dsp': return 'Downstack\nна Фигуру';
|
||||
case 'statCellNum.dspDescription': return '(Сокращенно DS/P) Downstack (спуск вниз) на Фигуру показывает как много мусорных линий в среднем игрок убирает одну фигуру.';
|
||||
case 'statCellNum.appdsp': return 'APP + DS/P';
|
||||
case 'statCellNum.appdspDescription': return 'Просто сумма Атаки на Фигуру и Downstack на Фигуру.';
|
||||
case 'statCellNum.cheese': return 'Индекс сыра';
|
||||
case 'statCellNum.cheeseDescription': return '(Сокращенно Cheese) Индекс сыра является аппроксимацией того, насколько чистый / дырявый мусор игрок отправляет. Меньше = более чистый. Больше = более дырявый.\nПридумал kerrmunism';
|
||||
case 'statCellNum.gbe': return 'Garbage\nEfficiency';
|
||||
case 'statCellNum.gbeDescription': return '(Сокращенно Gb Eff.) Garbage Efficiency показывает насколько хорошо игрок использует свой мусор. Больше = лучше (или он использует больше мусора). Меньше = в основном отправляют сыр (или он редко чистит мусор).\nПридумали Zepheniah и Dragonboy.';
|
||||
case 'statCellNum.nyaapp': return 'Взвешенный\nAPP';
|
||||
case 'statCellNum.nyaappDescription': return '(Сокращенно wAPP) По сути, показывает способность отправлять сыр, сохраняя при этом высокую эффективность.\nПридумал Wertj.';
|
||||
case 'statCellNum.area': return 'Area';
|
||||
case 'statCellNum.areaDescription': return 'Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM';
|
||||
case 'statCellNum.estOfTR': return 'Расчётный TR';
|
||||
case 'statCellNum.accOfEst': return 'Точность расчёта';
|
||||
case 'playerRole.user': return 'Пользователь';
|
||||
case 'playerRole.banned': return 'Заблокированный пользователь';
|
||||
case 'playerRole.bot': return 'Бот';
|
||||
|
@ -1380,6 +1594,8 @@ extension on _StringsRu {
|
|||
case 'numOfGameActions.hold': return 'В запас';
|
||||
case 'numOfGameActions.tspinsTotal': return 'T-spins всего';
|
||||
case 'numOfGameActions.lineClears': return 'Линий очищено';
|
||||
case 'popupActions.cancel': return 'Отменить';
|
||||
case 'popupActions.submit': return 'Подтвердить';
|
||||
case 'popupActions.ok': return 'OK';
|
||||
case 'errors.connection': return ({required Object code, required Object message}) => 'Проблема с подключением: ${code} ${message}';
|
||||
case 'errors.noSuchUser': return 'Нет такого пользователя';
|
||||
|
|
|
@ -74,33 +74,31 @@ class SettingsState extends State<SettingsView> {
|
|||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Settings"),
|
||||
title: Text(t.settings),
|
||||
),
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: const Text("Export local database"),
|
||||
subtitle: const Text(
|
||||
"It contains states and Tetra League records of the tracked players and list of tracked players."),
|
||||
title: Text(t.exportDB),
|
||||
subtitle: Text(t.exportDBDescription),
|
||||
onTap: () {
|
||||
if (Platform.isLinux || Platform.isWindows) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text("Desktop export",
|
||||
style: TextStyle(
|
||||
title: Text(t.desktopExportAlertTitle,
|
||||
style: const TextStyle(
|
||||
fontFamily: "Eurostile Round Extended")),
|
||||
content: const SingleChildScrollView(
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(children: [
|
||||
Text(
|
||||
"It seems like you using this app on desktop. Check your documents folder, you should find \"TetraStats.db\". Copy it somewhere")
|
||||
Text(t.desktopExportText)
|
||||
]),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
child: Text(t.popupActions.ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
|
@ -116,15 +114,15 @@ class SettingsState extends State<SettingsView> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text("Android export",
|
||||
style: TextStyle(
|
||||
title: Text(t.androidExportAlertTitle,
|
||||
style: const TextStyle(
|
||||
fontFamily: "Eurostile Round Extended")),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(children: [Text("Exported.\n$exportedDB")]),
|
||||
child: ListBody(children: [Text(t.androidExportText(exportedDB: exportedDB))]),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
child: Text(t.popupActions.ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
|
@ -136,8 +134,8 @@ class SettingsState extends State<SettingsView> {
|
|||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("Import local database"),
|
||||
subtitle: const Text("Restore your backup. Notice that already stored database will be overwritten."),
|
||||
title: Text(t.importDB),
|
||||
subtitle: Text(t.importDBDescription),
|
||||
onTap: () {
|
||||
if(Platform.isAndroid){
|
||||
FilePicker.platform.pickFiles(
|
||||
|
@ -147,18 +145,18 @@ class SettingsState extends State<SettingsView> {
|
|||
var newDB = value.paths[0]!;
|
||||
teto.close().then((value){
|
||||
if(!newDB.endsWith("db")){
|
||||
return ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Wrong file type")));
|
||||
return ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.importWrongFileType)));
|
||||
}
|
||||
getApplicationDocumentsDirectory().then((value){
|
||||
var oldDB = File("${value.path}/TetraStats.db");
|
||||
oldDB.writeAsBytes(File(newDB).readAsBytesSync(), flush: true).then((value){
|
||||
teto.open();
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Import successful")));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.importSuccess)));
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Operation was cancelled")));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.importCancelled)));
|
||||
}
|
||||
});
|
||||
}else{
|
||||
|
@ -174,42 +172,41 @@ class SettingsState extends State<SettingsView> {
|
|||
var oldDB = File("${value.path}/TetraStats.db");
|
||||
oldDB.writeAsBytes(File(newDB).readAsBytesSync()).then((value){
|
||||
teto.open();
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Import successful")));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.importSuccess)));
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Operation was cancelled")));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.importCancelled)));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("Your TETR.IO account"),
|
||||
title: Text(t.yourID),
|
||||
trailing: Text(defaultNickname),
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text("Your TETR.IO account nickname or ID",
|
||||
style: TextStyle(
|
||||
title: Text(t.yourIDAlertTitle,
|
||||
style: const TextStyle(
|
||||
fontFamily: "Eurostile Round Extended")),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(children: [
|
||||
const Text(
|
||||
"Every time when app loads, stats of that player will be fetched. Please prefer ID over nickname because nickname can be changed."),
|
||||
Text(t.yourIDText),
|
||||
TextField(controller: _playertext, maxLength: 25)
|
||||
]),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('Cancel'),
|
||||
child: Text(t.popupActions.cancel),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('Submit'),
|
||||
child: Text(t.popupActions.submit),
|
||||
onPressed: () {
|
||||
_setPlayer(_playertext.text.toLowerCase().trim());
|
||||
Navigator.of(context).pop();
|
||||
|
@ -220,7 +217,7 @@ class SettingsState extends State<SettingsView> {
|
|||
)),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("Language"),
|
||||
title: Text(t.language),
|
||||
trailing: DropdownButton(
|
||||
items: locales,
|
||||
value: LocaleSettings.currentLocale,
|
||||
|
@ -229,13 +226,8 @@ class SettingsState extends State<SettingsView> {
|
|||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: const Text("About app"),
|
||||
subtitle: Text("""
|
||||
${_packageInfo.appName} (${_packageInfo.packageName}) Version ${_packageInfo.version} Build ${_packageInfo.buildNumber}
|
||||
|
||||
Developed by dan63047
|
||||
Formulas provided by kerrmunism
|
||||
"""),
|
||||
title: Text(t.aboutApp),
|
||||
subtitle: Text(t.aboutAppText(appName: _packageInfo.appName, packageName: _packageInfo.packageName, version: _packageInfo.version, buildNumber: _packageInfo.buildNumber)),
|
||||
),
|
||||
],
|
||||
)),
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/widgets/tl_thingy.dart';
|
||||
import 'package:tetra_stats/widgets/user_thingy.dart';
|
||||
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
|
||||
class StateView extends StatefulWidget {
|
||||
final TetrioPlayer state;
|
||||
const StateView({Key? key, required this.state}) : super(key: key);
|
||||
|
@ -26,9 +30,10 @@ class StateState extends State<StateView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("${widget.state.username.toUpperCase()} account on ${widget.state.state}"),
|
||||
title: Text(t.stateViewTitle(nickname: widget.state.username.toUpperCase(), date: dateFormat.format(widget.state.state))),
|
||||
),
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/views/compare_view.dart';
|
||||
import 'package:tetra_stats/views/state_view.dart';
|
||||
|
||||
|
@ -12,14 +13,14 @@ class StatesView extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => StatesState();
|
||||
}
|
||||
|
||||
final DateFormat dateFormat = DateFormat.yMMMd().add_Hms();
|
||||
|
||||
class StatesState extends State<StatesView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("${widget.states.length} states of ${widget.states.last.username.toUpperCase()} account"),
|
||||
title: Text(t.statesViewTitle(number: widget.states.length, nickname: widget.states.last.username.toUpperCase())),
|
||||
),
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
|
@ -27,14 +28,14 @@ class StatesState extends State<StatesView> {
|
|||
itemCount: widget.states.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text("On ${dateFormat.format(widget.states[index].state)}"),
|
||||
subtitle: Text("Level ${widget.states[index].level.toStringAsFixed(2)}, ${widget.states[index].gameTime} of gametime, ${widget.states[index].friendCount} friends, ${NumberFormat.compact().format(widget.states[index].tlSeason1.rd)} RD"),
|
||||
title: Text(dateFormat.format(widget.states[index].state)),
|
||||
subtitle: Text(t.statesViewEntry(level: widget.states[index].level.toStringAsFixed(2), gameTime: widget.states[index].gameTime, friends: widget.states[index].friendCount, rd: NumberFormat.compact().format(widget.states[index].tlSeason1.rd))),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.delete_forever),
|
||||
onPressed: () {
|
||||
DateTime nn = widget.states[index].state;
|
||||
teto.deleteState(widget.states[index]).then((value) => setState(() {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("${dateFormat.format(nn)} state was removed from database!")));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.stateRemoved(date: dateFormat.format(nn)))));
|
||||
}));
|
||||
},
|
||||
),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/gen/strings.g.dart';
|
||||
import 'package:tetra_stats/services/tetrio_crud.dart';
|
||||
import 'package:tetra_stats/views/states_view.dart';
|
||||
|
||||
|
@ -13,14 +14,14 @@ class TrackedPlayersView extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => TrackedPlayersState();
|
||||
}
|
||||
|
||||
final DateFormat dateFormat = DateFormat.yMMMd().add_Hms();
|
||||
|
||||
class TrackedPlayersState extends State<TrackedPlayersView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final t = Translations.of(context);
|
||||
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Stored data"),
|
||||
title: Text(t.trackedPlayersViewTitle),
|
||||
),
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
|
@ -38,9 +39,9 @@ class TrackedPlayersState extends State<TrackedPlayersView> {
|
|||
headerSliverBuilder: (context, value) {
|
||||
String howManyPlayers(int numberOfPlayers) => Intl.plural(
|
||||
numberOfPlayers,
|
||||
zero: 'Empty list. Press "Track" button in previous view to add current player here',
|
||||
one: 'There is only one player',
|
||||
other: 'There are $numberOfPlayers players',
|
||||
zero: t.trackedPlayersZeroEntrys,
|
||||
one: t.trackedPlayersOneEntry,
|
||||
other: t.trackedPlayersManyEntrys(numberOfPlayers: numberOfPlayers),
|
||||
name: 'howManyPeople',
|
||||
args: [numberOfPlayers],
|
||||
desc: 'Description of how many people are seen in a place.',
|
||||
|
@ -62,15 +63,14 @@ class TrackedPlayersState extends State<TrackedPlayersView> {
|
|||
itemCount: allPlayers.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text("${allPlayers[keys[index]]?.last.username}: ${allPlayers[keys[index]]?.length} states"),
|
||||
subtitle: Text(
|
||||
"From ${dateFormat.format(allPlayers[keys[index]]!.first.state)} until ${dateFormat.format(allPlayers[keys[index]]!.last.state)}"),
|
||||
title: Text(t.trackedPlayersEntry(nickname: allPlayers[keys[index]]!.last.username, numberOfStates: allPlayers[keys[index]]!.length)),
|
||||
subtitle: Text(t.trackedPlayersDescription(firstStateDate: dateFormat.format(allPlayers[keys[index]]!.first.state), lastStateDate: dateFormat.format(allPlayers[keys[index]]!.last.state))),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.delete_forever),
|
||||
onPressed: () {
|
||||
String nn = allPlayers[keys[index]]!.last.username;
|
||||
teto.deletePlayer(keys[index]);
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("$nn states was removed from database!")));
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.trackedPlayersStatesDeleted(nickname: nn))));
|
||||
},
|
||||
),
|
||||
onTap: () {
|
||||
|
|
|
@ -8,12 +8,16 @@ class StatCellNum extends StatelessWidget {
|
|||
required this.playerStatLabel,
|
||||
required this.isScreenBig,
|
||||
this.alertWidgets,
|
||||
this.fractionDigits, this.oldPlayerStat, required this.higherIsBetter});
|
||||
this.fractionDigits,
|
||||
this.oldPlayerStat,
|
||||
required this.higherIsBetter,
|
||||
this.okText});
|
||||
|
||||
final num playerStat;
|
||||
final num? oldPlayerStat;
|
||||
final bool higherIsBetter;
|
||||
final String playerStatLabel;
|
||||
final String? okText;
|
||||
final bool isScreenBig;
|
||||
final List<Widget>? alertWidgets;
|
||||
final int? fractionDigits;
|
||||
|
@ -58,10 +62,8 @@ class StatCellNum extends StatelessWidget {
|
|||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(okText??"OK"),
|
||||
onPressed: () {Navigator.of(context).pop();}
|
||||
)
|
||||
],
|
||||
));
|
||||
|
|
|
@ -121,7 +121,7 @@ class TLThingy extends StatelessWidget {
|
|||
width: 200,
|
||||
height: 120,
|
||||
child: SfRadialGauge(
|
||||
title: const GaugeTitle(text: "Attack Per Piece"),
|
||||
title: GaugeTitle(text: t.statCellNum.app),
|
||||
axes: [RadialAxis(
|
||||
startAngle: 180,
|
||||
endAngle: 360,
|
||||
|
@ -155,18 +155,18 @@ class TLThingy extends StatelessWidget {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text("Attack Per Piece",
|
||||
style: TextStyle(
|
||||
title: Text(t.statCellNum.app,
|
||||
style: const TextStyle(
|
||||
fontFamily: "Eurostile Round Extended")),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(children: [
|
||||
const Text("Main efficiency metric. Tells how many attack you producing per piece"),
|
||||
Text("Raw value: ${tl.nerdStats!.app}")
|
||||
Text(t.statCellNum.appDescription),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.app}")
|
||||
]),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
child: Text(t.popupActions.ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
|
@ -222,13 +222,13 @@ class TLThingy extends StatelessWidget {
|
|||
fontFamily: "Eurostile Round Extended")),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(children: [
|
||||
const Text("Basically, tells how much and how efficient you using garbage in your attacks"),
|
||||
Text("Raw value: ${tl.nerdStats!.vsapm}")
|
||||
Text(t.statCellNum.vsapmDescription),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.vsapm}")
|
||||
]),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
child: Text(t.popupActions.ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
|
@ -251,46 +251,53 @@ class TLThingy extends StatelessWidget {
|
|||
crossAxisAlignment: WrapCrossAlignment.start,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
children: [
|
||||
StatCellNum(playerStat: tl.nerdStats!.dss, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: "Downstack\nPer Second",
|
||||
alertWidgets: [const Text("Downstack per Second measures how many garbage lines you clear in a second."),
|
||||
const Text("Formula: (VS / 100) - (APM / 60)"),
|
||||
Text("Raw value: ${tl.nerdStats!.dss}"),],
|
||||
StatCellNum(playerStat: tl.nerdStats!.dss, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.dss,
|
||||
alertWidgets: [Text(t.statCellNum.dssDescription),
|
||||
Text("${t.formula}: (VS / 100) - (APM / 60)"),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.dss}"),],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
oldPlayerStat: oldTl?.nerdStats?.dss,),
|
||||
StatCellNum(playerStat: tl.nerdStats!.dsp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: "Downstack\nPer Piece",
|
||||
alertWidgets: [const Text("Downstack per Piece measures how many garbage lines you clear per piece."),
|
||||
const Text("Formula: DS/S / PPS"),
|
||||
Text("Raw value: ${tl.nerdStats!.dsp}"),],
|
||||
StatCellNum(playerStat: tl.nerdStats!.dsp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.dsp,
|
||||
alertWidgets: [Text(t.statCellNum.dspDescription),
|
||||
Text("${t.formula}: DS/S / PPS"),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.dsp}"),],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
oldPlayerStat: oldTl?.nerdStats?.dsp,),
|
||||
StatCellNum(playerStat: tl.nerdStats!.appdsp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: "APP + DS/P",
|
||||
alertWidgets: [const Text("Just a sum of Attack per Piece and Downstack per Piece."),
|
||||
const Text("Formula: APP + DS/P"),
|
||||
Text("Raw value: ${tl.nerdStats!.appdsp}"),],
|
||||
StatCellNum(playerStat: tl.nerdStats!.appdsp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.appdsp,
|
||||
alertWidgets: [Text(t.statCellNum.appdspDescription),
|
||||
Text("${t.formula}: APP + DS/P"),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.appdsp}"),],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
oldPlayerStat: oldTl?.nerdStats?.appdsp,),
|
||||
StatCellNum(playerStat: tl.nerdStats!.cheese, isScreenBig: bigScreen, fractionDigits: 2, playerStatLabel: "Cheese\nIndex",
|
||||
alertWidgets: [const Text("Cheese Index is an approximation how much clean / cheese garbage player sends. Lower = more clean. Higher = more cheese.\nInvented by kerrmunism"),
|
||||
const Text("Formula: (DS/P * 150) + ((VS/APM - 2) * 50) + (0.6 - APP) * 125"),
|
||||
Text("Raw value: ${tl.nerdStats!.cheese}"),],
|
||||
StatCellNum(playerStat: tl.nerdStats!.cheese, isScreenBig: bigScreen, fractionDigits: 2, playerStatLabel: t.statCellNum.cheese,
|
||||
alertWidgets: [Text(t.statCellNum.cheeseDescription),
|
||||
Text("${t.formula}: (DS/P * 150) + ((VS/APM - 2) * 50) + (0.6 - APP) * 125"),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.cheese}"),],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
oldPlayerStat: oldTl?.nerdStats?.cheese,),
|
||||
StatCellNum(playerStat: tl.nerdStats!.gbe, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: "Garbage\nEfficiency",
|
||||
alertWidgets: [const Text("Garbage Efficiency measures how well player uses their garbage. Higher = better or they use their garbage more. Lower = they mostly send their garbage back at cheese or rarely clear garbage.\nInvented by Zepheniah and Dragonboy."),
|
||||
const Text("Formula: ((APP * DS/S) / PPS) * 2"),
|
||||
Text("Raw value: ${tl.nerdStats!.gbe}"),],
|
||||
StatCellNum(playerStat: tl.nerdStats!.gbe, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.gbe,
|
||||
alertWidgets: [Text(t.statCellNum.gbeDescription),
|
||||
Text("${t.formula}: ((APP * DS/S) / PPS) * 2"),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.gbe}"),],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
oldPlayerStat: oldTl?.nerdStats?.gbe,),
|
||||
StatCellNum(playerStat: tl.nerdStats!.nyaapp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: "Weighted\nAPP",
|
||||
alertWidgets: [const Text("Essentially, a measure of your ability to send cheese while still maintaining a high APP.\nInvented by Wertj."),
|
||||
const Text("Formula: APP - 5 * tan(radians((Cheese Index / -30) + 1))"),
|
||||
Text("Raw value: ${tl.nerdStats!.nyaapp}"),],
|
||||
StatCellNum(playerStat: tl.nerdStats!.nyaapp, isScreenBig: bigScreen, fractionDigits: 3, playerStatLabel: t.statCellNum.nyaapp,
|
||||
alertWidgets: [Text(t.statCellNum.nyaappDescription),
|
||||
Text("${t.formula}: APP - 5 * tan(radians((Cheese Index / -30) + 1))"),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.nyaapp}"),],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
oldPlayerStat: oldTl?.nerdStats?.nyaapp,),
|
||||
StatCellNum(playerStat: tl.nerdStats!.area, isScreenBig: bigScreen, fractionDigits: 1, playerStatLabel: "Area",
|
||||
alertWidgets: [const Text("How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections"),
|
||||
const Text("Formula: APM * 1 + PPS * 45 + VS * 0.444 + APP * 185 + DS/S * 175 + DS/P * 450 + Garbage Effi * 315"),
|
||||
Text("Raw value: ${tl.nerdStats!.area}"),],
|
||||
StatCellNum(playerStat: tl.nerdStats!.area, isScreenBig: bigScreen, fractionDigits: 1, playerStatLabel: t.statCellNum.area,
|
||||
alertWidgets: [Text(t.statCellNum.areaDescription),
|
||||
Text("${t.formula}: APM * 1 + PPS * 45 + VS * 0.444 + APP * 185 + DS/S * 175 + DS/P * 450 + Garbage Effi * 315"),
|
||||
Text("${t.exactValue}: ${tl.nerdStats!.area}"),],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
oldPlayerStat: oldTl?.nerdStats?.area,)
|
||||
])
|
||||
|
@ -307,9 +314,9 @@ class TLThingy extends StatelessWidget {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
"Est. of TR:",
|
||||
style: TextStyle(fontSize: 24),
|
||||
Text(
|
||||
"${t.statCellNum.estOfTR}:",
|
||||
style: const TextStyle(fontSize: 24),
|
||||
),
|
||||
Text(
|
||||
f2.format(tl.estTr!.esttr),
|
||||
|
@ -321,9 +328,9 @@ class TLThingy extends StatelessWidget {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
"Accuracy:",
|
||||
style: TextStyle(fontSize: 24),
|
||||
Text(
|
||||
"${t.statCellNum.accOfEst}:",
|
||||
style: const TextStyle(fontSize: 24),
|
||||
),
|
||||
Text(
|
||||
fDiff.format(tl.esttracc!),
|
||||
|
@ -499,7 +506,7 @@ class TLThingy extends StatelessWidget {
|
|||
)
|
||||
]
|
||||
: [
|
||||
const Text("That user never played Tetra League", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28)),
|
||||
Text(t.neverPlayedTL, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28)),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
|
@ -170,7 +170,8 @@ 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("Progress to next level: ${((player.level - player.level.floor()) * 100).toStringAsFixed(2)} %"), Text("Progress from 0 XP to level 5000: ${((player.xp / 67009017.7589378) * 100).toStringAsFixed(2)} %")],
|
||||
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)} %")],
|
||||
okText: t.popupActions.ok,
|
||||
higherIsBetter: true,
|
||||
),
|
||||
if (player.gameTime >= Duration.zero)
|
||||
|
|
|
@ -45,8 +45,41 @@
|
|||
"gamesUntilRanked": "${left} games until being ranked",
|
||||
"nerdStats": "Nerd Stats",
|
||||
"playersYouTrack": "Players you track",
|
||||
"formula": "Formula",
|
||||
"exactValue": "Exact value",
|
||||
"neverPlayedTL": "That user never played Tetra League",
|
||||
"exportDB": "Export local database",
|
||||
"exportDBDescription": "It contains states and Tetra League records of the tracked players and list of tracked players.",
|
||||
"desktopExportAlertTitle": "Desktop export",
|
||||
"desktopExportText": "It seems like you using this app on desktop. Check your documents folder, you should find \"TetraStats.db\". Copy it somewhere",
|
||||
"androidExportAlertTitle": "Android export",
|
||||
"androidExportText": "Exported.\n${exportedDB}",
|
||||
"importDB": "Import local database",
|
||||
"importDBDescription": "Restore your backup. Notice that already stored database will be overwritten.",
|
||||
"importWrongFileType": "Wrong file type",
|
||||
"importCancelled": "Operation was cancelled",
|
||||
"importSuccess": "Import successful",
|
||||
"yourID": "Your TETR.IO account",
|
||||
"yourIDAlertTitle": "Your TETR.IO account nickname or ID",
|
||||
"yourIDText": "Every time when app loads, stats of that player will be fetched. Please prefer ID over nickname because nickname can be changed.",
|
||||
"language": "Language",
|
||||
"aboutApp": "About app",
|
||||
"aboutAppText": "${appName} (${packageName}) Version ${version} Build ${buildNumber}\n\nDeveloped by dan63047\nFormulas provided by kerrmunism",
|
||||
"stateViewTitle": "${nickname} account on ${date}",
|
||||
"statesViewTitle": "${number} states of ${nickname} account",
|
||||
"statesViewEntry": "Level ${level}, ${gameTime} of gametime, ${friends} friends, ${rd} RD",
|
||||
"stateRemoved": "${date} state was removed from database!",
|
||||
"trackedPlayersViewTitle": "Stored data",
|
||||
"trackedPlayersZeroEntrys": "Empty list. Press \"Track\" button in previous view to add current player here",
|
||||
"trackedPlayersOneEntry": "There is only one player",
|
||||
"trackedPlayersManyEntrys": "There are ${numberOfPlayers} players",
|
||||
"trackedPlayersEntry": "${nickname}: ${numberOfStates} states",
|
||||
"trackedPlayersDescription": "From ${firstStateDate} until ${lastStateDate}",
|
||||
"trackedPlayersStatesDeleted": "${nickname} states was removed from database!",
|
||||
"statCellNum":{
|
||||
"xpLevel": "XP Level",
|
||||
"xpProgress": "Progress to next level",
|
||||
"xpFrom0To5000": "Progress from 0 XP to level 5000",
|
||||
"hoursPlayed": "Hours\nPlayed",
|
||||
"onlineGames": "Online\nGames",
|
||||
"gamesWon": "Games\nWon",
|
||||
|
@ -67,7 +100,26 @@
|
|||
"finessePercentage": "Finesse\nPercentage",
|
||||
"keys": "Key\nPresses",
|
||||
"kpp": "KP Per\nPiece",
|
||||
"kps": "KP Per\nSecond"
|
||||
"kps": "KP Per\nSecond",
|
||||
"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",
|
||||
"dss": "Downstack\nPer Second",
|
||||
"dssDescription": "Downstack per Second measures how many garbage lines you clear in a second.",
|
||||
"dsp": "Downstack\nPer Piece",
|
||||
"dspDescription": "Downstack per Piece measures how many garbage lines you clear per piece.",
|
||||
"appdsp": "APP + DS/P",
|
||||
"appdspDescription": "Just a sum of Attack per Piece and Downstack per Piece.",
|
||||
"cheese": "Cheese\nIndex",
|
||||
"cheeseDescription": "Cheese Index is an approximation how much clean / cheese garbage player sends. Lower = more clean. Higher = more cheese.\nInvented by kerrmunism",
|
||||
"gbe": "Garbage\nEfficiency",
|
||||
"gbeDescription": "Garbage Efficiency measures how well player uses their garbage. Higher = better or they use their garbage more. Lower = they mostly send their garbage back at cheese or rarely clear garbage.\nInvented by Zepheniah and Dragonboy.",
|
||||
"nyaapp": "Weighted\nAPP",
|
||||
"nyaappDescription": "Essentially, a measure of your ability to send cheese while still maintaining a high APP.\nInvented by Wertj.",
|
||||
"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"
|
||||
},
|
||||
"playerRole(map)": {
|
||||
"user": "User",
|
||||
|
@ -86,6 +138,8 @@
|
|||
"lineClears": "Line clears"
|
||||
},
|
||||
"popupActions":{
|
||||
"cancel": "Cancel",
|
||||
"submit": "Submit",
|
||||
"ok": "OK"
|
||||
},
|
||||
"errors":{
|
||||
|
|
|
@ -45,8 +45,41 @@
|
|||
"gamesUntilRanked": "${left} матчей до получения рейтинга",
|
||||
"nerdStats": "Для задротов",
|
||||
"playersYouTrack": "Отслеживаемые игроки",
|
||||
"formula": "Формула",
|
||||
"exactValue": "Точное значение",
|
||||
"neverPlayedTL": "Этот игрок никогда не играл в Тетра Лигу",
|
||||
"exportDB": "Экспортировать локальную базу данных",
|
||||
"exportDBDescription": "Она содержит состояния аккаунтов и их матчей в Тетра Лиге для отслеживаемых игроков и список таких игроков.",
|
||||
"desktopExportAlertTitle": "Экспорт на десктопе",
|
||||
"desktopExportText": "Похоже, вы используете десктопную версию. Проверьте папку \"Документы\", там вы должны найти файл \"TetraStats.db\". Скопируйте его куда-нибудь",
|
||||
"androidExportAlertTitle": "Экспорт на Android",
|
||||
"androidExportText": "Экспортировано.\n${exportedDB}",
|
||||
"importDB": "Импортировать локальную базу данных",
|
||||
"importDBDescription": "Восстановите свою резеврную копию. Обратите внимание, что текущая база данных будет перезаписана.",
|
||||
"importWrongFileType": "Неверный тип файла",
|
||||
"importCancelled": "Операция была отменена",
|
||||
"importSuccess": "Успешно импортировано",
|
||||
"yourID": "Ваш аккаунт в TETR.IO",
|
||||
"yourIDAlertTitle": "Никнейм или ID вашего аккаунта в TETR.IO",
|
||||
"yourIDText": "Каждый раз, когда приложение запускается, приложение будет получать статистику этого игрока. Пожалуйста, отдайте предпочтение ID, так как никнейм можно изменить.",
|
||||
"language": "Язык (Language)",
|
||||
"aboutApp": "О приложении",
|
||||
"aboutAppText": "${appName} (${packageName}) Версия ${version} Сборка ${buildNumber}\n\nРазработал dan63047\nФормулы предоставил kerrmunism",
|
||||
"stateViewTitle": "Аккаунт ${nickname} ${date}",
|
||||
"statesViewTitle": "${number} состояний аккаунта ${nickname}",
|
||||
"statesViewEntry": "${level} уровень, ${gameTime} сыграно, ${friends} друзей, ${rd} RD",
|
||||
"stateRemoved": "$Состояние от {date} было удалено из локальной базы данных!",
|
||||
"trackedPlayersViewTitle": "Сохранённые данные",
|
||||
"trackedPlayersZeroEntrys": "Пустой список. Вернитесь на предыдущий экран и нажмите кнопку \"Отслеживать\", чтобы текущий игрок появился здесь",
|
||||
"trackedPlayersOneEntry": "В списке только один игрок",
|
||||
"trackedPlayersManyEntrys": "В списке ${numberOfPlayers} игроков",
|
||||
"trackedPlayersEntry": "${nickname}: ${numberOfStates} состояний",
|
||||
"trackedPlayersDescription": "Начиная с ${firstStateDate} и заканчивая ${lastStateDate}",
|
||||
"trackedPlayersStatesDeleted": "Состояния аккаунта ${nickname} были удалены из локальной базы данных!",
|
||||
"statCellNum": {
|
||||
"xpLevel": "Уровень\nопыта",
|
||||
"xpProgress": "Прогресс до следующего уровня",
|
||||
"xpFrom0To5000": "Прогресс от 0 XP до 5000 уровня",
|
||||
"hoursPlayed": "Часов\nСыграно",
|
||||
"onlineGames": "Онлайн\nИгр",
|
||||
"gamesWon": "Онлайн\nПобед",
|
||||
|
@ -67,7 +100,26 @@
|
|||
"finessePercentage": "% Качества\nТехники",
|
||||
"keys": "Нажатий\nКлавиш",
|
||||
"kpp": "Нажатий\nна Фигуру",
|
||||
"kps": "Нажатий\nв Секунду"
|
||||
"kps": "Нажатий\nв Секунду",
|
||||
"app": "Атака на Фигуру",
|
||||
"appDescription": "(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру",
|
||||
"vsapmDescription": "В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.",
|
||||
"dss": "Downstack\nв Секунду",
|
||||
"dssDescription": "(Сокращенно DS/S) Downstack (спуск вниз) в Секунду показывает как много мусорных линий в среднем игрок убирает за одну секунду.",
|
||||
"dsp": "Downstack\nна Фигуру",
|
||||
"dspDescription": "(Сокращенно DS/P) Downstack (спуск вниз) на Фигуру показывает как много мусорных линий в среднем игрок убирает одну фигуру.",
|
||||
"appdsp": "APP + DS/P",
|
||||
"appdspDescription": "Просто сумма Атаки на Фигуру и Downstack на Фигуру.",
|
||||
"cheese": "Индекс сыра",
|
||||
"cheeseDescription": "(Сокращенно Cheese) Индекс сыра является аппроксимацией того, насколько чистый / дырявый мусор игрок отправляет. Меньше = более чистый. Больше = более дырявый.\nПридумал kerrmunism",
|
||||
"gbe": "Garbage\nEfficiency",
|
||||
"gbeDescription": "(Сокращенно Gb Eff.) Garbage Efficiency показывает насколько хорошо игрок использует свой мусор. Больше = лучше (или он использует больше мусора). Меньше = в основном отправляют сыр (или он редко чистит мусор).\nПридумали Zepheniah и Dragonboy.",
|
||||
"nyaapp": "Взвешенный\nAPP",
|
||||
"nyaappDescription": "(Сокращенно wAPP) По сути, показывает способность отправлять сыр, сохраняя при этом высокую эффективность.\nПридумал Wertj.",
|
||||
"area": "Area",
|
||||
"areaDescription": "Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM",
|
||||
"estOfTR": "Расчётный TR",
|
||||
"accOfEst": "Точность расчёта"
|
||||
},
|
||||
"playerRole(map)": {
|
||||
"user": "Пользователь",
|
||||
|
@ -86,6 +138,8 @@
|
|||
"lineClears": "Линий очищено"
|
||||
},
|
||||
"popupActions":{
|
||||
"cancel": "Отменить",
|
||||
"submit": "Подтвердить",
|
||||
"ok": "OK"
|
||||
},
|
||||
"errors":{
|
||||
|
|
Loading…
Reference in New Issue