Season 1 end is near, 1.6.1 is here

This commit is contained in:
dan63047 2024-07-10 18:31:00 +03:00
parent d34b072fcd
commit 0e89b2bf3e
15 changed files with 1132 additions and 1173 deletions

File diff suppressed because it is too large Load Diff

View File

@ -897,9 +897,9 @@ class TetraLeagueAlphaRecord{
TetraLeagueAlphaRecord({required this.replayId, required this.ownId, required this.timestamp, required this.endContext, required this.replayAvalable}); TetraLeagueAlphaRecord({required this.replayId, required this.ownId, required this.timestamp, required this.endContext, required this.replayAvalable});
TetraLeagueAlphaRecord.fromJson(Map<String, dynamic> json) { TetraLeagueAlphaRecord.fromJson(Map<String, dynamic> json) {
ownId = json['_id'];
endContext = [EndContextMulti.fromJson(json['endcontext'][0]), EndContextMulti.fromJson(json['endcontext'][1])]; endContext = [EndContextMulti.fromJson(json['endcontext'][0]), EndContextMulti.fromJson(json['endcontext'][1])];
replayId = json['replayid']; replayId = json['replayid'];
ownId = json['_id']??replayId;
timestamp = DateTime.parse(json['ts']); timestamp = DateTime.parse(json['ts']);
replayAvalable = true; replayAvalable = true;
} }
@ -973,19 +973,19 @@ class EndContextMulti {
EndContextMulti.fromJson(Map<String, dynamic> json) { EndContextMulti.fromJson(Map<String, dynamic> json) {
userId = json['id'] ?? json['user']['_id']; userId = json['id'] ?? json['user']['_id'];
username = json['username'] ?? json['user']['username']; username = json['username'] ?? json['user']['username'];
handling = Handling.fromJson(json['handling']); handling = json['handling'] != null ? Handling.fromJson(json['handling']) : Handling(arr: -1, das: -1, sdf: -1, dcd: 0, cancel: true, safeLock: true);
success = json['success']; success = json['success'];
inputs = json['inputs']; inputs = json['inputs'] ?? -1;
piecesPlaced = json['piecesplaced']; piecesPlaced = json['piecesplaced'] ?? -1;
naturalOrder = json['naturalorder']; naturalOrder = json['naturalorder'];
wins = json['wins']; wins = json['wins'];
points = json['points']['primary']; points = json['points']['primary'];
secondary = json['points']['secondary'].toDouble(); secondary = json['points']['secondary'].toDouble();
tertiary = json['points']['tertiary'].toDouble(); tertiary = json['points']['tertiary'].toDouble();
secondaryTracking = json['points']['secondaryAvgTracking'].map((e) => e.toDouble()).toList(); secondaryTracking = json['points']['secondaryAvgTracking'] != null ? json['points']['secondaryAvgTracking'].map((e) => e.toDouble()).toList() : [];
tertiaryTracking = json['points']['tertiaryAvgTracking'].map((e) => e.toDouble()).toList(); tertiaryTracking = json['points']['tertiaryAvgTracking'] != null ? json['points']['tertiaryAvgTracking'].map((e) => e.toDouble()).toList() : [];
extra = json['points']['extra']['vs'].toDouble(); extra = json['points']['extra']['vs'].toDouble();
extraTracking = json['points']['extraAvgTracking']['aggregatestats___vsscore'].map((e) => e.toDouble()).toList(); extraTracking = json['points']['extraAvgTracking'] != null ? json['points']['extraAvgTracking']['aggregatestats___vsscore'].map((e) => e.toDouble()).toList() : [];
nerdStats = NerdStats(secondary, tertiary, extra); nerdStats = NerdStats(secondary, tertiary, extra);
nerdStatsTracking = [for (int i = 0; i < secondaryTracking.length; i++) NerdStats(secondaryTracking[i], tertiaryTracking[i], extraTracking[i])]; nerdStatsTracking = [for (int i = 0; i < secondaryTracking.length; i++) NerdStats(secondaryTracking[i], tertiaryTracking[i], extraTracking[i])];
estTr = EstTr(secondary, tertiary, extra, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe); estTr = EstTr(secondary, tertiary, extra, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
/// Locales: 2 /// Locales: 2
/// Strings: 1182 (591 per locale) /// Strings: 1182 (591 per locale)
/// ///
/// Built on 2024-06-16 at 21:03 UTC /// Built on 2024-07-10 at 15:23 UTC
// coverage:ignore-file // coverage:ignore-file
// ignore_for_file: type=lint // ignore_for_file: type=lint
@ -321,7 +321,7 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
String get fromBeginning => 'From beginning'; String get fromBeginning => 'From beginning';
String get calc => 'Calc'; String get calc => 'Calc';
String get calcViewNoValues => 'Enter values to calculate the stats'; String get calcViewNoValues => 'Enter values to calculate the stats';
String get rankAveragesViewTitle => 'Ranks cutoff and average stats'; String get rankAveragesViewTitle => 'Ranks cutoffs';
String get sprintAndBlitsViewTitle => '40 lines and Blitz averages'; String get sprintAndBlitsViewTitle => '40 lines and Blitz averages';
String sprintAndBlitsRelevance({required Object date}) => 'Relevance: ${date}'; String sprintAndBlitsRelevance({required Object date}) => 'Relevance: ${date}';
String get rank => 'Rank'; String get rank => 'Rank';
@ -1016,7 +1016,7 @@ class _StringsRu implements Translations {
@override String get fromBeginning => 'С начала'; @override String get fromBeginning => 'С начала';
@override String get calc => 'Считать'; @override String get calc => 'Считать';
@override String get calcViewNoValues => 'Введите значения, чтобы посчитать статистику'; @override String get calcViewNoValues => 'Введите значения, чтобы посчитать статистику';
@override String get rankAveragesViewTitle => 'Требования рангов и средние значения'; @override String get rankAveragesViewTitle => 'Требования рангов';
@override String get sprintAndBlitsViewTitle => 'Средние результаты 40 линий и блица'; @override String get sprintAndBlitsViewTitle => 'Средние результаты 40 линий и блица';
@override String sprintAndBlitsRelevance({required Object date}) => 'Актуальность: ${date}'; @override String sprintAndBlitsRelevance({required Object date}) => 'Актуальность: ${date}';
@override String get rank => 'Ранг'; @override String get rank => 'Ранг';
@ -1703,7 +1703,7 @@ extension on Translations {
case 'fromBeginning': return 'From beginning'; case 'fromBeginning': return 'From beginning';
case 'calc': return 'Calc'; case 'calc': return 'Calc';
case 'calcViewNoValues': return 'Enter values to calculate the stats'; case 'calcViewNoValues': return 'Enter values to calculate the stats';
case 'rankAveragesViewTitle': return 'Ranks cutoff and average stats'; case 'rankAveragesViewTitle': return 'Ranks cutoffs';
case 'sprintAndBlitsViewTitle': return '40 lines and Blitz averages'; case 'sprintAndBlitsViewTitle': return '40 lines and Blitz averages';
case 'sprintAndBlitsRelevance': return ({required Object date}) => 'Relevance: ${date}'; case 'sprintAndBlitsRelevance': return ({required Object date}) => 'Relevance: ${date}';
case 'rank': return 'Rank'; case 'rank': return 'Rank';
@ -2314,7 +2314,7 @@ extension on _StringsRu {
case 'fromBeginning': return 'С начала'; case 'fromBeginning': return 'С начала';
case 'calc': return 'Считать'; case 'calc': return 'Считать';
case 'calcViewNoValues': return 'Введите значения, чтобы посчитать статистику'; case 'calcViewNoValues': return 'Введите значения, чтобы посчитать статистику';
case 'rankAveragesViewTitle': return 'Требования рангов и средние значения'; case 'rankAveragesViewTitle': return 'Требования рангов';
case 'sprintAndBlitsViewTitle': return 'Средние результаты 40 линий и блица'; case 'sprintAndBlitsViewTitle': return 'Средние результаты 40 линий и блица';
case 'sprintAndBlitsRelevance': return ({required Object date}) => 'Актуальность: ${date}'; case 'sprintAndBlitsRelevance': return ({required Object date}) => 'Актуальность: ${date}';
case 'rank': return 'Ранг'; case 'rank': return 'Ранг';

View File

@ -606,7 +606,7 @@ class TetrioService extends DB {
if (kIsWeb) { if (kIsWeb) {
url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLMatches", "user": userID}); url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLMatches", "user": userID});
} else { } else {
url = Uri.https('api.p1nkl0bst3r.xyz', 'tlmatches/$userID'); url = Uri.https('api.p1nkl0bst3r.xyz', 'tlmatches/$userID', {"before": "66749c93ffcbce61b2a1d912"});
} }
try{ try{
@ -614,62 +614,9 @@ class TetrioService extends DB {
switch (response.statusCode) { switch (response.statusCode) {
case 200: case 200:
// that one api returns csv instead of json TetraLeagueAlphaStream stream = TetraLeagueAlphaStream.fromJson(jsonDecode(response.body)['data']['records'], userID);
List<List<dynamic>> csv = const CsvToListConverter().convert(response.body)..removeAt(0); saveTLMatchesFromStream(stream);
List<TetraLeagueAlphaRecord> matches = []; return stream.records;
// parsing data into TetraLeagueAlphaRecord objects
for (var entry in csv){
TetraLeagueAlphaRecord match = TetraLeagueAlphaRecord(
replayId: entry[0].toString(),
ownId: entry[0].toString(), // i gonna disting p1nkl0bst3r entries with it
timestamp: DateTime.parse(entry[1]),
endContext: [
EndContextMulti(
userId: entry[2].toString(),
username: entry[3].toString(),
naturalOrder: 0,
inputs: -1,
piecesPlaced: -1,
handling: Handling(arr: -1, das: -1, sdf: -1, dcd: 0, cancel: true, safeLock: true),
points: entry[4],
wins: entry[4],
secondary: entry[6],
secondaryTracking: [],
tertiary: entry[5],
tertiaryTracking: [],
extra: entry[7],
extraTracking: [],
success: true
),
EndContextMulti(
userId: entry[8].toString(),
username: entry[9].toString(),
naturalOrder: 1,
inputs: -1,
piecesPlaced: -1,
handling: Handling(arr: -1, das: -1, sdf: -1, dcd: 0, cancel: true, safeLock: true),
points: entry[10],
wins: entry[10],
secondary: entry[12],
secondaryTracking: [],
tertiary: entry[11],
tertiaryTracking: [],
extra: entry[13],
extraTracking: [],
success: false
)
],
replayAvalable: false
);
matches.add(match);
}
// trying to dump it to local DB
TetraLeagueAlphaStream fakeStream = TetraLeagueAlphaStream(userId: userID, records: matches);
saveTLMatchesFromStream(fakeStream);
return matches;
case 404: case 404:
developer.log("fetchAndSaveOldTLmatches: Probably, history doesn't exist", name: "services/tetrio_crud", error: response.statusCode); developer.log("fetchAndSaveOldTLmatches: Probably, history doesn't exist", name: "services/tetrio_crud", error: response.statusCode);
throw TetrioHistoryNotExist(); throw TetrioHistoryNotExist();

View File

@ -306,7 +306,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
}); });
} }
return [me, records, states, tlMatches, compareWith, isTracking, news, topTR, recent, sprint, blitz]; return [me, records, states, tlMatches, compareWith, isTracking, news, topTR, recent, sprint, blitz, tlMatches.elementAtOrNull(0)?.timestamp];
} }
/// Triggers widgets rebuild /// Triggers widgets rebuild
@ -459,6 +459,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
userID: snapshot.data![0].userId, userID: snapshot.data![0].userId,
states: snapshot.data![2], states: snapshot.data![2],
topTR: snapshot.data![7]?.tr, topTR: snapshot.data![7]?.tr,
lastMatchPlayed: snapshot.data![11],
bot: snapshot.data![0].role == "bot", bot: snapshot.data![0].role == "bot",
guest: snapshot.data![0].role == "anon", guest: snapshot.data![0].role == "anon",
thatRankCutoff: thatRankCutoff, thatRankCutoff: thatRankCutoff,

View File

@ -49,14 +49,13 @@ class RanksAverages extends State<RankAveragesView> {
child: averages.isEmpty ? const Center(child: Text('Fetching...')) : ListView.builder( child: averages.isEmpty ? const Center(child: Text('Fetching...')) : ListView.builder(
itemCount: averages.length, itemCount: averages.length,
itemBuilder: (context, index){ itemBuilder: (context, index){
bool bigScreen = MediaQuery.of(context).size.width > 768;
List<String> keys = averages.keys.toList(); List<String> keys = averages.keys.toList();
return ListTile( return ListTile(
leading: Image.asset("res/tetrio_tl_alpha_ranks/${keys[index]}.png", height: 48), leading: Image.asset("res/tetrio_tl_alpha_ranks/${keys[index]}.png", height: 48),
title: Text(t.players(n: averages[keys[index]]?[1]["players"]), style: const TextStyle(fontFamily: "Eurostile Round Extended")), title: Text(t.players(n: averages[keys[index]]?[1]["players"]), style: const TextStyle(fontFamily: "Eurostile Round Extended")),
subtitle: Text("${f2.format(averages[keys[index]]?[0].apm)} APM, ${f2.format(averages[keys[index]]?[0].pps)} PPS, ${f2.format(averages[keys[index]]?[0].vs)} VS, ${f2.format(averages[keys[index]]?[0].nerdStats.app)} APP, ${f2.format(averages[keys[index]]?[0].nerdStats.vsapm)} VS/APM", subtitle: Text("${f2.format(averages[keys[index]]?[0].apm)} APM, ${f2.format(averages[keys[index]]?[0].pps)} PPS, ${f2.format(averages[keys[index]]?[0].vs)} VS, ${f2.format(averages[keys[index]]?[0].nerdStats.app)} APP, ${f2.format(averages[keys[index]]?[0].nerdStats.vsapm)} VS/APM",
style: const TextStyle(fontFamily: "Eurostile Round Condensed", color: Colors.grey)), style: const TextStyle(fontFamily: "Eurostile Round Condensed", color: Colors.grey, fontSize: 13)),
trailing: Text("${f2.format(averages[keys[index]]?[1]["toEnterTR"])} TR", style: bigScreen ? const TextStyle(fontSize: 28) : null), trailing: Text("${f2.format(averages[keys[index]]?[1]["toEnterTR"])} TR", style: const TextStyle(fontSize: 28, fontFamily: "Eurostile Round")),
onTap: (){ onTap: (){
if (averages[keys[index]]?[1]["players"] > 0) { if (averages[keys[index]]?[1]["players"] > 0) {
Navigator.push( Navigator.push(

View File

@ -58,7 +58,7 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
); );
}, },
icon: const Icon(Icons.compress), icon: const Icon(Icons.compress),
tooltip: t.averages, tooltip: t.rankAveragesViewTitle,
), ),
], ],
), ),
@ -102,11 +102,11 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
), ),
TextButton(onPressed: (){ TextButton(onPressed: (){
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => RankView(rank: snapshot.data!.getAverageOfRank("")), builder: (context) => RankView(rank: snapshot.data!.getAverageOfRank("")),
), ),
); );
}, child: Text(t.everyoneAverages, }, child: Text(t.everyoneAverages,
style: const TextStyle(fontSize: 25))) style: const TextStyle(fontSize: 25)))
],) ],)
@ -184,12 +184,12 @@ class TLLeaderboardState extends State<TLLeaderboardView> {
style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 28 : 24, height: 0.9) style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 28 : 24, height: 0.9)
), ),
title: Text(allPlayers[index].username, style: TextStyle(fontFamily: bigScreen ? "Eurostile Round Extended" : "Eurostile Round", height: 0.9)), title: Text(allPlayers[index].username, style: TextStyle(fontFamily: bigScreen ? "Eurostile Round Extended" : "Eurostile Round", height: 0.9)),
subtitle: Text(_sortBy == Stats.tr ? "${f2.format(allPlayers[index].apm)} APM, ${f2.format(allPlayers[index].pps)} PPS, ${f2.format(allPlayers[index].vs)} VS, ${f2.format(allPlayers[index].nerdStats.app)} APP, ${f2.format(allPlayers[index].nerdStats.vsapm)} VS/APM" : "${_f4.format(allPlayers[index].getStatByEnum(_sortBy))} ${chartsShortTitles[_sortBy]}", subtitle: (bigScreen || _sortBy != Stats.tr) ? Text(_sortBy == Stats.tr ? "${f2.format(allPlayers[index].apm)} APM, ${f2.format(allPlayers[index].pps)} PPS, ${f2.format(allPlayers[index].vs)} VS, ${f2.format(allPlayers[index].nerdStats.app)} APP, ${f2.format(allPlayers[index].nerdStats.vsapm)} VS/APM" : "${_f4.format(allPlayers[index].getStatByEnum(_sortBy))} ${chartsShortTitles[_sortBy]}",
style: TextStyle(fontFamily: "Eurostile Round Condensed", fontSize: bigScreen ? null : 12, color: _sortBy == Stats.tr ? Colors.grey : null)), style: TextStyle(fontFamily: "Eurostile Round Condensed", fontSize: bigScreen ? null : 13, color: _sortBy == Stats.tr ? Colors.grey : null)) : null,
trailing: Row( trailing: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text("${f2.format(allPlayers[index].rating)} TR", style: TextStyle(fontSize: bigScreen ? 28 : 22)), Text("${f2.format(allPlayers[index].rating)} TR", style: const TextStyle(fontSize: 28)),
Image.asset("res/tetrio_tl_alpha_ranks/${allPlayers[index].rank}.png", height: bigScreen ? 48 : 36), Image.asset("res/tetrio_tl_alpha_ranks/${allPlayers[index].rank}.png", height: bigScreen ? 48 : 36),
], ],
), ),

