From 23a17bcbc055762648afca19fab2a0ca8ce1ee57 Mon Sep 17 00:00:00 2001 From: dan63047 Date: Mon, 21 Aug 2023 18:39:04 +0300 Subject: [PATCH] distinguishment + slight redesign of main view Prepared for the new release --- README.md | 26 +- lib/data_objects/tetrio.dart | 8 +- lib/gen/strings.g.dart | 8 +- lib/main.dart | 4 +- lib/views/compare_view.dart | 4 +- lib/views/main_view.dart | 84 +++++-- lib/views/rank_averages_view.dart | 11 +- pubspec.lock | 40 ++++ pubspec.yaml | 5 +- res/i18n/strings.i18n.json | 1 + res/i18n/strings_ru.i18n.json | 1 + res/icons/osk.svg | 83 +++++++ res/icons/tetrio-logo.svg | 383 ++++++++++++++++++++++++++++++ 13 files changed, 599 insertions(+), 59 deletions(-) create mode 100644 res/icons/osk.svg create mode 100644 res/icons/tetrio-logo.svg diff --git a/README.md b/README.md index c189774..7d7b11a 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,22 @@ # Tetra Stats -
Track your and other players stats in TETR.IO
+Track your and other players stats in TETR.IO -![Screenshot of the app](https://imgur.com/CKGYyBg.png) +You can [download an app](https://github.com/dan63047/TetraStats/releases), or [use web version](https://ts.dan63.by). -You can [try it out right now](https://ts.dan63.by)!!! (web version) +![Screenshot of the app 1](https://imgur.com/CKGYyBg.png) -If you want an app, you can find it [here](https://github.com/dan63047/TetraStats/releases)! # Available functionality - Advanced stats for players -- Rank cutoffs and averages -- Sqlite database, that can store all data +- Ranks cutoffs +- Minimums, averages, and maximums for every stat of every rank, as well, as whole leaderboard +- Chart for analyzing tetra league state +- Local database, that can store players data - Comparison to players, rank averages, and player stats from the past - Stats Calculator - Player history in charts -# I forgorπŸ’€ to do -- UI Animations -- im still not rendering distinguishment - ---- - -Special thanks to kerrmunism for formulas - -and to osk for TETR.IO \ No newline at end of file +# Special thanks +- **kerrmunism** β€” formulas +- **p1nkl0bst3r** β€” providing players history +- **osk** and his team β€” TETR.IO \ No newline at end of file diff --git a/lib/data_objects/tetrio.dart b/lib/data_objects/tetrio.dart index 6a4fbfd..cfb86ba 100644 --- a/lib/data_objects/tetrio.dart +++ b/lib/data_objects/tetrio.dart @@ -1,3 +1,5 @@ +// ignore_for_file: hash_and_equals + import 'dart:math'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -533,9 +535,9 @@ class EstTr { statrank = 11.2 * atan((srarea - 93) / 130) + 1; if (statrank <= 0) statrank = 0.001; estglicko = (4.0867 * srarea + 186.68); - double temp = (1500 - estglicko) * pi; - double temp2 = pow((15.9056943314 * (pow(_rd, 2)) + 3527584.25978), 0.5) as double; - double temp3 = 1 + pow(10, (temp / temp2)) as double; + // double temp = (1500 - estglicko) * pi; + // double temp2 = pow((15.9056943314 * (pow(_rd, 2)) + 3527584.25978), 0.5) as double; + // double temp3 = 1 + pow(10, (temp / temp2)) as double; //esttr = 25000 / temp3; double ntemp = _pps*(150+(((_vs/_apm) - 1.66)*35))+_app*290+_dsp*700; esttr = 25000 / diff --git a/lib/gen/strings.g.dart b/lib/gen/strings.g.dart index da4e39a..559f23c 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: 896 (448 per locale) +/// Strings: 898 (449 per locale) /// -/// Built on 2023-08-20 at 21:53 UTC +/// Built on 2023-08-21 at 09:52 UTC // coverage:ignore-file // ignore_for_file: type=lint @@ -160,6 +160,7 @@ class _StringsEn implements BaseTranslations { String get sprint => '40 Lines'; String get blitz => 'Blitz'; String get other => 'Other'; + String get distinguishment => 'Distinguishment'; String get zen => 'Zen'; String get bio => 'Bio'; String get openSearch => 'Search player'; @@ -683,6 +684,7 @@ class _StringsRu implements _StringsEn { @override String get sprint => '40 Π»ΠΈΠ½ΠΈΠΉ'; @override String get blitz => 'Π‘Π»ΠΈΡ†'; @override String get other => 'Π”Ρ€ΡƒΠ³ΠΎΠ΅'; + @override String get distinguishment => 'Заслуга'; @override String get zen => 'Π”Π·Π΅Π½'; @override String get bio => 'Биография'; @override String get openSearch => 'Π˜ΡΠΊΠ°Ρ‚ΡŒ ΠΈΠ³Ρ€ΠΎΠΊΠ°'; @@ -1185,6 +1187,7 @@ extension on _StringsEn { case 'sprint': return '40 Lines'; case 'blitz': return 'Blitz'; case 'other': return 'Other'; + case 'distinguishment': return 'Distinguishment'; case 'zen': return 'Zen'; case 'bio': return 'Bio'; case 'openSearch': return 'Search player'; @@ -1643,6 +1646,7 @@ extension on _StringsRu { case 'sprint': return '40 Π»ΠΈΠ½ΠΈΠΉ'; case 'blitz': return 'Π‘Π»ΠΈΡ†'; case 'other': return 'Π”Ρ€ΡƒΠ³ΠΎΠ΅'; + case 'distinguishment': return 'Заслуга'; case 'zen': return 'Π”Π·Π΅Π½'; case 'bio': return 'Биография'; case 'openSearch': return 'Π˜ΡΠΊΠ°Ρ‚ΡŒ ΠΈΠ³Ρ€ΠΎΠΊΠ°'; diff --git a/lib/main.dart b/lib/main.dart index 4c48be5..d6d0222 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -29,7 +29,7 @@ void main() async { LocaleSettings.setLocaleRaw(locale); } runApp(TranslationProvider( - child: MyApp(), + child: const MyApp(), )); } @@ -41,7 +41,7 @@ class MyApp extends StatelessWidget { return MaterialApp( title: "Tetra Stats", home: const MainView(), - scrollBehavior: MaterialScrollBehavior().copyWith( + scrollBehavior: const MaterialScrollBehavior().copyWith( dragDevices: {PointerDeviceKind.mouse, PointerDeviceKind.touch, PointerDeviceKind.stylus, PointerDeviceKind.unknown}, ), locale: TranslationProvider.of(context).flutterLocale, diff --git a/lib/views/compare_view.dart b/lib/views/compare_view.dart index 918fd08..c553adb 100644 --- a/lib/views/compare_view.dart +++ b/lib/views/compare_view.dart @@ -250,7 +250,7 @@ class CompareState extends State { titleRedSide = "${theRedSide[2].apm} APM, ${theRedSide[2].pps} PPS, ${theRedSide[2].vs} VS"; break; case Mode.averages: - titleRedSide = t.averageXrank(rankLetter: theRedSide[2].rank.toUpperCase());; + titleRedSide = t.averageXrank(rankLetter: theRedSide[2].rank.toUpperCase()); break; } return Scaffold( @@ -863,7 +863,7 @@ class PlayerSelector extends StatelessWidget { final Function fetch; final Function change; final Function updateState; - PlayerSelector( + const PlayerSelector( {super.key, required this.data, required this.mode, diff --git a/lib/views/main_view.dart b/lib/views/main_view.dart index 5728b81..5e8ccf6 100644 --- a/lib/views/main_view.dart +++ b/lib/views/main_view.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; import 'dart:math'; import 'package:fl_chart/fl_chart.dart'; @@ -331,7 +332,7 @@ class _MainState extends State with SingleTickerProviderStateMixin { ? snapshot.data![1]['blitz'][0] : null), _OtherThingy( - zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio) + zen: snapshot.data![1]['zen'], bio: snapshot.data![0].bio, distinguishment: snapshot.data![0].distinguishment,) ], ), ), @@ -581,7 +582,7 @@ class _HistoryChartThigy extends StatelessWidget{ bottomTitles: AxisTitles(sideTitles: SideTitles(interval: xInterval, showTitles: true, reservedSize: 30, getTitlesWidget: (double value, TitleMeta meta){ return value != meta.min && value != meta.max ? SideTitleWidget( axisSide: meta.axisSide, - child: Text(DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode) .format(DateTime.fromMillisecondsSinceEpoch(value.floor()))), + child: Text(DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).format(DateTime.fromMillisecondsSinceEpoch(value.floor()))), ) : Container(); })), leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: leftSpace, getTitlesWidget: (double value, TitleMeta meta){ @@ -628,7 +629,12 @@ class _RecordThingy extends StatelessWidget { fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), if (record!.stream.contains("40l")) - Text( + if (record!.endContext!.finalTime.inMicroseconds > 60000000) Text( + "${(record!.endContext!.finalTime.inMicroseconds/1000000/60).floor()}:${(f2.format(record!.endContext!.finalTime.inMicroseconds /1000000 % 60))}", + style: TextStyle( + fontFamily: "Eurostile Round Extended", + fontSize: bigScreen ? 42 : 28)) + else Text( timeInSec.format( record!.endContext!.finalTime.inMicroseconds / 1000000), @@ -936,9 +942,34 @@ class _RecordThingy extends StatelessWidget { class _OtherThingy extends StatelessWidget { final TetrioZen? zen; final String? bio; - const _OtherThingy({Key? key, required this.zen, required this.bio}) + final Distinguishment? distinguishment; + const _OtherThingy({Key? key, required this.zen, required this.bio, required this.distinguishment}) : super(key: key); + List getDistinguishmentSetOfWidgets(String text) { + var exploded = text.split(" "); + List result = []; + for (String shit in exploded){ + switch (shit) { + case "%osk%": + result.add(WidgetSpan(child: Padding( + padding: const EdgeInsets.only(left: 8), + child: SvgPicture.asset("res/icons/osk.svg", height: 28), + ))); + break; + case "%tetrio%": + result.add(WidgetSpan(child: Padding( + padding: const EdgeInsets.only(left: 8), + child: SvgPicture.asset("res/icons/tetrio-logo.svg", height: 28), + ))); + break; + default: + result.add(TextSpan(text: " $shit", style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold))); + } + } + return result; + } + @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { @@ -949,27 +980,19 @@ class _OtherThingy extends StatelessWidget { itemBuilder: (BuildContext context, int index) { return Column( children: [ - Text(t.other, - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - if (zen != null) + if (distinguishment != null) Padding( - padding: const EdgeInsets.fromLTRB(0, 48, 0, 48), + padding: const EdgeInsets.fromLTRB(0, 0, 0, 48), child: Column( children: [ - Text(t.zen, - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - Text( - "${t.statCellNum.level} ${NumberFormat.decimalPattern().format(zen!.level)}", - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), - Text( - "${t.statCellNum.score} ${NumberFormat.decimalPattern().format(zen!.score)}", - style: const TextStyle(fontSize: 18)), + Text(t.distinguishment, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), + RichText( + text: TextSpan( + style: DefaultTextStyle.of(context).style, + children: getDistinguishmentSetOfWidgets(distinguishment!.header!), + ), + ), + Text(distinguishment!.footer!, style: const TextStyle(fontSize: 18)), ], ), ), @@ -978,14 +1001,23 @@ class _OtherThingy extends StatelessWidget { padding: const EdgeInsets.fromLTRB(0, 0, 0, 48), child: Column( children: [ - Text(t.bio, - style: TextStyle( - fontFamily: "Eurostile Round Extended", - fontSize: bigScreen ? 42 : 28)), + Text(t.bio, style: TextStyle(fontFamily: "Eurostile Round Extended",fontSize: bigScreen ? 42 : 28)), Text(bio!, style: const TextStyle(fontSize: 18)), ], ), ), + if (zen != null) + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Column( + children: [ + Text(t.zen, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)), + Text("${t.statCellNum.level} ${NumberFormat.decimalPattern().format(zen!.level)}", style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold)), + Text("${t.statCellNum.score} ${NumberFormat.decimalPattern().format(zen!.score)}", style: const TextStyle(fontSize: 18)), + ], + ), + ), + ], ); }, diff --git a/lib/views/rank_averages_view.dart b/lib/views/rank_averages_view.dart index 5cf3819..13fe714 100644 --- a/lib/views/rank_averages_view.dart +++ b/lib/views/rank_averages_view.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -7,9 +5,6 @@ import 'package:tetra_stats/data_objects/tetrio.dart'; //import 'package:tetra_stats/data_objects/tetrio.dart'; import 'package:tetra_stats/gen/strings.g.dart'; import 'package:tetra_stats/views/main_view.dart' show MainView, f4, f2; -import 'package:tetra_stats/widgets/stat_sell_num.dart'; -import 'package:tetra_stats/widgets/tl_thingy.dart'; -//import 'package:tetra_stats/widgets/tl_thingy.dart'; List chartsShortTitles = [ "TR", @@ -39,7 +34,7 @@ List chartsShortTitles = [ "Stride - Plonk", "Opener - Inf. DS" ]; -var chartsShortTitlesDropdowns = [for (String e in chartsShortTitles) DropdownMenuItem(child: Text(e), value: e,)]; +var chartsShortTitlesDropdowns = [for (String e in chartsShortTitles) DropdownMenuItem(value: e,child: Text(e),)]; int chartsIndexX = 0; int chartsIndexY = 6; //final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms(); @@ -204,7 +199,7 @@ class RankState extends State with SingleTickerProviderStateMixin { scatterTouchData: ScatterTouchData(touchTooltipData: ScatterTouchTooltipData( fitInsideHorizontally: true, fitInsideVertically: true, getTooltipItems: (touchedSpot) { touchedSpot as _MyScatterSpot; - return ScatterTooltipItem("${touchedSpot.nickname}\n", textStyle: TextStyle(fontFamily: "Eurostile Round Extended"), children: [TextSpan(text: "${f4.format(touchedSpot.x)} ${chartsShortTitles[chartsIndexX]}\n${f4.format(touchedSpot.y)} ${chartsShortTitles[chartsIndexY]}", style: TextStyle(fontFamily: "Eurostile Round"))]); + return ScatterTooltipItem("${touchedSpot.nickname}\n", textStyle: const TextStyle(fontFamily: "Eurostile Round Extended"), children: [TextSpan(text: "${f4.format(touchedSpot.x)} ${chartsShortTitles[chartsIndexX]}\n${f4.format(touchedSpot.y)} ${chartsShortTitles[chartsIndexY]}", style: const TextStyle(fontFamily: "Eurostile Round"))]); }), touchCallback:(event, response) { if (event.runtimeType == FlTapDownEvent && response?.touchedSpot?.spot != null){ @@ -219,7 +214,7 @@ class RankState extends State with SingleTickerProviderStateMixin { } },), ), - swapAnimationDuration: Duration(milliseconds: 150), // Optional + swapAnimationDuration: const Duration(milliseconds: 150), // Optional swapAnimationCurve: Curves.linear, // Optional ), ), diff --git a/pubspec.lock b/pubspec.lock index b19d111..95ed1f6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -299,6 +299,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.15" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338" + url: "https://pub.dev" + source: hosted + version: "2.0.7" flutter_test: dependency: "direct dev" description: flutter @@ -485,6 +493,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.3" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" path_provider: dependency: "direct main" description: @@ -922,6 +938,30 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.7" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f" + url: "https://pub.dev" + source: hosted + version: "1.1.7" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f" + url: "https://pub.dev" + source: hosted + version: "1.1.7" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e" + url: "https://pub.dev" + source: hosted + version: "1.1.7" vector_math: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index cf7078e..8767f33 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.0.1+6 +version: 1.1.0+7 environment: sdk: '>=2.19.6 <3.0.0' @@ -38,6 +38,7 @@ dependencies: slang_flutter: ^3.20.0 csv: ^5.0.2 url_launcher: ^6.1.12 + flutter_svg: any dev_dependencies: flutter_test: @@ -79,6 +80,8 @@ flutter: - res/avatars/tetrio_anon.png - res/avatars/tetrio_banned.png - res/icons/kagari.png + - res/icons/osk.svg + - res/icons/tetrio-logo.svg - res/tetrio_tl_alpha_ranks/x.png - res/tetrio_tl_alpha_ranks/u.png - res/tetrio_tl_alpha_ranks/ss.png diff --git a/res/i18n/strings.i18n.json b/res/i18n/strings.i18n.json index 0e6c384..35af696 100644 --- a/res/i18n/strings.i18n.json +++ b/res/i18n/strings.i18n.json @@ -9,6 +9,7 @@ "sprint": "40 Lines", "blitz": "Blitz", "other": "Other", + "distinguishment": "Distinguishment", "zen": "Zen", "bio": "Bio", "openSearch": "Search player", diff --git a/res/i18n/strings_ru.i18n.json b/res/i18n/strings_ru.i18n.json index 70d7942..1eadca7 100644 --- a/res/i18n/strings_ru.i18n.json +++ b/res/i18n/strings_ru.i18n.json @@ -9,6 +9,7 @@ "sprint": "40 Π»ΠΈΠ½ΠΈΠΉ", "blitz": "Π‘Π»ΠΈΡ†", "other": "Π”Ρ€ΡƒΠ³ΠΎΠ΅", + "distinguishment": "Заслуга", "zen": "Π”Π·Π΅Π½", "bio": "Биография", "openSearch": "Π˜ΡΠΊΠ°Ρ‚ΡŒ ΠΈΠ³Ρ€ΠΎΠΊΠ°", diff --git a/res/icons/osk.svg b/res/icons/osk.svg new file mode 100644 index 0000000..da3e6ba --- /dev/null +++ b/res/icons/osk.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/res/icons/tetrio-logo.svg b/res/icons/tetrio-logo.svg new file mode 100644 index 0000000..c7c6edd --- /dev/null +++ b/res/icons/tetrio-logo.svg @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + +