From dd385ad71362823fc85a80048263bf8447de734c Mon Sep 17 00:00:00 2001 From: dan63047 Date: Fri, 9 Aug 2024 02:01:46 +0300 Subject: [PATCH] Oh yeah I'm gonna have shitton of leaderboards to look at --- lib/main.dart | 2 +- lib/views/main_view.dart | 1 - lib/views/main_view_tiles.dart | 798 +++++++++++++++++++++++++-------- lib/widgets/stat_sell_num.dart | 30 +- test/api_test.dart | 364 +++++++-------- 5 files changed, 797 insertions(+), 398 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 3f81e0f..5890c20 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,7 +16,7 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart'; import 'package:tetra_stats/gen/strings.g.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:tetra_stats/views/main_view.dart'; +import 'package:tetra_stats/views/main_view_tiles.dart'; import 'package:tetra_stats/views/settings_view.dart'; import 'package:tetra_stats/views/tracked_players_view.dart'; import 'package:tetra_stats/views/calc_view.dart'; diff --git a/lib/views/main_view.dart b/lib/views/main_view.dart index c74a52b..b590e9a 100644 --- a/lib/views/main_view.dart +++ b/lib/views/main_view.dart @@ -871,7 +871,6 @@ class _History extends StatelessWidget{ )); } bool bigScreen = MediaQuery.of(context).size.width > 768; - //List<_HistoryChartSpot> selectedGraph = _gamesPlayedInsteadOfDateAndTime ? chartsDataGamesPlayed[_chartsIndex].value! : chartsData[_chartsIndex].value!; List<_HistoryChartSpot> selectedGraph = chartsData[_chartsIndex].value!; return SingleChildScrollView( scrollDirection: Axis.vertical, diff --git a/lib/views/main_view_tiles.dart b/lib/views/main_view_tiles.dart index fda44c4..41edc67 100644 --- a/lib/views/main_view_tiles.dart +++ b/lib/views/main_view_tiles.dart @@ -4,8 +4,10 @@ import 'package:flutter/material.dart' hide Badge; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:tetra_stats/gen/strings.g.dart'; +import 'package:tetra_stats/services/crud_exceptions.dart'; import 'package:tetra_stats/utils/numers_formats.dart'; import 'package:tetra_stats/utils/relative_timestamps.dart'; import 'package:tetra_stats/utils/text_shadow.dart'; @@ -103,10 +105,9 @@ News testNews = News("6098518e3d5155e6ec429cdc", [ late ScrollController controller; class _MainState extends State with TickerProviderStateMixin { + int destination = 0; String _searchFor = "6098518e3d5155e6ec429cdc"; - Cards rightCard = Cards.tetraLeague; final TextEditingController _searchController = TextEditingController(); - Duration postSeasonLeft = seasonStart.difference(DateTime.now()); @override void initState() { @@ -154,22 +155,22 @@ class _MainState extends State with TickerProviderStateMixin { NavigationRailDestination( icon: Icon(Icons.home), selectedIcon: Icon(Icons.home), - label: Text('First'), + label: Text('Home'), ), NavigationRailDestination( icon: Icon(Icons.data_thresholding_outlined), selectedIcon: Icon(Icons.data_thresholding_outlined), - label: Text('First'), + label: Text('Graphs'), ), NavigationRailDestination( icon: Icon(Icons.leaderboard), selectedIcon: Icon(Icons.leaderboard), - label: Text('Second'), + label: Text('Leaderboards'), ), NavigationRailDestination( icon: Icon(Icons.compress), selectedIcon: Icon(Icons.compress), - label: Text('Third'), + label: Text('Cutoffs'), ), NavigationRailDestination( icon: Icon(Icons.calculate), @@ -179,201 +180,581 @@ class _MainState extends State with TickerProviderStateMixin { NavigationRailDestination( icon: Icon(Icons.settings), selectedIcon: Icon(Icons.settings), - label: Text('Third'), + label: Text('Settings'), ) ], - selectedIndex: 0 + selectedIndex: destination, + onDestinationSelected: (value) { + setState(() { + destination = value; + }); + }, ), - Row( + switch (destination){ + 0 => DestinationHome(searchFor: _searchFor, constraints: constraints), + 1 => DestinationGraphs(searchFor: _searchFor, constraints: constraints), + 2 => DestinationLeaderboards(constraints: constraints), + _ => Text("Unknown destination $destination") + } + ]); + }, + )); + } +} + +class DestinationLeaderboards extends StatefulWidget{ + final BoxConstraints constraints; + + const DestinationLeaderboards({super.key, required this.constraints}); + + @override + State createState() => _DestinationLeaderboardsState(); +} + +class _DestinationLeaderboardsState extends State { + Cards rightCard = Cards.tetraLeague; + Duration postSeasonLeft = seasonStart.difference(DateTime.now()); + final List leaderboards = ["Tetra League", "Quick Play", "Quick Play Expert"]; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + SizedBox( + width: 350.0, + height: widget.constraints.maxHeight, + child: Column( + children: [ + Card( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Spacer(), + Text("Leaderboards", style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 36)), + const Spacer() + ], + ), + ), + Expanded( + child: ListView.builder( + itemCount: leaderboards.length, + itemBuilder: (BuildContext context, int index) { + return Card( + surfaceTintColor: theme.colorScheme.primary, + child: ListTile( + title: Text(leaderboards[index]), + ), + ); + } + ), + ), + ], + ), + ), + SizedBox( + width: widget.constraints.maxWidth - 350 - 88, + child: Column( + children: [ + + ], + ), + ), + ], + ); + } +} + +class DestinationGraphs extends StatefulWidget{ + final String searchFor; + //final Function setState; + final BoxConstraints constraints; + + const DestinationGraphs({super.key, required this.searchFor, required this.constraints}); + + @override + State createState() => _DestinationGraphsState(); +} + +class _DestinationGraphsState extends State { + Cards rightCard = Cards.tetraLeague; + bool fetchData = false; + bool _gamesPlayedInsteadOfDateAndTime = false; + late ZoomPanBehavior _zoomPanBehavior; + late TooltipBehavior _tooltipBehavior; + String yAxisTitle = ""; + bool _smooth = false; + final List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS/S", "DS/P", "APP + DS/P", "VS/APM", "Cheese", "GbE", "wAPP", "Area", "eTR", "±eTR", "Opener", "Plonk", "Inf. DS", "Stride"]; + int _chartsIndex = 0; + late List>> chartsData; + Duration postSeasonLeft = seasonStart.difference(DateTime.now()); + + @override + void initState(){ + _tooltipBehavior = TooltipBehavior( + color: Colors.black, + borderColor: Colors.white, + enable: true, + animationDuration: 0, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - SizedBox( - width: 450.0, - child: FutureBuilder(future: teto.fetchPlayer(_searchFor), builder:(context, snapshot) { - switch (snapshot.connectionState){ - case ConnectionState.none: - case ConnectionState.waiting: - case ConnectionState.active: - return const Center(child: CircularProgressIndicator()); - case ConnectionState.done: - if (snapshot.hasData){ - return Column( + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + "${f4.format(data.stat)} $yAxisTitle", + style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 20), + ), + ), + Text(_gamesPlayedInsteadOfDateAndTime ? t.gamesPlayed(games: t.games(n: data.gamesPlayed)) : timestamp(data.timestamp)) + ], + ), + ); + } + ); + _zoomPanBehavior = ZoomPanBehavior( + enablePinching: true, + enableSelectionZooming: true, + enableMouseWheelZooming : true, + enablePanning: true, + ); + super.initState(); + } + + Future>>> getChartsData(bool fetchHistory) async { + List states = []; + Set uniqueTL = {}; + + if(fetchHistory){ + try{ + var history = await teto.fetchAndsaveTLHistory(widget.searchFor); + if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.fetchAndsaveTLHistoryResult(number: history.length)))); + }on TetrioHistoryNotExist{ + if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.noHistorySaved))); + }on P1nkl0bst3rForbidden { + if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.p1nkl0bst3rForbidden))); + }on P1nkl0bst3rInternalProblem { + if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.p1nkl0bst3rinternal))); + }on P1nkl0bst3rTooManyRequests{ + if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.p1nkl0bst3rTooManyRequests))); + } + } + + states.addAll(await teto.getPlayer(widget.searchFor)); + for (var element in states) { + if (element.tlSeason1 != null && uniqueTL.isNotEmpty && uniqueTL.last != element.tlSeason1) uniqueTL.add(element.tlSeason1!); + if (uniqueTL.isEmpty) uniqueTL.add(element.tlSeason1!); + } + + if (uniqueTL.length >= 2){ + chartsData = >>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rating)], child: Text(t.statCellNum.tr)), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.glicko!)], child: const Text("Glicko")), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.rd!)], child: const Text("Rating Deviation")), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.apm != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.apm!)], child: Text(t.statCellNum.apm.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.pps != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.pps!)], child: Text(t.statCellNum.pps.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.vs != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.vs!)], child: Text(t.statCellNum.vs.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.app)], child: Text(t.statCellNum.app.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.dss)], child: Text(t.statCellNum.dss.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.dsp)], child: Text(t.statCellNum.dsp.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.appdsp)], child: const Text("APP + DS/P")), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.vsapm)], child: const Text("VS/APM")), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.cheese)], child: Text(t.statCellNum.cheese.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.gbe)], child: Text(t.statCellNum.gbe.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.nyaapp)], child: Text(t.statCellNum.nyaapp.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.nerdStats != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.nerdStats!.area)], child: Text(t.statCellNum.area.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.estTr != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.estTr!.esttr)], child: Text(t.statCellNum.estOfTR.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.esttracc != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.esttracc!)], child: Text(t.statCellNum.accOfEst.replaceAll(RegExp(r'\n'), " "))), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.playstyle!.opener)], child: const Text("Opener")), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.playstyle!.plonk)], child: const Text("Plonk")), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.playstyle!.infds)], child: const Text("Inf. DS")), + DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.playstyle != null) _HistoryChartSpot(tl.timestamp, tl.gamesPlayed, tl.rank, tl.playstyle!.stride)], child: const Text("Stride")), + ]; + }else{ + chartsData = []; + } + + fetchData = false; + + return chartsData; + } + + @override + Widget build(BuildContext context) { + return FutureBuilder>>>( + future: getChartsData(fetchData), + builder: (context, snapshot) { + switch (snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const Center(child: CircularProgressIndicator()); + case ConnectionState.done: + if (snapshot.hasData){ + List<_HistoryChartSpot> selectedGraph = snapshot.data![_chartsIndex].value!; + yAxisTitle = _historyShortTitles[_chartsIndex]; + return SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Card( + child: Wrap( + spacing: 20, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Row( + mainAxisSize: MainAxisSize.min, children: [ - NewUserThingy(player: snapshot.data!, showStateTimestamp: false, setState: setState), - if (snapshot.data!.badges.isNotEmpty) BadgesThingy(badges: snapshot.data!.badges), - if (snapshot.data!.distinguishment != null) DistinguishmentThingy(snapshot.data!.distinguishment!), - if (snapshot.data!.bio != null) Card( - child: Column( - children: [ - Row( - children: [ - const Spacer(), - Text(t.bio, style: const TextStyle(fontFamily: "Eurostile Round Extended")), - const Spacer() - ], - ), - Padding( - padding: const EdgeInsets.only(bottom: 8.0), - child: MarkdownBody(data: snapshot.data!.bio!, styleSheet: MarkdownStyleSheet(textAlign: WrapAlignment.center)), - ) - ], - ), + const Padding(padding: EdgeInsets.all(8.0), child: Text("X:", style: TextStyle(fontSize: 22))), + DropdownButton( + items: const [DropdownMenuItem(value: false, child: Text("Date & Time")), DropdownMenuItem(value: true, child: Text("Games Played"))], + value: _gamesPlayedInsteadOfDateAndTime, + onChanged: (value) { + setState(() { + _gamesPlayedInsteadOfDateAndTime = value!; + }); + } ), - //if (testNews != null && testNews!.news.isNotEmpty) - Expanded( - child: FutureBuilder( - future: teto.fetchNews(_searchFor), - builder: (context, snapshot) { - switch (snapshot.connectionState){ - case ConnectionState.none: - case ConnectionState.waiting: - case ConnectionState.active: - return Card(child: Center(child: CircularProgressIndicator())); - case ConnectionState.done: - if (snapshot.hasData){ - return NewsThingy(snapshot.data!); - }else if (snapshot.hasError){ - return Card(child: Column(children: [ - Text(snapshot.error.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), - Text(snapshot.stackTrace.toString()) - ] - )); - } - } - return Text("what?"); - } - ), - ) ], - ); - }else{ - return Center(child: - Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(snapshot.error != null ? snapshot.error.toString() : "lol", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Text(snapshot.stackTrace != null ? snapshot.stackTrace.toString() : "lol", textAlign: TextAlign.center), - ), - ], - ) - ); - } - } - }, - )), - SizedBox( - width: constraints.maxWidth - 450 - 80, - child: Column( - //crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: constraints.maxHeight - 64, - child: SingleChildScrollView( - child: Column( - //mainAxisSize: MainAxisSize.min, + ), + Row( + mainAxisSize: MainAxisSize.min, children: [ - Card( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Spacer(), - Text(t.tetraLeague, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42)), - const Spacer() - ], - ), + const Padding(padding: EdgeInsets.all(8.0), child: Text("Y:", style: TextStyle(fontSize: 22))), + DropdownButton( + items: chartsData, + value: chartsData[_chartsIndex].value, + onChanged: (value) { + setState(() { + _chartsIndex = chartsData.indexWhere((element) => element.value == value); + }); + } ), - Card( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(t.seasonStarts), - Center(child: Text(countdown(postSeasonLeft), textAlign: TextAlign.center, style: const TextStyle(fontSize: 32.0))), - ], - ), - ), - TetraLeagueThingy(league: testPlayer.tlSeason1!), - Card( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Spacer(), - Text(t.nerdStats, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42)), - const Spacer() - ], - ), - ), - NerdStatsThingy(nerdStats: testPlayer.tlSeason1!.nerdStats!) ], ), + if (selectedGraph.length > 300) Row( + mainAxisSize: MainAxisSize.min, + children: [ + Checkbox(value: _smooth, + checkColor: Colors.black, + onChanged: ((value) { + setState(() { + _smooth = value!; + }); + })), + Text(t.smooth, style: const TextStyle(color: Colors.white, fontSize: 22)) + ], + ), + IconButton(onPressed: () => _zoomPanBehavior.reset(), icon: const Icon(Icons.refresh), alignment: Alignment.center,) + ], + ), + ), + if(chartsData[_chartsIndex].value!.length > 1) Card( + child: SizedBox( + width: MediaQuery.of(context).size.width - 88, + height: MediaQuery.of(context).size.height - 60, + child: Padding( padding: const EdgeInsets.fromLTRB(40, 30, 40, 30), + child: SfCartesianChart( + tooltipBehavior: _tooltipBehavior, + zoomPanBehavior: _zoomPanBehavior, + primaryXAxis: _gamesPlayedInsteadOfDateAndTime ? const NumericAxis() : const DateTimeAxis(), + primaryYAxis: const NumericAxis( + rangePadding: ChartRangePadding.additional, + ), + margin: const EdgeInsets.all(0), + series: [ + if (_gamesPlayedInsteadOfDateAndTime) StepLineSeries<_HistoryChartSpot, int>( + enableTooltip: true, + dataSource: chartsData[_chartsIndex].value!, + animationDuration: 0, + opacity: _smooth ? 0 : 1, + xValueMapper: (_HistoryChartSpot data, _) => data.gamesPlayed, + yValueMapper: (_HistoryChartSpot data, _) => data.stat, + color: Theme.of(context).colorScheme.primary, + trendlines:[ + Trendline( + isVisible: _smooth, + period: (chartsData[_chartsIndex].value!.length/175).floor(), + type: TrendlineType.movingAverage, + color: Theme.of(context).colorScheme.primary) + ], + ) + else StepLineSeries<_HistoryChartSpot, DateTime>( + enableTooltip: true, + dataSource: chartsData[_chartsIndex].value!, + animationDuration: 0, + opacity: _smooth ? 0 : 1, + xValueMapper: (_HistoryChartSpot data, _) => data.timestamp, + yValueMapper: (_HistoryChartSpot data, _) => data.stat, + color: Theme.of(context).colorScheme.primary, + trendlines:[ + Trendline( + isVisible: _smooth, + period: (chartsData[_chartsIndex].value!.length/175).floor(), + type: TrendlineType.movingAverage, + color: Theme.of(context).colorScheme.primary) + ], + ), + ], + ), + ) + ), + ) + else if (chartsData[_chartsIndex].value!.length <= 1) Center(child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(t.notEnoughData, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)), + Text(t.errors.actionSuggestion), + TextButton(onPressed: (){setState(() { + fetchData = true; + });}, child: Text(t.fetchAndsaveTLHistory)) + ], + )) + ], + ), + ); + } + if (snapshot.hasError){ + return Center(child: + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(snapshot.error != null ? snapshot.error.toString() : "lol", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text(snapshot.stackTrace != null ? snapshot.stackTrace.toString() : "lol", textAlign: TextAlign.center), + ), + ], + ) + ); + } + } + return Center(child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text("lol", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28)), + ], + )); + }, + ); + } +} + +class _HistoryChartSpot{ + final DateTime timestamp; + final int gamesPlayed; + final String rank; + final double stat; + const _HistoryChartSpot(this.timestamp, this.gamesPlayed, this.rank, this.stat); +} + +class DestinationHome extends StatefulWidget{ + final String searchFor; + //final Function setState; + final BoxConstraints constraints; + + const DestinationHome({super.key, required this.searchFor, required this.constraints}); + + @override + State createState() => _DestinationHomeState(); +} + +class _DestinationHomeState extends State { + Cards rightCard = Cards.tetraLeague; + Duration postSeasonLeft = seasonStart.difference(DateTime.now()); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + SizedBox( + width: 450.0, + child: FutureBuilder(future: teto.fetchPlayer(widget.searchFor), builder:(context, snapshot) { + switch (snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const Center(child: CircularProgressIndicator()); + case ConnectionState.done: + if (snapshot.hasData){ + return Column( + children: [ + NewUserThingy(player: snapshot.data!, showStateTimestamp: false, setState: setState), + if (snapshot.data!.badges.isNotEmpty) BadgesThingy(badges: snapshot.data!.badges), + if (snapshot.data!.distinguishment != null) DistinguishmentThingy(snapshot.data!.distinguishment!), + if (snapshot.data!.bio != null) Card( + child: Column( + children: [ + Row( + children: [ + const Spacer(), + Text(t.bio, style: const TextStyle(fontFamily: "Eurostile Round Extended")), + const Spacer() + ], + ), + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: MarkdownBody(data: snapshot.data!.bio!, styleSheet: MarkdownStyleSheet(textAlign: WrapAlignment.center)), + ) + ], ), ), - SegmentedButton( - showSelectedIcon: false, - selected: {CardMod.info}, - segments: >[ - ButtonSegment( - value: CardMod.info, - label: Text('PB'), - //icon: Icon(Icons.calendar_view_day) - ), - ButtonSegment( - value: CardMod.recent, - label: Text('Recent'), - //icon: Icon(Icons.calendar_view_day) - ), - ] + //if (testNews != null && testNews!.news.isNotEmpty) + Expanded( + child: FutureBuilder( + future: teto.fetchNews(widget.searchFor), + builder: (context, snapshot) { + switch (snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return Card(child: Center(child: CircularProgressIndicator())); + case ConnectionState.done: + if (snapshot.hasData){ + return NewsThingy(snapshot.data!); + }else if (snapshot.hasError){ + return Card(child: Column(children: [ + Text(snapshot.error.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + Text(snapshot.stackTrace.toString()) + ] + )); + } + } + return Text("what?"); + } + ), + ) + ], + ); + }else{ + return Center(child: + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(snapshot.error != null ? snapshot.error.toString() : "lol", style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text(snapshot.stackTrace != null ? snapshot.stackTrace.toString() : "lol", textAlign: TextAlign.center), + ), + ], + ) + ); + } + } + }, + )), + SizedBox( + width: widget.constraints.maxWidth - 450 - 80, + child: Column( + //crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: widget.constraints.maxHeight - 64, + child: SingleChildScrollView( + child: Column( + //mainAxisSize: MainAxisSize.min, + children: [ + Card( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Spacer(), + Text(t.tetraLeague, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42)), + const Spacer() + ], + ), ), - SegmentedButton( - showSelectedIcon: false, - segments: >[ - ButtonSegment( - value: Cards.overview, - //label: Text('Overview'), - icon: Icon(Icons.calendar_view_day)), - ButtonSegment( - value: Cards.tetraLeague, - //label: Text('Tetra League'), - icon: SvgPicture.asset("res/icons/league.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), - ButtonSegment( - value: Cards.quickPlay, - //label: Text('Quick Play'), - icon: SvgPicture.asset("res/icons/qp.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), - // ButtonSegment( - // value: Cards.quickPlayExpert, - // label: Text('QP Expert'), - // icon: Icon(Icons.calendar_today)), - ButtonSegment( - value: Cards.sprint, - //label: Text('40 Lines'), - icon: SvgPicture.asset("res/icons/40l.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), - ButtonSegment( - value: Cards.blitz, - //label: Text('Blitz'), - icon: SvgPicture.asset("res/icons/blitz.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), - // ButtonSegment( - // value: Cards.other, - // label: Text('Other'), - // icon: Icon(Icons.calendar_today)), - ], - selected: {rightCard}, - onSelectionChanged: (Set newSelection) { - setState(() { - rightCard = newSelection.first; - });}) + Card( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(t.seasonStarts), + Center(child: Text(countdown(postSeasonLeft), textAlign: TextAlign.center, style: const TextStyle(fontSize: 32.0))), + ], + ), + ), + TetraLeagueThingy(league: testPlayer.tlSeason1!), + Card( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Spacer(), + Text(t.nerdStats, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 42)), + const Spacer() + ], + ), + ), + NerdStatsThingy(nerdStats: testPlayer.tlSeason1!.nerdStats!) ], ), ), - // SizedBox( - // width: 450, - // child: _TLRecords(userID: "snapshot.data![0].userId", changePlayer: changePlayer, data: [], wasActiveInTL: true, oldMathcesHere: false, separateScrollController: true) - // ) - ], ), - ], - ); - }, - )); + SegmentedButton( + showSelectedIcon: false, + selected: {CardMod.info}, + segments: >[ + ButtonSegment( + value: CardMod.info, + label: Text('PB'), + //icon: Icon(Icons.calendar_view_day) + ), + ButtonSegment( + value: CardMod.recent, + label: Text('Recent'), + //icon: Icon(Icons.calendar_view_day) + ), + ] + ), + SegmentedButton( + showSelectedIcon: false, + segments: >[ + ButtonSegment( + value: Cards.overview, + //label: Text('Overview'), + icon: Icon(Icons.calendar_view_day)), + ButtonSegment( + value: Cards.tetraLeague, + //label: Text('Tetra League'), + icon: SvgPicture.asset("res/icons/league.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), + ButtonSegment( + value: Cards.quickPlay, + //label: Text('Quick Play'), + icon: SvgPicture.asset("res/icons/qp.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), + // ButtonSegment( + // value: Cards.quickPlayExpert, + // label: Text('QP Expert'), + // icon: Icon(Icons.calendar_today)), + ButtonSegment( + value: Cards.sprint, + //label: Text('40 Lines'), + icon: SvgPicture.asset("res/icons/40l.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), + ButtonSegment( + value: Cards.blitz, + //label: Text('Blitz'), + icon: SvgPicture.asset("res/icons/blitz.svg", height: 16, colorFilter: ColorFilter.mode(theme.colorScheme.primary, BlendMode.modulate))), + // ButtonSegment( + // value: Cards.other, + // label: Text('Other'), + // icon: Icon(Icons.calendar_today)), + ], + selected: {rightCard}, + onSelectionChanged: (Set newSelection) { + setState(() { + rightCard = newSelection.first; + });}) + ], + ), + ), + // SizedBox( + // width: 450, + // child: _TLRecords(userID: "snapshot.data![0].userId", changePlayer: changePlayer, data: [], wasActiveInTL: true, oldMathcesHere: false, separateScrollController: true) + // ) + ], + ); } } @@ -778,7 +1159,6 @@ class NewUserThingy extends StatelessWidget { Widget build(BuildContext context) { final t = Translations.of(context); return LayoutBuilder(builder: (context, constraints) { - //bool bigScreen = constraints.maxWidth > 768; double pfpHeight = 128; int xpTableID = 0; @@ -1131,6 +1511,11 @@ class TetraLeagueThingy extends StatelessWidget{ child: Table( defaultColumnWidth:IntrinsicColumnWidth(), children: [ + TableRow(children: [ + //Text("VS: ", style: TextStyle(fontSize: 21)), + Text("№ ${intf.format(league.standingLocal)}", textAlign: TextAlign.right, style: TextStyle(fontSize: 21)), + Text(" in BY", style: TextStyle(fontSize: 21)) + ]), TableRow(children: [ //Text("APM: ", style: TextStyle(fontSize: 21)), Text(intf.format(league.gamesPlayed), textAlign: TextAlign.right, style: TextStyle(fontSize: 21)), @@ -1140,11 +1525,6 @@ class TetraLeagueThingy extends StatelessWidget{ //Text("PPS: ", style: TextStyle(fontSize: 21)), Text(intf.format(league.gamesWon), textAlign: TextAlign.right, style: TextStyle(fontSize: 21)), Text(" Won", style: TextStyle(fontSize: 21)) - ]), - TableRow(children: [ - //Text("VS: ", style: TextStyle(fontSize: 21)), - Text("№ ${intf.format(league.standingLocal)}", textAlign: TextAlign.right, style: TextStyle(fontSize: 21)), - Text(" in BY", style: TextStyle(fontSize: 21)) ]) ], ), @@ -1169,6 +1549,7 @@ class NerdStatsThingy extends StatelessWidget{ child: Column( children: [ Row( + mainAxisSize: MainAxisSize.min, children: [ SizedBox( height: 256.0, @@ -1236,34 +1617,53 @@ class NerdStatsThingy extends StatelessWidget{ ] ), ), - Wrap( - children: [ - GaugetThingy(value: nerdStats.dss, min: 0, max: 1.0, label: t.statCellNum.dss, sideSize: 128.0, fractionDigits: 3), - GaugetThingy(value: nerdStats.dsp, min: 0, max: 1.0, label: t.statCellNum.dsp, sideSize: 128.0, fractionDigits: 3), - GaugetThingy(value: nerdStats.appdsp, min: 0, max: 1.2, label: t.statCellNum.appdsp, sideSize: 128.0, fractionDigits: 3) - ], + Expanded( + child: Wrap( + children: [ + GaugetThingy(value: nerdStats.dss, min: 0, max: 1.0, tickInterval: .2, label: "DS/S", sideSize: 128.0, fractionDigits: 3), + GaugetThingy(value: nerdStats.dsp, min: 0, max: 1.0, tickInterval: .2, label: "DS/P", sideSize: 128.0, fractionDigits: 3), + GaugetThingy(value: nerdStats.appdsp, min: 0, max: 1.2, tickInterval: .2, label: "APP+DS/P", sideSize: 128.0, fractionDigits: 3), + GaugetThingy(value: nerdStats.cheese, min: -80, max: 80, tickInterval: 40, label: "Cheese", sideSize: 128.0, fractionDigits: 2), + GaugetThingy(value: nerdStats.gbe, min: 0, max: 1.0, tickInterval: .2, label: "GbE", sideSize: 128.0, fractionDigits: 3), + GaugetThingy(value: nerdStats.nyaapp, min: 0, max: 1.2, tickInterval: .2, label: "wAPP", sideSize: 128.0, fractionDigits: 3), + GaugetThingy(value: nerdStats.area, min: 0, max: 1000, tickInterval: 100, label: "Area", sideSize: 128.0, fractionDigits: 1), + ], + ), ) ] ), ], ) ); - } + } +} + +class EstTrThingy extends StatelessWidget{ + final EstTr estTr; + + const EstTrThingy({super.key, required this.estTr}); + @override + Widget build(BuildContext context) { + // TODO: implement build + throw UnimplementedError(); + } } class GaugetThingy extends StatelessWidget{ final double value; final double min; final double max; + final double tickInterval; final String label; final double sideSize; final int fractionDigits; - GaugetThingy({super.key, required this.value, required this.min, required this.max, required this.label, required this.sideSize, required this.fractionDigits}); + GaugetThingy({super.key, required this.value, required this.min, required this.max, required this.tickInterval, required this.label, required this.sideSize, required this.fractionDigits}); @override Widget build(BuildContext context) { + NumberFormat f = NumberFormat.decimalPatternDigits(locale: LocaleSettings.currentLocale.languageCode, decimalDigits: fractionDigits); return SizedBox( height: sideSize, width: sideSize, @@ -1277,14 +1677,14 @@ class GaugetThingy extends StatelessWidget{ //radiusFactor: 1.5, showTicks: true, showLabels: false, - interval: 0.1, + interval: tickInterval, //labelsPosition: ElementsPosition.outside, ranges:[ GaugeRange(startValue: 0, endValue: value, color: theme.colorScheme.primary) ], annotations: [ GaugeAnnotation(widget: Container(child: - Text(f3.format(value), textAlign: TextAlign.center, style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold))), + Text(f.format(value), textAlign: TextAlign.center, style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold))), angle: 90,positionFactor: 0.25 ), GaugeAnnotation(widget: Container(child: diff --git a/lib/widgets/stat_sell_num.dart b/lib/widgets/stat_sell_num.dart index 76edf64..f837bb4 100644 --- a/lib/widgets/stat_sell_num.dart +++ b/lib/widgets/stat_sell_num.dart @@ -88,21 +88,21 @@ class StatCellNum extends StatelessWidget { : TextButton( onPressed: () { showDialog( - context: context, - builder: (BuildContext context) => AlertDialog( - title: Text(alertTitle??playerStatLabel.replaceAll(RegExp(r'\n'), " "), - style: const TextStyle( - fontFamily: "Eurostile Round Extended")), - content: SingleChildScrollView( - child: ListBody(children: alertWidgets!), - ), - actions: [ - TextButton( - child: Text(okText??"OK"), - onPressed: () {Navigator.of(context).pop();} - ) - ], - ) + context: context, + builder: (BuildContext context) => AlertDialog( + title: Text(alertTitle??playerStatLabel.replaceAll(RegExp(r'\n'), " "), + style: const TextStyle( + fontFamily: "Eurostile Round Extended")), + content: SingleChildScrollView( + child: ListBody(children: alertWidgets!), + ), + actions: [ + TextButton( + child: Text(okText??"OK"), + onPressed: () {Navigator.of(context).pop();} + ) + ], + ) ); }, style: ButtonStyle( diff --git a/test/api_test.dart b/test/api_test.dart index 52f3e87..4f4f8d6 100644 --- a/test/api_test.dart +++ b/test/api_test.dart @@ -1,186 +1,186 @@ -import 'dart:io'; -import 'dart:ui'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:sqflite_common_ffi/sqflite_ffi.dart'; -import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart'; -import 'package:test/test.dart'; -import 'package:tetra_stats/data_objects/tetrio.dart'; -import 'package:tetra_stats/services/crud_exceptions.dart'; -import 'package:tetra_stats/services/tetrio_crud.dart'; +// import 'dart:io'; +// import 'dart:ui'; +// import 'package:flutter/foundation.dart'; +// import 'package:flutter/material.dart'; +// import 'package:sqflite_common_ffi/sqflite_ffi.dart'; +// import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart'; +// import 'package:test/test.dart'; +// import 'package:tetra_stats/data_objects/tetrio.dart'; +// import 'package:tetra_stats/services/crud_exceptions.dart'; +// import 'package:tetra_stats/services/tetrio_crud.dart'; -void main() { - WidgetsFlutterBinding.ensureInitialized(); - DartPluginRegistrant.ensureInitialized(); - late TetrioService teto; - setUp(() { - if (kIsWeb) { - sqfliteFfiInit(); - databaseFactory = databaseFactoryFfiWeb; - } else if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) { - sqfliteFfiInit(); - databaseFactory = databaseFactoryFfi; - } - teto = TetrioService(); - }); +// void main() { +// WidgetsFlutterBinding.ensureInitialized(); +// DartPluginRegistrant.ensureInitialized(); +// late TetrioService teto; +// setUp(() { +// if (kIsWeb) { +// sqfliteFfiInit(); +// databaseFactory = databaseFactoryFfiWeb; +// } else if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) { +// sqfliteFfiInit(); +// databaseFactory = databaseFactoryFfi; +// } +// teto = TetrioService(); +// }); - test("Initialize TetrioServise", () async { - teto.open(); - }); // a fucking MissingPluginException how does that even happening? - // i guess i will be unable to test iteractions with DB +// test("Initialize TetrioServise", () async { +// teto.open(); +// }); // a fucking MissingPluginException how does that even happening? +// // i guess i will be unable to test iteractions with DB - group("Test fetchPlayer with different players", () { - // those tests exist in order to detect a tiny little change in Tetra Channel API in case of some update. - test("dan63047 (user who have activity in tetra league)", () async { - TetrioPlayer dan63047 = await teto.fetchPlayer("6098518e3d5155e6ec429cdc"); - expect(dan63047.userId, "6098518e3d5155e6ec429cdc"); - expect(dan63047.registrationTime != null, true); - expect(dan63047.avatarRevision != null, true); - expect(dan63047.connections != null, true); - expect(dan63047.role, "user"); - expect(dan63047.distinguishment, null); // imagine if that one fails one day lol - expect(dan63047.tlSeason1.glicko != null, true); - //expect(dan63047.tlSeason1.rank != "z", true); lol - expect(dan63047.tlSeason1.percentileRank != "z", true); - expect(dan63047.tlSeason1.rating > -1, true); - expect(dan63047.tlSeason1.gamesPlayed > 9, true); - expect(dan63047.tlSeason1.gamesWon > 0, true); - //expect(dan63047.tlSeason1.standing, -1); - //expect(dan63047.tlSeason1.standingLocal, -1); - expect(dan63047.tlSeason1.apm != null, true); - expect(dan63047.tlSeason1.pps != null, true); - expect(dan63047.tlSeason1.vs != null, true); - expect(dan63047.tlSeason1.nerdStats != null, true); - expect(dan63047.tlSeason1.estTr != null, true); - expect(dan63047.tlSeason1.esttracc != null, true); - expect(dan63047.tlSeason1.playstyle != null, true); - }); - test("osk (sysop who have activity in tetra league)", () async { - TetrioPlayer osk = await teto.fetchPlayer("5e32fc85ab319c2ab1beb07c"); - expect(osk.userId, "5e32fc85ab319c2ab1beb07c"); - expect(osk.registrationTime, null); - expect(osk.country, "XM"); - expect(osk.avatarRevision != null, true); - expect(osk.bannerRevision != null, true); - expect(osk.connections != null, true); - expect(osk.verified, true); - expect(osk.role, "sysop"); - expect(osk.distinguishment != null, true); - expect(osk.tlSeason1.glicko != null, true); - expect(osk.tlSeason1.glicko != null, true); - expect(osk.tlSeason1.rank == "z", true); - expect(osk.tlSeason1.percentileRank != "z", true); - expect(osk.tlSeason1.rating > -1, true); - expect(osk.tlSeason1.gamesPlayed > 9, true); - expect(osk.tlSeason1.gamesWon > 0, true); - expect(osk.tlSeason1.standing, -1); - expect(osk.tlSeason1.standingLocal, -1); - expect(osk.tlSeason1.apm != null, true); - expect(osk.tlSeason1.pps != null, true); - expect(osk.tlSeason1.vs != null, true); - expect(osk.tlSeason1.nerdStats != null, true); - expect(osk.tlSeason1.estTr != null, true); - expect(osk.tlSeason1.esttracc != null, true); - expect(osk.tlSeason1.playstyle != null, true); - }); - test("kagari (sysop who have zero activity)", () async { - TetrioPlayer kagari = await teto.fetchPlayer("5e331c3ce24a5a3e258f7a1b"); - expect(kagari.userId, "5e331c3ce24a5a3e258f7a1b"); - expect(kagari.registrationTime, null); - expect(kagari.country, "XM"); - expect(kagari.xp, 0); - expect(kagari.gamesPlayed, -1); - expect(kagari.gamesWon, -1); - expect(kagari.gameTime, const Duration(seconds: -1)); - expect(kagari.avatarRevision != null, true); - expect(kagari.bannerRevision != null, true); - expect(kagari.connections, null); - expect(kagari.verified, true); - expect(kagari.distinguishment != null, true); - expect(kagari.distinguishment!.detail, "kagarin"); - expect(kagari.friendCount, 1); - expect(kagari.tlSeason1.glicko, null); - expect(kagari.tlSeason1.rank, "z"); - expect(kagari.tlSeason1.percentileRank, "z"); - expect(kagari.tlSeason1.rating, -1); - expect(kagari.tlSeason1.decaying, false); - expect(kagari.tlSeason1.gamesPlayed, 0); - expect(kagari.tlSeason1.gamesWon, 0); - expect(kagari.tlSeason1.standing, -1); - expect(kagari.tlSeason1.standingLocal, -1); - expect(kagari.tlSeason1.apm, null); - expect(kagari.tlSeason1.pps, null); - expect(kagari.tlSeason1.vs, null); - expect(kagari.tlSeason1.nerdStats, null); - expect(kagari.tlSeason1.estTr, null); - expect(kagari.tlSeason1.esttracc, null); - expect(kagari.tlSeason1.playstyle, null); - }); - test("furry (banned account)", () async { - TetrioPlayer furry = await teto.fetchPlayer("5eea0ff69a1ba76c20347086"); - expect(furry.userId, "5eea0ff69a1ba76c20347086"); - expect(furry.registrationTime, DateTime.parse("2020-06-17T12:43:34.790Z")); - expect(furry.role, "banned"); - expect(furry.badges.isEmpty, true); - expect(furry.badstanding, false); - expect(furry.xp, 0); - expect(furry.supporterTier, 0); - expect(furry.verified, false); - expect(furry.connections, null); - expect(furry.gamesPlayed, 0); - expect(furry.gamesWon, 0); - expect(furry.gameTime, Duration.zero); - expect(furry.tlSeason1.glicko, null); - expect(furry.tlSeason1.rank, "z"); - expect(furry.tlSeason1.percentileRank, "z"); - expect(furry.tlSeason1.rating, -1); - expect(furry.tlSeason1.decaying, false); - expect(furry.tlSeason1.gamesPlayed, 0); - expect(furry.tlSeason1.gamesWon, 0); - expect(furry.tlSeason1.standing, -1); - expect(furry.tlSeason1.standingLocal, -1); - expect(furry.tlSeason1.apm, null); - expect(furry.tlSeason1.pps, null); - expect(furry.tlSeason1.vs, null); - expect(furry.tlSeason1.nerdStats, null); - expect(furry.tlSeason1.estTr, null); - expect(furry.tlSeason1.esttracc, null); - expect(furry.tlSeason1.playstyle, null); - }); - test("oskwarefan (anon account)", () async { - TetrioPlayer oskwarefan = await teto.fetchPlayer("646cb8273e887a054d64febe"); - expect(oskwarefan.userId, "646cb8273e887a054d64febe"); - expect(oskwarefan.registrationTime, DateTime.parse("2023-05-23T12:57:11.481Z")); - expect(oskwarefan.role, "anon"); - expect(oskwarefan.xp > 0, true); - expect(oskwarefan.gamesPlayed > -1, true); - expect(oskwarefan.gamesWon > -1, true); - expect(oskwarefan.gameTime.isNegative, false); - expect(oskwarefan.country, null); - expect(oskwarefan.verified, false); - expect(oskwarefan.connections, null); - expect(oskwarefan.friendCount, 0); - expect(oskwarefan.tlSeason1.glicko, null); - expect(oskwarefan.tlSeason1.rank, "z"); - expect(oskwarefan.tlSeason1.percentileRank, "z"); - expect(oskwarefan.tlSeason1.rating, -1); - expect(oskwarefan.tlSeason1.decaying, true); // ??? why true? - expect(oskwarefan.tlSeason1.gamesPlayed, 0); - expect(oskwarefan.tlSeason1.gamesWon, 0); - expect(oskwarefan.tlSeason1.standing, -1); - expect(oskwarefan.tlSeason1.standingLocal, -1); - expect(oskwarefan.tlSeason1.apm, null); - expect(oskwarefan.tlSeason1.pps, null); - expect(oskwarefan.tlSeason1.vs, null); - expect(oskwarefan.tlSeason1.nerdStats, null); - expect(oskwarefan.tlSeason1.estTr, null); - expect(oskwarefan.tlSeason1.esttracc, null); - expect(oskwarefan.tlSeason1.playstyle, null); - }); +// group("Test fetchPlayer with different players", () { +// // those tests exist in order to detect a tiny little change in Tetra Channel API in case of some update. +// test("dan63047 (user who have activity in tetra league)", () async { +// TetrioPlayer dan63047 = await teto.fetchPlayer("6098518e3d5155e6ec429cdc"); +// expect(dan63047.userId, "6098518e3d5155e6ec429cdc"); +// expect(dan63047.registrationTime != null, true); +// expect(dan63047.avatarRevision != null, true); +// expect(dan63047.connections != null, true); +// expect(dan63047.role, "user"); +// expect(dan63047.distinguishment, null); // imagine if that one fails one day lol +// expect(dan63047.tlSeason1.glicko != null, true); +// //expect(dan63047.tlSeason1.rank != "z", true); lol +// expect(dan63047.tlSeason1.percentileRank != "z", true); +// expect(dan63047.tlSeason1.rating > -1, true); +// expect(dan63047.tlSeason1.gamesPlayed > 9, true); +// expect(dan63047.tlSeason1.gamesWon > 0, true); +// //expect(dan63047.tlSeason1.standing, -1); +// //expect(dan63047.tlSeason1.standingLocal, -1); +// expect(dan63047.tlSeason1.apm != null, true); +// expect(dan63047.tlSeason1.pps != null, true); +// expect(dan63047.tlSeason1.vs != null, true); +// expect(dan63047.tlSeason1.nerdStats != null, true); +// expect(dan63047.tlSeason1.estTr != null, true); +// expect(dan63047.tlSeason1.esttracc != null, true); +// expect(dan63047.tlSeason1.playstyle != null, true); +// }); +// test("osk (sysop who have activity in tetra league)", () async { +// TetrioPlayer osk = await teto.fetchPlayer("5e32fc85ab319c2ab1beb07c"); +// expect(osk.userId, "5e32fc85ab319c2ab1beb07c"); +// expect(osk.registrationTime, null); +// expect(osk.country, "XM"); +// expect(osk.avatarRevision != null, true); +// expect(osk.bannerRevision != null, true); +// expect(osk.connections != null, true); +// expect(osk.verified, true); +// expect(osk.role, "sysop"); +// expect(osk.distinguishment != null, true); +// expect(osk.tlSeason1.glicko != null, true); +// expect(osk.tlSeason1.glicko != null, true); +// expect(osk.tlSeason1.rank == "z", true); +// expect(osk.tlSeason1.percentileRank != "z", true); +// expect(osk.tlSeason1.rating > -1, true); +// expect(osk.tlSeason1.gamesPlayed > 9, true); +// expect(osk.tlSeason1.gamesWon > 0, true); +// expect(osk.tlSeason1.standing, -1); +// expect(osk.tlSeason1.standingLocal, -1); +// expect(osk.tlSeason1.apm != null, true); +// expect(osk.tlSeason1.pps != null, true); +// expect(osk.tlSeason1.vs != null, true); +// expect(osk.tlSeason1.nerdStats != null, true); +// expect(osk.tlSeason1.estTr != null, true); +// expect(osk.tlSeason1.esttracc != null, true); +// expect(osk.tlSeason1.playstyle != null, true); +// }); +// test("kagari (sysop who have zero activity)", () async { +// TetrioPlayer kagari = await teto.fetchPlayer("5e331c3ce24a5a3e258f7a1b"); +// expect(kagari.userId, "5e331c3ce24a5a3e258f7a1b"); +// expect(kagari.registrationTime, null); +// expect(kagari.country, "XM"); +// expect(kagari.xp, 0); +// expect(kagari.gamesPlayed, -1); +// expect(kagari.gamesWon, -1); +// expect(kagari.gameTime, const Duration(seconds: -1)); +// expect(kagari.avatarRevision != null, true); +// expect(kagari.bannerRevision != null, true); +// expect(kagari.connections, null); +// expect(kagari.verified, true); +// expect(kagari.distinguishment != null, true); +// expect(kagari.distinguishment!.detail, "kagarin"); +// expect(kagari.friendCount, 1); +// expect(kagari.tlSeason1.glicko, null); +// expect(kagari.tlSeason1.rank, "z"); +// expect(kagari.tlSeason1.percentileRank, "z"); +// expect(kagari.tlSeason1.rating, -1); +// expect(kagari.tlSeason1.decaying, false); +// expect(kagari.tlSeason1.gamesPlayed, 0); +// expect(kagari.tlSeason1.gamesWon, 0); +// expect(kagari.tlSeason1.standing, -1); +// expect(kagari.tlSeason1.standingLocal, -1); +// expect(kagari.tlSeason1.apm, null); +// expect(kagari.tlSeason1.pps, null); +// expect(kagari.tlSeason1.vs, null); +// expect(kagari.tlSeason1.nerdStats, null); +// expect(kagari.tlSeason1.estTr, null); +// expect(kagari.tlSeason1.esttracc, null); +// expect(kagari.tlSeason1.playstyle, null); +// }); +// test("furry (banned account)", () async { +// TetrioPlayer furry = await teto.fetchPlayer("5eea0ff69a1ba76c20347086"); +// expect(furry.userId, "5eea0ff69a1ba76c20347086"); +// expect(furry.registrationTime, DateTime.parse("2020-06-17T12:43:34.790Z")); +// expect(furry.role, "banned"); +// expect(furry.badges.isEmpty, true); +// expect(furry.badstanding, false); +// expect(furry.xp, 0); +// expect(furry.supporterTier, 0); +// expect(furry.verified, false); +// expect(furry.connections, null); +// expect(furry.gamesPlayed, 0); +// expect(furry.gamesWon, 0); +// expect(furry.gameTime, Duration.zero); +// expect(furry.tlSeason1.glicko, null); +// expect(furry.tlSeason1.rank, "z"); +// expect(furry.tlSeason1.percentileRank, "z"); +// expect(furry.tlSeason1.rating, -1); +// expect(furry.tlSeason1.decaying, false); +// expect(furry.tlSeason1.gamesPlayed, 0); +// expect(furry.tlSeason1.gamesWon, 0); +// expect(furry.tlSeason1.standing, -1); +// expect(furry.tlSeason1.standingLocal, -1); +// expect(furry.tlSeason1.apm, null); +// expect(furry.tlSeason1.pps, null); +// expect(furry.tlSeason1.vs, null); +// expect(furry.tlSeason1.nerdStats, null); +// expect(furry.tlSeason1.estTr, null); +// expect(furry.tlSeason1.esttracc, null); +// expect(furry.tlSeason1.playstyle, null); +// }); +// test("oskwarefan (anon account)", () async { +// TetrioPlayer oskwarefan = await teto.fetchPlayer("646cb8273e887a054d64febe"); +// expect(oskwarefan.userId, "646cb8273e887a054d64febe"); +// expect(oskwarefan.registrationTime, DateTime.parse("2023-05-23T12:57:11.481Z")); +// expect(oskwarefan.role, "anon"); +// expect(oskwarefan.xp > 0, true); +// expect(oskwarefan.gamesPlayed > -1, true); +// expect(oskwarefan.gamesWon > -1, true); +// expect(oskwarefan.gameTime.isNegative, false); +// expect(oskwarefan.country, null); +// expect(oskwarefan.verified, false); +// expect(oskwarefan.connections, null); +// expect(oskwarefan.friendCount, 0); +// expect(oskwarefan.tlSeason1.glicko, null); +// expect(oskwarefan.tlSeason1.rank, "z"); +// expect(oskwarefan.tlSeason1.percentileRank, "z"); +// expect(oskwarefan.tlSeason1.rating, -1); +// expect(oskwarefan.tlSeason1.decaying, true); // ??? why true? +// expect(oskwarefan.tlSeason1.gamesPlayed, 0); +// expect(oskwarefan.tlSeason1.gamesWon, 0); +// expect(oskwarefan.tlSeason1.standing, -1); +// expect(oskwarefan.tlSeason1.standingLocal, -1); +// expect(oskwarefan.tlSeason1.apm, null); +// expect(oskwarefan.tlSeason1.pps, null); +// expect(oskwarefan.tlSeason1.vs, null); +// expect(oskwarefan.tlSeason1.nerdStats, null); +// expect(oskwarefan.tlSeason1.estTr, null); +// expect(oskwarefan.tlSeason1.esttracc, null); +// expect(oskwarefan.tlSeason1.playstyle, null); +// }); - test("not existing account", () async { - var future = teto.fetchPlayer("hasdbashdbs"); - await expectLater(future, throwsA(isA())); - }); - }); -} \ No newline at end of file +// test("not existing account", () async { +// var future = teto.fetchPlayer("hasdbashdbs"); +// await expectLater(future, throwsA(isA())); +// }); +// }); +// } \ No newline at end of file