View File

@ -269,7 +269,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
label: "Sent", higherIsBetter: true), label: "Sent", higherIsBetter: true),
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.recived, CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.recived,
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.recived, redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.recived : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.recived,
label: "Recived", higherIsBetter: true), label: "Received", higherIsBetter: true),
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.attack, CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.attack,
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.attack, redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.attack : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.attack,
label: "Attack", higherIsBetter: true), label: "Attack", higherIsBetter: true),

View File

@ -1,3 +1,5 @@
import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:tetra_stats/data_objects/tetrio.dart'; import 'package:tetra_stats/data_objects/tetrio.dart';
@ -6,14 +8,16 @@ import 'package:tetra_stats/main.dart' show prefs;
import 'package:tetra_stats/utils/numers_formats.dart'; import 'package:tetra_stats/utils/numers_formats.dart';
var fDiff = NumberFormat("+#,###.####;-#,###.####"); var fDiff = NumberFormat("+#,###.####;-#,###.####");
DateTime seasonEnd = DateTime.utc(2024, 07, 26);
class TLRatingThingy extends StatelessWidget{ class TLRatingThingy extends StatelessWidget{
final String userID; final String userID;
final TetraLeagueAlpha tlData; final TetraLeagueAlpha tlData;
final TetraLeagueAlpha? oldTl; final TetraLeagueAlpha? oldTl;
final double? topTR; final double? topTR;
final DateTime? lastMatchPlayed;
const TLRatingThingy({super.key, required this.userID, required this.tlData, this.oldTl, this.topTR}); const TLRatingThingy({super.key, required this.userID, required this.tlData, this.oldTl, this.topTR, this.lastMatchPlayed});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -23,6 +27,11 @@ class TLRatingThingy extends StatelessWidget{
List<String> formatedTR = f4.format(tlData.rating).split(decimalSeparator); List<String> formatedTR = f4.format(tlData.rating).split(decimalSeparator);
List<String> formatedGlicko = f4.format(tlData.glicko).split(decimalSeparator); List<String> formatedGlicko = f4.format(tlData.glicko).split(decimalSeparator);
List<String> formatedPercentile = f4.format(tlData.percentile * 100).split(decimalSeparator); List<String> formatedPercentile = f4.format(tlData.percentile * 100).split(decimalSeparator);
DateTime now = DateTime.now();
bool beforeS1end = now.isBefore(seasonEnd);
int daysLeft = seasonEnd.difference(now).inDays;
print(max(0, 7 - (lastMatchPlayed != null ? now.difference(lastMatchPlayed!).inDays : 7)));
int safeRD = min(100, (100 + ((tlData.rd! >= 100 && tlData.decaying) ? 7 : max(0, 7 - (lastMatchPlayed != null ? now.difference(lastMatchPlayed!).inDays : 7))) - daysLeft).toInt());
return Wrap( return Wrap(
direction: Axis.horizontal, direction: Axis.horizontal,
alignment: WrapAlignment.spaceAround, alignment: WrapAlignment.spaceAround,
@ -83,7 +92,8 @@ class TLRatingThingy extends StatelessWidget{
if (topTR != null) TextSpan(text: " (${f2.format(topTR)} TR)"), if (topTR != null) TextSpan(text: " (${f2.format(topTR)} TR)"),
TextSpan(text: "${prefs.getInt("ratingMode") == 1 ? "${f2.format(tlData.rating)} TR • RD: " : "Glicko: ${f2.format(tlData.glicko!)}±"}"), TextSpan(text: "${prefs.getInt("ratingMode") == 1 ? "${f2.format(tlData.rating)} TR • RD: " : "Glicko: ${f2.format(tlData.glicko!)}±"}"),
TextSpan(text: f2.format(tlData.rd!), style: tlData.decaying ? TextStyle(color: tlData.rd! > 98 ? Colors.red : Colors.yellow) : null), TextSpan(text: f2.format(tlData.rd!), style: tlData.decaying ? TextStyle(color: tlData.rd! > 98 ? Colors.red : Colors.yellow) : null),
if (tlData.decaying) WidgetSpan(child: Icon(Icons.trending_up, color: tlData.rd! > 98 ? Colors.red : Colors.yellow,), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic) if (tlData.decaying) WidgetSpan(child: Icon(Icons.trending_up, color: tlData.rd! > 98 ? Colors.red : Colors.yellow,), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic),
if (beforeS1end) tlData.rd! <= safeRD ? TextSpan(text: " (Safe)", style: TextStyle(color: Colors.greenAccent)) : TextSpan(text: " (> ${safeRD} RD !!!)", style: TextStyle(color: Colors.redAccent))
], ],
), ),
), ),

View File

@ -31,7 +31,8 @@ class TLThingy extends StatefulWidget {
final double? nextRankCutoff; final double? nextRankCutoff;
final double? nextRankCutoffGlicko; final double? nextRankCutoffGlicko;
final double? nextRankTarget; final double? nextRankTarget;
const TLThingy({super.key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.guest=false, this.topTR, this.lbPositions, this.averages, this.nextRankCutoff, this.thatRankCutoff, this.thatRankCutoffGlicko, this.nextRankCutoffGlicko, this.nextRankTarget, this.thatRankTarget}); final DateTime? lastMatchPlayed;
const TLThingy({super.key, required this.tl, required this.userID, required this.states, this.showTitle = true, this.bot=false, this.guest=false, this.topTR, this.lbPositions, this.averages, this.nextRankCutoff, this.thatRankCutoff, this.thatRankCutoffGlicko, this.nextRankCutoffGlicko, this.nextRankTarget, this.thatRankTarget, this.lastMatchPlayed});
@override @override
State<TLThingy> createState() => _TLThingyState(); State<TLThingy> createState() => _TLThingyState();
@ -92,7 +93,7 @@ class _TLThingyState extends State<TLThingy> {
}); });
}, },
), ),
if (currentTl.gamesPlayed >= 10) TLRatingThingy(userID: widget.userID, tlData: currentTl, oldTl: oldTl, topTR: widget.topTR), if (currentTl.gamesPlayed > 9) TLRatingThingy(userID: widget.userID, tlData: currentTl, oldTl: oldTl, topTR: widget.topTR, lastMatchPlayed: widget.lastMatchPlayed),
if (currentTl.gamesPlayed > 9) TLProgress( if (currentTl.gamesPlayed > 9) TLProgress(
tlData: currentTl, tlData: currentTl,
previousRankTRcutoff: widget.thatRankCutoff, previousRankTRcutoff: widget.thatRankCutoff,

View File

@ -2,7 +2,7 @@ name: tetra_stats
description: Track your and other player stats in TETR.IO description: Track your and other player stats in TETR.IO
publish_to: 'none' publish_to: 'none'
version: 1.6.0+20 version: 1.6.1+21
environment: environment:
sdk: '>=3.0.0' sdk: '>=3.0.0'

View File

@ -186,7 +186,7 @@
"fromBeginning": "From beginning", "fromBeginning": "From beginning",
"calc": "Calc", "calc": "Calc",
"calcViewNoValues": "Enter values to calculate the stats", "calcViewNoValues": "Enter values to calculate the stats",
"rankAveragesViewTitle": "Ranks cutoff and average stats", "rankAveragesViewTitle": "Ranks cutoffs",
"sprintAndBlitsViewTitle": "40 lines and Blitz averages", "sprintAndBlitsViewTitle": "40 lines and Blitz averages",
"sprintAndBlitsRelevance": "Relevance: ${date}", "sprintAndBlitsRelevance": "Relevance: ${date}",
"rank": "Rank", "rank": "Rank",

View File

@ -186,7 +186,7 @@
"fromBeginning": "С начала", "fromBeginning": "С начала",
"calc": "Считать", "calc": "Считать",
"calcViewNoValues": "Введите значения, чтобы посчитать статистику", "calcViewNoValues": "Введите значения, чтобы посчитать статистику",
"rankAveragesViewTitle": "Требования рангов и средние значения", "rankAveragesViewTitle": "Требования рангов",
"sprintAndBlitsViewTitle": "Средние результаты 40 линий и блица", "sprintAndBlitsViewTitle": "Средние результаты 40 линий и блица",
"sprintAndBlitsRelevance": "Актуальность: ${date}", "sprintAndBlitsRelevance": "Актуальность: ${date}",
"rank": "Ранг", "rank": "Ранг",

View File

@ -150,7 +150,7 @@
let tip = document.querySelector("#tip"); let tip = document.querySelector("#tip");
const tips = [ const tips = [
// Promoting Tetra Stats "native" // Promoting Tetra Stats "native"
"Want a better perfomance?<br><a href=\"ya.ru\">Try out Tetra Stats Native</a>", "Want a better perfomance?<br><a href=\"https://github.com/dan63047/TetraStats/releases\">Try out Tetra Stats \"Native\"</a>",
"Imagine a world, where Tetra Stats was written in JS", "Imagine a world, where Tetra Stats was written in JS",
"Welcome to fullscreen canvas", "Welcome to fullscreen canvas",
@ -172,6 +172,7 @@
let appRunner = await engineInitializer.initializeEngine(); let appRunner = await engineInitializer.initializeEngine();
await appRunner.runApp(); await appRunner.runApp();
preloader.classList.add("hidden"); preloader.classList.add("hidden");
tip.classList.add("hidden");
} }
}); });
} catch (e){ } catch (e){