Compare commits
3 Commits
d34b072fcd
...
54a5cc683c
Author | SHA1 | Date |
---|---|---|
dan63047 | 54a5cc683c | |
dan63047 | 29ac38c034 | |
dan63047 | 0e89b2bf3e |
File diff suppressed because it is too large
Load Diff
|
@ -897,11 +897,11 @@ 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 = ownId != replayId;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
|
@ -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
|
@ -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 'Ранг';
|
||||||
|
|
|
@ -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": "0", "count": "9000"});
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -1084,7 +1085,7 @@ class _TwoRecordsThingy extends StatelessWidget {
|
||||||
if (sprint != null) FinesseThingy(sprint?.endContext.finesse, sprint?.endContext.finessePercentage),
|
if (sprint != null) FinesseThingy(sprint?.endContext.finesse, sprint?.endContext.finessePercentage),
|
||||||
if (sprint != null) LineclearsThingy(sprint!.endContext.clears, sprint!.endContext.lines, sprint!.endContext.holds, sprint!.endContext.tSpins),
|
if (sprint != null) LineclearsThingy(sprint!.endContext.clears, sprint!.endContext.lines, sprint!.endContext.holds, sprint!.endContext.tSpins),
|
||||||
if (sprint != null) Text("${sprint!.endContext.inputs} KP • ${f2.format(sprint!.endContext.kps)} KPS"),
|
if (sprint != null) Text("${sprint!.endContext.inputs} KP • ${f2.format(sprint!.endContext.kps)} KPS"),
|
||||||
Wrap(
|
if (sprint != null) Wrap(
|
||||||
alignment: WrapAlignment.spaceBetween,
|
alignment: WrapAlignment.spaceBetween,
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
|
@ -1170,7 +1171,7 @@ class _TwoRecordsThingy extends StatelessWidget {
|
||||||
if (blitz != null) FinesseThingy(blitz?.endContext.finesse, blitz?.endContext.finessePercentage),
|
if (blitz != null) FinesseThingy(blitz?.endContext.finesse, blitz?.endContext.finessePercentage),
|
||||||
if (blitz != null) LineclearsThingy(blitz!.endContext.clears, blitz!.endContext.lines, blitz!.endContext.holds, blitz!.endContext.tSpins),
|
if (blitz != null) LineclearsThingy(blitz!.endContext.clears, blitz!.endContext.lines, blitz!.endContext.holds, blitz!.endContext.tSpins),
|
||||||
if (blitz != null) Text("${blitz!.endContext.piecesPlaced} P • ${blitz!.endContext.inputs} KP • ${f2.format(blitz!.endContext.kpp)} KPP • ${f2.format(blitz!.endContext.kps)} KPS"),
|
if (blitz != null) Text("${blitz!.endContext.piecesPlaced} P • ${blitz!.endContext.inputs} KP • ${f2.format(blitz!.endContext.kpp)} KPP • ${f2.format(blitz!.endContext.kps)} KPS"),
|
||||||
Wrap(
|
if (blitz != null) Wrap(
|
||||||
alignment: WrapAlignment.spaceBetween,
|
alignment: WrapAlignment.spaceBetween,
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -288,13 +288,13 @@ class SettingsState extends State<SettingsView> {
|
||||||
subtitle: Text(t.aboutAppText(appName: packageInfo.appName, packageName: packageInfo.packageName, version: packageInfo.version, buildNumber: packageInfo.buildNumber)),
|
subtitle: Text(t.aboutAppText(appName: packageInfo.appName, packageName: packageInfo.packageName, version: packageInfo.version, buildNumber: packageInfo.buildNumber)),
|
||||||
trailing: const Icon(Icons.arrow_right)
|
trailing: const Icon(Icons.arrow_right)
|
||||||
),
|
),
|
||||||
Wrap(
|
// Wrap(
|
||||||
alignment: WrapAlignment.center,
|
// alignment: WrapAlignment.center,
|
||||||
spacing: 8,
|
// spacing: 8,
|
||||||
children: [
|
// children: [
|
||||||
TextButton(child: Text("Donate to me"), onPressed: (){},),TextButton(child: Text("Donate to NOT me"), onPressed: (){},),TextButton(child: Text("Donate to someone else"), onPressed: (){},),
|
// TextButton(child: Text("Donate to me"), onPressed: (){},),TextButton(child: Text("Donate to NOT me"), onPressed: (){},),TextButton(child: Text("Donate to someone else"), onPressed: (){},),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -126,7 +126,7 @@ class SingleplayerRecord extends StatelessWidget {
|
||||||
LineclearsThingy(record!.endContext.clears, record!.endContext.lines, record!.endContext.holds, record!.endContext.tSpins),
|
LineclearsThingy(record!.endContext.clears, record!.endContext.lines, record!.endContext.holds, record!.endContext.tSpins),
|
||||||
if (record!.endContext.gameType == "40l") Text("${record!.endContext.inputs} KP • ${f2.format(record!.endContext.kps)} KPS"),
|
if (record!.endContext.gameType == "40l") Text("${record!.endContext.inputs} KP • ${f2.format(record!.endContext.kps)} KPS"),
|
||||||
if (record!.endContext.gameType == "blitz") Text("${record!.endContext.piecesPlaced} P • ${record!.endContext.inputs} KP • ${f2.format(record!.endContext.kpp)} KPP • ${f2.format(record!.endContext.kps)} KPS"),
|
if (record!.endContext.gameType == "blitz") Text("${record!.endContext.piecesPlaced} P • ${record!.endContext.inputs} KP • ${f2.format(record!.endContext.kpp)} KPP • ${f2.format(record!.endContext.kps)} KPS"),
|
||||||
Wrap(
|
if (record != null) Wrap(
|
||||||
alignment: WrapAlignment.spaceBetween,
|
alignment: WrapAlignment.spaceBetween,
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
|
|
|
@ -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))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
"fromBeginning": "С начала",
|
"fromBeginning": "С начала",
|
||||||
"calc": "Считать",
|
"calc": "Считать",
|
||||||
"calcViewNoValues": "Введите значения, чтобы посчитать статистику",
|
"calcViewNoValues": "Введите значения, чтобы посчитать статистику",
|
||||||
"rankAveragesViewTitle": "Требования рангов и средние значения",
|
"rankAveragesViewTitle": "Требования рангов",
|
||||||
"sprintAndBlitsViewTitle": "Средние результаты 40 линий и блица",
|
"sprintAndBlitsViewTitle": "Средние результаты 40 линий и блица",
|
||||||
"sprintAndBlitsRelevance": "Актуальность: ${date}",
|
"sprintAndBlitsRelevance": "Актуальность: ${date}",
|
||||||
"rank": "Ранг",
|
"rank": "Ранг",
|
||||||
|
|
|
@ -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){
|
||||||
|
|
Loading…
Reference in New Issue