diff --git a/lib/gen/strings.g.dart b/lib/gen/strings.g.dart index 4d8805c..a8b8209 100644 --- a/lib/gen/strings.g.dart +++ b/lib/gen/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 2 -/// Strings: 1216 (608 per locale) +/// Strings: 1210 (605 per locale) /// -/// Built on 2024-08-07 at 15:58 UTC +/// Built on 2024-09-04 at 20:41 UTC // coverage:ignore-file // ignore_for_file: type=lint @@ -224,9 +224,6 @@ class Translations implements BaseTranslations { String get smooth => 'Smooth'; String get postSeason => 'Off-season'; String get seasonStarts => 'Season starts in:'; - String get myMessadgeHeader => 'A messadge from dan63'; - String get myMessadgeBody => 'TETR.IO Tetra Channel API has been seriously modified after the last update, therefore, some functions may not work. I will try to catch up and add new stats (and return back the old ones) as soon, as public docs on new Tetra Channel API will be available.'; - String preSeasonMessage({required Object n}) => 'Right now you can play unranked FT3 matches with hidden glicko (200 RD 🙂).\nSeason ${n} rules applied'; String get nanow => 'Not avaliable for now...'; String seasonEnds({required Object countdown}) => 'Season ends in ${countdown}'; String get seasonEnded => 'Season has ended'; @@ -293,7 +290,7 @@ class Translations implements BaseTranslations { 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 matchesViewTitle({required Object nickname}) => '${nickname} TL matches'; - String statesViewEntry({required Object level, required Object gameTime, required Object friends, required Object rd}) => 'Level ${level}, ${gameTime} of gametime, ${friends} friends, ${rd} RD'; + String statesViewEntry({required Object level, required Object glicko, required Object rd, required Object games}) => '${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно'; String stateRemoved({required Object date}) => '${date} state was removed from database!'; String matchRemoved({required Object date}) => '${date} match was removed from database!'; String get viewAllMatches => 'View all matches'; @@ -938,9 +935,6 @@ class _StringsRu implements Translations { @override String get smooth => 'Гладкий'; @override String get postSeason => 'Внесезонье'; @override String get seasonStarts => 'Сезон начнётся через:'; - @override String get myMessadgeHeader => 'Сообщение от dan63'; - @override String get myMessadgeBody => 'TETR.IO Tetra Channel API был серьёзно изменён после последнего обновления, поэтому некоторый функционал может не работать. Я постараюсь добавить новую статистику (и вернуть старую) как только будут опубликована новая документация по данному API.'; - @override String preSeasonMessage({required Object n}) => 'Прямо сейчас вы можете сыграть безранговый матч до трёх побед со скрытым Glicko (200 RD 🙂).\nПрименяются правила ${n} сезона'; @override String get nanow => 'Пока недоступно...'; @override String seasonEnds({required Object countdown}) => 'Сезон закончится через ${countdown}'; @override String get seasonEnded => 'Сезон закончился'; @@ -1007,7 +1001,7 @@ class _StringsRu implements Translations { @override String stateViewTitle({required Object nickname, required Object date}) => 'Аккаунт ${nickname} ${date}'; @override String statesViewTitle({required Object number, required Object nickname}) => '${number} состояний аккаунта ${nickname}'; @override String matchesViewTitle({required Object nickname}) => 'Матчи аккаунта ${nickname}'; - @override String statesViewEntry({required Object level, required Object gameTime, required Object friends, required Object rd}) => '${level} уровень, ${gameTime} сыграно, ${friends} друзей, ${rd} RD'; + @override String statesViewEntry({required Object level, required Object glicko, required Object rd, required Object games}) => '${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно'; @override String stateRemoved({required Object date}) => 'Состояние от ${date} было удалено из локальной базы данных!'; @override String matchRemoved({required Object date}) => 'Матч от ${date} был удален из локальной базы данных!'; @override String get viewAllMatches => 'Все матчи'; @@ -1644,9 +1638,6 @@ extension on Translations { case 'smooth': return 'Smooth'; case 'postSeason': return 'Off-season'; case 'seasonStarts': return 'Season starts in:'; - case 'myMessadgeHeader': return 'A messadge from dan63'; - case 'myMessadgeBody': return 'TETR.IO Tetra Channel API has been seriously modified after the last update, therefore, some functions may not work. I will try to catch up and add new stats (and return back the old ones) as soon, as public docs on new Tetra Channel API will be available.'; - case 'preSeasonMessage': return ({required Object n}) => 'Right now you can play unranked FT3 matches with hidden glicko (200 RD 🙂).\nSeason ${n} rules applied'; case 'nanow': return 'Not avaliable for now...'; case 'seasonEnds': return ({required Object countdown}) => 'Season ends in ${countdown}'; case 'seasonEnded': return 'Season has ended'; @@ -1713,7 +1704,7 @@ extension on Translations { 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 'matchesViewTitle': return ({required Object nickname}) => '${nickname} TL matches'; - 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 'statesViewEntry': return ({required Object level, required Object glicko, required Object rd, required Object games}) => '${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно'; case 'stateRemoved': return ({required Object date}) => '${date} state was removed from database!'; case 'matchRemoved': return ({required Object date}) => '${date} match was removed from database!'; case 'viewAllMatches': return 'View all matches'; @@ -2274,9 +2265,6 @@ extension on _StringsRu { case 'smooth': return 'Гладкий'; case 'postSeason': return 'Внесезонье'; case 'seasonStarts': return 'Сезон начнётся через:'; - case 'myMessadgeHeader': return 'Сообщение от dan63'; - case 'myMessadgeBody': return 'TETR.IO Tetra Channel API был серьёзно изменён после последнего обновления, поэтому некоторый функционал может не работать. Я постараюсь добавить новую статистику (и вернуть старую) как только будут опубликована новая документация по данному API.'; - case 'preSeasonMessage': return ({required Object n}) => 'Прямо сейчас вы можете сыграть безранговый матч до трёх побед со скрытым Glicko (200 RD 🙂).\nПрименяются правила ${n} сезона'; case 'nanow': return 'Пока недоступно...'; case 'seasonEnds': return ({required Object countdown}) => 'Сезон закончится через ${countdown}'; case 'seasonEnded': return 'Сезон закончился'; @@ -2343,7 +2331,7 @@ extension on _StringsRu { case 'stateViewTitle': return ({required Object nickname, required Object date}) => 'Аккаунт ${nickname} ${date}'; case 'statesViewTitle': return ({required Object number, required Object nickname}) => '${number} состояний аккаунта ${nickname}'; case 'matchesViewTitle': return ({required Object nickname}) => 'Матчи аккаунта ${nickname}'; - case 'statesViewEntry': return ({required Object level, required Object gameTime, required Object friends, required Object rd}) => '${level} уровень, ${gameTime} сыграно, ${friends} друзей, ${rd} RD'; + case 'statesViewEntry': return ({required Object level, required Object glicko, required Object rd, required Object games}) => '${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно'; case 'stateRemoved': return ({required Object date}) => 'Состояние от ${date} было удалено из локальной базы данных!'; case 'matchRemoved': return ({required Object date}) => 'Матч от ${date} был удален из локальной базы данных!'; case 'viewAllMatches': return 'Все матчи'; diff --git a/lib/services/tetrio_crud.dart b/lib/services/tetrio_crud.dart index 8308dcb..102dc89 100644 --- a/lib/services/tetrio_crud.dart +++ b/lib/services/tetrio_crud.dart @@ -213,6 +213,7 @@ class TetrioService extends DB { _players.removeWhere((key, value) => key == id); _tetrioStreamController.add(_players); } + await db.delete(tetrioLeagueTable, where: "id LIKE ?", whereArgs: ["$id%"]); } /// Gets nickname from database or requests it from API if missing. @@ -1117,46 +1118,14 @@ class TetrioService extends DB { } } - /// Remove state (which is [tetrioPlayer]) from the local database - // Future deleteState(TetrioPlayer tetrioPlayer) async { - // await ensureDbIsOpen(); - // final db = getDatabaseOrThrow(); - // //List states = await getPlayer(tetrioPlayer.userId); - // // removing state from map that contain every state of each user - // states.removeWhere((element) => element.state == tetrioPlayer.state); - - // // Making map of the states (without deleted one) - // final Map statesJson = {}; - // // for (var e in states) { - // // statesJson.addEntries({(e.state.millisecondsSinceEpoch ~/ 1000).toString(): e.toJson()}.entries); - // // } - // // Rewriting database entry with new json - // await db.update(tetrioUsersTable, {idCol: tetrioPlayer.userId, nickCol: tetrioPlayer.username, statesCol: jsonEncode(statesJson)}, - // where: '$idCol = ?', whereArgs: [tetrioPlayer.userId]); - // _tetrioStreamController.add(_players); - // } - - /// Returns list of all states of player with given [id] from database. Can return empty list if player - /// was not found. - // Future> getPlayer(String id) async { - // await ensureDbIsOpen(); - // final db = getDatabaseOrThrow(); - // List states = []; - // final results = await db.query(tetrioUsersTable, limit: 1, where: '$idCol = ?', whereArgs: [id.toLowerCase()]); - // if (results.isEmpty) { - // return states; // it empty - // } else { - // dynamic rawStates = results.first['jsonStates'] as String; - // rawStates = json.decode(rawStates); - // // recreating objects of states - // rawStates.forEach((k, v) => states.add(TetrioPlayer.fromJson(v, DateTime.fromMillisecondsSinceEpoch(int.parse(k) * 1000), id, results.first[nickCol] as String))); - // // updating the stream - // _players.removeWhere((key, value) => key == id); - // _players.addEntries({states.last.userId: states.last.username}.entries); - // _tetrioStreamController.add(_players); - // return states; - // } - // } + /// Remove state, which has [dbID] from the local database + /// ([dbid] is a concatenation of player id and UINX milliseconds in hex) + Future deleteState(String dbID) async { + await ensureDbIsOpen(); + final db = getDatabaseOrThrow(); + int result = await db.delete(tetrioLeagueTable, where: "id = ?", whereArgs: [dbID]); + if (result == 0) throw Exception("Failed to remove a row $dbID - it's probably not exist"); + } /// Retrieves general stats of [user] (nickname or id) from Tetra Channel api. Returns [TetrioPlayer] object of this user. /// If [isItDiscordID] is true, function expects [user] to be a discord user id. Throws an exception if fails to retrieve. @@ -1256,17 +1225,14 @@ class TetrioService extends DB { } } - /// Retrieves whole [tetrioUsersTable] and returns Map with [TetrioPlayer] objects of everyone in database - Future>> getAllPlayers() async { + /// Retrieves whole [tetrioUsersTable] and returns Map {id: nickname} of everyone in database + Future> getAllPlayers() async { await ensureDbIsOpen(); final db = getDatabaseOrThrow(); final players = await db.query(tetrioUsersTable); - Map> data = {}; + Map data = {}; for (var entry in players){ - var test = json.decode(entry['jsonStates'] as String); - List states = []; - test.forEach((k, v) => states.add(TetrioPlayer.fromJson(v, DateTime.fromMillisecondsSinceEpoch(int.parse(k) * 1000), entry[idCol] as String, entry[nickCol] as String))); - data.addEntries({states.last.userId: states}.entries); + data[entry[idCol] as String] = entry[nickCol] as String; } return data; } diff --git a/lib/views/state_view.dart b/lib/views/state_view.dart index 9be1ccf..b97f141 100644 --- a/lib/views/state_view.dart +++ b/lib/views/state_view.dart @@ -4,14 +4,15 @@ 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/text_timestamp.dart'; +import 'package:tetra_stats/widgets/tl_thingy.dart'; import 'package:tetra_stats/widgets/user_thingy.dart'; import 'package:window_manager/window_manager.dart'; final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms(); class StateView extends StatefulWidget { - final TetrioPlayer state; + final TetraLeague state; const StateView({super.key, required this.state}); @override @@ -28,7 +29,7 @@ class StateState extends State { _scrollController = ScrollController(); if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS){ windowManager.getTitle().then((value) => oldWindowTitle = value); - windowManager.setTitle("Tetra Stats: ${t.stateViewTitle(nickname: widget.state.username.toUpperCase(), date: dateFormat.format(widget.state.state))}"); + windowManager.setTitle("State from ${timestamp(widget.state.timestamp)}"); } super.initState(); } @@ -48,16 +49,13 @@ class StateState extends State { Widget build(BuildContext context) { final t = Translations.of(context); return Scaffold( - appBar: AppBar( - title: Text(t.stateViewTitle(nickname: widget.state.username.toUpperCase(), date: dateFormat.format(widget.state.state))), - ), - backgroundColor: Colors.black, - body: SafeArea( - child: NestedScrollView( - controller: _scrollController, - headerSliverBuilder: (context, value) { - return [SliverToBoxAdapter(child: UserThingy(player: widget.state, showStateTimestamp: true, setState: _justUpdate))]; - }, - body: Container()))); + appBar: AppBar( + title: Text("State from ${timestamp(widget.state.timestamp)}"), + ), + backgroundColor: Colors.black, + body: SafeArea( + child: TLThingy(tl: widget.state, userID: widget.state.id, states: []) + ) + ); } } diff --git a/lib/views/states_view.dart b/lib/views/states_view.dart index af7b32f..bf0fc5f 100644 --- a/lib/views/states_view.dart +++ b/lib/views/states_view.dart @@ -1,18 +1,19 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; 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/main.dart' show teto; +import 'package:tetra_stats/utils/numers_formats.dart'; import 'package:tetra_stats/views/mathes_view.dart'; import 'package:tetra_stats/views/state_view.dart'; import 'package:tetra_stats/widgets/text_timestamp.dart'; import 'package:window_manager/window_manager.dart'; class StatesView extends StatefulWidget { - final List states; - const StatesView({super.key, required this.states}); + final String nickname; + final String id; + const StatesView({required this.nickname, required this.id, super.key}); @override State createState() => StatesState(); @@ -25,7 +26,7 @@ class StatesState extends State { void initState() { if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS){ windowManager.getTitle().then((value) => oldWindowTitle = value); - windowManager.setTitle("Tetra Stats: ${t.statesViewTitle(number: widget.states.length, nickname: widget.states.last.id.toUpperCase())}"); + //windowManager.setTitle("Tetra Stats: ${t.statesViewTitle(number: widget.states.length, nickname: widget.states.last.id.toUpperCase())}"); } super.initState(); } @@ -41,45 +42,78 @@ class StatesState extends State { final t = Translations.of(context); return Scaffold( appBar: AppBar( - title: Text(t.statesViewTitle(number: widget.states.length, nickname: widget.states.first.id)), + title: Text(t.statesViewTitle(number: "", nickname: widget.nickname)), actions: [ IconButton( onPressed: (){ Navigator.push( - context, - MaterialPageRoute( - builder: (context) => MatchesView(userID: widget.states.first.id, username: widget.states.first.id), - ), - ); + context, + MaterialPageRoute( + builder: (context) => MatchesView(userID: widget.id, username: widget.nickname), + ), + ); }, icon: const Icon(Icons.list), tooltip: t.viewAllMatches) ], ), backgroundColor: Colors.black, body: SafeArea( - child: ListView.builder( - itemCount: widget.states.length, - itemBuilder: (context, index) { - return ListTile( - title: Text(timestamp(widget.states[index].timestamp)), - //subtitle: Text(t.statesViewEntry(level: widget.states[index].level.toStringAsFixed(2), gameTime: widget.states[index].gameTime, friends: widget.states[index].friendCount, rd: 0)), - 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(t.stateRemoved(date: timestamp(nn))))); - // })); - }, + child: FutureBuilder>(future: teto.getStates(widget.id), builder: (context, snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const Center(child: CircularProgressIndicator(color: Colors.white)); + case ConnectionState.done: + if (snapshot.hasData) { + return ListView.builder( + itemCount: snapshot.data!.length, + prototypeItem: ListTile( + title: Text(""), + subtitle: Text("", style: TextStyle(color: Colors.grey)), + trailing: IconButton(icon: const Icon(Icons.delete_forever), onPressed: (){}), ), - onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => StateView(state: widget.states[index]), - // ), - // ); - }, + itemBuilder: (context, index) { + return ListTile( + title: Text(timestamp(snapshot.data![index].timestamp)), + subtitle: Text( + t.statesViewEntry(level: f2.format(snapshot.data![index].tr), games: intf.format(snapshot.data![index].gamesPlayed), glicko: snapshot.data![index].glicko != null ? f2.format(snapshot.data![index].glicko) : "---", rd: snapshot.data![index].rd != null ? f2.format(snapshot.data![index].rd) : "--"), + style: TextStyle(color: Colors.grey), + ), + trailing: IconButton( + icon: const Icon(Icons.delete_forever), + onPressed: () { + teto.deleteState(snapshot.data![index].id+snapshot.data![index].timestamp.millisecondsSinceEpoch.toRadixString(16)).then((value) => setState(() { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.stateRemoved(date: timestamp(snapshot.data![index].timestamp))))); + })); + }, + ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => StateView(state: snapshot.data![index]), + ), + ); + }, + ); + }); + } else if (snapshot.hasError) { + return Center(child: + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(snapshot.error.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text(snapshot.stackTrace.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 18), textAlign: TextAlign.center), + ), + ], + ) ); - }))); + } + break; + } + return const Center(child: Text('default case of FutureBuilder', style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42), textAlign: TextAlign.center)); + } + )));} } -} diff --git a/lib/views/tracked_players_view.dart b/lib/views/tracked_players_view.dart index ef4cc6c..721bce4 100644 --- a/lib/views/tracked_players_view.dart +++ b/lib/views/tracked_players_view.dart @@ -78,7 +78,7 @@ class TrackedPlayersState extends State { case ConnectionState.active: return const Center(child: CircularProgressIndicator(color: Colors.white)); case ConnectionState.done: - final allPlayers = (snapshot.data != null) ? snapshot.data as Map> : >{}; + final allPlayers = (snapshot.data != null) ? snapshot.data as Map : {}; List keys = allPlayers.keys.toList(); return NestedScrollView( headerSliverBuilder: (context, value) { @@ -105,29 +105,29 @@ class TrackedPlayersState extends State { ]; }, body: ListView.builder( - itemCount: allPlayers.length, - itemBuilder: (context, index) { - return ListTile( - title: Text(t.trackedPlayersEntry(nickname: allPlayers[keys[index]]!.last.username, numberOfStates: allPlayers[keys[index]]!.length)), - subtitle: Text(t.trackedPlayersDescription(firstStateDate: timestamp(allPlayers[keys[index]]!.first.state), lastStateDate: timestamp(allPlayers[keys[index]]!.last.state))), - trailing: IconButton( - icon: const Icon(Icons.delete_forever), - onPressed: () { - String nn = allPlayers[keys[index]]!.last.username; - setState(() {teto.deletePlayer(keys[index]);}); - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.trackedPlayersStatesDeleted(nickname: nn)))); - }, - ), - onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => StatesView(states: allPlayers[keys[index]]!), - // ), - // ); + itemCount: allPlayers.length, + itemBuilder: (context, index) { + print(index); + return ListTile( + title: Text(allPlayers[keys[index]]??"No nickname (huh?)"), + subtitle: Text(keys[index], style: TextStyle(fontFamily: "Eurostile Round Condensed", color: Colors.grey)), + trailing: IconButton( + icon: const Icon(Icons.delete_forever), + onPressed: () { + setState(() {teto.deletePlayer(keys[index]);}); + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.trackedPlayersStatesDeleted(nickname: allPlayers[keys[index]]??"No nickname (huh?)")))); }, - ); - })); + ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => StatesView(nickname: allPlayers[keys[index]]!, id: keys[index]), + ), + ); + }, + ); + })); } })), ); diff --git a/pubspec.yaml b/pubspec.yaml index 4ac97d4..5b7c6ad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: tetra_stats description: Track your and other player stats in TETR.IO publish_to: 'none' -version: 1.6.8+34 +version: 1.6.9+35 environment: sdk: '>=3.0.0' diff --git a/res/i18n/strings.i18n.json b/res/i18n/strings.i18n.json index 789e25e..1f3ba9a 100644 --- a/res/i18n/strings.i18n.json +++ b/res/i18n/strings.i18n.json @@ -89,9 +89,6 @@ "smooth": "Smooth", "postSeason": "Off-season", "seasonStarts": "Season starts in:", - "myMessadgeHeader": "A messadge from dan63", - "myMessadgeBody": "TETR.IO Tetra Channel API has been seriously modified after the last update, therefore, some functions may not work. I will try to catch up and add new stats (and return back the old ones) as soon, as public docs on new Tetra Channel API will be available.", - "preSeasonMessage": "Right now you can play unranked FT3 matches with hidden glicko (200 RD 🙂).\nSeason ${n} rules applied", "nanow": "Not avaliable for now...", "seasonEnds": "Season ends in ${countdown}", "seasonEnded": "Season has ended", @@ -158,7 +155,7 @@ "stateViewTitle": "${nickname} account on ${date}", "statesViewTitle": "${number} states of ${nickname} account", "matchesViewTitle": "${nickname} TL matches", - "statesViewEntry": "Level ${level}, ${gameTime} of gametime, ${friends} friends, ${rd} RD", + "statesViewEntry": "${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно", "stateRemoved": "${date} state was removed from database!", "matchRemoved": "${date} match was removed from database!", "viewAllMatches": "View all matches", diff --git a/res/i18n/strings_ru.i18n.json b/res/i18n/strings_ru.i18n.json index f8dbbc9..5f48489 100644 --- a/res/i18n/strings_ru.i18n.json +++ b/res/i18n/strings_ru.i18n.json @@ -89,9 +89,6 @@ "smooth": "Гладкий", "postSeason": "Внесезонье", "seasonStarts": "Сезон начнётся через:", - "myMessadgeHeader": "Сообщение от dan63", - "myMessadgeBody": "TETR.IO Tetra Channel API был серьёзно изменён после последнего обновления, поэтому некоторый функционал может не работать. Я постараюсь добавить новую статистику (и вернуть старую) как только будут опубликована новая документация по данному API.", - "preSeasonMessage": "Прямо сейчас вы можете сыграть безранговый матч до трёх побед со скрытым Glicko (200 RD 🙂).\nПрименяются правила ${n} сезона", "nanow": "Пока недоступно...", "seasonEnds": "Сезон закончится через ${countdown}", "seasonEnded": "Сезон закончился", @@ -158,7 +155,7 @@ "stateViewTitle": "Аккаунт ${nickname} ${date}", "statesViewTitle": "${number} состояний аккаунта ${nickname}", "matchesViewTitle": "Матчи аккаунта ${nickname}", - "statesViewEntry": "${level} уровень, ${gameTime} сыграно, ${friends} друзей, ${rd} RD", + "statesViewEntry": "${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно", "stateRemoved": "Состояние от ${date} было удалено из локальной базы данных!", "matchRemoved": "Матч от ${date} был удален из локальной базы данных!", "viewAllMatches": "Все матчи",