diff --git a/lib/services/tetrio_crud.dart b/lib/services/tetrio_crud.dart index c74c16b..efce458 100644 --- a/lib/services/tetrio_crud.dart +++ b/lib/services/tetrio_crud.dart @@ -500,7 +500,7 @@ class TetrioService extends DB { } Future fetchCutoffsBeanserver() async { - Cutoffs? cached = _cache.get("", Cutoffs); + Cutoffs? cached = _cache.get("CutoffsTetrioleague_ranks", Cutoffs); if (cached != null) return cached; Uri url = Uri.https('ts.dan63.by', 'beanserver_blaster/cutoffs.json'); diff --git a/lib/views/compare_view_tiles.dart b/lib/views/compare_view_tiles.dart index b772888..5c9992a 100644 --- a/lib/views/compare_view_tiles.dart +++ b/lib/views/compare_view_tiles.dart @@ -7,13 +7,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:tetra_stats/data_objects/aggregate_stats.dart'; -import 'package:tetra_stats/data_objects/nerd_stats.dart'; -import 'package:tetra_stats/data_objects/playstyle.dart'; import 'package:tetra_stats/data_objects/summaries.dart'; -import 'package:tetra_stats/data_objects/tetra_league.dart'; import 'package:tetra_stats/data_objects/tetrio_constants.dart'; import 'package:tetra_stats/data_objects/tetrio_player.dart'; -import 'package:tetra_stats/data_objects/tetrio_zen.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'; @@ -21,9 +17,7 @@ import 'package:tetra_stats/utils/relative_timestamps.dart'; import 'package:tetra_stats/utils/text_shadow.dart'; import 'package:tetra_stats/widgets/graphs.dart'; import 'package:tetra_stats/widgets/text_timestamp.dart'; -import 'package:tetra_stats/widgets/vs_graphs.dart'; import 'package:transparent_image/transparent_image.dart'; -import 'package:vector_math/vector_math_64.dart' hide Colors; import 'package:window_manager/window_manager.dart'; enum Mode{ @@ -308,7 +302,7 @@ class CompareState extends State { s.zen.level ]); formattedValues[0].add([ - Text(timestamp(p.registrationTime!)), + Text(timestamp(p.registrationTime)), RichText(text: p.xp.isNegative ? TextSpan(text: "hidden", style: TextStyle(fontFamily: "Eurostile Round", color: Colors.grey)) : TextSpan(text: intf.format(p.xp), style: TextStyle(fontFamily: "Eurostile Round"), children: [TextSpan(text: " (lvl ${intf.format(p.level.floor())})", style: TextStyle(color: Colors.grey))])), Text(p.gameTime.isNegative ? "hidden" : playtime(p.gameTime), style: TextStyle(color: p.gameTime.isNegative ? Colors.grey : Colors.white)), Text(p.gamesPlayed.isNegative ? "hidden" : intf.format(p.gamesPlayed), style: TextStyle(color: p.gamesPlayed.isNegative ? Colors.grey : Colors.white)), @@ -573,14 +567,14 @@ class CompareState extends State { )); } - void _justUpdate() { - setState(() {}); - } + // void _justUpdate() { + // setState(() {}); + // } @override Widget build(BuildContext context) { - final t = Translations.of(context); - bool bigScreen = MediaQuery.of(context).size.width > 768; + // final t = Translations.of(context); + // bool bigScreen = MediaQuery.of(context).size.width > 768; return Scaffold( floatingActionButtonLocation: FloatingActionButtonLocation.startTop, floatingActionButton: Padding( @@ -757,7 +751,6 @@ class _AddNewColumnCardState extends State with SingleTickerPr @override Widget build(BuildContext context) { - // TODO: implement build return SizedBox( height: 175.0, child: Card( diff --git a/lib/views/main_view.dart b/lib/views/main_view.dart index c02d45f..af9923b 100644 --- a/lib/views/main_view.dart +++ b/lib/views/main_view.dart @@ -295,10 +295,7 @@ class _MainState extends State with TickerProviderStateMixin { // if (element.tlSeason1 != null && uniqueTL.isNotEmpty && uniqueTL.last != element.tlSeason1) uniqueTL.add(element.tlSeason1!); // if (uniqueTL.isEmpty) uniqueTL.add(summaries.league); // } - // Also i need previous Tetra League State for comparison if avaliable - TetraLeague? compareWith; if (states[1].length >= 2 || states[0].length >= 2){ - compareWith = states[1].length >= 2 ? states[1].elementAtOrNull(states.length - 2) : null; chartsData = [for (List s in states) >>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid DropdownMenuItem(value: [for (var tl in s) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.tr)], child: Text(t.statCellNum.tr)), DropdownMenuItem(value: [for (var tl in s) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.glicko!)], child: const Text("Glicko")), @@ -323,7 +320,6 @@ class _MainState extends State with TickerProviderStateMixin { DropdownMenuItem(value: [for (var tl in s) if (tl.playstyle != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.playstyle!.stride)], child: const Text("Stride")), ]]; }else{ - compareWith = null; chartsData = []; } diff --git a/lib/views/main_view_tiles.dart b/lib/views/main_view_tiles.dart index c77697a..f918201 100644 --- a/lib/views/main_view_tiles.dart +++ b/lib/views/main_view_tiles.dart @@ -53,6 +53,8 @@ import 'package:tetra_stats/widgets/user_thingy.dart'; import 'package:transparent_image/transparent_image.dart'; import 'package:vector_math/vector_math_64.dart' hide Colors; +// TODO: Refactor it + var fDiff = NumberFormat("+#,###.####;-#,###.####"); late Future _data; late Future _newsData; @@ -232,13 +234,28 @@ class _DestinationSavedData extends State { String? selectedID; Future<(List, List, List)> getDataAbout(String id) async { - return (await teto.getStates(id), await teto.getStates(id, season: 1), await teto.getTLMatchesbyPlayerID(id)); + return (await teto.getStates(id, season: currentSeason), await teto.getStates(id, season: 1), await teto.getTLMatchesbyPlayerID(id)); } Widget getTetraLeagueListTile(TetraLeague data){ return ListTile( - title: Text(timestamp(data.timestamp)), - subtitle: Text("${intf.format(data.gamesPlayed)} games"), + title: Text("${timestamp(data.timestamp)}"), + subtitle: Text("${f2.format(data.apm)} APM, ${f2.format(data.pps)} PPS, ${f2.format(data.vs)} VS, ${intf.format(data.gamesPlayed)} games", style: TextStyle(color: Colors.grey)), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text("${f2.format(data.tr)} TR", style: TextStyle(fontSize: 28)), + Image.asset("res/tetrio_tl_alpha_ranks/${data.rank}.png", height: 36) + ], + ), + leading: IconButton( + onPressed: () { + teto.deleteState(data.id+data.timestamp.millisecondsSinceEpoch.toRadixString(16)).then((value) => setState(() { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.stateRemoved(date: timestamp(data.timestamp))))); + })); + }, + icon: Icon(Icons.delete_forever) + ), ); } @@ -274,7 +291,7 @@ class _DestinationSavedData extends State { for (String id in snapshot.data!.keys) Card( child: ListTile( title: Text(snapshot.data![id]!), - subtitle: Text("NaN states, NaN TL records", style: TextStyle(color: Colors.grey)), + //subtitle: Text("NaN states, NaN TL records", style: TextStyle(color: Colors.grey)), onTap: () => setState(() { selectedID = id; }), @@ -309,7 +326,7 @@ class _DestinationSavedData extends State { ]), ), SizedBox( - height: widget.constraints.maxHeight - 164, + height: widget.constraints.maxHeight - 64, child: TabBarView(children: [ ListView.builder( itemCount: snapshot.data!.$1.length, @@ -366,34 +383,6 @@ enum CalcCards{ damage } -class Damage{ - final int clear; - final double combo; - final double b2b; - final int surge; - final int pc; - final double multiplier; - - int get total => ((clear + combo + b2b + surge + pc) * multiplier).floor(); - - const Damage(this.clear, this.combo, this.b2b, this.surge, this.pc, this.multiplier); - - @override - String toString(){ - return total.toString(); - } - - Damage operator+(Damage other){ - return Damage( - clear+other.clear, - combo+other.combo, - b2b+other.b2b, - surge+other.surge, - pc+other.pc, - multiplier); - } -} - class ClearData{ final String title; final Lineclears lineclear; @@ -542,11 +531,11 @@ class _DestinationCalculatorState extends State { } } - void calcDamage(){ - for (ClearData lineclear in clears){ + // void calcDamage(){ + // for (ClearData lineclear in clears){ - } - } + // } + // } Widget getCalculator(){ return SingleChildScrollView( @@ -669,12 +658,22 @@ class _DestinationCalculatorState extends State { int b2b = -1; int previousB2B = -1; int totalDamage = 0; + int normalDamage = 0; + int comboDamage = 0; + int b2bDamage = 0; + int surgeDamage = 0; + int pcDamage = 0; for (ClearData lineclear in clears){ previousB2B = b2b; if (lineclear.difficultClear) b2b++; else if (lineclear.lines > 0) b2b = -1; if (lineclear.lines > 0) combo++; else combo = -1; + int pcDmg = lineclear.perfectClear ? (rules.pcDamage * rules.multiplier).floor() : 0; + int normalDmg = lineclear.dealsDamage(0, 0, 0, rules) - pcDmg; + int surgeDmg = (!lineclear.difficultClear && rules.surge && previousB2B >= rules.surgeInitAtB2b && b2b == -1) ? rules.surgeInitAmount + (previousB2B - rules.surgeInitAtB2b) : 0; + int b2bDmg = lineclear.dealsDamage(0, b2b, b2b-1, rules) - normalDmg - pcDmg; int dmg = lineclear.dealsDamage(combo, b2b, previousB2B, rules); + int comboDmg = dmg - normalDmg - b2bDmg - surgeDmg - pcDmg; lSideWidgets.add( ListTile( key: ValueKey(lineclear.id), @@ -686,7 +685,7 @@ class _DestinationCalculatorState extends State { ], ), title: Text("${lineclear.title}${lineclear.perfectClear ? " PC" : ""}${combo > 0 ? ", ${combo} combo" : ""}${b2b > 0 ? ", B2Bx${b2b}" : ""}"), - subtitle: lineclear.lines > 0 ? Text("What should i write here?", style: TextStyle(color: Colors.grey)) : null, + subtitle: lineclear.lines > 0 ? Text("${dmg == normalDmg ? "No bonuses" : ""}${b2bDmg > 0 ? "+${intf.format(b2bDmg)} for B2B" : ""}${(b2bDmg > 0 && comboDmg > 0) ? ", " : ""}${comboDmg > 0 ? "+${intf.format(comboDmg)} for combo" : ""}${(comboDmg > 0 && lineclear.perfectClear) ? ", " : ""}${lineclear.perfectClear ? "+${intf.format(pcDmg)} for PC" : ""}${(surgeDmg > 0 && (lineclear.perfectClear || comboDmg > 0)) ? ", " : ""}${surgeDmg > 0 ? "Surge released: +${intf.format(surgeDmg)}" : ""}", style: TextStyle(color: Colors.grey)) : null, trailing: lineclear.lines > 0 ? Padding( padding: const EdgeInsets.only(right: 10.0), child: Text(dmg.toString(), style: TextStyle(fontSize: 36, fontWeight: ui.FontWeight.w100)), @@ -694,8 +693,17 @@ class _DestinationCalculatorState extends State { ) ); totalDamage += dmg; + normalDamage += normalDmg; + comboDamage += comboDmg; + b2bDamage += b2bDmg; + surgeDamage += surgeDmg; + pcDamage += pcDmg; } - + // values for "the bar" + double sec2end = normalDamage.toDouble()+comboDamage.toDouble(); + double sec3end = normalDamage.toDouble()+comboDamage.toDouble()+b2bDamage.toDouble(); + double sec4end = normalDamage.toDouble()+comboDamage.toDouble()+b2bDamage.toDouble()+surgeDamage.toDouble(); + double sec5end = normalDamage.toDouble()+comboDamage.toDouble()+b2bDamage.toDouble()+surgeDamage.toDouble()+pcDamage.toDouble(); return Column( children: [ Card( @@ -816,11 +824,12 @@ class _DestinationCalculatorState extends State { ), SizedBox( width: widget.constraints.maxWidth - 350 - 80, - height: widget.constraints.maxHeight - 148, + height: widget.constraints.maxHeight - 108, child: clears.isEmpty ? Center(child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.info_outline, size: 128.0, color: Colors.grey.shade800), + SizedBox(height: 5.0), Text("Click on the actions on the left to add them here", textAlign: ui.TextAlign.center), ], )) : @@ -851,10 +860,58 @@ class _DestinationCalculatorState extends State { children: [ Text("Total damage:", style: TextStyle(fontSize: 36, fontWeight: ui.FontWeight.w100)), Spacer(), - Text(totalDamage.toString(), style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: ui.FontWeight.w100)) + Text(intf.format(totalDamage), style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36, fontWeight: ui.FontWeight.w100)) ], ), ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text("Lineclears: ${intf.format(normalDamage)}"), + Text("Combo: ${intf.format(comboDamage)}"), + Text("B2B: ${intf.format(b2bDamage)}"), + Text("Surge: ${intf.format(surgeDamage)}"), + Text("PC's: ${intf.format(pcDamage)}") + ], + ), + SfLinearGauge( + minimum: 0, + maximum: totalDamage.toDouble(), + showLabels: false, + showTicks: false, + ranges: [ + LinearGaugeRange( + color: Colors.green, + startValue: 0, + endValue: normalDamage.toDouble(), + position: LinearElementPosition.cross, + ), + LinearGaugeRange( + color: Colors.yellow, + startValue: normalDamage.toDouble(), + endValue: sec2end, + position: LinearElementPosition.cross, + ), + LinearGaugeRange( + color: Colors.blue, + startValue: sec2end, + endValue: sec3end, + position: LinearElementPosition.cross, + ), + LinearGaugeRange( + color: Colors.red, + startValue: sec3end, + endValue: sec4end, + position: LinearElementPosition.cross, + ), + LinearGaugeRange( + color: Colors.orange, + startValue: sec4end, + endValue: sec5end, + position: LinearElementPosition.cross, + ), + ], + ), ElevatedButton.icon(onPressed: (){setState((){clears.clear();});}, icon: const Icon(Icons.clear), label: Text("Clear all"), style: const ButtonStyle(shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0)))))) ], ) @@ -1387,6 +1444,7 @@ class _DestinationLeaderboardsState extends State { ), itemBuilder: (BuildContext context, int index){ return ListTile( + // TODO: make it clickable leading: Text(intf.format(index+1)), title: Text(snapshot.data![index].username, style: TextStyle(fontSize: 22)), trailing: switch (_currentLb){ @@ -1623,6 +1681,7 @@ class _DestinationGraphsState extends State { if (snapshot.hasData){ List<_HistoryChartSpot> selectedGraph = snapshot.data![_season][_Ychart]!; yAxisTitle = chartsShortTitles[_Ychart]!; + // TODO: this graph can Krash return SfCartesianChart( tooltipBehavior: _historyTooltipBehavior, zoomPanBehavior: _zoomPanBehavior, @@ -3569,7 +3628,7 @@ class NewUserThingy extends StatelessWidget { style: const TextStyle(fontFamily: "Eurostile Round"), children: [ if (player.country != null) TextSpan(text: "${t.countries[player.country]} • "), - TextSpan(text: player.registrationTime == null ? t.wasFromBeginning : timestamp(player.registrationTime!), style: const TextStyle(color: Colors.grey)) + TextSpan(text: timestamp(player.registrationTime), style: const TextStyle(color: Colors.grey)) ] ) ), @@ -4203,11 +4262,10 @@ class _TLRecords extends StatelessWidget { final List data; final bool wasActiveInTL; final bool oldMathcesHere; - final bool separateScrollController; /// Widget, that displays Tetra League records. /// Accepts list of TL records ([data]) and [userID] of player from the view - const _TLRecords({required this.userID, required this.changePlayer, required this.data, required this.wasActiveInTL, required this.oldMathcesHere, this.separateScrollController = false}); + const _TLRecords({required this.userID, required this.changePlayer, required this.data, required this.wasActiveInTL, required this.oldMathcesHere}); @override Widget build(BuildContext context) { @@ -4225,7 +4283,7 @@ class _TLRecords extends StatelessWidget { int length = data.length; return ListView.builder( physics: const AlwaysScrollableScrollPhysics(), - controller: separateScrollController ? ScrollController() : null, + //controller: separateScrollController ? ScrollController() : null, itemCount: oldMathcesHere ? length : length + 1, itemBuilder: (BuildContext context, int index) { if (index == length) { diff --git a/lib/widgets/graphs.dart b/lib/widgets/graphs.dart index 35e5153..3049eeb 100644 --- a/lib/widgets/graphs.dart +++ b/lib/widgets/graphs.dart @@ -7,7 +7,6 @@ import 'package:fl_chart/src/chart/radar_chart/radar_chart_painter.dart'; import 'package:fl_chart/src/chart/radar_chart/radar_chart_renderer.dart'; import 'package:fl_chart/src/chart/base/base_chart/base_chart_painter.dart'; import 'package:fl_chart/src/utils/canvas_wrapper.dart'; -import 'package:fl_chart/src/utils/utils.dart'; import 'package:tetra_stats/data_objects/nerd_stats.dart'; import 'package:tetra_stats/data_objects/playstyle.dart'; import 'package:tetra_stats/data_objects/tetrio_constants.dart'; diff --git a/lib/widgets/user_thingy.dart b/lib/widgets/user_thingy.dart index ee6dc92..957f4d5 100644 --- a/lib/widgets/user_thingy.dart +++ b/lib/widgets/user_thingy.dart @@ -339,7 +339,7 @@ class UserThingy extends StatelessWidget { ), children: [ if (player.country != null) TextSpan(text: "${t.countries[player.country]} • "), - TextSpan(text: "${t.playerRole[player.role]}${t.playerRoleAccount}${player.registrationTime == null ? t.wasFromBeginning : '${t.created} ${timestamp(player.registrationTime!)}'}"), + TextSpan(text: "${t.playerRole[player.role]}${t.playerRoleAccount}${t.created} ${timestamp(player.registrationTime)}"), if (player.supporterTier > 0) const TextSpan(text: " • "), if (player.supporterTier > 0) WidgetSpan(child: Icon(player.supporterTier > 1 ? Icons.star : Icons.star_border, color: player.supporterTier > 1 ? Colors.yellowAccent : Colors.white), alignment: PlaceholderAlignment.middle, baseline: TextBaseline.alphabetic), if (player.supporterTier > 0) TextSpan(text: player.supporterTier.toString(), style: TextStyle(color: player.supporterTier > 1 ? Colors.yellowAccent : Colors.white))